Cleanup some numeric code.
[pdfium.git] / core / src / fpdfapi / fpdf_parser / fpdf_parser_utility.cpp
index 63454d2..d7c4136 100644 (file)
@@ -5,6 +5,13 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "../../../include/fpdfapi/fpdf_parser.h"
+#include "../../../include/fxcrt/fx_ext.h"
+
+// Indexed by 8-bit character code, contains either:
+//   'W' - for whitespace: NUL, TAB, CR, LF, FF, 0x80, 0xff
+//   'N' - for numeric: 0123456789+-.
+//   'D' - for delimiter: %()/<>[]{}
+//   'R' - otherwise.
 const char PDF_CharType[256] = {
     // NUL  SOH  STX  ETX  EOT  ENQ  ACK  BEL  BS   HT   LF   VT   FF   CR   SO
     // SI
@@ -72,45 +79,37 @@ void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart,
   dwSize = 0;
   type = PDFWORD_EOF;
   uint8_t ch;
-  char chartype;
   while (1) {
-    if (m_dwSize <= m_dwCurPos) {
+    if (m_dwSize <= m_dwCurPos)
       return;
-    }
     ch = m_pData[m_dwCurPos++];
-    chartype = PDF_CharType[ch];
-    while (chartype == 'W') {
-      if (m_dwSize <= m_dwCurPos) {
+    while (PDFCharIsWhitespace(ch)) {
+      if (m_dwSize <= m_dwCurPos)
         return;
-      }
       ch = m_pData[m_dwCurPos++];
-      chartype = PDF_CharType[ch];
     }
-    if (ch != '%') {
+
+    if (ch != '%')
       break;
-    }
+
     while (1) {
-      if (m_dwSize <= m_dwCurPos) {
+      if (m_dwSize <= m_dwCurPos)
         return;
-      }
       ch = m_pData[m_dwCurPos++];
-      if (ch == '\r' || ch == '\n') {
+      if (ch == '\r' || ch == '\n')
         break;
-      }
     }
-    chartype = PDF_CharType[ch];
   }
+
   FX_DWORD start_pos = m_dwCurPos - 1;
   pStart = m_pData + start_pos;
-  if (chartype == 'D') {
+  if (PDFCharIsDelimiter(ch)) {
     if (ch == '/') {
       while (1) {
-        if (m_dwSize <= m_dwCurPos) {
+        if (m_dwSize <= m_dwCurPos)
           return;
-        }
         ch = m_pData[m_dwCurPos++];
-        chartype = PDF_CharType[ch];
-        if (chartype != 'R' && chartype != 'N') {
+        if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
           m_dwCurPos--;
           dwSize = m_dwCurPos - start_pos;
           type = PDFWORD_NAME;
@@ -121,41 +120,36 @@ void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart,
       type = PDFWORD_DELIMITER;
       dwSize = 1;
       if (ch == '<') {
-        if (m_dwSize <= m_dwCurPos) {
+        if (m_dwSize <= m_dwCurPos)
           return;
-        }
         ch = m_pData[m_dwCurPos++];
-        if (ch == '<') {
+        if (ch == '<')
           dwSize = 2;
-        } else {
+        else
           m_dwCurPos--;
-        }
       } else if (ch == '>') {
-        if (m_dwSize <= m_dwCurPos) {
+        if (m_dwSize <= m_dwCurPos)
           return;
-        }
         ch = m_pData[m_dwCurPos++];
-        if (ch == '>') {
+        if (ch == '>')
           dwSize = 2;
-        } else {
+        else
           m_dwCurPos--;
-        }
       }
     }
     return;
   }
+
   type = PDFWORD_NUMBER;
   dwSize = 1;
   while (1) {
-    if (chartype != 'N') {
+    if (!PDFCharIsNumeric(ch))
       type = PDFWORD_TEXT;
-    }
-    if (m_dwSize <= m_dwCurPos) {
+    if (m_dwSize <= m_dwCurPos)
       return;
-    }
     ch = m_pData[m_dwCurPos++];
-    chartype = PDF_CharType[ch];
-    if (chartype == 'D' || chartype == 'W') {
+
+    if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
       m_dwCurPos--;
       break;
     }
@@ -286,18 +280,7 @@ FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token,
   }
   return FALSE;
 }
-static int _hex2dec(char ch) {
-  if (ch >= '0' && ch <= '9') {
-    return ch - '0';
-  }
-  if (ch >= 'a' && ch <= 'f') {
-    return ch - 'a' + 10;
-  }
-  if (ch >= 'A' && ch <= 'F') {
-    return ch - 'A' + 10;
-  }
-  return 0;
-}
+
 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) {
   int size = bstr.GetLength();
   const FX_CHAR* pSrc = bstr.GetCStr();
@@ -309,7 +292,7 @@ CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) {
   FX_CHAR* pDest = pDestStart;
   for (int i = 0; i < size; i++) {
     if (pSrc[i] == '#' && i < size - 2) {
-      *pDest++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]);
+      *pDest++ = HexCharToDigit(pSrc[i + 1]) * 16 + HexCharToDigit(pSrc[i + 2]);
       i += 2;
     } else {
       *pDest++ = pSrc[i];
@@ -331,23 +314,23 @@ CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) {
   int i;
   for (i = 0; i < src_len; i++) {
     uint8_t ch = src_buf[i];
-    if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' ||
-        PDF_CharType[ch] == 'D') {
+    if (ch >= 0x80 || PDFCharIsWhitespace(ch) || ch == '#' ||
+        PDFCharIsDelimiter(ch)) {
       dest_len += 3;
     } else {
       dest_len++;
     }
   }
-  if (dest_len == src_len) {
+  if (dest_len == src_len)
     return orig;
-  }
+
   CFX_ByteString res;
   FX_CHAR* dest_buf = res.GetBuffer(dest_len);
   dest_len = 0;
   for (i = 0; i < src_len; i++) {
     uint8_t ch = src_buf[i];
-    if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' ||
-        PDF_CharType[ch] == 'D') {
+    if (ch >= 0x80 || PDFCharIsWhitespace(ch) || ch == '#' ||
+        PDFCharIsDelimiter(ch)) {
       dest_buf[dest_len++] = '#';
       dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16];
       dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16];
@@ -372,24 +355,20 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) {
     case PDFOBJ_NUMBER:
       buf << " " << pObj->GetString();
       break;
-    case PDFOBJ_STRING: {
-      CFX_ByteString str = pObj->GetString();
-      FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex();
-      buf << PDF_EncodeString(str, bHex);
+    case PDFOBJ_STRING:
+      buf << PDF_EncodeString(pObj->GetString(), pObj->AsString()->IsHex());
       break;
-    }
     case PDFOBJ_NAME: {
       CFX_ByteString str = pObj->GetString();
       buf << FX_BSTRC("/") << PDF_NameEncode(str);
       break;
     }
     case PDFOBJ_REFERENCE: {
-      CPDF_Reference* p = (CPDF_Reference*)pObj;
-      buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R ");
+      buf << " " << pObj->AsReference()->GetRefObjNum() << FX_BSTRC(" 0 R ");
       break;
     }
     case PDFOBJ_ARRAY: {
-      CPDF_Array* p = (CPDF_Array*)pObj;
+      const CPDF_Array* p = pObj->AsArray();
       buf << FX_BSTRC("[");
       for (FX_DWORD i = 0; i < p->GetCount(); i++) {
         CPDF_Object* pElement = p->GetElement(i);
@@ -403,7 +382,7 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) {
       break;
     }
     case PDFOBJ_DICTIONARY: {
-      CPDF_Dictionary* p = (CPDF_Dictionary*)pObj;
+      const CPDF_Dictionary* p = pObj->AsDictionary();
       buf << FX_BSTRC("<<");
       FX_POSITION pos = p->GetStartPos();
       while (pos) {
@@ -420,7 +399,7 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) {
       break;
     }
     case PDFOBJ_STREAM: {
-      CPDF_Stream* p = (CPDF_Stream*)pObj;
+      const CPDF_Stream* p = pObj->AsStream();
       buf << p->GetDict() << FX_BSTRC("stream\r\n");
       CPDF_StreamAcc acc;
       acc.LoadAllData(p, TRUE);