CFX_ByteString CPDF_StreamParser::ReadHexString() {
  if (!PositionIsInBounds())
    return CFX_ByteString();

  CFX_ByteTextBuf buf;
  bool bFirst = true;
  int code = 0;
  while (PositionIsInBounds()) {
    int ch = m_pBuf[m_Pos++];

    if (ch == '>')
      break;

    if (!std::isxdigit(ch))
      continue;

    int val = FXSYS_toHexDigit(ch);
    if (bFirst) {
      code = val * 16;
    } else {
      code += val;
      buf.AppendByte((uint8_t)code);
    }
    bFirst = !bFirst;
  }
  if (!bFirst)
    buf.AppendChar((char)code);

  if (buf.GetLength() > MAX_STRING_LENGTH)
    return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);

  return buf.GetByteString();
}
CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) {
  int size = bstr.GetLength();
  const FX_CHAR* pSrc = bstr.GetCStr();
  if (!FXSYS_memchr(pSrc, '#', size)) {
    return bstr;
  }
  CFX_ByteString result;
  FX_CHAR* pDestStart = result.GetBuffer(size);
  FX_CHAR* pDest = pDestStart;
  for (int i = 0; i < size; i++) {
    if (pSrc[i] == '#' && i < size - 2) {
      *pDest++ =
          FXSYS_toHexDigit(pSrc[i + 1]) * 16 + FXSYS_toHexDigit(pSrc[i + 2]);
      i += 2;
    } else {
      *pDest++ = pSrc[i];
    }
  }
  result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart));
  return result;
}