const TCHAR* RasterWeather::ItemLabel(unsigned i) { if (gcc_unlikely(i >= MAX_WEATHER_MAP)) return NULL; const TCHAR *label = WeatherDescriptors[i].label; if (gcc_unlikely(label == NULL)) return NULL; return gettext(label); }
const TCHAR* RasterWeather::ItemHelp(unsigned i) { if (gcc_unlikely(i >= MAX_WEATHER_MAP)) return NULL; const TCHAR *help = WeatherDescriptors[i].help; if (gcc_unlikely(help == NULL)) return NULL; return gettext(help); }
gcc_const static unsigned ContourInterval(const int h, const unsigned contour_height_scale) { if (gcc_unlikely(RasterBuffer::IsSpecial(h)) || h <= 0) return 0; return std::min(254u, unsigned(h) >> contour_height_scale); }
gcc_const static unsigned ContourInterval(const TerrainHeight h, const unsigned contour_height_scale) { if (gcc_unlikely(h.IsSpecial()) || h.GetValue() <= 0) return 0; return ContourInterval(h.GetValue(), contour_height_scale); }
static inline int32_t mad_fixed_to_24_sample(mad_fixed_t sample) { enum { bits = 24, MIN = -MAD_F_ONE, MAX = MAD_F_ONE - 1 }; /* round */ sample = sample + (1L << (MAD_F_FRACBITS - bits)); /* clip */ if (gcc_unlikely(sample > MAX)) sample = MAX; else if (gcc_unlikely(sample < MIN)) sample = MIN; /* quantize */ return sample >> (MAD_F_FRACBITS + 1 - bits); }
bool Start(const char *const*argv) { /* double fork to detach from this process */ const pid_t pid = fork(); if (gcc_unlikely(pid < 0)) return false; if (pid == 0) _exit(ForkExec(argv) ? 0 : 1); return Wait(pid); }
void RasterRenderer::GenerateUnshadedImage(unsigned height_scale, const unsigned contour_height_scale) { const short *src = height_matrix.GetData(); const BGRColor *oColorBuf = color_table + 64 * 256; BGRColor *dest = image->GetTopRow(); for (unsigned y = height_matrix.GetHeight(); y > 0; --y) { BGRColor *p = dest; dest = image->GetNextRow(dest); unsigned contour_row_base = ContourInterval(*src, contour_height_scale); unsigned char *contour_this_column_base = contour_column_base; for (unsigned x = height_matrix.GetWidth(); x > 0; --x) { int h = *src++; if (gcc_likely(!RasterBuffer::IsSpecial(h))) { if (h < 0) h = 0; const unsigned contour_interval = ContourInterval(h, contour_height_scale); h = std::min(254, h >> height_scale); if (gcc_unlikely((contour_interval != contour_row_base) || (contour_interval != *contour_this_column_base))) { *p++ = oColorBuf[h-64*256]; *contour_this_column_base = contour_row_base = contour_interval; } else { *p++ = oColorBuf[h]; } } else if (RasterBuffer::IsWater(h)) { // we're in the water, so look up the color for water *p++ = oColorBuf[255]; } else { /* outside the terrain file bounds: white background */ *p++ = BGRColor(0xff, 0xff, 0xff); } contour_this_column_base++; } }
/** * Recursively parse an XML element. */ static bool XML::ParseXMLElement(XMLNode &node, Parser *pXML) { bool is_declaration; const TCHAR *text = nullptr; XMLNode *pNew; enum Status status; // inside or outside a tag enum Attrib attrib = eAttribName; /* the name of the attribute that is currently being */ tstring attribute_name; assert(pXML); // If this is the first call to the function if (pXML->nFirst) { // Assume we are outside of a tag definition pXML->nFirst = false; status = eOutsideTag; } else { // If this is not the first call then we should only be called when inside a tag. status = eInsideTag; } // Iterate through the tokens in the document while (true) { // Obtain the next token NextToken token = GetNextToken(pXML); if (gcc_unlikely(token.type == eTokenError)) return false; // Check the current status switch (status) { // If we are outside of a tag definition case eOutsideTag: // Check what type of token we obtained switch (token.type) { // If we have found text or quoted text case eTokenText: case eTokenQuotedText: case eTokenEquals: if (text == nullptr) text = token.pStr; break; // If we found a start tag '<' and declarations '<?' case eTokenTagStart: case eTokenDeclaration: // Cache whether this new element is a declaration or not is_declaration = token.type == eTokenDeclaration; // If we have node text then add this to the element if (text != nullptr) { size_t length = StripRight(text, token.pStr - text); node.AddText(text, length); text = nullptr; } // Find the name of the tag token = GetNextToken(pXML); // Return an error if we couldn't obtain the next token or // it wasnt text if (token.type != eTokenText) { pXML->error = eXMLErrorMissingTagName; return false; } // If the name of the new element differs from the name of // the current element we need to add the new element to // the current one and recurse pNew = &node.AddChild(token.pStr, token.length, is_declaration); while (true) { // Callself to process the new node. If we return // FALSE this means we dont have any more // processing to do... if (!ParseXMLElement(*pNew, pXML)) { return false; } else { // If the call to recurse this function // evented in a end tag specified in XML then // we need to unwind the calls to this // function until we find the appropriate node // (the element name and end tag name must // match) if (pXML->cbEndTag) { // If we are back at the root node then we // have an unmatched end tag if (node.GetName() == nullptr) { pXML->error = eXMLErrorUnmatchedEndTag; return false; } // If the end tag matches the name of this // element then we only need to unwind // once more... if (CompareTagName(node.GetName(), pXML->lpEndTag)) { pXML->cbEndTag = 0; } return true; } else { // If we didn't have a new element to create break; } } } break; // If we found an end tag case eTokenTagEnd: // If we have node text then add this to the element if (text != nullptr) { size_t length = StripRight(text, token.pStr - text); TCHAR *text2 = FromXMLString(text, length); if (text2 == nullptr) { pXML->error = eXMLErrorUnexpectedToken; return false; } node.AddText(text2); free(text2); text = nullptr; } // Find the name of the end tag token = GetNextToken(pXML); // The end tag should be text if (token.type != eTokenText) { pXML->error = eXMLErrorMissingEndTagName; return false; } // After the end tag we should find a closing tag if (GetNextToken(pXML).type != eTokenCloseTag) { pXML->error = eXMLErrorMissingEndTagName; return false; } // We need to return to the previous caller. If the name // of the tag cannot be found we need to keep returning to // caller until we find a match if (!CompareTagName(node.GetName(), token.pStr)) { pXML->lpEndTag = token.pStr; pXML->cbEndTag = token.length; } // Return to the caller return true; // Errors... case eTokenCloseTag: /* '>' */ case eTokenShortHandClose: /* '/>' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } break; // If we are inside a tag definition we need to search for attributes case eInsideTag: // Check what part of the attribute (name, equals, value) we // are looking for. switch (attrib) { // If we are looking for a new attribute case eAttribName: // Check what the current token type is switch (token.type) { // If the current type is text... // Eg. 'attribute' case eTokenText: // Cache the token then indicate that we are next to // look for the equals attribute_name.assign(token.pStr, token.length); attrib = eAttribEquals; break; // If we found a closing tag... // Eg. '>' case eTokenCloseTag: // We are now outside the tag status = eOutsideTag; break; // If we found a short hand '/>' closing tag then we can // return to the caller case eTokenShortHandClose: return true; // Errors... case eTokenQuotedText: /* '"SomeText"' */ case eTokenTagStart: /* '<' */ case eTokenTagEnd: /* '</' */ case eTokenEquals: /* '=' */ case eTokenDeclaration: /* '<?' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } break; // If we are looking for an equals case eAttribEquals: // Check what the current token type is switch (token.type) { // If the current type is text... // Eg. 'Attribute AnotherAttribute' case eTokenText: // Add the unvalued attribute to the list node.AddAttribute(std::move(attribute_name), _T(""), 0); // Cache the token then indicate. We are next to // look for the equals attribute attribute_name.assign(token.pStr, token.length); break; // If we found a closing tag 'Attribute >' or a short hand // closing tag 'Attribute />' case eTokenShortHandClose: case eTokenCloseTag: assert(!attribute_name.empty()); // If we are a declaration element '<?' then we need // to remove extra closing '?' if it exists if (node.IsDeclaration() && attribute_name.back() == _T('?')) { attribute_name.pop_back(); } if (!attribute_name.empty()) // Add the unvalued attribute to the list node.AddAttribute(std::move(attribute_name), _T(""), 0); // If this is the end of the tag then return to the caller if (token.type == eTokenShortHandClose) return true; // We are now outside the tag status = eOutsideTag; break; // If we found the equals token... // Eg. 'Attribute =' case eTokenEquals: // Indicate that we next need to search for the value // for the attribute attrib = eAttribValue; break; // Errors... case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ case eTokenTagStart: /* 'Attribute <' */ case eTokenTagEnd: /* 'Attribute </' */ case eTokenDeclaration: /* 'Attribute <?' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } break; // If we are looking for an attribute value case eAttribValue: // Check what the current token type is switch (token.type) { // If the current type is text or quoted text... // Eg. 'Attribute = "Value"' or 'Attribute = Value' or // 'Attribute = 'Value''. case eTokenText: case eTokenQuotedText: // If we are a declaration element '<?' then we need // to remove extra closing '?' if it exists if (node.IsDeclaration() && (token.pStr[token.length - 1]) == _T('?')) { token.length--; } // Add the valued attribute to the list if (token.type == eTokenQuotedText) { token.pStr++; token.length -= 2; } assert(!attribute_name.empty()); { TCHAR *value = FromXMLString(token.pStr, token.length); if (value == nullptr) { pXML->error = eXMLErrorUnexpectedToken; return false; } node.AddAttribute(std::move(attribute_name), value, _tcslen(value)); free(value); } // Indicate we are searching for a new attribute attrib = eAttribName; break; // Errors... case eTokenTagStart: /* 'Attr = <' */ case eTokenTagEnd: /* 'Attr = </' */ case eTokenCloseTag: /* 'Attr = >' */ case eTokenShortHandClose: /* "Attr = />" */ case eTokenEquals: /* 'Attr = =' */ case eTokenDeclaration: /* 'Attr = <?' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } } } } }
/** * Find the next token in a string. */ static XML::NextToken XML::GetNextToken(Parser *pXML) { XML::NextToken result; const TCHAR *lpXML; TCHAR ch; TCHAR temp_ch; size_t size; unsigned n; bool found_match; bool is_text = false; // Find next non-white space character ch = FindNonWhiteSpace(pXML); if (gcc_unlikely(ch == 0)) { // If we failed to obtain a valid character return { nullptr, 0, eTokenError }; } // Cache the current string pointer lpXML = pXML->lpXML; result.pStr = &lpXML[pXML->nIndex - 1]; switch (ch) { // Check for quotes case _T('\''): case _T('\"'): // Type of token result.type = eTokenQuotedText; temp_ch = ch; n = pXML->nIndex; // Set the size size = 1; found_match = false; // Search through the string to find a matching quote while (((ch = GetNextChar(pXML))) != 0) { size++; if (ch == temp_ch) { found_match = true; break; } if (ch == _T('<')) break; } // If we failed to find a matching quote if (!found_match) { pXML->nIndex = n; is_text = true; break; } // 4.02.2002 if (FindNonWhiteSpace(pXML)) { pXML->nIndex--; } break; // Equals (used with attribute values) case _T('='): size = 1; result.type = eTokenEquals; break; // Close tag case _T('>'): size = 1; result.type = eTokenCloseTag; break; // Check for tag start and tag end case _T('<'): // Peek at the next character to see if we have an end tag '</', // or an xml declaration '<?' temp_ch = pXML->lpXML[pXML->nIndex]; // If we have a tag end... if (temp_ch == _T('/')) { // Set the type and ensure we point at the next character GetNextChar(pXML); result.type = eTokenTagEnd; size = 2; } // If we have an XML declaration tag else if (temp_ch == _T('?')) { // Set the type and ensure we point at the next character GetNextChar(pXML); result.type = eTokenDeclaration; size = 2; } // Otherwise we must have a start tag else { result.type = eTokenTagStart; size = 1; } break; // Check to see if we have a short hand type end tag ('/>'). case _T('/'): // Peek at the next character to see if we have a short end tag '/>' temp_ch = pXML->lpXML[pXML->nIndex]; // If we have a short hand end tag... if (temp_ch == _T('>')) { // Set the type and ensure we point at the next character GetNextChar(pXML); result.type = eTokenShortHandClose; size = 2; break; } // If we haven't found a short hand closing tag then drop into the // text process #if GCC_CHECK_VERSION(7,0) [[fallthrough]]; #endif // Other characters default: is_text = true; } // If this is a TEXT node if (is_text) { // Indicate we are dealing with text result.type = eTokenText; size = 1; bool nExit = false; while (!nExit && ((ch = GetNextChar(pXML)) != 0)) { if (IsWhitespaceOrNull(ch)) // Break when we find white space break; switch (ch) { // If we find a slash then this maybe text or a short hand end tag. case _T('/'): // Peek at the next character to see it we have short hand end tag temp_ch = pXML->lpXML[pXML->nIndex]; // If we found a short hand end tag then we need to exit the loop if (temp_ch == _T('>')) { pXML->nIndex--; // 03.02.2002 nExit = true; } else { size++; } break; // Break when we find a terminator and decrement the index and // column count so that we are pointing at the right character // the next time we are called. case _T('<'): case _T('>'): case _T('='): pXML->nIndex--; nExit = true; break; case 0: nExit = true; break; default: size++; } } } result.length = size; return result; }
/** * Recursively parse an XML element. */ bool XMLNode::ParseXMLElement(XML *pXML) { const TCHAR *lpszTemp = NULL; size_t cbTemp; unsigned nDeclaration; const TCHAR *lpszText = NULL; XMLNode pNew; enum Status status; // inside or outside a tag enum Attrib attrib = eAttribName; assert(pXML); // If this is the first call to the function if (pXML->nFirst) { // Assume we are outside of a tag definition pXML->nFirst = false; status = eOutsideTag; } else { // If this is not the first call then we should only be called when inside a tag. status = eInsideTag; } // Iterate through the tokens in the document while (true) { // Obtain the next token size_t cbToken; enum TokenTypeTag type; NextToken token = GetNextToken(pXML, &cbToken, &type); if (gcc_unlikely(type == eTokenError)) return false; // Check the current status switch (status) { // If we are outside of a tag definition case eOutsideTag: // Check what type of token we obtained switch (type) { // If we have found text or quoted text case eTokenText: case eTokenQuotedText: case eTokenEquals: if (!lpszText) lpszText = token.pStr; break; // If we found a start tag '<' and declarations '<?' case eTokenTagStart: case eTokenDeclaration: // Cache whether this new element is a declaration or not nDeclaration = type == eTokenDeclaration; // If we have node text then add this to the element if (lpszText) { cbTemp = token.pStr - lpszText; FindEndOfText(lpszText, &cbTemp); AddText(lpszText, cbTemp); lpszText = NULL; } // Find the name of the tag token = GetNextToken(pXML, &cbToken, &type); // Return an error if we couldn't obtain the next token or // it wasnt text if (type != eTokenText) { pXML->error = eXMLErrorMissingTagName; return false; } // If we found a new element which is the same as this // element then we need to pass this back to the caller.. #ifdef APPROXIMATE_PARSING if (d->lpszName && myTagCompare(d->lpszName, token.pStr)) { // Indicate to the caller that it needs to create a // new element. pXML->lpNewElement = token.pStr; pXML->cbNewElement = cbToken; return true; } #endif // If the name of the new element differs from the name of // the current element we need to add the new element to // the current one and recurse pNew = AddChild(stringDup(token.pStr, cbToken), nDeclaration); while (true) { // Callself to process the new node. If we return // FALSE this means we dont have any more // processing to do... if (!pNew.ParseXMLElement(pXML)) { return false; } else { // If the call to recurse this function // evented in a end tag specified in XML then // we need to unwind the calls to this // function until we find the appropriate node // (the element name and end tag name must // match) if (pXML->cbEndTag) { // If we are back at the root node then we // have an unmatched end tag if (!d->lpszName) { pXML->error = eXMLErrorUnmatchedEndTag; return false; } // If the end tag matches the name of this // element then we only need to unwind // once more... if (myTagCompare(d->lpszName, pXML->lpEndTag)) { pXML->cbEndTag = 0; } return true; } else if (pXML->cbNewElement) { // If the call indicated a new element is to // be created on THIS element. // If the name of this element matches the // name of the element we need to create // then we need to return to the caller // and let it process the element. if (myTagCompare(d->lpszName, pXML->lpNewElement)) return true; // Add the new element and recurse pNew = AddChild(stringDup(pXML->lpNewElement, pXML->cbNewElement), false); pXML->cbNewElement = 0; } else { // If we didn't have a new element to create break; } } } break; // If we found an end tag case eTokenTagEnd: // If we have node text then add this to the element if (lpszText) { cbTemp = token.pStr - lpszText; FindEndOfText(lpszText, &cbTemp); TCHAR *text = fromXMLString(lpszText, cbTemp); if (text == NULL) { pXML->error = eXMLErrorUnexpectedToken; return false; } AddText(text); free(text); lpszText = NULL; } // Find the name of the end tag token = GetNextToken(pXML, &cbTemp, &type); // The end tag should be text if (type != eTokenText) { pXML->error = eXMLErrorMissingEndTagName; return false; } lpszTemp = token.pStr; // After the end tag we should find a closing tag token = GetNextToken(pXML, &cbToken, &type); if (type != eTokenCloseTag) { pXML->error = eXMLErrorMissingEndTagName; return false; } // We need to return to the previous caller. If the name // of the tag cannot be found we need to keep returning to // caller until we find a match if (!myTagCompare(d->lpszName, lpszTemp)) { pXML->lpEndTag = lpszTemp; pXML->cbEndTag = cbTemp; } // Return to the caller return true; // Errors... case eTokenCloseTag: /* '>' */ case eTokenShortHandClose: /* '/>' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } break; // If we are inside a tag definition we need to search for attributes case eInsideTag: // Check what part of the attribute (name, equals, value) we // are looking for. switch (attrib) { // If we are looking for a new attribute case eAttribName: // Check what the current token type is switch (type) { // If the current type is text... // Eg. 'attribute' case eTokenText: // Cache the token then indicate that we are next to // look for the equals lpszTemp = token.pStr; cbTemp = cbToken; attrib = eAttribEquals; break; // If we found a closing tag... // Eg. '>' case eTokenCloseTag: // We are now outside the tag status = eOutsideTag; break; // If we found a short hand '/>' closing tag then we can // return to the caller case eTokenShortHandClose: return true; // Errors... case eTokenQuotedText: /* '"SomeText"' */ case eTokenTagStart: /* '<' */ case eTokenTagEnd: /* '</' */ case eTokenEquals: /* '=' */ case eTokenDeclaration: /* '<?' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } break; // If we are looking for an equals case eAttribEquals: // Check what the current token type is switch (type) { // If the current type is text... // Eg. 'Attribute AnotherAttribute' case eTokenText: // Add the unvalued attribute to the list AddAttribute(stringDup(lpszTemp, cbTemp), NULL); // Cache the token then indicate. We are next to // look for the equals attribute lpszTemp = token.pStr; cbTemp = cbToken; break; // If we found a closing tag 'Attribute >' or a short hand // closing tag 'Attribute />' case eTokenShortHandClose: case eTokenCloseTag: // If we are a declaration element '<?' then we need // to remove extra closing '?' if it exists if (d->isDeclaration && (lpszTemp[cbTemp - 1]) == _T('?')) cbTemp--; if (cbTemp) // Add the unvalued attribute to the list AddAttribute(stringDup(lpszTemp, cbTemp), NULL); // If this is the end of the tag then return to the caller if (type == eTokenShortHandClose) return true; // We are now outside the tag status = eOutsideTag; break; // If we found the equals token... // Eg. 'Attribute =' case eTokenEquals: // Indicate that we next need to search for the value // for the attribute attrib = eAttribValue; break; // Errors... case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ case eTokenTagStart: /* 'Attribute <' */ case eTokenTagEnd: /* 'Attribute </' */ case eTokenDeclaration: /* 'Attribute <?' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } break; // If we are looking for an attribute value case eAttribValue: // Check what the current token type is switch (type) { // If the current type is text or quoted text... // Eg. 'Attribute = "Value"' or 'Attribute = Value' or // 'Attribute = 'Value''. case eTokenText: case eTokenQuotedText: // If we are a declaration element '<?' then we need // to remove extra closing '?' if it exists if (d->isDeclaration && (token.pStr[cbToken - 1]) == _T('?')) { cbToken--; } if (cbTemp) { // Add the valued attribute to the list if (type == eTokenQuotedText) { token.pStr++; cbToken -= 2; } AddAttribute(stringDup(lpszTemp, cbTemp), fromXMLString( token.pStr, cbToken)); } // Indicate we are searching for a new attribute attrib = eAttribName; break; // Errors... case eTokenTagStart: /* 'Attr = <' */ case eTokenTagEnd: /* 'Attr = </' */ case eTokenCloseTag: /* 'Attr = >' */ case eTokenShortHandClose: /* "Attr = />" */ case eTokenEquals: /* 'Attr = =' */ case eTokenDeclaration: /* 'Attr = <?' */ pXML->error = eXMLErrorUnexpectedToken; return false; default: break; } } } } }
/** * Find the next token in a string. * * @param pcbToken contains the number of characters that have been read */ static NextToken GetNextToken(XML *pXML, size_t *pcbToken, enum TokenTypeTag *pType) { NextToken result; const TCHAR *lpXML; TCHAR ch; TCHAR chTemp; size_t nSize; bool nFoundMatch; unsigned n; bool nIsText = false; // Find next non-white space character ch = FindNonWhiteSpace(pXML); if (gcc_unlikely(ch == 0)) { // If we failed to obtain a valid character *pcbToken = 0; *pType = eTokenError; result.pStr = NULL; return result; } // Cache the current string pointer lpXML = pXML->lpXML; result.pStr = &lpXML[pXML->nIndex - 1]; chTemp = 0; switch (ch) { // Check for quotes case _T('\''): case _T('\"'): // Type of token *pType = eTokenQuotedText; chTemp = ch; n = pXML->nIndex; // Set the size nSize = 1; nFoundMatch = false; // Search through the string to find a matching quote while (((ch = getNextChar(pXML))) != 0) { nSize++; if (ch == chTemp) { nFoundMatch = true; break; } if (ch == _T('<')) break; } // If we failed to find a matching quote if (!nFoundMatch) { pXML->nIndex = n - 1; ch = getNextChar(pXML); nIsText = true; break; } // 4.02.2002 if (FindNonWhiteSpace(pXML)) { pXML->nIndex--; } break; // Equals (used with attribute values) case _T('='): nSize = 1; *pType = eTokenEquals; break; // Close tag case _T('>'): nSize = 1; *pType = eTokenCloseTag; break; // Check for tag start and tag end case _T('<'): // Peek at the next character to see if we have an end tag '</', // or an xml declaration '<?' chTemp = pXML->lpXML[pXML->nIndex]; // If we have a tag end... if (chTemp == _T('/')) { // Set the type and ensure we point at the next character getNextChar(pXML); *pType = eTokenTagEnd; nSize = 2; } // If we have an XML declaration tag else if (chTemp == _T('?')) { // Set the type and ensure we point at the next character getNextChar(pXML); *pType = eTokenDeclaration; nSize = 2; } // Otherwise we must have a start tag else { *pType = eTokenTagStart; nSize = 1; } break; // Check to see if we have a short hand type end tag ('/>'). case _T('/'): // Peek at the next character to see if we have a short end tag '/>' chTemp = pXML->lpXML[pXML->nIndex]; // If we have a short hand end tag... if (chTemp == _T('>')) { // Set the type and ensure we point at the next character getNextChar(pXML); *pType = eTokenShortHandClose; nSize = 2; break; } // If we haven't found a short hand closing tag then drop into the // text process // Other characters default: nIsText = true; } // If this is a TEXT node if (nIsText) { // Indicate we are dealing with text *pType = eTokenText; nSize = 1; bool nExit = false; while (!nExit && ((ch = getNextChar(pXML)) != 0)) { switch (ch) { // Break when we find white space case _T('\n'): case _T(' '): case _T('\t'): case _T('\r'): nExit = true; break; // If we find a slash then this maybe text or a short hand end tag. case _T('/'): // Peek at the next character to see it we have short hand end tag chTemp = pXML->lpXML[pXML->nIndex]; // If we found a short hand end tag then we need to exit the loop if (chTemp == _T('>')) { pXML->nIndex--; // 03.02.2002 nExit = true; } else { nSize++; } break; // Break when we find a terminator and decrement the index and // column count so that we are pointing at the right character // the next time we are called. case _T('<'): case _T('>'): case _T('='): pXML->nIndex--; nExit = true; break; case 0: nExit = true; break; default: nSize++; } } } *pcbToken = nSize; return result; }
FileMapping::FileMapping(const TCHAR *path) :m_data(NULL) #ifndef HAVE_POSIX , hMapping(NULL) #endif { #ifdef HAVE_POSIX int fd = open(path, O_RDONLY); if (fd < 0) return; struct stat st; if (fstat(fd, &st) < 0 || /* mapping empty files can't be useful, let's make this a failure */ st.st_size <= 0 || /* file is too large */ st.st_size > 1024 * 1024 * 1024) { close(fd); return; } m_size = (size_t)st.st_size; m_data = mmap(NULL, m_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if (m_data == NULL) return; madvise(m_data, m_size, MADV_WILLNEED); #else /* !HAVE_POSIX */ #if defined(_WIN32_WCE) && _WIN32_WCE < 0x0500 /* old Windows CE versions need a HANDLE returned from CreateFileForMapping(); this system is not needed with WM5, and it is deprecated in WM6 */ hFile = ::CreateFileForMapping(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); #else hFile = ::CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); #endif if (gcc_unlikely(hFile == INVALID_HANDLE_VALUE)) return; struct { BY_HANDLE_FILE_INFORMATION fi; #ifdef _WIN32_WCE /* on Windows CE, GetFileInformationByHandle() seems to overflow the BY_HANDLE_FILE_INFORMATION variable by 4 bytes (undocumented on MSDN); adding the following DWORD gives it enough buffer to play with */ DWORD dummy; #endif } i; if (!::GetFileInformationByHandle(hFile, &i.fi) || i.fi.nFileSizeHigh > 0 || i.fi.nFileSizeLow > 1024 * 1024 * 1024) return; m_size = i.fi.nFileSizeLow; hMapping = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, i.fi.nFileSizeHigh, i.fi.nFileSizeLow, NULL); #if defined(_WIN32_WCE) && _WIN32_WCE < 0x0500 /* CreateFileForMapping() automatically closes the file handle */ hFile = INVALID_HANDLE_VALUE; #endif if (gcc_unlikely(hMapping == NULL)) return; m_data = ::MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, m_size); #endif /* !HAVE_POSIX */ }
FileMapping::FileMapping(Path path) :m_data(nullptr) #ifndef HAVE_POSIX , hMapping(nullptr) #endif { #ifdef HAVE_POSIX int flags = O_RDONLY; #ifdef O_NOCTTY flags |= O_NOCTTY; #endif #ifdef O_CLOEXEC flags |= O_CLOEXEC; #endif int fd = open(path.c_str(), flags); if (fd < 0) return; struct stat st; if (fstat(fd, &st) < 0 || /* mapping empty files can't be useful, let's make this a failure */ st.st_size <= 0 || /* file is too large */ st.st_size > 1024 * 1024 * 1024) { close(fd); return; } m_size = (size_t)st.st_size; m_data = mmap(nullptr, m_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if (m_data == nullptr) return; madvise(m_data, m_size, MADV_WILLNEED); #else /* !HAVE_POSIX */ hFile = ::CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (gcc_unlikely(hFile == INVALID_HANDLE_VALUE)) return; BY_HANDLE_FILE_INFORMATION fi; if (!::GetFileInformationByHandle(hFile, &fi) || fi.nFileSizeHigh > 0 || fi.nFileSizeLow > 1024 * 1024 * 1024) return; m_size = fi.nFileSizeLow; hMapping = ::CreateFileMapping(hFile, nullptr, PAGE_READONLY, fi.nFileSizeHigh, fi.nFileSizeLow, nullptr); if (gcc_unlikely(hMapping == nullptr)) return; m_data = ::MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, m_size); #endif /* !HAVE_POSIX */ }