// returns true if successful, false otherwise bool MsdFile::ReadFile( CString sNewPath ) { error = ""; RageFile f; /* Open a file. */ if( !f.Open( sNewPath ) ) { error = f.GetError(); return false; } // allocate a string to hold the file CString FileString; FileString.reserve( f.GetFileSize() ); int iBytesRead = f.Read( FileString ); if( iBytesRead == -1 ) { error = f.GetError(); return false; } ReadBuf( (char*) FileString.c_str(), iBytesRead ); return true; }
CString CMSWindowsClipboardAnyTextConverter::convertLinefeedToUnix( const CString& src) const { // count newlines in string UInt32 numNewlines = 0; UInt32 n = (UInt32)src.size(); for (const char* scan = src.c_str(); n > 0; ++scan, --n) { if (scan[0] == '\r' && scan[1] == '\n') { ++numNewlines; } } if (numNewlines == 0) { return src; } // allocate new string CString dst; dst.reserve(src.size()); // copy string, converting newlines n = (UInt32)src.size(); for (const char* scan = src.c_str(); n > 0; ++scan, --n) { if (scan[0] != '\r' || scan[1] != '\n') { dst += scan[0]; } } return dst; }
void SongUtil::SortSongPointerArrayByGrade( vector<Song*> &arraySongPointers ) { /* Optimize by pre-writing a string to compare, since doing GetNumNotesWithGrade * inside the sort is too slow. */ typedef pair< Song *, CString > val; vector<val> vals; vals.reserve( arraySongPointers.size() ); unsigned i; for( i = 0; i < arraySongPointers.size(); ++i ) { Song *pSong = arraySongPointers[i]; int iCounts[NUM_GRADES]; PROFILEMAN->GetMachineProfile()->GetGrades( pSong, GAMESTATE->GetCurrentStyle()->m_StepsType, iCounts ); CString foo; foo.reserve(256); for( int g=GRADE_TIER_1; g<=GRADE_NO_DATA; ++g ) AppendOctal( iCounts[g], 3, foo ); vals.push_back( val(pSong, foo) ); } sort( vals.begin(), vals.end(), CompDescending ); for( i = 0; i < arraySongPointers.size(); ++i ) arraySongPointers[i] = vals[i].first; }
CString CMSWindowsClipboardAnyTextConverter::convertLinefeedToWin32( const CString& src) const { // note -- we assume src is a valid UTF-8 string // count newlines in string UInt32 numNewlines = 0; UInt32 n = (UInt32)src.size(); for (const char* scan = src.c_str(); n > 0; ++scan, --n) { if (*scan == '\n') { ++numNewlines; } } if (numNewlines == 0) { return src; } // allocate new string CString dst; dst.reserve(src.size() + numNewlines); // copy string, converting newlines n = (UInt32)src.size(); for (const char* scan = src.c_str(); n > 0; ++scan, --n) { if (scan[0] == '\n') { dst += '\r'; } dst += scan[0]; } return dst; }
int RageFile::Read( CString &buffer, int bytes ) { buffer.erase( buffer.begin(), buffer.end() ); buffer.reserve( bytes != -1? bytes: this->GetFileSize() ); int ret = 0; char buf[4096]; while( bytes == -1 || ret < bytes ) { int ToRead = sizeof(buf); if( bytes != -1 ) ToRead = min( ToRead, bytes-ret ); const int got = Read( buf, ToRead ); if( got == 0 ) break; if( got == -1 ) return -1; buffer.append( buf, got ); ret += got; } return ret; }
int RageFileObj::Read( CString &sBuffer, int iBytes ) { sBuffer.erase( sBuffer.begin(), sBuffer.end() ); sBuffer.reserve( iBytes != -1? iBytes: this->GetFileSize() ); int iRet = 0; char buf[4096]; while( iBytes == -1 || iRet < iBytes ) { int ToRead = sizeof(buf); if( iBytes != -1 ) ToRead = min( ToRead, iBytes-iRet ); const int iGot = Read( buf, ToRead ); if( iGot == 0 ) break; if( iGot == -1 ) return -1; sBuffer.append( buf, iGot ); iRet += iGot; } return iRet; }
bool IKeyState::CKeyInfo::contains(const char* screens, const CString& name) { // special cases if (isDefault(screens)) { return false; } if (screens[0] == '*') { return true; } // search CString match; match.reserve(name.size() + 2); match += ":"; match += name; match += ":"; return (strstr(screens, match.c_str()) != NULL); }
CString IClipboard::marshall(const IClipboard* clipboard) { assert(clipboard != NULL); CString data; std::vector<CString> formatData; formatData.resize(IClipboard::kNumFormats); // FIXME -- use current time clipboard->open(0); // compute size of marshalled data UInt32 size = 4; UInt32 numFormats = 0; for (UInt32 format = 0; format != IClipboard::kNumFormats; ++format) { if (clipboard->has(static_cast<IClipboard::EFormat>(format))) { ++numFormats; formatData[format] = clipboard->get(static_cast<IClipboard::EFormat>(format)); size += 4 + 4 + (UInt32)formatData[format].size(); } } // allocate space data.reserve(size); // marshall the data writeUInt32(&data, numFormats); for (UInt32 format = 0; format != IClipboard::kNumFormats; ++format) { if (clipboard->has(static_cast<IClipboard::EFormat>(format))) { writeUInt32(&data, format); writeUInt32(&data, (UInt32)formatData[format].size()); data += formatData[format]; } } clipboard->close(); return data; }
void FormatLogMessage(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage, CString& output) { #if 1 output.Empty(); output.Preallocate(1024); if (type != eLM_DirectOutput) { output += pszDate; output += _T(' '); output += pszTime; #if defined(LOG_THREAD_NAME) output += _T(" ["); output += pszThreadId; output += _T(":"); size_t nThreadNameLen = _tcslen(pszThreadName); if (nThreadNameLen > 12) output.append(pszThreadName, 12); else { output.append(12 - nThreadNameLen, _T(' ')); output += pszThreadName; } output += _T("] "); #else output += _T(" "); #endif switch (type) { case eLM_Info: output += _T('I'); break; case eLM_Debug: output += _T('-'); break; case eLM_Warning: output += _T('W'); break; case eLM_Error: output += _T('E'); break; default: ASSERT(false); } if (nLevel>0) output.AppendFormat(_T("%i"), nLevel); else output += _T(' '); #if 0 output += _T(" : ["); output += pszModule; output += _T("] "); #else output += _T(" : "); #endif } output += pszMessage; output.TrimRight(); #else output.Empty(); output.reserve(1024); output += pszDate; output += _T(' '); output += pszTime; output += _T("\t"); output += pszThreadId; output += _T("\t"); output += pszThreadName; output += _T("\t"); output += pszModule; output += _T("\t"); switch (type) { case eLM_Info: output += _T("Inf"); break; case eLM_Debug: output += _T("Dbg"); break; case eLM_Warning: output += _T("Wrn"); break; case eLM_Error: output += _T("Err"); break; default: ASSERT(false); } if (nLevel>0) output.AppendFormat(_T("%i"), nLevel); output += _T('\t'); output += pszMessage; output.TrimRight(); #endif }
CString CString::Escape_n(EEscape eFrom, EEscape eTo) const { CString sRet; const char szHex[] = "0123456789ABCDEF"; const unsigned char *pStart = (const unsigned char*) data(); const unsigned char *p = (const unsigned char*) data(); size_type iLength = length(); sRet.reserve(iLength *3); unsigned char pTmp[21]; unsigned int iCounted = 0; for (unsigned int a = 0; a < iLength; a++, p = pStart + a) { unsigned char ch = 0; switch (eFrom) { case EHTML: if ((*p == '&') && (strnchr((unsigned char*) p, ';', sizeof(pTmp) - 1, pTmp, &iCounted))) { // please note that we do not have any Unicode or UTF-8 support here at all. if ((iCounted >= 3) && (pTmp[1] == '#')) { // do XML and HTML a < int base = 10; if ((pTmp[2] & 0xDF) == 'X') { base = 16; } char* endptr = NULL; unsigned long int b = strtol((const char*) (pTmp +2 + (base == 16)), &endptr, base); if ((*endptr == ';') && (b <= 255)) { // incase they do something like � ch = (unsigned char)b; a += iCounted; break; } } if (ch == 0) { if (!strncasecmp((const char*) &pTmp, "<", 2)) ch = '<'; else if (!strncasecmp((const char*) &pTmp, ">", 2)) ch = '>'; else if (!strncasecmp((const char*) &pTmp, """, 4)) ch = '"'; else if (!strncasecmp((const char*) &pTmp, "&", 3)) ch = '&'; } if (ch > 0) { a += iCounted; } else { ch = *p; // Not a valid escape, just record the & } } else { ch = *p; } break; case EASCII: ch = *p; break; case EURL: if (*p == '%' && (a +2) < iLength && isxdigit(*(p +1)) && isxdigit(*(p +2))) { p++; if (isdigit(*p)) { ch = (unsigned char)((*p - '0') << 4); } else { ch = (unsigned char)((tolower(*p) - 'a' +10) << 4); } p++; if (isdigit(*p)) { ch |= (unsigned char)(*p - '0'); } else { ch |= (unsigned char)(tolower(*p) - 'a' +10); } a += 2; } else if (pStart[a] == '+') { ch = ' '; } else { ch = *p; } break; case ESQL: if (*p != '\\' || iLength < (a +1)) { ch = *p; } else { a++; p++; if (*p == 'n') { ch = '\n'; } else if (*p == 'r') { ch = '\r'; } else if (*p == '0') { ch = '\0'; } else if (*p == 't') { ch = '\t'; } else if (*p == 'b') { ch = '\b'; } else { ch = *p; } } break; case ENAMEDFMT: if (*p != '\\' || iLength < (a +1)) { ch = *p; } else { a++; p++; ch = *p; } break; case EDEBUG: if (*p == '\\' && (a +3) < iLength && *(p +1) == 'x' && isxdigit(*(p +2)) && isxdigit(*(p +3))) { p += 2; if (isdigit(*p)) { ch = (unsigned char)((*p - '0') << 4); } else { ch = (unsigned char)((tolower(*p) - 'a' +10) << 4); } p++; if (isdigit(*p)) { ch |= (unsigned char)(*p - '0'); } else { ch |= (unsigned char)(tolower(*p) - 'a' +10); } a += 3; } else if (*p == '\\' && a+1 < iLength && *(p+1) == '.') { a++; p++; ch = '\\'; } else { ch = *p; } } switch (eTo) { case EHTML: if (ch == '<') sRet += "<"; else if (ch == '>') sRet += ">"; else if (ch == '"') sRet += """; else if (ch == '&') sRet += "&"; else { sRet += ch; } break; case EASCII: sRet += ch; break; case EURL: if (isalnum(ch) || ch == '_' || ch == '.' || ch == '-') { sRet += ch; } else if (ch == ' ') { sRet += '+'; } else { sRet += '%'; sRet += szHex[ch >> 4]; sRet += szHex[ch & 0xf]; } break; case ESQL: if (ch == '\0') { sRet += '\\'; sRet += '0'; } else if (ch == '\n') { sRet += '\\'; sRet += 'n'; } else if (ch == '\t') { sRet += '\\'; sRet += 't'; } else if (ch == '\r') { sRet += '\\'; sRet += 'r'; } else if (ch == '\b') { sRet += '\\'; sRet += 'b'; } else if (ch == '\"') { sRet += '\\'; sRet += '\"'; } else if (ch == '\'') { sRet += '\\'; sRet += '\''; } else if (ch == '\\') { sRet += '\\'; sRet += '\\'; } else { sRet += ch; } break; case ENAMEDFMT: if (ch == '\\') { sRet += '\\'; sRet += '\\'; } else if (ch == '{') { sRet += '\\'; sRet += '{'; } else if (ch == '}') { sRet += '\\'; sRet += '}'; } else { sRet += ch; } break; case EDEBUG: if (ch < 0x20 || ch == 0x7F) { sRet += "\\x"; sRet += szHex[ch >> 4]; sRet += szHex[ch & 0xf]; } else if (ch == '\\') { sRet += "\\."; } else { sRet += ch; } break; }
bool CXWindowsClipboard::sendReply(CReply* reply) { assert(reply != NULL); // bail out immediately if reply is done if (reply->m_done) { LOG((CLOG_DEBUG1 "clipboard: finished reply to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property)); return true; } // start in failed state if property is None bool failed = (reply->m_property == None); if (!failed) { LOG((CLOG_DEBUG1 "clipboard: setting property on 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property)); // send using INCR if already sending incrementally or if reply // is too large, otherwise just send it. const UInt32 maxRequestSize = 3 * XMaxRequestSize(m_display); const bool useINCR = (reply->m_data.size() > maxRequestSize); // send INCR reply if incremental and we haven't replied yet if (useINCR && !reply->m_replied) { UInt32 size = reply->m_data.size(); if (!CXWindowsUtil::setWindowProperty(m_display, reply->m_requestor, reply->m_property, &size, 4, m_atomINCR, 32)) { failed = true; } } // send more INCR reply or entire non-incremental reply else { // how much more data should we send? UInt32 size = reply->m_data.size() - reply->m_ptr; if (size > maxRequestSize) size = maxRequestSize; // send it if (!CXWindowsUtil::setWindowProperty(m_display, reply->m_requestor, reply->m_property, reply->m_data.data() + reply->m_ptr, size, reply->m_type, reply->m_format)) { failed = true; } else { reply->m_ptr += size; // we've finished the reply if we just sent the zero // size incremental chunk or if we're not incremental. reply->m_done = (size == 0 || !useINCR); } } } // if we've failed then delete the property and say we're done. // if we haven't replied yet then we can send a failure notify, // otherwise we've failed in the middle of an incremental // transfer; i don't know how to cancel that so i'll just send // the final zero-length property. // FIXME -- how do you gracefully cancel an incremental transfer? if (failed) { LOG((CLOG_DEBUG1 "clipboard: sending failure to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property)); reply->m_done = true; if (reply->m_property != None) { CXWindowsUtil::CErrorLock lock(m_display); XDeleteProperty(m_display, reply->m_requestor, reply->m_property); } if (!reply->m_replied) { sendNotify(reply->m_requestor, m_selection, reply->m_target, None, reply->m_time); // don't wait for any reply (because we're not expecting one) return true; } else { static const char dummy = 0; CXWindowsUtil::setWindowProperty(m_display, reply->m_requestor, reply->m_property, &dummy, 0, reply->m_type, reply->m_format); // wait for delete notify return false; } } // send notification if we haven't yet if (!reply->m_replied) { LOG((CLOG_DEBUG1 "clipboard: sending notify to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property)); reply->m_replied = true; // dump every property on the requestor window to the debug2 // log. we've seen what appears to be a bug in lesstif and // knowing the properties may help design a workaround, if // it becomes necessary. if (CLOG->getFilter() >= CLog::kDEBUG2) { CXWindowsUtil::CErrorLock lock(m_display); int n; Atom* props = XListProperties(m_display, reply->m_requestor, &n); LOG((CLOG_DEBUG2 "properties of 0x%08x:", reply->m_requestor)); for (int i = 0; i < n; ++i) { Atom target; CString data; char* name = XGetAtomName(m_display, props[i]); if (!CXWindowsUtil::getWindowProperty(m_display, reply->m_requestor, props[i], &data, &target, NULL, False)) { LOG((CLOG_DEBUG2 " %s: <can't read property>", name)); } else { // if there are any non-ascii characters in string // then print the binary data. static const char* hex = "0123456789abcdef"; for (CString::size_type j = 0; j < data.size(); ++j) { if (data[j] < 32 || data[j] > 126) { CString tmp; tmp.reserve(data.size() * 3); for (j = 0; j < data.size(); ++j) { unsigned char v = (unsigned char)data[j]; tmp += hex[v >> 16]; tmp += hex[v & 15]; tmp += ' '; } data = tmp; break; } } char* type = XGetAtomName(m_display, target); LOG((CLOG_DEBUG2 " %s (%s): %s", name, type, data.c_str())); if (type != NULL) { XFree(type); } } if (name != NULL) { XFree(name); } }
CString CStringUtil::vformat(const char* fmt, va_list args) { // find highest indexed substitution and the locations of substitutions std::vector<size_t> pos; std::vector<size_t> width; std::vector<int> index; int maxIndex = 0; for (const char* scan = fmt; *scan != '\0'; ++scan) { if (*scan == '%') { ++scan; if (*scan == '\0') { break; } else if (*scan == '%') { // literal index.push_back(0); pos.push_back(static_cast<int>(scan - 1 - fmt)); width.push_back(2); } else if (*scan == '{') { // get argument index char* end; int i = static_cast<int>(strtol(scan + 1, &end, 10)); if (*end != '}') { // invalid index -- ignore scan = end - 1; } else { index.push_back(i); pos.push_back(static_cast<int>(scan - 1 - fmt)); width.push_back(static_cast<int>(end - scan + 2)); if (i > maxIndex) { maxIndex = i; } scan = end; } } else { // improper escape -- ignore } } } // get args std::vector<const char*> value; std::vector<size_t> length; value.push_back("%"); length.push_back(1); for (int i = 0; i < maxIndex; ++i) { const char* arg = va_arg(args, const char*); size_t len = strlen(arg); value.push_back(arg); length.push_back(len); } // compute final length size_t resultLength = strlen(fmt); const int n = static_cast<int>(pos.size()); for (int i = 0; i < n; ++i) { resultLength -= width[i]; resultLength += length[index[i]]; } // substitute CString result; result.reserve(resultLength); size_t src = 0; for (int i = 0; i < n; ++i) { result.append(fmt + src, pos[i] - src); result.append(value[index[i]]); src = pos[i] + width[i]; } result.append(fmt + src); return result; }
// Strip special controle char, like color, bold, ... CString CLogMod::Sanitize(const CString& sLine) { unsigned int i,l; // Color codes format (regex): \x03([0-9]{1,2}(,[0-9]{1,2})?)? // e: escape, if true, we have met an escape char (\x03) and are still striping. bool e; // c: comma, if we passed the comma yet or not bool c; // d: the number of digits we already striped (maximum 2 each time) unsigned int d=0; CString sRet; l = sLine.length(); sRet.reserve(l); e=false; d=0; c=false; for(i=0; i<l; i++) { unsigned char ch = sLine[i]; switch (ch) { case '\x02': // Bold case '\x0f': // Reset case '\x12': // Reverse Color case '\x15': // Underline case '\x16': // Reverse case '\x1D': // Italic case '\x1f': // Underline continue; case '\x03': // Color e=true; d=0; c=false; continue; case ',': if (e) { if(!c && d>0) { c=true; d=0; continue; } } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (e && d <2) { d++; continue; } default: e=false; sRet += ch; } } sRet.reserve(0); return sRet; }