| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../../include/fpdfapi/fpdf_parser.h" | 7 #include "../../../include/fpdfapi/fpdf_parser.h" |
| 8 const char PDF_CharType[256] = { | 8 const char PDF_CharType[256] = { |
| 9 //NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO S
I | 9 // NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO |
| 10 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', '
R', | 10 // SI |
| 11 | 11 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', |
| 12 //DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS U
S | 12 'R', |
| 13 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 13 |
| 14 | 14 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS |
| 15 //SP ! " # $ % & ´ ( ) * + , - .
/ | 15 // US |
| 16 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', '
D', | 16 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 17 | 17 'R', |
| 18 // 0 1 2 3 4 5 6 7 8 9 : ; < = >
? | 18 |
| 19 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', '
R', | 19 // SP ! " # $ % & ´ ( ) * + , - . |
| 20 | 20 // / |
| 21 // @ A B C D E F G H I J K L M N
O | 21 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', |
| 22 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 22 'D', |
| 23 | 23 |
| 24 // P Q R S T U V W X Y Z [ \ ] ^
_ | 24 // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
| 25 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', '
R', | 25 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', |
| 26 | 26 'R', |
| 27 // ` a b c d e f g h i j k l m n
o | 27 |
| 28 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 28 // @ A B C D E F G H I J K L M N O |
| 29 | 29 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 30 // p q r s t u v w x y z { | } ~ D
EL | 30 'R', |
| 31 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', '
R', | 31 |
| 32 | 32 // P Q R S T U V W X Y Z [ \ ] ^ _ |
| 33 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 33 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', |
| 34 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 34 'R', |
| 35 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 35 |
| 36 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 36 // ` a b c d e f g h i j k l m n o |
| 37 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 37 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 38 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 38 'R', |
| 39 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 39 |
| 40 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
W' | 40 // p q r s t u v w x y z { | } ~ |
| 41 }; | 41 // DEL |
| 42 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', |
| 43 'R', |
| 44 |
| 45 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 46 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 47 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 48 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 49 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 50 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 51 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 52 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 53 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'}; |
| 42 | 54 |
| 43 #ifndef MAX_PATH | 55 #ifndef MAX_PATH |
| 44 #define MAX_PATH 4096 | 56 #define MAX_PATH 4096 |
| 45 #endif | 57 #endif |
| 46 CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) | 58 CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) { |
| 47 { | 59 m_pData = pData; |
| 48 m_pData = pData; | 60 m_dwSize = dwSize; |
| 49 m_dwSize = dwSize; | 61 m_dwCurPos = 0; |
| 50 m_dwCurPos = 0; | 62 } |
| 51 } | 63 CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) { |
| 52 CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) | 64 m_pData = str.GetPtr(); |
| 53 { | 65 m_dwSize = str.GetLength(); |
| 54 m_pData = str.GetPtr(); | 66 m_dwCurPos = 0; |
| 55 m_dwSize = str.GetLength(); | 67 } |
| 56 m_dwCurPos = 0; | 68 void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, |
| 57 } | 69 FX_DWORD& dwSize, |
| 58 void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, FX_DWORD& dwSize, int&
type) | 70 int& type) { |
| 59 { | 71 pStart = NULL; |
| 60 pStart = NULL; | 72 dwSize = 0; |
| 61 dwSize = 0; | 73 type = PDFWORD_EOF; |
| 62 type = PDFWORD_EOF; | 74 uint8_t ch; |
| 63 uint8_t ch; | 75 char chartype; |
| 64 char chartype; | 76 while (1) { |
| 77 if (m_dwSize <= m_dwCurPos) { |
| 78 return; |
| 79 } |
| 80 ch = m_pData[m_dwCurPos++]; |
| 81 chartype = PDF_CharType[ch]; |
| 82 while (chartype == 'W') { |
| 83 if (m_dwSize <= m_dwCurPos) { |
| 84 return; |
| 85 } |
| 86 ch = m_pData[m_dwCurPos++]; |
| 87 chartype = PDF_CharType[ch]; |
| 88 } |
| 89 if (ch != '%') { |
| 90 break; |
| 91 } |
| 65 while (1) { | 92 while (1) { |
| 93 if (m_dwSize <= m_dwCurPos) { |
| 94 return; |
| 95 } |
| 96 ch = m_pData[m_dwCurPos++]; |
| 97 if (ch == '\r' || ch == '\n') { |
| 98 break; |
| 99 } |
| 100 } |
| 101 chartype = PDF_CharType[ch]; |
| 102 } |
| 103 FX_DWORD start_pos = m_dwCurPos - 1; |
| 104 pStart = m_pData + start_pos; |
| 105 if (chartype == 'D') { |
| 106 if (ch == '/') { |
| 107 while (1) { |
| 66 if (m_dwSize <= m_dwCurPos) { | 108 if (m_dwSize <= m_dwCurPos) { |
| 67 return; | 109 return; |
| 68 } | 110 } |
| 69 ch = m_pData[m_dwCurPos++]; | 111 ch = m_pData[m_dwCurPos++]; |
| 70 chartype = PDF_CharType[ch]; | 112 chartype = PDF_CharType[ch]; |
| 71 while (chartype == 'W') { | 113 if (chartype != 'R' && chartype != 'N') { |
| 72 if (m_dwSize <= m_dwCurPos) { | 114 m_dwCurPos--; |
| 73 return; | 115 dwSize = m_dwCurPos - start_pos; |
| 74 } | 116 type = PDFWORD_NAME; |
| 75 ch = m_pData[m_dwCurPos++]; | 117 return; |
| 76 chartype = PDF_CharType[ch]; | 118 } |
| 77 } | 119 } |
| 78 if (ch != '%') { | 120 } else { |
| 79 break; | 121 type = PDFWORD_DELIMITER; |
| 80 } | 122 dwSize = 1; |
| 81 while (1) { | 123 if (ch == '<') { |
| 82 if (m_dwSize <= m_dwCurPos) { | 124 if (m_dwSize <= m_dwCurPos) { |
| 83 return; | 125 return; |
| 84 } | 126 } |
| 85 ch = m_pData[m_dwCurPos++]; | 127 ch = m_pData[m_dwCurPos++]; |
| 86 if (ch == '\r' || ch == '\n') { | 128 if (ch == '<') { |
| 87 break; | 129 dwSize = 2; |
| 88 } | |
| 89 } | |
| 90 chartype = PDF_CharType[ch]; | |
| 91 } | |
| 92 FX_DWORD start_pos = m_dwCurPos - 1; | |
| 93 pStart = m_pData + start_pos; | |
| 94 if (chartype == 'D') { | |
| 95 if (ch == '/') { | |
| 96 while (1) { | |
| 97 if (m_dwSize <= m_dwCurPos) { | |
| 98 return; | |
| 99 } | |
| 100 ch = m_pData[m_dwCurPos++]; | |
| 101 chartype = PDF_CharType[ch]; | |
| 102 if (chartype != 'R' && chartype != 'N') { | |
| 103 m_dwCurPos --; | |
| 104 dwSize = m_dwCurPos - start_pos; | |
| 105 type = PDFWORD_NAME; | |
| 106 return; | |
| 107 } | |
| 108 } | |
| 109 } else { | 130 } else { |
| 110 type = PDFWORD_DELIMITER; | 131 m_dwCurPos--; |
| 111 dwSize = 1; | 132 } |
| 112 if (ch == '<') { | 133 } else if (ch == '>') { |
| 113 if (m_dwSize <= m_dwCurPos) { | |
| 114 return; | |
| 115 } | |
| 116 ch = m_pData[m_dwCurPos++]; | |
| 117 if (ch == '<') { | |
| 118 dwSize = 2; | |
| 119 } else { | |
| 120 m_dwCurPos --; | |
| 121 } | |
| 122 } else if (ch == '>') { | |
| 123 if (m_dwSize <= m_dwCurPos) { | |
| 124 return; | |
| 125 } | |
| 126 ch = m_pData[m_dwCurPos++]; | |
| 127 if (ch == '>') { | |
| 128 dwSize = 2; | |
| 129 } else { | |
| 130 m_dwCurPos --; | |
| 131 } | |
| 132 } | |
| 133 } | |
| 134 return; | |
| 135 } | |
| 136 type = PDFWORD_NUMBER; | |
| 137 dwSize = 1; | |
| 138 while (1) { | |
| 139 if (chartype != 'N') { | |
| 140 type = PDFWORD_TEXT; | |
| 141 } | |
| 142 if (m_dwSize <= m_dwCurPos) { | 134 if (m_dwSize <= m_dwCurPos) { |
| 143 return; | 135 return; |
| 144 } | 136 } |
| 145 ch = m_pData[m_dwCurPos++]; | 137 ch = m_pData[m_dwCurPos++]; |
| 146 chartype = PDF_CharType[ch]; | 138 if (ch == '>') { |
| 147 if (chartype == 'D' || chartype == 'W') { | 139 dwSize = 2; |
| 148 m_dwCurPos --; | 140 } else { |
| 149 break; | 141 m_dwCurPos--; |
| 150 } | 142 } |
| 151 dwSize ++; | 143 } |
| 152 } | 144 } |
| 153 } | 145 return; |
| 154 CFX_ByteStringC CPDF_SimpleParser::GetWord() | 146 } |
| 155 { | 147 type = PDFWORD_NUMBER; |
| 156 const uint8_t* pStart; | 148 dwSize = 1; |
| 157 FX_DWORD dwSize; | 149 while (1) { |
| 158 int type; | 150 if (chartype != 'N') { |
| 159 ParseWord(pStart, dwSize, type); | 151 type = PDFWORD_TEXT; |
| 160 if (dwSize == 1 && pStart[0] == '<') { | 152 } |
| 161 while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { | 153 if (m_dwSize <= m_dwCurPos) { |
| 162 m_dwCurPos ++; | 154 return; |
| 163 } | 155 } |
| 164 if (m_dwCurPos < m_dwSize) { | 156 ch = m_pData[m_dwCurPos++]; |
| 165 m_dwCurPos ++; | 157 chartype = PDF_CharType[ch]; |
| 166 } | 158 if (chartype == 'D' || chartype == 'W') { |
| 167 return CFX_ByteStringC(pStart, (FX_STRSIZE)(m_dwCurPos - (pStart - m_pDa
ta))); | 159 m_dwCurPos--; |
| 168 } | 160 break; |
| 169 if (dwSize == 1 && pStart[0] == '(') { | 161 } |
| 170 int level = 1; | 162 dwSize++; |
| 171 while (m_dwCurPos < m_dwSize) { | 163 } |
| 172 if (m_pData[m_dwCurPos] == ')') { | 164 } |
| 173 level --; | 165 CFX_ByteStringC CPDF_SimpleParser::GetWord() { |
| 174 if (level == 0) { | 166 const uint8_t* pStart; |
| 175 break; | 167 FX_DWORD dwSize; |
| 176 } | 168 int type; |
| 177 } | 169 ParseWord(pStart, dwSize, type); |
| 178 if (m_pData[m_dwCurPos] == '\\') { | 170 if (dwSize == 1 && pStart[0] == '<') { |
| 179 if (m_dwSize <= m_dwCurPos) { | 171 while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { |
| 180 break; | 172 m_dwCurPos++; |
| 181 } | 173 } |
| 182 m_dwCurPos ++; | 174 if (m_dwCurPos < m_dwSize) { |
| 183 } else if (m_pData[m_dwCurPos] == '(') { | 175 m_dwCurPos++; |
| 184 level ++; | 176 } |
| 185 } | 177 return CFX_ByteStringC(pStart, |
| 186 if (m_dwSize <= m_dwCurPos) { | 178 (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); |
| 187 break; | 179 } |
| 188 } | 180 if (dwSize == 1 && pStart[0] == '(') { |
| 189 m_dwCurPos ++; | 181 int level = 1; |
| 190 } | 182 while (m_dwCurPos < m_dwSize) { |
| 191 if (m_dwCurPos < m_dwSize) { | 183 if (m_pData[m_dwCurPos] == ')') { |
| 192 m_dwCurPos ++; | 184 level--; |
| 193 } | 185 if (level == 0) { |
| 194 return CFX_ByteStringC(pStart, (FX_STRSIZE)(m_dwCurPos - (pStart - m_pDa
ta))); | 186 break; |
| 195 } | 187 } |
| 196 return CFX_ByteStringC(pStart, dwSize); | 188 } |
| 197 } | 189 if (m_pData[m_dwCurPos] == '\\') { |
| 198 FX_BOOL CPDF_SimpleParser::SearchToken(const CFX_ByteStringC& token) | 190 if (m_dwSize <= m_dwCurPos) { |
| 199 { | 191 break; |
| 200 int token_len = token.GetLength(); | 192 } |
| 201 while (m_dwCurPos < m_dwSize - token_len) { | 193 m_dwCurPos++; |
| 202 if (FXSYS_memcmp(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0)
{ | 194 } else if (m_pData[m_dwCurPos] == '(') { |
| 203 break; | 195 level++; |
| 204 } | 196 } |
| 205 m_dwCurPos ++; | 197 if (m_dwSize <= m_dwCurPos) { |
| 206 } | 198 break; |
| 207 if (m_dwCurPos == m_dwSize - token_len) { | 199 } |
| 208 return FALSE; | 200 m_dwCurPos++; |
| 209 } | 201 } |
| 210 m_dwCurPos += token_len; | 202 if (m_dwCurPos < m_dwSize) { |
| 211 return TRUE; | 203 m_dwCurPos++; |
| 212 } | 204 } |
| 213 FX_BOOL CPDF_SimpleParser::SkipWord(const CFX_ByteStringC& token) | 205 return CFX_ByteStringC(pStart, |
| 214 { | 206 (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); |
| 215 while (1) { | 207 } |
| 216 CFX_ByteStringC word = GetWord(); | 208 return CFX_ByteStringC(pStart, dwSize); |
| 217 if (word.IsEmpty()) { | 209 } |
| 218 return FALSE; | 210 FX_BOOL CPDF_SimpleParser::SearchToken(const CFX_ByteStringC& token) { |
| 219 } | 211 int token_len = token.GetLength(); |
| 220 if (word == token) { | 212 while (m_dwCurPos < m_dwSize - token_len) { |
| 221 return TRUE; | 213 if (FXSYS_memcmp(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0) { |
| 222 } | 214 break; |
| 223 } | 215 } |
| 216 m_dwCurPos++; |
| 217 } |
| 218 if (m_dwCurPos == m_dwSize - token_len) { |
| 224 return FALSE; | 219 return FALSE; |
| 225 } | 220 } |
| 226 FX_BOOL CPDF_SimpleParser::FindTagPair(const CFX_ByteStringC& start_token, const
CFX_ByteStringC& end_token, | 221 m_dwCurPos += token_len; |
| 227 FX_DWORD& start_pos, FX_DWORD& end_pos) | 222 return TRUE; |
| 228 { | 223 } |
| 229 if (!start_token.IsEmpty()) { | 224 FX_BOOL CPDF_SimpleParser::SkipWord(const CFX_ByteStringC& token) { |
| 230 if (!SkipWord(start_token)) { | 225 while (1) { |
| 231 return FALSE; | 226 CFX_ByteStringC word = GetWord(); |
| 232 } | 227 if (word.IsEmpty()) { |
| 233 start_pos = m_dwCurPos; | 228 return FALSE; |
| 234 } | 229 } |
| 235 while (1) { | 230 if (word == token) { |
| 236 end_pos = m_dwCurPos; | 231 return TRUE; |
| 237 CFX_ByteStringC word = GetWord(); | 232 } |
| 238 if (word.IsEmpty()) { | 233 } |
| 239 return FALSE; | 234 return FALSE; |
| 240 } | 235 } |
| 241 if (word == end_token) { | 236 FX_BOOL CPDF_SimpleParser::FindTagPair(const CFX_ByteStringC& start_token, |
| 242 return TRUE; | 237 const CFX_ByteStringC& end_token, |
| 243 } | 238 FX_DWORD& start_pos, |
| 244 } | 239 FX_DWORD& end_pos) { |
| 245 return FALSE; | 240 if (!start_token.IsEmpty()) { |
| 246 } | 241 if (!SkipWord(start_token)) { |
| 247 FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token, int nParam
s) | 242 return FALSE; |
| 248 { | 243 } |
| 249 nParams ++; | 244 start_pos = m_dwCurPos; |
| 250 FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); | 245 } |
| 251 int buf_index = 0; | 246 while (1) { |
| 252 int buf_count = 0; | 247 end_pos = m_dwCurPos; |
| 253 while (1) { | 248 CFX_ByteStringC word = GetWord(); |
| 254 pBuf[buf_index++] = m_dwCurPos; | 249 if (word.IsEmpty()) { |
| 255 if (buf_index == nParams) { | 250 return FALSE; |
| 256 buf_index = 0; | 251 } |
| 257 } | 252 if (word == end_token) { |
| 258 buf_count ++; | 253 return TRUE; |
| 259 if (buf_count > nParams) { | 254 } |
| 260 buf_count = nParams; | 255 } |
| 261 } | 256 return FALSE; |
| 262 CFX_ByteStringC word = GetWord(); | 257 } |
| 263 if (word.IsEmpty()) { | 258 FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token, |
| 264 FX_Free(pBuf); | 259 int nParams) { |
| 265 return FALSE; | 260 nParams++; |
| 266 } | 261 FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); |
| 267 if (word == token) { | 262 int buf_index = 0; |
| 268 if (buf_count < nParams) { | 263 int buf_count = 0; |
| 269 continue; | 264 while (1) { |
| 270 } | 265 pBuf[buf_index++] = m_dwCurPos; |
| 271 m_dwCurPos = pBuf[buf_index]; | 266 if (buf_index == nParams) { |
| 272 FX_Free(pBuf); | 267 buf_index = 0; |
| 273 return TRUE; | 268 } |
| 274 } | 269 buf_count++; |
| 275 } | 270 if (buf_count > nParams) { |
| 276 return FALSE; | 271 buf_count = nParams; |
| 277 } | 272 } |
| 278 static int _hex2dec(char ch) | 273 CFX_ByteStringC word = GetWord(); |
| 279 { | 274 if (word.IsEmpty()) { |
| 280 if (ch >= '0' && ch <= '9') { | 275 FX_Free(pBuf); |
| 281 return ch - '0'; | 276 return FALSE; |
| 282 } | 277 } |
| 283 if (ch >= 'a' && ch <= 'f') { | 278 if (word == token) { |
| 284 return ch - 'a' + 10; | 279 if (buf_count < nParams) { |
| 285 } | 280 continue; |
| 286 if (ch >= 'A' && ch <= 'F') { | 281 } |
| 287 return ch - 'A' + 10; | 282 m_dwCurPos = pBuf[buf_index]; |
| 288 } | 283 FX_Free(pBuf); |
| 284 return TRUE; |
| 285 } |
| 286 } |
| 287 return FALSE; |
| 288 } |
| 289 static int _hex2dec(char ch) { |
| 290 if (ch >= '0' && ch <= '9') { |
| 291 return ch - '0'; |
| 292 } |
| 293 if (ch >= 'a' && ch <= 'f') { |
| 294 return ch - 'a' + 10; |
| 295 } |
| 296 if (ch >= 'A' && ch <= 'F') { |
| 297 return ch - 'A' + 10; |
| 298 } |
| 299 return 0; |
| 300 } |
| 301 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) { |
| 302 int size = bstr.GetLength(); |
| 303 const FX_CHAR* pSrc = bstr.GetCStr(); |
| 304 if (FXSYS_memchr(pSrc, '#', size) == NULL) { |
| 305 return bstr; |
| 306 } |
| 307 CFX_ByteString result; |
| 308 FX_CHAR* pDestStart = result.GetBuffer(size); |
| 309 FX_CHAR* pDest = pDestStart; |
| 310 for (int i = 0; i < size; i++) { |
| 311 if (pSrc[i] == '#' && i < size - 2) { |
| 312 *pDest++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]); |
| 313 i += 2; |
| 314 } else { |
| 315 *pDest++ = pSrc[i]; |
| 316 } |
| 317 } |
| 318 result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); |
| 319 return result; |
| 320 } |
| 321 CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) { |
| 322 if (FXSYS_memchr(orig.c_str(), '#', orig.GetLength()) == NULL) { |
| 323 return orig; |
| 324 } |
| 325 return PDF_NameDecode(CFX_ByteStringC(orig)); |
| 326 } |
| 327 CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) { |
| 328 uint8_t* src_buf = (uint8_t*)orig.c_str(); |
| 329 int src_len = orig.GetLength(); |
| 330 int dest_len = 0; |
| 331 int i; |
| 332 for (i = 0; i < src_len; i++) { |
| 333 uint8_t ch = src_buf[i]; |
| 334 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || |
| 335 PDF_CharType[ch] == 'D') { |
| 336 dest_len += 3; |
| 337 } else { |
| 338 dest_len++; |
| 339 } |
| 340 } |
| 341 if (dest_len == src_len) { |
| 342 return orig; |
| 343 } |
| 344 CFX_ByteString res; |
| 345 FX_CHAR* dest_buf = res.GetBuffer(dest_len); |
| 346 dest_len = 0; |
| 347 for (i = 0; i < src_len; i++) { |
| 348 uint8_t ch = src_buf[i]; |
| 349 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || |
| 350 PDF_CharType[ch] == 'D') { |
| 351 dest_buf[dest_len++] = '#'; |
| 352 dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; |
| 353 dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; |
| 354 } else { |
| 355 dest_buf[dest_len++] = ch; |
| 356 } |
| 357 } |
| 358 dest_buf[dest_len] = 0; |
| 359 res.ReleaseBuffer(); |
| 360 return res; |
| 361 } |
| 362 CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) { |
| 363 if (pObj == NULL) { |
| 364 buf << FX_BSTRC(" null"); |
| 365 return buf; |
| 366 } |
| 367 switch (pObj->GetType()) { |
| 368 case PDFOBJ_NULL: |
| 369 buf << FX_BSTRC(" null"); |
| 370 break; |
| 371 case PDFOBJ_BOOLEAN: |
| 372 case PDFOBJ_NUMBER: |
| 373 buf << " " << pObj->GetString(); |
| 374 break; |
| 375 case PDFOBJ_STRING: { |
| 376 CFX_ByteString str = pObj->GetString(); |
| 377 FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); |
| 378 buf << PDF_EncodeString(str, bHex); |
| 379 break; |
| 380 } |
| 381 case PDFOBJ_NAME: { |
| 382 CFX_ByteString str = pObj->GetString(); |
| 383 buf << FX_BSTRC("/") << PDF_NameEncode(str); |
| 384 break; |
| 385 } |
| 386 case PDFOBJ_REFERENCE: { |
| 387 CPDF_Reference* p = (CPDF_Reference*)pObj; |
| 388 buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R "); |
| 389 break; |
| 390 } |
| 391 case PDFOBJ_ARRAY: { |
| 392 CPDF_Array* p = (CPDF_Array*)pObj; |
| 393 buf << FX_BSTRC("["); |
| 394 for (FX_DWORD i = 0; i < p->GetCount(); i++) { |
| 395 CPDF_Object* pElement = p->GetElement(i); |
| 396 if (pElement->GetObjNum()) { |
| 397 buf << " " << pElement->GetObjNum() << FX_BSTRC(" 0 R"); |
| 398 } else { |
| 399 buf << pElement; |
| 400 } |
| 401 } |
| 402 buf << FX_BSTRC("]"); |
| 403 break; |
| 404 } |
| 405 case PDFOBJ_DICTIONARY: { |
| 406 CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; |
| 407 buf << FX_BSTRC("<<"); |
| 408 FX_POSITION pos = p->GetStartPos(); |
| 409 while (pos) { |
| 410 CFX_ByteString key; |
| 411 CPDF_Object* pValue = p->GetNextElement(pos, key); |
| 412 buf << FX_BSTRC("/") << PDF_NameEncode(key); |
| 413 if (pValue->GetObjNum()) { |
| 414 buf << " " << pValue->GetObjNum() << FX_BSTRC(" 0 R "); |
| 415 } else { |
| 416 buf << pValue; |
| 417 } |
| 418 } |
| 419 buf << FX_BSTRC(">>"); |
| 420 break; |
| 421 } |
| 422 case PDFOBJ_STREAM: { |
| 423 CPDF_Stream* p = (CPDF_Stream*)pObj; |
| 424 buf << p->GetDict() << FX_BSTRC("stream\r\n"); |
| 425 CPDF_StreamAcc acc; |
| 426 acc.LoadAllData(p, TRUE); |
| 427 buf.AppendBlock(acc.GetData(), acc.GetSize()); |
| 428 buf << FX_BSTRC("\r\nendstream"); |
| 429 break; |
| 430 } |
| 431 default: |
| 432 ASSERT(FALSE); |
| 433 break; |
| 434 } |
| 435 return buf; |
| 436 } |
| 437 FX_FLOAT PDF_ClipFloat(FX_FLOAT f) { |
| 438 if (f < 0) { |
| 289 return 0; | 439 return 0; |
| 290 } | 440 } |
| 291 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) | 441 if (f > 1.0f) { |
| 292 { | 442 return 1.0f; |
| 293 int size = bstr.GetLength(); | 443 } |
| 294 const FX_CHAR* pSrc = bstr.GetCStr(); | 444 return f; |
| 295 if (FXSYS_memchr(pSrc, '#', size) == NULL) { | 445 } |
| 296 return bstr; | 446 static CPDF_Object* SearchNumberNode(CPDF_Dictionary* pNode, int num) { |
| 297 } | 447 CPDF_Array* pLimits = pNode->GetArray("Limits"); |
| 298 CFX_ByteString result; | 448 if (pLimits && |
| 299 FX_CHAR* pDestStart = result.GetBuffer(size); | 449 (num < pLimits->GetInteger(0) || num > pLimits->GetInteger(1))) { |
| 300 FX_CHAR* pDest = pDestStart; | |
| 301 for (int i = 0; i < size; i ++) { | |
| 302 if (pSrc[i] == '#' && i < size - 2) { | |
| 303 *pDest ++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]); | |
| 304 i += 2; | |
| 305 } else { | |
| 306 *pDest ++ = pSrc[i]; | |
| 307 } | |
| 308 } | |
| 309 result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); | |
| 310 return result; | |
| 311 } | |
| 312 CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) | |
| 313 { | |
| 314 if (FXSYS_memchr(orig.c_str(), '#', orig.GetLength()) == NULL) { | |
| 315 return orig; | |
| 316 } | |
| 317 return PDF_NameDecode(CFX_ByteStringC(orig)); | |
| 318 } | |
| 319 CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) | |
| 320 { | |
| 321 uint8_t* src_buf = (uint8_t*)orig.c_str(); | |
| 322 int src_len = orig.GetLength(); | |
| 323 int dest_len = 0; | |
| 324 int i; | |
| 325 for (i = 0; i < src_len; i ++) { | |
| 326 uint8_t ch = src_buf[i]; | |
| 327 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || | |
| 328 PDF_CharType[ch] == 'D') { | |
| 329 dest_len += 3; | |
| 330 } else { | |
| 331 dest_len ++; | |
| 332 } | |
| 333 } | |
| 334 if (dest_len == src_len) { | |
| 335 return orig; | |
| 336 } | |
| 337 CFX_ByteString res; | |
| 338 FX_CHAR* dest_buf = res.GetBuffer(dest_len); | |
| 339 dest_len = 0; | |
| 340 for (i = 0; i < src_len; i ++) { | |
| 341 uint8_t ch = src_buf[i]; | |
| 342 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || | |
| 343 PDF_CharType[ch] == 'D') { | |
| 344 dest_buf[dest_len++] = '#'; | |
| 345 dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; | |
| 346 dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; | |
| 347 } else { | |
| 348 dest_buf[dest_len++] = ch; | |
| 349 } | |
| 350 } | |
| 351 dest_buf[dest_len] = 0; | |
| 352 res.ReleaseBuffer(); | |
| 353 return res; | |
| 354 } | |
| 355 CFX_ByteTextBuf& operator << (CFX_ByteTextBuf& buf, const CPDF_Object* pObj) | |
| 356 { | |
| 357 if (pObj == NULL) { | |
| 358 buf << FX_BSTRC(" null"); | |
| 359 return buf; | |
| 360 } | |
| 361 switch (pObj->GetType()) { | |
| 362 case PDFOBJ_NULL: | |
| 363 buf << FX_BSTRC(" null"); | |
| 364 break; | |
| 365 case PDFOBJ_BOOLEAN: | |
| 366 case PDFOBJ_NUMBER: | |
| 367 buf << " " << pObj->GetString(); | |
| 368 break; | |
| 369 case PDFOBJ_STRING: { | |
| 370 CFX_ByteString str = pObj->GetString(); | |
| 371 FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); | |
| 372 buf << PDF_EncodeString(str, bHex); | |
| 373 break; | |
| 374 } | |
| 375 case PDFOBJ_NAME: { | |
| 376 CFX_ByteString str = pObj->GetString(); | |
| 377 buf << FX_BSTRC("/") << PDF_NameEncode(str); | |
| 378 break; | |
| 379 } | |
| 380 case PDFOBJ_REFERENCE: { | |
| 381 CPDF_Reference* p = (CPDF_Reference*)pObj; | |
| 382 buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R "); | |
| 383 break; | |
| 384 } | |
| 385 case PDFOBJ_ARRAY: { | |
| 386 CPDF_Array* p = (CPDF_Array*)pObj; | |
| 387 buf << FX_BSTRC("["); | |
| 388 for (FX_DWORD i = 0; i < p->GetCount(); i ++) { | |
| 389 CPDF_Object* pElement = p->GetElement(i); | |
| 390 if (pElement->GetObjNum()) { | |
| 391 buf << " " << pElement->GetObjNum() << FX_BSTRC(" 0 R"); | |
| 392 } else { | |
| 393 buf << pElement; | |
| 394 } | |
| 395 } | |
| 396 buf << FX_BSTRC("]"); | |
| 397 break; | |
| 398 } | |
| 399 case PDFOBJ_DICTIONARY: { | |
| 400 CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; | |
| 401 buf << FX_BSTRC("<<"); | |
| 402 FX_POSITION pos = p->GetStartPos(); | |
| 403 while (pos) { | |
| 404 CFX_ByteString key; | |
| 405 CPDF_Object* pValue = p->GetNextElement(pos, key); | |
| 406 buf << FX_BSTRC("/") << PDF_NameEncode(key); | |
| 407 if (pValue->GetObjNum()) { | |
| 408 buf << " " << pValue->GetObjNum() << FX_BSTRC(" 0 R "); | |
| 409 } else { | |
| 410 buf << pValue; | |
| 411 } | |
| 412 } | |
| 413 buf << FX_BSTRC(">>"); | |
| 414 break; | |
| 415 } | |
| 416 case PDFOBJ_STREAM: { | |
| 417 CPDF_Stream* p = (CPDF_Stream*)pObj; | |
| 418 buf << p->GetDict() << FX_BSTRC("stream\r\n"); | |
| 419 CPDF_StreamAcc acc; | |
| 420 acc.LoadAllData(p, TRUE); | |
| 421 buf.AppendBlock(acc.GetData(), acc.GetSize()); | |
| 422 buf << FX_BSTRC("\r\nendstream"); | |
| 423 break; | |
| 424 } | |
| 425 default: | |
| 426 ASSERT(FALSE); | |
| 427 break; | |
| 428 } | |
| 429 return buf; | |
| 430 } | |
| 431 FX_FLOAT PDF_ClipFloat(FX_FLOAT f) | |
| 432 { | |
| 433 if (f < 0) { | |
| 434 return 0; | |
| 435 } | |
| 436 if (f > 1.0f) { | |
| 437 return 1.0f; | |
| 438 } | |
| 439 return f; | |
| 440 } | |
| 441 static CPDF_Object* SearchNumberNode(CPDF_Dictionary* pNode, int num) | |
| 442 { | |
| 443 CPDF_Array* pLimits = pNode->GetArray("Limits"); | |
| 444 if (pLimits && (num < pLimits->GetInteger(0) || num > pLimits->GetInteger(1)
)) { | |
| 445 return NULL; | |
| 446 } | |
| 447 CPDF_Array* pNumbers = pNode->GetArray("Nums"); | |
| 448 if (pNumbers) { | |
| 449 FX_DWORD dwCount = pNumbers->GetCount() / 2; | |
| 450 for (FX_DWORD i = 0; i < dwCount; i ++) { | |
| 451 int index = pNumbers->GetInteger(i * 2); | |
| 452 if (num == index) { | |
| 453 return pNumbers->GetElementValue(i * 2 + 1); | |
| 454 } | |
| 455 if (index > num) { | |
| 456 break; | |
| 457 } | |
| 458 } | |
| 459 return NULL; | |
| 460 } | |
| 461 CPDF_Array* pKids = pNode->GetArray("Kids"); | |
| 462 if (pKids == NULL) { | |
| 463 return NULL; | |
| 464 } | |
| 465 for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) { | |
| 466 CPDF_Dictionary* pKid = pKids->GetDict(i); | |
| 467 if (pKid == NULL) { | |
| 468 continue; | |
| 469 } | |
| 470 CPDF_Object* pFound = SearchNumberNode(pKid, num); | |
| 471 if (pFound) { | |
| 472 return pFound; | |
| 473 } | |
| 474 } | |
| 475 return NULL; | 450 return NULL; |
| 476 } | 451 } |
| 477 CPDF_Object* CPDF_NumberTree::LookupValue(int num) | 452 CPDF_Array* pNumbers = pNode->GetArray("Nums"); |
| 478 { | 453 if (pNumbers) { |
| 479 return SearchNumberNode(m_pRoot, num); | 454 FX_DWORD dwCount = pNumbers->GetCount() / 2; |
| 480 } | 455 for (FX_DWORD i = 0; i < dwCount; i++) { |
| 456 int index = pNumbers->GetInteger(i * 2); |
| 457 if (num == index) { |
| 458 return pNumbers->GetElementValue(i * 2 + 1); |
| 459 } |
| 460 if (index > num) { |
| 461 break; |
| 462 } |
| 463 } |
| 464 return NULL; |
| 465 } |
| 466 CPDF_Array* pKids = pNode->GetArray("Kids"); |
| 467 if (pKids == NULL) { |
| 468 return NULL; |
| 469 } |
| 470 for (FX_DWORD i = 0; i < pKids->GetCount(); i++) { |
| 471 CPDF_Dictionary* pKid = pKids->GetDict(i); |
| 472 if (pKid == NULL) { |
| 473 continue; |
| 474 } |
| 475 CPDF_Object* pFound = SearchNumberNode(pKid, num); |
| 476 if (pFound) { |
| 477 return pFound; |
| 478 } |
| 479 } |
| 480 return NULL; |
| 481 } |
| 482 CPDF_Object* CPDF_NumberTree::LookupValue(int num) { |
| 483 return SearchNumberNode(m_pRoot, num); |
| 484 } |
| OLD | NEW |