docs: private void parseCharRef(boolean doFlush) throws SAXException, IOException {
          int value = 0;
          char c;
  
          if (tryRead('x')) {
              loop1: while (true) {
                  c = readCh();
                  if (c == ';') {
                      break loop1;
                  } else {
                      int n = Character.digit(c, 16);
                      if (n == -1) {
                          fatal("illegal character in character reference", c,
                                  null);
                          break loop1;
                      }
                      value *= 16;
                      value += n;
                  }
              }
          } else {
              loop2: while (true) {
                  c = readCh();
                  if (c == ';') {
                      break loop2;
                  } else {
                      int n = Character.digit(c, 10);
                      if (n == -1) {
                          fatal("illegal character in character reference", c,
                                  null);
                          break loop2;
                      }
                      value *= 10;
                      value += c - '0';
                  }
              }
          }
  
          // check for character refs being legal XML
          if (((value < 0x0020) && !((value == '\n') || (value == '\t') || (value == '\r')))
                  || ((value >= 0xD800) && (value <= 0xDFFF))
                  || (value == 0xFFFE)
                  || (value == 0xFFFF) || (value > 0x0010ffff)) {
              fatal("illegal XML character reference U+"
                      + Integer.toHexString(value));
          } else if ((value >= 0x007F) && (value <= 0x009F)) // 2006-11-13 hsivonen
          {
              handler.warn("Character reference expands to a control character: U+00"
                      + Integer.toHexString(value) + ".");
          }
          if (isPrivateUse(value)) {
              warnAboutPrivateUseChar();
          }
  
          // Check for surrogates: 00000000 0000xxxx yyyyyyyy zzzzzzzz
          // (1101|10xx|xxyy|yyyy + 1101|11yy|zzzz|zzzz:
          if (value <= 0x0000ffff) {
              // no surrogates needed
              dataBufferAppend((char) value);
          } else if (value <= 0x0010ffff) {
              value -= 0x10000;
              // > 16 bits, surrogate needed
              dataBufferAppend((char) (0xd800 | (value >> 10)));
              dataBufferAppend((char) (0xdc00 | (value & 0x0003ff)));
          } else {
              // too big for surrogate
              fatal("character reference " + value + " is too large for UTF-16",
                      Integer.valueOf(value).toString(), null);
          }
          if (doFlush) {
              dataBufferFlush();
          }
      }