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