1// Copyright 2014 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7#include "../../../include/fpdfapi/fpdf_parser.h" 8#include "../../../include/fxcrt/fx_string.h" 9 10//static 11int CPDF_Object::s_nCurRefDepth = 0; 12 13void CPDF_Object::Release() 14{ 15 if (m_ObjNum) { 16 return; 17 } 18 Destroy(); 19} 20void CPDF_Object::Destroy() 21{ 22 switch (m_Type) { 23 case PDFOBJ_STRING: 24 delete (CPDF_String*)this; 25 break; 26 case PDFOBJ_NAME: 27 delete (CPDF_Name*)this; 28 break; 29 case PDFOBJ_ARRAY: 30 delete (CPDF_Array*)this; 31 break; 32 case PDFOBJ_DICTIONARY: 33 delete (CPDF_Dictionary*)this; 34 break; 35 case PDFOBJ_STREAM: 36 delete (CPDF_Stream*)this; 37 break; 38 default: 39 delete this; 40 } 41} 42CFX_ByteString CPDF_Object::GetString() const 43{ 44 switch (m_Type) { 45 case PDFOBJ_BOOLEAN: 46 return ((CPDF_Boolean*)this)->m_bValue ? "true" : "false"; 47 case PDFOBJ_NUMBER: 48 return ((CPDF_Number*)this)->GetString(); 49 case PDFOBJ_STRING: 50 return ((CPDF_String*)this)->m_String; 51 case PDFOBJ_NAME: 52 return ((CPDF_Name*)this)->m_Name; 53 case PDFOBJ_REFERENCE: { 54 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this; 55 if (pRef->m_pObjList == NULL) { 56 break; 57 } 58 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 59 if (pObj == NULL) { 60 return CFX_ByteString(); 61 } 62 return pObj->GetString(); 63 } 64 } 65 return CFX_ByteString(); 66} 67CFX_ByteStringC CPDF_Object::GetConstString() const 68{ 69 switch (m_Type) { 70 case PDFOBJ_STRING: 71 return CFX_ByteStringC((FX_LPCBYTE)((CPDF_String*)this)->m_String, ((CPDF_String*)this)->m_String.GetLength()); 72 case PDFOBJ_NAME: 73 return CFX_ByteStringC((FX_LPCBYTE)((CPDF_Name*)this)->m_Name, ((CPDF_Name*)this)->m_Name.GetLength()); 74 case PDFOBJ_REFERENCE: { 75 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this; 76 if (pRef->m_pObjList == NULL) { 77 break; 78 } 79 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 80 if (pObj == NULL) { 81 return CFX_ByteStringC(); 82 } 83 return pObj->GetConstString(); 84 } 85 } 86 return CFX_ByteStringC(); 87} 88FX_FLOAT CPDF_Object::GetNumber() const 89{ 90 switch (m_Type) { 91 case PDFOBJ_NUMBER: 92 return ((CPDF_Number*)this)->GetNumber(); 93 case PDFOBJ_REFERENCE: { 94 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this; 95 if (pRef->m_pObjList == NULL) { 96 break; 97 } 98 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 99 if (pObj == NULL) { 100 return 0; 101 } 102 return pObj->GetNumber(); 103 } 104 } 105 return 0; 106} 107FX_FLOAT CPDF_Object::GetNumber16() const 108{ 109 return GetNumber(); 110} 111int CPDF_Object::GetInteger() const 112{ 113 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); 114 if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) { 115 return 0; 116 } 117 switch (m_Type) { 118 case PDFOBJ_BOOLEAN: 119 return ((CPDF_Boolean*)this)->m_bValue; 120 case PDFOBJ_NUMBER: 121 return ((CPDF_Number*)this)->GetInteger(); 122 case PDFOBJ_REFERENCE: { 123 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this; 124 PARSE_CONTEXT context; 125 FXSYS_memset32(&context, 0, sizeof(PARSE_CONTEXT)); 126 if (pRef->m_pObjList == NULL) { 127 return 0; 128 } 129 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum, &context); 130 if (pObj == NULL) { 131 return 0; 132 } 133 return pObj->GetInteger(); 134 } 135 } 136 return 0; 137} 138CPDF_Dictionary* CPDF_Object::GetDict() const 139{ 140 switch (m_Type) { 141 case PDFOBJ_DICTIONARY: 142 return (CPDF_Dictionary*)this; 143 case PDFOBJ_STREAM: 144 return ((CPDF_Stream*)this)->GetDict(); 145 case PDFOBJ_REFERENCE: { 146 CPDF_Reference* pRef = (CPDF_Reference*)this; 147 if (pRef->m_pObjList == NULL) { 148 break; 149 } 150 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 151 if (pObj == NULL) { 152 return NULL; 153 } 154 return pObj->GetDict(); 155 } 156 } 157 return NULL; 158} 159CPDF_Array* CPDF_Object::GetArray() const 160{ 161 if (m_Type == PDFOBJ_ARRAY) 162 return (CPDF_Array*)this; 163 else 164 return NULL; 165} 166void CPDF_Object::SetString(const CFX_ByteString& str) 167{ 168 ASSERT(this != NULL); 169 switch (m_Type) { 170 case PDFOBJ_BOOLEAN: 171 ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0; 172 return; 173 case PDFOBJ_NUMBER: 174 ((CPDF_Number*)this)->SetString(str); 175 return; 176 case PDFOBJ_STRING: 177 ((CPDF_String*)this)->m_String = str; 178 return; 179 case PDFOBJ_NAME: 180 ((CPDF_Name*)this)->m_Name = str; 181 return; 182 } 183 ASSERT(FALSE); 184} 185int CPDF_Object::GetDirectType() const 186{ 187 if (m_Type != PDFOBJ_REFERENCE) { 188 return m_Type; 189 } 190 CPDF_Reference* pRef = (CPDF_Reference*)this; 191 return pRef->m_pObjList->GetIndirectType(pRef->m_RefObjNum); 192} 193FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const 194{ 195 if (this == pOther) { 196 return TRUE; 197 } 198 if (pOther == NULL) { 199 return FALSE; 200 } 201 if (pOther->m_Type != m_Type) { 202 if (m_Type == PDFOBJ_REFERENCE && GetDirect()) { 203 return GetDirect()->IsIdentical(pOther); 204 } else if (pOther->m_Type == PDFOBJ_REFERENCE) { 205 return IsIdentical(pOther->GetDirect()); 206 } 207 return FALSE; 208 } 209 switch (m_Type) { 210 case PDFOBJ_BOOLEAN: 211 return (((CPDF_Boolean*)this)->Identical((CPDF_Boolean*)pOther)); 212 case PDFOBJ_NUMBER: 213 return (((CPDF_Number*)this)->Identical((CPDF_Number*)pOther)); 214 case PDFOBJ_STRING: 215 return (((CPDF_String*)this)->Identical((CPDF_String*)pOther)); 216 case PDFOBJ_NAME: 217 return (((CPDF_Name*)this)->Identical((CPDF_Name*)pOther)); 218 case PDFOBJ_ARRAY: 219 return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther)); 220 case PDFOBJ_DICTIONARY: 221 return (((CPDF_Dictionary*)this)->Identical((CPDF_Dictionary*)pOther)); 222 case PDFOBJ_NULL: 223 return TRUE; 224 case PDFOBJ_STREAM: 225 return (((CPDF_Stream*)this)->Identical((CPDF_Stream*)pOther)); 226 case PDFOBJ_REFERENCE: 227 return (((CPDF_Reference*)this)->Identical((CPDF_Reference*)pOther)); 228 } 229 return FALSE; 230} 231CPDF_Object* CPDF_Object::GetDirect() const 232{ 233 if (m_Type != PDFOBJ_REFERENCE) { 234 return (CPDF_Object*)this; 235 } 236 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this; 237 if (pRef->m_pObjList == NULL) { 238 return NULL; 239 } 240 return pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 241} 242CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const 243{ 244 CFX_MapPtrToPtr visited; 245 return CloneInternal(bDirect, &visited); 246} 247CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const 248{ 249 switch (m_Type) { 250 case PDFOBJ_BOOLEAN: 251 return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue); 252 case PDFOBJ_NUMBER: 253 return new CPDF_Number(((CPDF_Number*)this)->m_bInteger, &((CPDF_Number*)this)->m_Integer); 254 case PDFOBJ_STRING: 255 return new CPDF_String(((CPDF_String*)this)->m_String, ((CPDF_String*)this)->IsHex()); 256 case PDFOBJ_NAME: 257 return new CPDF_Name(((CPDF_Name*)this)->m_Name); 258 case PDFOBJ_ARRAY: { 259 CPDF_Array* pCopy = new CPDF_Array(); 260 CPDF_Array* pThis = (CPDF_Array*)this; 261 int n = pThis->GetCount(); 262 for (int i = 0; i < n; i ++) { 263 CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i); 264 pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); 265 } 266 return pCopy; 267 } 268 case PDFOBJ_DICTIONARY: { 269 CPDF_Dictionary* pCopy = new CPDF_Dictionary(); 270 CPDF_Dictionary* pThis = (CPDF_Dictionary*)this; 271 FX_POSITION pos = pThis->m_Map.GetStartPosition(); 272 while (pos) { 273 CFX_ByteString key; 274 CPDF_Object* value; 275 pThis->m_Map.GetNextAssoc(pos, key, (void*&)value); 276 pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited)); 277 } 278 return pCopy; 279 } 280 case PDFOBJ_NULL: { 281 return new CPDF_Null; 282 } 283 case PDFOBJ_STREAM: { 284 CPDF_Stream* pThis = (CPDF_Stream*)this; 285 CPDF_StreamAcc acc; 286 acc.LoadAllData(pThis, TRUE); 287 FX_DWORD streamSize = acc.GetSize(); 288 CPDF_Stream* pObj; 289 if (pThis->GetDict()) 290 pObj = new CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited)); 291 else 292 pObj = new CPDF_Stream(acc.DetachData(), streamSize, NULL); 293 return pObj; 294 } 295 case PDFOBJ_REFERENCE: { 296 CPDF_Reference* pRef = (CPDF_Reference*)this; 297 FX_DWORD obj_num = pRef->m_RefObjNum; 298 if (bDirect && !visited->GetValueAt((void*)(FX_UINTPTR)obj_num)) { 299 visited->SetAt((void*)(FX_UINTPTR)obj_num, (void*)1); 300 CPDF_Object* ret; 301 if (pRef->GetDirect()) 302 ret = pRef->GetDirect()->CloneInternal(TRUE, visited); 303 else 304 ret = NULL; 305 return ret; 306 } else { 307 return new CPDF_Reference(pRef->m_pObjList, obj_num); 308 } 309 } 310 } 311 return NULL; 312} 313CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const 314{ 315 if (m_ObjNum) { 316 return new CPDF_Reference(pDoc, m_ObjNum); 317 } 318 return Clone(); 319} 320CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const 321{ 322 if (m_Type == PDFOBJ_STRING) { 323 return PDF_DecodeText(((CPDF_String*)this)->m_String, pCharMap); 324 } else if (m_Type == PDFOBJ_STREAM) { 325 CPDF_StreamAcc stream; 326 stream.LoadAllData((CPDF_Stream*)this, FALSE); 327 CFX_WideString result = PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); 328 return result; 329 } else if (m_Type == PDFOBJ_NAME) { 330 return PDF_DecodeText(((CPDF_Name*)this)->m_Name, pCharMap); 331 } 332 return CFX_WideString(); 333} 334void CPDF_Object::SetUnicodeText(FX_LPCWSTR pUnicodes, int len) 335{ 336 if (m_Type == PDFOBJ_STRING) { 337 ((CPDF_String*)this)->m_String = PDF_EncodeText(pUnicodes, len); 338 } else if (m_Type == PDFOBJ_STREAM) { 339 CFX_ByteString result = PDF_EncodeText(pUnicodes, len); 340 ((CPDF_Stream*)this)->SetData((FX_LPBYTE)result.c_str(), result.GetLength(), FALSE, FALSE); 341 } 342} 343 344CPDF_Number::CPDF_Number(int value) 345 : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(value) { 346} 347 348CPDF_Number::CPDF_Number(FX_FLOAT value) 349 : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(FALSE), m_Float(value) { 350} 351 352CPDF_Number::CPDF_Number(FX_BOOL bInteger, void* pData) 353 : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(bInteger), m_Integer(*(int*)pData) { 354} 355 356CPDF_Number::CPDF_Number(FX_BSTR str) : CPDF_Object(PDFOBJ_NUMBER) { 357 FX_atonum(str, m_bInteger, &m_Integer); 358} 359 360void CPDF_Number::SetString(FX_BSTR str) 361{ 362 FX_atonum(str, m_bInteger, &m_Integer); 363} 364FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const 365{ 366 return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer; 367} 368CFX_ByteString CPDF_Number::GetString() const 369{ 370 return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) : CFX_ByteString::FormatFloat(m_Float); 371} 372void CPDF_Number::SetNumber(FX_FLOAT value) 373{ 374 m_bInteger = FALSE; 375 m_Float = value; 376} 377CPDF_String::CPDF_String(const CFX_WideString& str) : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) { 378 m_String = PDF_EncodeText(str); 379} 380CPDF_Array::~CPDF_Array() 381{ 382 int size = m_Objects.GetSize(); 383 CPDF_Object** pList = (CPDF_Object**)m_Objects.GetData(); 384 for (int i = 0; i < size; i ++) { 385 if (pList[i]) 386 pList[i]->Release(); 387 } 388} 389CFX_FloatRect CPDF_Array::GetRect() 390{ 391 CFX_FloatRect rect; 392 if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) { 393 return rect; 394 } 395 rect.left = GetNumber(0); 396 rect.bottom = GetNumber(1); 397 rect.right = GetNumber(2); 398 rect.top = GetNumber(3); 399 return rect; 400} 401CFX_AffineMatrix CPDF_Array::GetMatrix() 402{ 403 CFX_AffineMatrix matrix; 404 if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) { 405 return matrix; 406 } 407 matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3), GetNumber(4), GetNumber(5)); 408 return matrix; 409} 410CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const 411{ 412 if (i >= (FX_DWORD)m_Objects.GetSize()) { 413 return NULL; 414 } 415 return (CPDF_Object*)m_Objects.GetAt(i); 416} 417CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const 418{ 419 if (i >= (FX_DWORD)m_Objects.GetSize()) { 420 return NULL; 421 } 422 return ((CPDF_Object*)m_Objects.GetAt(i))->GetDirect(); 423} 424CFX_ByteString CPDF_Array::GetString(FX_DWORD i) const 425{ 426 if (i < (FX_DWORD)m_Objects.GetSize()) { 427 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); 428 return p->GetString(); 429 } 430 else 431 return CFX_ByteString(); 432} 433CFX_ByteStringC CPDF_Array::GetConstString(FX_DWORD i) const 434{ 435 if (i < (FX_DWORD)m_Objects.GetSize()) { 436 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); 437 return p->GetConstString(); 438 } 439 else 440 return CFX_ByteStringC(); 441} 442int CPDF_Array::GetInteger(FX_DWORD i) const 443{ 444 if (i >= (FX_DWORD)m_Objects.GetSize()) { 445 return 0; 446 } 447 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); 448 return p->GetInteger(); 449} 450FX_FLOAT CPDF_Array::GetNumber(FX_DWORD i) const 451{ 452 if (i >= (FX_DWORD)m_Objects.GetSize()) { 453 return 0; 454 } 455 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); 456 return p->GetNumber(); 457} 458CPDF_Dictionary* CPDF_Array::GetDict(FX_DWORD i) const 459{ 460 CPDF_Object* p = GetElementValue(i); 461 if (p == NULL) { 462 return NULL; 463 } else if (p->GetType() == PDFOBJ_DICTIONARY) { 464 return (CPDF_Dictionary*)p; 465 } else if (p->GetType() == PDFOBJ_STREAM) { 466 return ((CPDF_Stream*)p)->GetDict(); 467 } 468 return NULL; 469} 470CPDF_Stream* CPDF_Array::GetStream(FX_DWORD i) const 471{ 472 CPDF_Object* p = GetElementValue(i); 473 if (p == NULL || p->GetType() != PDFOBJ_STREAM) { 474 return NULL; 475 } 476 return (CPDF_Stream*)p; 477} 478CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const 479{ 480 CPDF_Object* p = GetElementValue(i); 481 if (p == NULL || p->GetType() != PDFOBJ_ARRAY) { 482 return NULL; 483 } 484 return (CPDF_Array*)p; 485} 486void CPDF_Array::RemoveAt(FX_DWORD i) 487{ 488 ASSERT(m_Type == PDFOBJ_ARRAY); 489 if (i >= (FX_DWORD)m_Objects.GetSize()) { 490 return; 491 } 492 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); 493 if (p) 494 p->Release(); 495 m_Objects.RemoveAt(i); 496} 497void CPDF_Array::SetAt(FX_DWORD i, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) 498{ 499 ASSERT(m_Type == PDFOBJ_ARRAY); 500 ASSERT(i < (FX_DWORD)m_Objects.GetSize()); 501 if (i >= (FX_DWORD)m_Objects.GetSize()) { 502 return; 503 } 504 CPDF_Object* pOld = (CPDF_Object*)m_Objects.GetAt(i); 505 if (pOld) 506 pOld->Release(); 507 if (pObj->GetObjNum()) { 508 ASSERT(pObjs != NULL); 509 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum()); 510 } 511 m_Objects.SetAt(i, pObj); 512} 513void CPDF_Array::InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) 514{ 515 ASSERT(pObj != NULL); 516 if (pObj->GetObjNum()) { 517 ASSERT(pObjs != NULL); 518 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum()); 519 } 520 m_Objects.InsertAt(index, pObj); 521} 522void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) 523{ 524 ASSERT(pObj != NULL); 525 if (pObj->GetObjNum()) { 526 ASSERT(pObjs != NULL); 527 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum()); 528 } 529 m_Objects.Add(pObj); 530} 531void CPDF_Array::AddName(const CFX_ByteString& str) 532{ 533 ASSERT(m_Type == PDFOBJ_ARRAY); 534 Add(new CPDF_Name(str)); 535} 536void CPDF_Array::AddString(const CFX_ByteString& str) 537{ 538 ASSERT(m_Type == PDFOBJ_ARRAY); 539 Add(new CPDF_String(str)); 540} 541void CPDF_Array::AddInteger(int i) 542{ 543 ASSERT(m_Type == PDFOBJ_ARRAY); 544 Add(new CPDF_Number(i)); 545} 546void CPDF_Array::AddNumber(FX_FLOAT f) 547{ 548 ASSERT(m_Type == PDFOBJ_ARRAY); 549 CPDF_Number* pNumber = new CPDF_Number; 550 pNumber->SetNumber(f); 551 Add(pNumber); 552} 553void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) 554{ 555 ASSERT(m_Type == PDFOBJ_ARRAY); 556 Add(new CPDF_Reference(pDoc, objnum)); 557} 558FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const 559{ 560 if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { 561 return FALSE; 562 } 563 for (int i = 0; i < m_Objects.GetSize(); i ++) 564 if (!((CPDF_Object*)m_Objects[i])->IsIdentical((CPDF_Object*)pOther->m_Objects[i])) { 565 return FALSE; 566 } 567 return TRUE; 568} 569CPDF_Dictionary::~CPDF_Dictionary() 570{ 571 FX_POSITION pos = m_Map.GetStartPosition(); 572 while (pos) { 573 FX_LPVOID value = m_Map.GetNextValue(pos); 574 if (value) 575 ((CPDF_Object*)value)->Release(); 576 } 577} 578FX_POSITION CPDF_Dictionary::GetStartPos() const 579{ 580 return m_Map.GetStartPosition(); 581} 582CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const 583{ 584 if (pos == NULL) { 585 return NULL; 586 } 587 CPDF_Object* p; 588 m_Map.GetNextAssoc(pos, key, (FX_LPVOID&)p); 589 return p; 590} 591CPDF_Object* CPDF_Dictionary::GetElement(FX_BSTR key) const 592{ 593 CPDF_Object* p = NULL; 594 m_Map.Lookup(key, (void*&)p); 595 return p; 596} 597CPDF_Object* CPDF_Dictionary::GetElementValue(FX_BSTR key) const 598{ 599 CPDF_Object* p = NULL; 600 m_Map.Lookup(key, (void*&)p); 601 return p ? p->GetDirect() : NULL; 602} 603CFX_ByteString CPDF_Dictionary::GetString(FX_BSTR key) const 604{ 605 CPDF_Object* p = NULL; 606 m_Map.Lookup(key, (void*&)p); 607 if (p) 608 return p->GetString(); 609 else 610 return CFX_ByteString(); 611} 612CFX_ByteStringC CPDF_Dictionary::GetConstString(FX_BSTR key) const 613{ 614 CPDF_Object* p = NULL; 615 m_Map.Lookup(key, (void*&)p); 616 if (p) 617 return p->GetConstString(); 618 else 619 return CFX_ByteStringC(); 620} 621CFX_WideString CPDF_Dictionary::GetUnicodeText(FX_BSTR key, CFX_CharMap* pCharMap) const 622{ 623 CPDF_Object* p = NULL; 624 m_Map.Lookup(key, (void*&)p); 625 if (p) { 626 if(p->GetType() == PDFOBJ_REFERENCE) { 627 p = ((CPDF_Reference*)p)->GetDirect(); 628 if (p) { 629 return p->GetUnicodeText(pCharMap); 630 } 631 } else { 632 return p->GetUnicodeText(pCharMap); 633 } 634 } 635 return CFX_WideString(); 636} 637CFX_ByteString CPDF_Dictionary::GetString(FX_BSTR key, FX_BSTR def) const 638{ 639 CPDF_Object* p = NULL; 640 m_Map.Lookup(key, (void*&)p); 641 if (p) { 642 return p->GetString(); 643 } 644 return CFX_ByteString(def); 645} 646CFX_ByteStringC CPDF_Dictionary::GetConstString(FX_BSTR key, FX_BSTR def) const 647{ 648 CPDF_Object* p = NULL; 649 m_Map.Lookup(key, (void*&)p); 650 if (p) 651 return p->GetConstString(); 652 else 653 return CFX_ByteStringC(def); 654} 655int CPDF_Dictionary::GetInteger(FX_BSTR key) const 656{ 657 CPDF_Object* p = NULL; 658 m_Map.Lookup(key, (void*&)p); 659 if (p) { 660 return p->GetInteger(); 661 } 662 return 0; 663} 664int CPDF_Dictionary::GetInteger(FX_BSTR key, int def) const 665{ 666 CPDF_Object* p = NULL; 667 m_Map.Lookup(key, (void*&)p); 668 if (p) { 669 return p->GetInteger(); 670 } 671 return def; 672} 673FX_FLOAT CPDF_Dictionary::GetNumber(FX_BSTR key) const 674{ 675 CPDF_Object* p = NULL; 676 m_Map.Lookup(key, (void*&)p); 677 if (p) { 678 return p->GetNumber(); 679 } 680 return 0; 681} 682FX_BOOL CPDF_Dictionary::GetBoolean(FX_BSTR key, FX_BOOL bDefault) const 683{ 684 CPDF_Object* p = NULL; 685 m_Map.Lookup(key, (void*&)p); 686 if (p && p->GetType() == PDFOBJ_BOOLEAN) { 687 return p->GetInteger(); 688 } 689 return bDefault; 690} 691CPDF_Dictionary* CPDF_Dictionary::GetDict(FX_BSTR key) const 692{ 693 CPDF_Object* p = GetElementValue(key); 694 if (p == NULL) { 695 return NULL; 696 } else if (p->GetType() == PDFOBJ_DICTIONARY) { 697 return (CPDF_Dictionary*)p; 698 } else if (p->GetType() == PDFOBJ_STREAM) { 699 return ((CPDF_Stream*)p)->GetDict(); 700 } 701 return NULL; 702} 703CPDF_Array* CPDF_Dictionary::GetArray(FX_BSTR key) const 704{ 705 CPDF_Object* p = GetElementValue(key); 706 if (p == NULL || p->GetType() != PDFOBJ_ARRAY) { 707 return NULL; 708 } 709 return (CPDF_Array*)p; 710} 711CPDF_Stream* CPDF_Dictionary::GetStream(FX_BSTR key) const 712{ 713 CPDF_Object* p = GetElementValue(key); 714 if (p == NULL || p->GetType() != PDFOBJ_STREAM) { 715 return NULL; 716 } 717 return (CPDF_Stream*)p; 718} 719CFX_FloatRect CPDF_Dictionary::GetRect(FX_BSTR key) const 720{ 721 CFX_FloatRect rect; 722 CPDF_Array* pArray = GetArray(key); 723 if (pArray) { 724 rect = pArray->GetRect(); 725 } 726 return rect; 727} 728CFX_AffineMatrix CPDF_Dictionary::GetMatrix(FX_BSTR key) const 729{ 730 CFX_AffineMatrix matrix; 731 CPDF_Array* pArray = GetArray(key); 732 if (pArray) { 733 matrix = pArray->GetMatrix(); 734 } 735 return matrix; 736} 737FX_BOOL CPDF_Dictionary::KeyExist(FX_BSTR key) const 738{ 739 FX_LPVOID value; 740 return m_Map.Lookup(key, value); 741} 742void CPDF_Dictionary::SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) 743{ 744 ASSERT(m_Type == PDFOBJ_DICTIONARY); 745 CPDF_Object* p = NULL; 746 m_Map.Lookup(key, (void*&)p); 747 if (p == pObj) { 748 return; 749 } 750 if (p) 751 p->Release(); 752 if (pObj) { 753 if (pObj->GetObjNum()) { 754 ASSERT(pObjs != NULL); 755 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum()); 756 } 757 m_Map.SetAt(key, pObj); 758 } else { 759 m_Map.RemoveKey(key); 760 } 761} 762void CPDF_Dictionary::AddValue(FX_BSTR key, CPDF_Object* pObj) 763{ 764 ASSERT(m_Type == PDFOBJ_DICTIONARY); 765 m_Map.AddValue(key, pObj); 766} 767void CPDF_Dictionary::RemoveAt(FX_BSTR key) 768{ 769 ASSERT(m_Type == PDFOBJ_DICTIONARY); 770 CPDF_Object* p = NULL; 771 m_Map.Lookup(key, (void*&)p); 772 if (p == NULL) { 773 return; 774 } 775 p->Release(); 776 m_Map.RemoveKey(key); 777} 778void CPDF_Dictionary::ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey) 779{ 780 ASSERT(m_Type == PDFOBJ_DICTIONARY); 781 CPDF_Object* p = NULL; 782 m_Map.Lookup(oldkey, (void*&)p); 783 if (p == NULL) { 784 return; 785 } 786 m_Map.RemoveKey(oldkey); 787 m_Map.SetAt(newkey, p); 788} 789FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const 790{ 791 if (pOther == NULL) { 792 return FALSE; 793 } 794 if (m_Map.GetCount() != pOther->m_Map.GetCount()) { 795 return FALSE; 796 } 797 FX_POSITION pos = m_Map.GetStartPosition(); 798 while (pos) { 799 CFX_ByteString key; 800 FX_LPVOID value; 801 m_Map.GetNextAssoc(pos, key, value); 802 if (!value) 803 return FALSE; 804 if (!((CPDF_Object*)value)->IsIdentical(pOther->GetElement(key))) { 805 return FALSE; 806 } 807 } 808 return TRUE; 809} 810void CPDF_Dictionary::SetAtInteger(FX_BSTR key, int i) 811{ 812 SetAt(key, new CPDF_Number(i)); 813} 814void CPDF_Dictionary::SetAtName(FX_BSTR key, const CFX_ByteString& name) 815{ 816 SetAt(key, new CPDF_Name(name)); 817} 818void CPDF_Dictionary::SetAtString(FX_BSTR key, const CFX_ByteString& str) 819{ 820 SetAt(key, new CPDF_String(str)); 821} 822void CPDF_Dictionary::SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum) 823{ 824 SetAt(key, new CPDF_Reference(pDoc, objnum)); 825} 826void CPDF_Dictionary::AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum) 827{ 828 AddValue(key, new CPDF_Reference(pDoc, objnum)); 829} 830void CPDF_Dictionary::SetAtNumber(FX_BSTR key, FX_FLOAT f) 831{ 832 CPDF_Number* pNumber = new CPDF_Number; 833 pNumber->SetNumber(f); 834 SetAt(key, pNumber); 835} 836void CPDF_Dictionary::SetAtBoolean(FX_BSTR key, FX_BOOL bValue) 837{ 838 SetAt(key, new CPDF_Boolean(bValue)); 839} 840void CPDF_Dictionary::SetAtRect(FX_BSTR key, const CFX_FloatRect& rect) 841{ 842 CPDF_Array* pArray = new CPDF_Array; 843 pArray->AddNumber(rect.left); 844 pArray->AddNumber(rect.bottom); 845 pArray->AddNumber(rect.right); 846 pArray->AddNumber(rect.top); 847 SetAt(key, pArray); 848} 849void CPDF_Dictionary::SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix) 850{ 851 CPDF_Array* pArray = new CPDF_Array; 852 pArray->AddNumber16(matrix.a); 853 pArray->AddNumber16(matrix.b); 854 pArray->AddNumber16(matrix.c); 855 pArray->AddNumber16(matrix.d); 856 pArray->AddNumber(matrix.e); 857 pArray->AddNumber(matrix.f); 858 SetAt(key, pArray); 859} 860CPDF_Stream::CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict) 861 : CPDF_Object(PDFOBJ_STREAM) { 862 m_pDict = pDict; 863 m_dwSize = size; 864 m_GenNum = (FX_DWORD) - 1; 865 m_pDataBuf = pData; 866 m_pCryptoHandler = NULL; 867} 868CPDF_Stream::~CPDF_Stream() 869{ 870 if (m_GenNum == (FX_DWORD) - 1 && m_pDataBuf != NULL) { 871 FX_Free(m_pDataBuf); 872 } 873 if (m_pDict) { 874 m_pDict->Release(); 875 } 876} 877void CPDF_Stream::InitStream(CPDF_Dictionary* pDict) 878{ 879 if (pDict) { 880 if (m_pDict) { 881 m_pDict->Release(); 882 } 883 m_pDict = pDict; 884 } 885 if (m_GenNum == (FX_DWORD) - 1) { 886 if (m_pDataBuf) { 887 FX_Free(m_pDataBuf); 888 } 889 } 890 m_GenNum = 0; 891 m_pFile = NULL; 892 m_pCryptoHandler = NULL; 893 m_FileOffset = 0; 894} 895void CPDF_Stream::InitStream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict) 896{ 897 InitStream(pDict); 898 m_GenNum = (FX_DWORD) - 1; 899 m_pDataBuf = FX_Alloc(FX_BYTE, size); 900 if (pData) { 901 FXSYS_memcpy32(m_pDataBuf, pData, size); 902 } 903 m_dwSize = size; 904 if (m_pDict) { 905 m_pDict->SetAtInteger(FX_BSTRC("Length"), size); 906 } 907} 908void CPDF_Stream::SetData(FX_LPCBYTE pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf) 909{ 910 if (m_GenNum == (FX_DWORD) - 1) { 911 if (m_pDataBuf) { 912 FX_Free(m_pDataBuf); 913 } 914 } else { 915 m_GenNum = (FX_DWORD) - 1; 916 m_pCryptoHandler = NULL; 917 } 918 if (bKeepBuf) { 919 m_pDataBuf = (FX_LPBYTE)pData; 920 } else { 921 m_pDataBuf = FX_Alloc(FX_BYTE, size); 922 if (pData) { 923 FXSYS_memcpy32(m_pDataBuf, pData, size); 924 } 925 } 926 m_dwSize = size; 927 if (m_pDict == NULL) { 928 m_pDict = new CPDF_Dictionary; 929 } 930 m_pDict->SetAtInteger(FX_BSTRC("Length"), size); 931 if (!bCompressed) { 932 m_pDict->RemoveAt(FX_BSTRC("Filter")); 933 m_pDict->RemoveAt(FX_BSTRC("DecodeParms")); 934 } 935} 936FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, FX_LPBYTE buf, FX_DWORD size) const 937{ 938 if ((m_GenNum != (FX_DWORD) - 1) && m_pFile) { 939 return m_pFile->ReadBlock(buf, m_FileOffset + offset, size); 940 } 941 if (m_pDataBuf) { 942 FXSYS_memcpy32(buf, m_pDataBuf + offset, size); 943 } 944 return TRUE; 945} 946void CPDF_Stream::InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict) 947{ 948 InitStream(pDict); 949 m_pFile = pFile; 950 m_dwSize = (FX_DWORD)pFile->GetSize(); 951 if (m_pDict) { 952 m_pDict->SetAtInteger(FX_BSTRC("Length"), m_dwSize); 953 } 954} 955FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const 956{ 957 if (!m_pDict) 958 return pOther->m_pDict ? FALSE : TRUE; 959 960 if (!m_pDict->Identical(pOther->m_pDict)) { 961 return FALSE; 962 } 963 if (m_dwSize != pOther->m_dwSize) { 964 return FALSE; 965 } 966 if (m_GenNum != (FX_DWORD) - 1 && pOther->m_GenNum != (FX_DWORD) - 1) { 967 if (m_pFile == pOther->m_pFile && m_pFile == NULL) { 968 return TRUE; 969 } 970 if (!m_pFile || !pOther->m_pFile) { 971 return FALSE; 972 } 973 FX_BYTE srcBuf[1024]; 974 FX_BYTE destBuf[1024]; 975 FX_DWORD size = m_dwSize; 976 FX_DWORD srcOffset = m_FileOffset; 977 FX_DWORD destOffset = pOther->m_FileOffset; 978 if (m_pFile == pOther->m_pFile && srcOffset == destOffset) { 979 return TRUE; 980 } 981 while (size > 0) { 982 FX_DWORD actualSize = size > 1024 ? 1024 : size; 983 m_pFile->ReadBlock(srcBuf, srcOffset, actualSize); 984 pOther->m_pFile->ReadBlock(destBuf, destOffset, actualSize); 985 if (FXSYS_memcmp32(srcBuf, destBuf, actualSize) != 0) { 986 return FALSE; 987 } 988 size -= actualSize; 989 srcOffset += actualSize; 990 destOffset += actualSize; 991 } 992 return TRUE; 993 } 994 if (m_GenNum != (FX_DWORD) - 1 || pOther->m_GenNum != (FX_DWORD) - 1) { 995 IFX_FileRead* pFile = NULL; 996 FX_LPBYTE pBuf = NULL; 997 FX_DWORD offset = 0; 998 if (pOther->m_GenNum != (FX_DWORD) - 1) { 999 pFile = pOther->m_pFile; 1000 pBuf = m_pDataBuf; 1001 offset = pOther->m_FileOffset; 1002 } else if (m_GenNum != (FX_DWORD) - 1) { 1003 pFile = m_pFile; 1004 pBuf = pOther->m_pDataBuf; 1005 offset = m_FileOffset; 1006 } 1007 if (NULL == pBuf) { 1008 return FALSE; 1009 } 1010 FX_BYTE srcBuf[1024]; 1011 FX_DWORD size = m_dwSize; 1012 while (size > 0) { 1013 FX_DWORD actualSize = std::min(size, 1024U); 1014 pFile->ReadBlock(srcBuf, offset, actualSize); 1015 if (FXSYS_memcmp32(srcBuf, pBuf, actualSize) != 0) { 1016 return FALSE; 1017 } 1018 pBuf += actualSize; 1019 size -= actualSize; 1020 offset += actualSize; 1021 } 1022 return TRUE; 1023 } 1024 return FXSYS_memcmp32(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0; 1025} 1026CPDF_Stream* CPDF_Stream::Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const 1027{ 1028 CPDF_Dictionary *pCloneDict = (CPDF_Dictionary*)m_pDict->Clone(bDirect); 1029 IFX_FileStream *pFS = NULL; 1030 if (lpfCallback) { 1031 pFS = lpfCallback((CPDF_Stream*)this, pUserData); 1032 } 1033 if (!pFS) { 1034 CPDF_StreamAcc acc; 1035 acc.LoadAllData(this, TRUE); 1036 FX_DWORD streamSize = acc.GetSize(); 1037 return new CPDF_Stream(acc.DetachData(), streamSize, pCloneDict); 1038 } 1039 CPDF_Stream* pObj = new CPDF_Stream(NULL, 0, NULL); 1040 CPDF_StreamFilter *pSF = GetStreamFilter(TRUE); 1041 if (pSF) { 1042 FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, 4096); 1043 FX_DWORD dwRead; 1044 do { 1045 dwRead = pSF->ReadBlock(pBuf, 4096); 1046 if (dwRead) { 1047 pFS->WriteBlock(pBuf, dwRead); 1048 } 1049 } while (dwRead == 4096); 1050 pFS->Flush(); 1051 FX_Free(pBuf); 1052 delete pSF; 1053 } 1054 pObj->InitStream((IFX_FileRead*)pFS, pCloneDict); 1055 return pObj; 1056} 1057extern FX_BOOL PDF_DataDecode(FX_LPCBYTE src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict, 1058 FX_LPBYTE& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding, 1059 CPDF_Dictionary*& pImageParms, FX_DWORD estimated_size, FX_BOOL bImageAcc); 1060CPDF_StreamAcc::CPDF_StreamAcc() 1061{ 1062 m_bNewBuf = FALSE; 1063 m_pData = NULL; 1064 m_dwSize = 0; 1065 m_pImageParam = NULL; 1066 m_pStream = NULL; 1067 m_pSrcData = NULL; 1068} 1069void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, FX_BOOL bRawAccess, FX_DWORD estimated_size, 1070 FX_BOOL bImageAcc) 1071{ 1072 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { 1073 return; 1074 } 1075 m_pStream = pStream; 1076 if (pStream->IsMemoryBased() && 1077 (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess)) { 1078 m_dwSize = pStream->m_dwSize; 1079 m_pData = (FX_LPBYTE)pStream->m_pDataBuf; 1080 return; 1081 } 1082 FX_LPBYTE pSrcData; 1083 FX_DWORD dwSrcSize = pStream->m_dwSize; 1084 if (dwSrcSize == 0) { 1085 return; 1086 } 1087 if (!pStream->IsMemoryBased()) { 1088 pSrcData = m_pSrcData = FX_Alloc(FX_BYTE, dwSrcSize); 1089 if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) { 1090 return; 1091 } 1092 } else { 1093 pSrcData = pStream->m_pDataBuf; 1094 } 1095 FX_LPBYTE pDecryptedData; 1096 FX_DWORD dwDecryptedSize; 1097 if (pStream->m_pCryptoHandler) { 1098 CFX_BinaryBuf dest_buf; 1099 dest_buf.EstimateSize(pStream->m_pCryptoHandler->DecryptGetSize(dwSrcSize)); 1100 FX_LPVOID context = pStream->m_pCryptoHandler->DecryptStart(pStream->GetObjNum(), pStream->m_GenNum); 1101 pStream->m_pCryptoHandler->DecryptStream(context, pSrcData, dwSrcSize, dest_buf); 1102 pStream->m_pCryptoHandler->DecryptFinish(context, dest_buf); 1103 pDecryptedData = dest_buf.GetBuffer(); 1104 dwDecryptedSize = dest_buf.GetSize(); 1105 dest_buf.DetachBuffer(); 1106 } else { 1107 pDecryptedData = pSrcData; 1108 dwDecryptedSize = dwSrcSize; 1109 } 1110 if (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess) { 1111 m_pData = pDecryptedData; 1112 m_dwSize = dwDecryptedSize; 1113 } else { 1114 FX_BOOL bRet = PDF_DataDecode(pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), 1115 m_pData, m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc); 1116 if (!bRet) { 1117 m_pData = pDecryptedData; 1118 m_dwSize = dwDecryptedSize; 1119 } 1120 } 1121 if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) { 1122 FX_Free(pSrcData); 1123 } 1124 if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { 1125 FX_Free(pDecryptedData); 1126 } 1127 m_pSrcData = NULL; 1128 m_bNewBuf = m_pData != pStream->m_pDataBuf; 1129} 1130CPDF_StreamAcc::~CPDF_StreamAcc() 1131{ 1132 if (m_bNewBuf && m_pData) { 1133 FX_Free(m_pData); 1134 } 1135 if (m_pSrcData) { 1136 FX_Free(m_pSrcData); 1137 } 1138} 1139FX_LPCBYTE CPDF_StreamAcc::GetData() const 1140{ 1141 if (m_bNewBuf) { 1142 return m_pData; 1143 } 1144 if (!m_pStream) { 1145 return NULL; 1146 } 1147 return m_pStream->m_pDataBuf; 1148} 1149FX_DWORD CPDF_StreamAcc::GetSize() const 1150{ 1151 if (m_bNewBuf) { 1152 return m_dwSize; 1153 } 1154 if (!m_pStream) { 1155 return 0; 1156 } 1157 return m_pStream->m_dwSize; 1158} 1159FX_LPBYTE CPDF_StreamAcc::DetachData() 1160{ 1161 if (m_bNewBuf) { 1162 FX_LPBYTE p = m_pData; 1163 m_pData = NULL; 1164 m_dwSize = 0; 1165 return p; 1166 } 1167 FX_LPBYTE p = FX_Alloc(FX_BYTE, m_dwSize); 1168 FXSYS_memcpy32(p, m_pData, m_dwSize); 1169 return p; 1170} 1171void CPDF_Reference::SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) 1172{ 1173 m_pObjList = pDoc; 1174 m_RefObjNum = objnum; 1175} 1176CPDF_IndirectObjects::CPDF_IndirectObjects(CPDF_Parser* pParser) 1177{ 1178 m_pParser = pParser; 1179 m_IndirectObjs.InitHashTable(1013); 1180 if (pParser) { 1181 m_LastObjNum = m_pParser->GetLastObjNum(); 1182 } else { 1183 m_LastObjNum = 0; 1184 } 1185} 1186CPDF_IndirectObjects::~CPDF_IndirectObjects() 1187{ 1188 FX_POSITION pos = m_IndirectObjs.GetStartPosition(); 1189 while (pos) { 1190 FX_LPVOID key, value; 1191 m_IndirectObjs.GetNextAssoc(pos, key, value); 1192 ((CPDF_Object*)value)->Destroy(); 1193 } 1194} 1195CPDF_Object* CPDF_IndirectObjects::GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext) 1196{ 1197 if (objnum == 0) { 1198 return NULL; 1199 } 1200 FX_LPVOID value; 1201 { 1202 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) { 1203 if (((CPDF_Object*)value)->GetObjNum() == -1) { 1204 return NULL; 1205 } 1206 return (CPDF_Object*)value; 1207 } 1208 } 1209 CPDF_Object* pObj = NULL; 1210 if (m_pParser) { 1211 pObj = m_pParser->ParseIndirectObject(this, objnum, pContext); 1212 } 1213 if (pObj == NULL) { 1214 return NULL; 1215 } 1216 pObj->m_ObjNum = objnum; 1217 if (m_LastObjNum < objnum) { 1218 m_LastObjNum = objnum; 1219 } 1220 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) { 1221 if (value) { 1222 ((CPDF_Object *)value)->Destroy(); 1223 } 1224 } 1225 m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pObj); 1226 return pObj; 1227} 1228int CPDF_IndirectObjects::GetIndirectType(FX_DWORD objnum) 1229{ 1230 FX_LPVOID value; 1231 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) { 1232 return ((CPDF_Object*)value)->GetType(); 1233 } 1234 if (m_pParser) { 1235 PARSE_CONTEXT context; 1236 FXSYS_memset32(&context, 0, sizeof(PARSE_CONTEXT)); 1237 context.m_Flags = PDFPARSE_TYPEONLY; 1238 return (int)(FX_UINTPTR)m_pParser->ParseIndirectObject(this, objnum, &context); 1239 } 1240 return 0; 1241} 1242FX_DWORD CPDF_IndirectObjects::AddIndirectObject(CPDF_Object* pObj) 1243{ 1244 if (pObj->m_ObjNum) { 1245 return pObj->m_ObjNum; 1246 } 1247 m_LastObjNum ++; 1248 m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)m_LastObjNum, pObj); 1249 pObj->m_ObjNum = m_LastObjNum; 1250 return m_LastObjNum; 1251} 1252void CPDF_IndirectObjects::ReleaseIndirectObject(FX_DWORD objnum) 1253{ 1254 FX_LPVOID value; 1255 if (!m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) { 1256 return; 1257 } 1258 if (((CPDF_Object*)value)->GetObjNum() == -1) { 1259 return; 1260 } 1261 ((CPDF_Object*)value)->Destroy(); 1262 m_IndirectObjs.RemoveKey((FX_LPVOID)(FX_UINTPTR)objnum); 1263} 1264void CPDF_IndirectObjects::InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj) 1265{ 1266 if (objnum == 0 || pObj == NULL) { 1267 return; 1268 } 1269 FX_LPVOID value = NULL; 1270 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) { 1271 if (value) 1272 { 1273 if (pObj->GetGenNum() <= ((CPDF_Object*)value)->GetGenNum()) 1274 return; 1275 else 1276 ((CPDF_Object*)value)->Destroy(); 1277 } 1278 } 1279 pObj->m_ObjNum = objnum; 1280 m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pObj); 1281 if (m_LastObjNum < objnum) { 1282 m_LastObjNum = objnum; 1283 } 1284} 1285FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const 1286{ 1287 return m_LastObjNum; 1288} 1289