예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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++;

    }
  }
예제 #8
0
파일: Parser.cpp 프로젝트: Advi42/XCSoar
/**
 * 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;
        }
      }
    }
  }
}
예제 #9
0
파일: Parser.cpp 프로젝트: Advi42/XCSoar
/**
 * 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;
}
예제 #10
0
/**
 * 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;
        }
      }
    }
  }
}
예제 #11
0
/**
 * 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;
}
예제 #12
0
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 */
}
예제 #13
0
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 */
}