/** * * Determine if a substring is the "documentElement" in the document. * * All of our sniffed substrings: <rss, <feed, <rdf:RDF must be the "document" * element within the XML DOM, i.e. the root container element. Otherwise, * it's possible that someone embedded one of these tags inside a document of * another type, e.g. a HTML document, and we don't want to show the preview * page if the document isn't actually a feed. * * @param start * The beginning of the data being sniffed * @param end * The end of the data being sniffed, right before the substring that * was found. * @returns true if the found substring is the documentElement, false * otherwise. */ static bool IsDocumentElement(const char *start, const char* end) { // For every tag in the buffer, check to see if it's a PI, Doctype or // comment, our desired substring or something invalid. while ( (start = FindChar('<', start, end)) ) { ++start; if (start >= end) return false; // Check to see if the character following the '<' is either '?' or '!' // (processing instruction or doctype or comment)... these are valid nodes // to have in the prologue. if (*start != '?' && *start != '!') return false; // Now advance the iterator until the '>' (We do this because we don't want // to sniff indicator substrings that are embedded within other nodes, e.g. // comments: <!-- <rdf:RDF .. > --> start = FindChar('>', start, end); if (!start) return false; ++start; } return true; }
/** * @brief Split the command line into its parts * @author R.Lillback * @date 1-Sep-2015 * * @details This function uses my strings.c FindChar and GetSubString functions. * It splits the command line into 2 components. The syntax of a command is * COMMAND SUBCOMMAND * where COMMAND = Text * and SUBCOMMAND = a Number * * the subcommand is returned as an integer result from this function * * @param strCommand = pointer to the input buffer * @param strMainCmd = pointer to the main command buffer * @param strSubCmdOne = pointer to the text subcommand buffer * * @returns the integer value of the sub command, if any. If none, it returns 0. * */ int ParseCommands(char* strCommand, char strMainCmd[], char strSubCmdOne[]) { int iSpaceOne; // String location of the first space int iEnd; // String location of the end of the command int i; int iSubCmdOne; iSpaceOne = FindChar(' ', strCommand, 0); // Find the first space iEnd = FindChar('\0', strCommand, 0); // Get the end of line if (iSpaceOne > 0) { GetSubstring(0, iSpaceOne-1, strCommand, strMainCmd); // Get main command GetSubstring(iSpaceOne+1, iEnd, strCommand, strSubCmdOne); // Get sub command iSubCmdOne = StrToInt(strSubCmdOne); // Convert sub command to a number } else // No space, so just have one command { for (i=0; i<MAX_INPUT_LINE_LEN; i++) strMainCmd[i] = strCommand[i]; // we just have a single command for (i=0; i<MAX_INPUT_LINE_LEN; i++) strSubCmdOne[i] = '\0'; // Sub-command is blank iSubCmdOne = 0; } return iSubCmdOne; } // ParseCommands
char* MiniApache::ExtractRequestPath(){ int rlen = strlen(_HTTP_request); int start = FindChar(_HTTP_request, ' ', 0, rlen) + 1; int end = FindChar(_HTTP_request, '?', start, rlen); if (end == -1){ end = FindChar(_HTTP_request, ' ', start, rlen); } char * retVal = SubStr(_HTTP_request, start, end); return retVal; // Remember to delete [] retVal to not leak memory }
char* MiniApache::ExtractRequestData(){ int rlen = strlen(_HTTP_request); int start = FindChar(_HTTP_request, '?', 0, rlen) + 1; int end = FindChar(_HTTP_request, ' ', start, rlen); if (start == 0){ start = end; } char * retVal = SubStr(_HTTP_request, start, end); // extract GET data return retVal; // Remember to delete [] retVal to not leak memory }
bool Decode(const Platform::String& source, Platform::String& result) { int index = 0; Platform::String::Iterator iterator = source.GetIterator(); while(iterator.CanMoveNext()) { Platform::Char ch; Platform::StaticString<8> buffer; switch(TakeMorseWord(iterator, buffer)) { case R_WORD: ch = FindChar(buffer); break; case R_SPACE: ch = ' '; break; case R_EOF: return true; } result[index] = ch; index++; } return true; }
/* This routine extracts tokens from a string that are separated by one or more spaces. It returns the number of tokens found. */ int tokenize(char *ptr, char *tokens[]) { int num = 0; while (*ptr) { ptr = SkipChar(ptr, ' '); if (*ptr == 0) break; if (ptr[0] == '>') { ptr++; if (ptr[0] == '>') { tokens[num++] = ">>"; ptr++; } else tokens[num++] = ">"; continue; } if (ptr[0] == '<') { ptr++; tokens[num++] = "<"; continue; } tokens[num++] = ptr; ptr = FindChar(ptr, ' '); if (*ptr) *ptr++ = 0; } return num; }
char* MiniApache::GetGETVariable(char * name){ char * varp = JoinStr(name, "="); int dlen = strlen(GET_data); int vlen = strlen(varp); int start = -1; char * sub; for (int i = 0; i < dlen; i++) { // Find variable sub = SubStr(GET_data, i, i + vlen); if (strcmp(varp, sub) == 0 && (i == 0 || GET_data[i-1] == '&')) { start = i + vlen; delete [] sub; break; } delete [] sub; } if (start == -1) { start = dlen; } int end = FindChar(GET_data, '&', start, dlen); if (end == -1) { end = dlen; } delete [] varp; char * retVal = SubStr(GET_data, start, end); return retVal; // Remember to delete [] retVal to not leak memory }
size_t CCharRefArray::AttachChar( const CChar *pChar ) { ADDTOCALLSTACK("CCharRefArray::AttachChar"); size_t i = FindChar(pChar); if ( i != m_uidCharArray.BadIndex() ) return i; return m_uidCharArray.Add(pChar->GetUID()); }
size_t CCharRefArray::DetachChar( const CChar *pChar ) { ADDTOCALLSTACK("CCharRefArray::DetachChar"); size_t i = FindChar(pChar); if ( i != m_uidCharArray.BadIndex() ) DetachChar(i); return i; }
bool FileList::Key(dword key, int count) { if(key == K_ESCAPE && IsEdit()) { EndEdit(); return true; } if(key == K_ENTER && IsEdit()) { OkEdit(); return true; } if(accelkey) { int c = ToUpper((int)key); if(key < 256 && IsAlNum(c)) { if(!FindChar(GetCursor() + 1, c)) FindChar(0, c); return true; } } return ColumnList::Key(key, count); }
int FindString(FILE *f,char *y) { int indic=0; do { if (FindChar(f,y[indic])) { if (indic) return 1; else return 2; } indic++; } while (y[indic]!='\0'); return 0; }
void String::TruncateToLeftSection(char separator, bool exclude_separator) { if (_meta && separator) { size_t slice_at = FindChar(separator); if (slice_at != -1) { TruncateToLeft(exclude_separator ? slice_at : slice_at + 1); } } }
bool String::FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, size_t &from, size_t &to) const { if (!_meta || !separator) { return false; } if (first > last) { return false; } size_t this_field = 0; size_t slice_from = 0; size_t slice_to = _meta->Length; size_t slice_at = -1; do { slice_at = FindChar(separator, slice_at + 1); if (slice_at == -1) slice_at = _meta->Length; // found where previous field ends if (this_field == last) { // if previous field is the last one to be included, // then set the section tail slice_to = exclude_last_sep ? slice_at : slice_at + 1; } if (slice_at != _meta->Length) { this_field++; if (this_field == first) { // if the new field is the first one to be included, // then set the section head slice_from = exclude_first_sep ? slice_at + 1 : slice_at; } } } while (slice_at < _meta->Length && this_field <= last); // the search is a success if at least the first field was found if (this_field >= first) { // correct the indices to stay in the [0; length] range assert(slice_from <= slice_to); from = Math::Clamp((size_t)0, _meta->Length, slice_from); to = Math::Clamp((size_t)0, _meta->Length, slice_to); return true; } return false; }
// Extract leftmost part, separated by the given char String String::LeftSection(char separator, bool exclude_separator) const { if (_meta && separator) { int slice_at = FindChar(separator); if (slice_at >= 0) { slice_at = exclude_separator ? slice_at : slice_at + 1; return Left(slice_at + 1); } } return String(); }
inline char DecodeHalf(short s) const { IMatrix r; #ifdef DEBUG cout << "Half word to decode: "; Print(s, 8); #endif MatrixProduct(ScanChar(s), hm, r); #ifdef DEBUG cout << "Product Vector: "; PrintArray(r[0]); #endif return FindChar(r[0]); }
void String::ClipLeftSection(char separator, bool include_separator) { if (_meta && separator) { size_t slice_at = FindChar(separator); if (slice_at != -1) { ClipLeft(include_separator ? slice_at + 1 : slice_at); } else Empty(); } }
String String::LeftSection(char separator, bool exclude_separator) const { if (_meta && separator) { size_t slice_at = FindChar(separator); if (slice_at != -1) { slice_at = exclude_separator ? slice_at : slice_at + 1; return Left(slice_at); } } return *this; }
bool String::FindSection(char separator, int first, int last, bool exclude_first_sep, bool exclude_last_sep, int &from, int &to) const { if (!_meta || !separator) { return false; } int slice_from = -1; int slice_to = _meta->Length; int slice_at = -1; int sep_count = 0; do { slice_at = FindChar(separator, slice_at + 1); if (slice_at < 0) { break; } sep_count++; if (sep_count == first) { slice_from = exclude_first_sep ? slice_at + 1 : slice_at; if (slice_to < _meta->Length) { break; } } if (sep_count == last) { slice_to = exclude_last_sep ? slice_at - 1 : slice_at; if (slice_from >= 0) { break; } } } while (slice_at < _meta->Length); from = slice_from; to = slice_to; if ((slice_from >= 0 || slice_to < _meta->Length) && slice_from <= slice_to && first <= last) { slice_from = slice_from >= 0 ? slice_from : 0; slice_to = slice_to < _meta->Length ? slice_to : _meta->Length - 1; return true; } return false; }
BOOL CFileUtil::IsAbsolutePath(char* szPathName) { char* pcPos; pcPos = FindChar(szPathName, FILE_SEPARATOR[0]); if (pcPos == szPathName) { return TRUE; } else { return FALSE; } }
VOID CFile::NextLine() { DWORD_PTR totalBufLen = GetBufferInWCharLength(); if (totalBufLen == 0) { goto SetEOF; } const WCHAR *pwch = GetBufferInWChar(); DWORD_PTR indexTrace = 0; // in char if (FindChar(L'\r', pwch, totalBufLen, &indexTrace) != S_OK) { goto SetEOF; } if (indexTrace >= DWORD_MAX -1) { goto SetEOF; } indexTrace++; // skip CR totalBufLen -= indexTrace; if (totalBufLen == 0) { goto SetEOF; } if (pwch[indexTrace] != L'\n') { _filePosPointer += (indexTrace * sizeof(WCHAR)); return; } indexTrace++; totalBufLen--; if (totalBufLen == 0) { goto SetEOF; } _filePosPointer += (indexTrace * sizeof(WCHAR)); return; SetEOF: _filePosPointer = _fileSize; return; }
// find start of string, read data until ending quote found, allocate memory and return a string static char * ReadString(FreeImageIO *io, fi_handle handle) { if( !FindChar(io, handle,'"') ) return NULL; BYTE c; std::string s; io->read_proc(&c, sizeof(BYTE), 1, handle); while(c != '"') { s += c; if( io->read_proc(&c, sizeof(BYTE), 1, handle) != 1 ) return NULL; } char *cstr = (char *)malloc(s.length()+1); strcpy(cstr,s.c_str()); return cstr; }
size_t CCharRefArray::InsertChar( const CChar *pChar, size_t i ) { ADDTOCALLSTACK("CCharRefArray::InsertChar"); size_t currentIndex = FindChar(pChar); if ( currentIndex != m_uidCharArray.BadIndex() ) { if ( currentIndex == i ) // already there return i; DetachChar(currentIndex); // remove from list } if ( !IsValidIndex(i) ) // prevent from being inserted too high i = GetCharCount(); m_uidCharArray.InsertAt(i, pChar->GetUID() ); return i; }
static void ReadAnswers(FILE *infile, questionT q) { string line, ans; int len, cpos, nextq, nAnswers; nAnswers = 0; while ((line = ReadLine(infile)) != NULL && (len = StringLength(line)) != 0) { cpos = FindChar(':', line, 0); if (cpos == -1) Error("Illegal answer format"); ans = SubString(line, 0, cpos - 1); nextq = StringToInteger(SubString(line, cpos+1, len-1)); q->answers[nAnswers].ans = ConvertToUpperCase(ans); q->answers[nAnswers].nextq = nextq; nAnswers++; } q->nAnswers = nAnswers; }
BOOL CFileUtil::IsAbsolutePath(const char*szPathName) { const char* szPos; char cDrive; szPos = FindChar(szPathName, FILE_SEPARATOR[0]); if (szPos == szPathName) { return TRUE; } else { cDrive = GetDriveLetter(szPathName); if (cDrive != '\0') { return TRUE; } else { return FALSE; } } }
HttpHeader::ResultEnum HttpHeader::ProcessHeaderData(const char* buffer, size_t length, bool eof) { log_trace(); if (length < startIndex_) { log_warn("Incorrect length=" << length << ", previous start=" << startIndex_); headerResult_ = HEADER_FAULT; } else while (headerResult_ == HEADER_INCOMPLETE) { const char* endLine = FindChar(buffer+startIndex_, length-startIndex_, '\n'); if (endLine == NULL) { if (eof) { log_warn("EOF before header fully parsed"); headerResult_ = HEADER_FAULT; } break; } size_t lineLength = endLine - buffer - startIndex_; if ((lineLength > 0) && (*(endLine-1) == '\r')) lineLength--; std::string line(buffer+startIndex_, lineLength); if (startIndex_ == 0) headerResult_ = ProcessFirstLine(line); else headerResult_ = ProcessLine(line); startIndex_ = endLine - buffer + 1; } return headerResult_; }
static void WINAPI Abbreviate(HDC hdc, int nWidth, LPTSTR lpch, int nMaxChars) { /* string is too long to fit; chop it */ /* set up new prefix & determine remaining space in control */ LPTSTR lpszFileName = NULL; LPTSTR lpszCur = CharNext(CharNext(lpch)); lpszCur = FindChar(lpszCur, TEXT('\\')); // algorithm will insert \... so allocate extra 4 LPTSTR lpszNew = (LPTSTR)OleStdMalloc((lstrlen(lpch)+5) * sizeof(TCHAR)); if (lpszNew == NULL) return; if (lpszCur != NULL) // at least one backslash { *lpszNew = (TCHAR)0; *lpszCur = (TCHAR)0; lstrcpy(lpszNew, lpch); *lpszCur = TEXT('\\'); // lpszNew now contains c: or \\servername lstrcat(lpszNew, TEXT("\\...")); // lpszNew now contains c:\... or \\servername\... LPTSTR lpszEnd = lpszNew; while (*lpszEnd != (TCHAR)0) lpszEnd = CharNext(lpszEnd); // lpszEnd is now at the end of c:\... or \\servername\... // move down directories until it fits or no more directories while (lpszCur != NULL) { *lpszEnd = (TCHAR)0; lstrcat(lpszEnd, lpszCur); if (GetTextWSize(hdc, lpszNew) <= nWidth && lstrlen(lpszNew) < nMaxChars) { lstrcpyn(lpch, lpszNew, nMaxChars); OleStdFree(lpszNew); return; } lpszCur = CharNext(lpszCur); // advance past backslash lpszCur = FindChar(lpszCur, TEXT('\\')); } // try just ...filename and then shortening filename lpszFileName = FindReverseChar(lpch, TEXT('\\')); } else lpszFileName = lpch; while (*lpszFileName != (TCHAR)0) { lstrcpy(lpszNew, TEXT("...")); lstrcat(lpszNew, lpszFileName); if (GetTextWSize(hdc, lpszNew) <= nWidth && lstrlen(lpszNew) < nMaxChars) { lstrcpyn(lpch, lpszNew, nMaxChars); OleStdFree(lpszNew); return; } lpszFileName = CharNext(lpszFileName); } OleStdFree(lpszNew); // not even a single character fit *lpch = (TCHAR)0; }
// ---------------------------------------------------------------------------- void MSW_ProcessMacro::SendMacroString(wxString wsMacro, wxWindow* pWin) // ---------------------------------------------------------------------------- { #ifdef LOGGING wxString msg; msg.Printf(wxT("ProcessMacro:SendMacroString[%s]"), wsMacro.c_str() ); //-WriteLog( msg ); #if defined(LOGGING) LOGIT( _T("[%s]"), msg.c_str()); #endif #endif //LOGGING char macroChar; string::size_type macroStrIndex = 0 ; bool bPreviousCapsLockState = false; long attachError = 0; // Focus window to accept keystrokes // Dont do the following or {ALT} to activate menu won't work //-::SetForegroundWindow( (HWND)pWin->GetHandle()); //-::SetFocus((HWND)pWin->GetHandle()); // Set focus to SU, else HiddenFrame can get focus after menu scans ::SetFocus(g_hWndSketchUp); ::SetForegroundWindow(g_hWndSketchUp); // Memorize CapsLock position if ( m_bCapsLockState == true ) bPreviousCapsLockState = DoKeyToggle(VK_CAPITAL, OFF); // wait for user to stop leaning on the keyboard so we can type in the macro DWORD thisThread = GetCurrentThreadId(); DWORD winThread = GetWindowThreadProcessId( (HWND)(pWin->GetHandle()), NULL); //FIXME: attaching fails and is unnecessary when code used in same process bool attachOk = AttachThreadInput(thisThread, winThread, true); if (not attachOk) attachError = GetLastError(); BYTE lpKeyState[256]={0}; BOOL getStateOk = GetKeyboardState( lpKeyState); //wxString str(wxChar('.'),256); //wxString str; //msg.Clear(); if ( attachOk && getStateOk ) { // ------------------------------------------------------------------- //// -- ways *not* to hold macro while user sleeps on the keyboard --- // ------------------------------------------------------------------- ////for ( int i = 0 ; i < 255; ++i){ // //-if ( lpKeyState[i] & 0x01) continue; // ignore toggle keys // //-if ( lpKeyState[i] & 0x80 ){ // key down // //-if ( lpKeyState[i] ) str.Append(msg.Format(wxT("[%d][%x]"),i,lpKeyState[i])); // key down //// if ( (lpKeyState[VK_CONTROL] | lpKeyState[VK_SHIFT] | lpKeyState[VK_MENU]) & 0x80) //// { //str = str.Format(wxT("Ctrl Status[%d][%x]"),i,lpKeyState[VK_CONTROL]); //// wxMilliSleep(128); //// getStateOk = GetKeyboardState( lpKeyState); //// if (not getStateOk) break; //// i = 0; //// }//else str.Append('.'); ////}//for ////WriteLog(str); // If user is leaning on the keyboard, our chars can't get stuffed into the keyboard. // wait for user to release Ctrl &/or Shift &/or Alt while ((lpKeyState[VK_CONTROL] | lpKeyState[VK_SHIFT] | lpKeyState[VK_MENU]) & 0x80) { wxMilliSleep(128); getStateOk = GetKeyboardState( lpKeyState); if (not getStateOk) break; }//while }//if #ifdef LOGGING else { // Attach always fails when we're operating in the same process msg.Printf( _T("SendMacroString: failed attach[%d %ld] getState[%d]"),attachOk, attachError, getStateOk); //-WriteLog( msg ); #if defined(LOGGING) //LOGIT( _T("[%s]"), msg.c_str()); #endif } #endif //FIXME: attaching fails and is unnecessary when code in same process attachOk = AttachThreadInput(thisThread, winThread, false); if (not attachOk) { attachError = GetLastError(); #if defined(LOGGING) // Attach always fails when we're operating in the same process msg.Printf( _T("SendMacroString: failed AttachThreadInput[%d %ld]"),attachOk, attachError); //-WriteLog( msg ); //LOGIT( _T("[%s]"), msg.c_str()); #endif } // translate unicode to ascii wxWX2MBbuf cb = kmU2C(wsMacro); string asciiString(cb); string namedMacroString(cb); // Process macro characters and named Macro Keys while ( macroStrIndex < asciiString.size() ) { macroChar = asciiString[macroStrIndex++]; // check for ALT '!',CTRL '^',SHIFT '+',and named macros '{' if ( '!' == macroChar ) { m_nShiftFlags |= SEND_ALT_FLAG; } else if ( '^' == macroChar ) { m_nShiftFlags |= SEND_CTRL_FLAG; } else if ( '+' == macroChar ) { m_nShiftFlags |= SEND_SHIFT_FLAG;} else if ( '{' == macroChar ) { // have a named macro eg., {CTRL DN}, {INSERT ON}, {ENTER} etc. string::size_type savedMacroStrIndex = macroStrIndex; if ( not FindChar( '}', asciiString, namedMacroString, macroStrIndex) ) { // missing '}' to end named macro, just send single char macroStrIndex = savedMacroStrIndex; InjectMacroChar('{', 1); }//if else { // translate named macro to virtual key and inject to kbd queue InjectNamedKeyMacro( namedMacroString ); m_nShiftFlags &= CLEAR_SEND_FLAGS; }//else } else // inject a single key to keyboard { InjectMacroChar(macroChar, 1); //#ifdef LOGGING // WriteLog( _T("SendMacroSting[%c]"),wxChar(macroChar) ); //#endif //LOGGING m_nShiftFlags &= CLEAR_SEND_FLAGS; }//else } // End While // restore CapsLock position if ( m_bCapsLockState ) DoKeyToggle(VK_CAPITAL, bPreviousCapsLockState); }//SendMacro()
void ScanGrub2::ScanConfigFile (char *dir, char *file_name) { bool scan_kernel_setup = false; bool added_to_menu = false; bool found = false; bool variables = false; FILE *pf; //int default_boot_number = 0; pf = fopen (file_name, "r"); if (!pf) { Log ("Couldn't open '%s'/'%s'", dir, file_name); ScanDirectory (dir); return; } else { Log ("Parsing '%s'/'%s'", dir, file_name); } MenuEntry menuEntry; menuEntry.Reset(); menuEntry.check_default_boot = true; while (fgets (cfg_line, sizeof (cfg_line), pf)) { RemoveUnneededChars (cfg_line, '#'); TabToSpace (cfg_line); StripChar (cfg_line, '{'); // dirty hack, use menuentry as start if (!variables && FindChar (cfg_line, '$')) { variables = true; } /* if ((strncasecmp (cfg_line, "set default", 11) == 0) && !FindChar (cfg_line, '$')) { GetValue(cfg_line); default_boot_number = atoi (cfg_line); continue; } */ if (strncasecmp (cfg_line, "menuentry ", 10) == 0) { if (variables) { Log ("Warning: Grub2 added menu entry '%s' with variable/s, they were removed.", cfg_line); variables = false; } // when a new label has been found then add the previous collected data to the menu if (!added_to_menu && found) { menu->AddEntry (menuEntry); menuEntry.Reset(); added_to_menu = true; found = false; } StripChar (cfg_line, '"'); menuEntry.SetMenuLabel (cfg_line + 10); scan_kernel_setup = true; } if (scan_kernel_setup) { //if (FindChar (cfg_line, '$')) // Log ("Grub2: Adding initrd/kernel args with variable '%s'", cfg_line); if (strncasecmp (cfg_line, "linux ", 6) == 0) { menuEntry.SetKernel (cfg_line + 6, dir); found = true; added_to_menu = false; char append[1024]; strncpy (append, cfg_line + 6, sizeof (append)); int start = Trim (append); int pos = FindChar (append + start, ' '); if (pos > -1) { menuEntry.SetAppend (append + start + pos); } } else if (strncasecmp (cfg_line, "initrd ", 7) == 0) { menuEntry.SetInitrd (cfg_line, dir); } } } if (!added_to_menu && found) { menu->AddEntry (menuEntry); } fclose (pf); }
static FIBITMAP * DLL_CALLCONV Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { char msg[256]; FIBITMAP *dib = NULL; if (!handle) return NULL; try { char *str; //find the starting brace if( !FindChar(io, handle,'{') ) throw "Could not find starting brace"; //read info string str = ReadString(io, handle); if(!str) throw "Error reading info string"; int width, height, colors, cpp; if( sscanf(str, "%d %d %d %d", &width, &height, &colors, &cpp) != 4 ) { free(str); throw "Improperly formed info string"; } free(str); if (colors > 256) { dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK); } else { dib = FreeImage_Allocate(width, height, 8); } //build a map of color chars to rgb values std::map<std::string,FILE_RGBA> rawpal; //will store index in Alpha if 8bpp for(int i = 0; i < colors; i++ ) { FILE_RGBA rgba; str = ReadString(io, handle); if(!str) throw "Error reading color strings"; std::string chrs(str,cpp); //create a string for the color chars using the first cpp chars char *keys = str + cpp; //the color keys for these chars start after the first cpp chars //translate all the tabs to spaces char *tmp = keys; while( strchr(tmp,'\t') ) { tmp = strchr(tmp,'\t'); *tmp++ = ' '; } //prefer the color visual if( strstr(keys," c ") ) { char *clr = strstr(keys," c ") + 3; while( *clr == ' ' ) clr++; //find the start of the hex rgb value if( *clr == '#' ) { int red = 0, green = 0, blue = 0, n; clr++; //end string at first space, if any found if( strchr(clr,' ') ) *(strchr(clr,' ')) = '\0'; //parse hex color, it can be #rgb #rrggbb #rrrgggbbb or #rrrrggggbbbb switch( strlen(clr) ) { case 3: n = sscanf(clr,"%01x%01x%01x",&red,&green,&blue); red |= (red << 4); green |= (green << 4); blue |= (blue << 4); break; case 6: n = sscanf(clr,"%02x%02x%02x",&red,&green,&blue); break; case 9: n = sscanf(clr,"%03x%03x%03x",&red,&green,&blue); red >>= 4; green >>= 4; blue >>= 4; break; case 12: n = sscanf(clr,"%04x%04x%04x",&red,&green,&blue); red >>= 8; green >>= 8; blue >>= 8; break; default: n = 0; break; } if( n != 3 ) { free(str); throw "Improperly formed hex color value"; } rgba.r = (BYTE)red; rgba.g = (BYTE)green; rgba.b = (BYTE)blue; } else if( !strncmp(clr,"None",4) || !strncmp(clr,"none",4) ) { rgba.r = rgba.g = rgba.b = 0xFF; } else { char *tmp = clr; //scan forward for each space, if its " x " or " xx " end the string there //this means its probably some other visual data beyond that point and not //part of the color name. How many named color end with a 1 or 2 character //word? Probably none in our list at least. while( (tmp = strchr(tmp,' ')) != NULL ) { if( tmp[1] != ' ' ) { if( (tmp[2] == ' ') || (tmp[2] != ' ' && tmp[3] == ' ') ) { tmp[0] = '\0'; break; } } tmp++; } //remove any trailing spaces tmp = clr+strlen(clr)-1; while( *tmp == ' ' ) { *tmp = '\0'; tmp--; } if (!FreeImage_LookupX11Color(clr, &rgba.r, &rgba.g, &rgba.b)) { sprintf(msg, "Unknown color name '%s'", str); free(str); throw msg; } } } else {