IGUANA_INLINE void parse_escape_xml()

in include/ylt/standalone/iguana/xml_util.hpp [301:389]


IGUANA_INLINE void parse_escape_xml(U &value, It &&it, It &&end) {
  static const unsigned char lookup_digits[256] = {
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   255, 255,
      255, 255, 255, 255, 255, 10,  11,  12,  13,  14,  15,  255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 10,  11,  12,  13,  14,  15,  255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      255};
  switch (*(it + 1)) {
    // & '
    case 'a':
      if (is_match<'m', 'p', ';'>(it + 2, end)) {
        value.push_back('&');
        it += 5;
        return;
      }
      if (is_match<'p', 'o', 's', ';'>(it + 2, end)) {
        value.push_back('\'');
        it += 6;
      }
      break;
    // &quot;
    case 'q':
      if (is_match<'u', 'o', 't', ';'>(it + 2, end)) {
        value.push_back('\"');
        it += 6;
      }
      break;
    // &gt;
    case 'g':
      if (is_match<'t', ';'>(it + 2, end)) {
        value.push_back('>');
        it += 4;
      }
      break;
    // &lt;
    case 'l':
      if (is_match<'t', ';'>(it + 2, end)) {
        value.push_back('<');
        it += 4;
      }
      break;
    case '#':
      if (*(it + 2) == 'x') {
        // &#x
        unsigned long codepoint = 0;
        it += 3;
        while (true) {
          auto digit = lookup_digits[static_cast<unsigned char>(*it)];
          if (digit == 0xFF)
            break;
          codepoint = codepoint * 16 + digit;
          ++it;
        }
        encode_utf8(value, codepoint);
      }
      else {
        unsigned long codepoint = 0;
        it += 2;
        while (true) {
          auto digit = lookup_digits[static_cast<unsigned char>(*it)];
          if (digit == 0xFF)
            break;
          codepoint = codepoint * 10 + digit;
          ++it;
        }
        encode_utf8(value, codepoint);
      }
      match<';'>(it, end);
      break;
    default:
      // skip '&'
      // loose policy: allow '&'
      value.push_back(*(it++));
      break;
  }
}