| OLD | NEW |
| (Empty) |
| 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 "core/include/fpdfapi/fpdf_objects.h" | |
| 8 | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "core/include/fpdfapi/cpdf_parser.h" | |
| 12 #include "core/include/fpdfapi/fpdf_parser_decode.h" | |
| 13 #include "core/include/fxcrt/fx_string.h" | |
| 14 #include "third_party/base/stl_util.h" | |
| 15 | |
| 16 CPDF_Object::~CPDF_Object() {} | |
| 17 | |
| 18 CPDF_Object* CPDF_Object::GetDirect() const { | |
| 19 return const_cast<CPDF_Object*>(this); | |
| 20 } | |
| 21 | |
| 22 void CPDF_Object::Release() { | |
| 23 if (m_ObjNum) { | |
| 24 return; | |
| 25 } | |
| 26 Destroy(); | |
| 27 } | |
| 28 | |
| 29 CFX_ByteString CPDF_Object::GetString() const { | |
| 30 return CFX_ByteString(); | |
| 31 } | |
| 32 | |
| 33 CFX_ByteStringC CPDF_Object::GetConstString() const { | |
| 34 return CFX_ByteStringC(); | |
| 35 } | |
| 36 | |
| 37 CFX_WideString CPDF_Object::GetUnicodeText() const { | |
| 38 return CFX_WideString(); | |
| 39 } | |
| 40 | |
| 41 FX_FLOAT CPDF_Object::GetNumber() const { | |
| 42 return 0; | |
| 43 } | |
| 44 | |
| 45 int CPDF_Object::GetInteger() const { | |
| 46 return 0; | |
| 47 } | |
| 48 | |
| 49 CPDF_Dictionary* CPDF_Object::GetDict() const { | |
| 50 return nullptr; | |
| 51 } | |
| 52 | |
| 53 CPDF_Array* CPDF_Object::GetArray() const { | |
| 54 return nullptr; | |
| 55 } | |
| 56 | |
| 57 void CPDF_Object::SetString(const CFX_ByteString& str) { | |
| 58 ASSERT(FALSE); | |
| 59 } | |
| 60 | |
| 61 bool CPDF_Object::IsArray() const { | |
| 62 return false; | |
| 63 } | |
| 64 | |
| 65 bool CPDF_Object::IsBoolean() const { | |
| 66 return false; | |
| 67 } | |
| 68 | |
| 69 bool CPDF_Object::IsDictionary() const { | |
| 70 return false; | |
| 71 } | |
| 72 | |
| 73 bool CPDF_Object::IsName() const { | |
| 74 return false; | |
| 75 } | |
| 76 | |
| 77 bool CPDF_Object::IsNumber() const { | |
| 78 return false; | |
| 79 } | |
| 80 | |
| 81 bool CPDF_Object::IsReference() const { | |
| 82 return false; | |
| 83 } | |
| 84 | |
| 85 bool CPDF_Object::IsStream() const { | |
| 86 return false; | |
| 87 } | |
| 88 | |
| 89 bool CPDF_Object::IsString() const { | |
| 90 return false; | |
| 91 } | |
| 92 | |
| 93 CPDF_Array* CPDF_Object::AsArray() { | |
| 94 return nullptr; | |
| 95 } | |
| 96 | |
| 97 const CPDF_Array* CPDF_Object::AsArray() const { | |
| 98 return nullptr; | |
| 99 } | |
| 100 | |
| 101 CPDF_Boolean* CPDF_Object::AsBoolean() { | |
| 102 return nullptr; | |
| 103 } | |
| 104 | |
| 105 const CPDF_Boolean* CPDF_Object::AsBoolean() const { | |
| 106 return nullptr; | |
| 107 } | |
| 108 | |
| 109 CPDF_Dictionary* CPDF_Object::AsDictionary() { | |
| 110 return nullptr; | |
| 111 } | |
| 112 | |
| 113 const CPDF_Dictionary* CPDF_Object::AsDictionary() const { | |
| 114 return nullptr; | |
| 115 } | |
| 116 | |
| 117 CPDF_Name* CPDF_Object::AsName() { | |
| 118 return nullptr; | |
| 119 } | |
| 120 | |
| 121 const CPDF_Name* CPDF_Object::AsName() const { | |
| 122 return nullptr; | |
| 123 } | |
| 124 | |
| 125 CPDF_Number* CPDF_Object::AsNumber() { | |
| 126 return nullptr; | |
| 127 } | |
| 128 | |
| 129 const CPDF_Number* CPDF_Object::AsNumber() const { | |
| 130 return nullptr; | |
| 131 } | |
| 132 | |
| 133 CPDF_Reference* CPDF_Object::AsReference() { | |
| 134 return nullptr; | |
| 135 } | |
| 136 | |
| 137 const CPDF_Reference* CPDF_Object::AsReference() const { | |
| 138 return nullptr; | |
| 139 } | |
| 140 | |
| 141 CPDF_Stream* CPDF_Object::AsStream() { | |
| 142 return nullptr; | |
| 143 } | |
| 144 | |
| 145 const CPDF_Stream* CPDF_Object::AsStream() const { | |
| 146 return nullptr; | |
| 147 } | |
| 148 | |
| 149 CPDF_String* CPDF_Object::AsString() { | |
| 150 return nullptr; | |
| 151 } | |
| 152 | |
| 153 const CPDF_String* CPDF_Object::AsString() const { | |
| 154 return nullptr; | |
| 155 } | |
| 156 | |
| 157 CPDF_Boolean::~CPDF_Boolean() {} | |
| 158 | |
| 159 CPDF_Object::Type CPDF_Boolean::GetType() const { | |
| 160 return BOOLEAN; | |
| 161 } | |
| 162 | |
| 163 CPDF_Object* CPDF_Boolean::Clone(FX_BOOL bDirect) const { | |
| 164 return new CPDF_Boolean(m_bValue); | |
| 165 } | |
| 166 | |
| 167 CFX_ByteString CPDF_Boolean::GetString() const { | |
| 168 return m_bValue ? "true" : "false"; | |
| 169 } | |
| 170 | |
| 171 int CPDF_Boolean::GetInteger() const { | |
| 172 return m_bValue; | |
| 173 } | |
| 174 | |
| 175 void CPDF_Boolean::SetString(const CFX_ByteString& str) { | |
| 176 m_bValue = (str == "true"); | |
| 177 } | |
| 178 | |
| 179 bool CPDF_Boolean::IsBoolean() const { | |
| 180 return true; | |
| 181 } | |
| 182 | |
| 183 CPDF_Boolean* CPDF_Boolean::AsBoolean() { | |
| 184 return this; | |
| 185 } | |
| 186 | |
| 187 const CPDF_Boolean* CPDF_Boolean::AsBoolean() const { | |
| 188 return this; | |
| 189 } | |
| 190 | |
| 191 CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) { | |
| 192 FX_atonum(str, m_bInteger, &m_Integer); | |
| 193 } | |
| 194 | |
| 195 CPDF_Number::~CPDF_Number() {} | |
| 196 | |
| 197 CPDF_Object::Type CPDF_Number::GetType() const { | |
| 198 return NUMBER; | |
| 199 } | |
| 200 | |
| 201 CPDF_Object* CPDF_Number::Clone(FX_BOOL bDirect) const { | |
| 202 return m_bInteger ? new CPDF_Number(m_Integer) : new CPDF_Number(m_Float); | |
| 203 } | |
| 204 | |
| 205 FX_FLOAT CPDF_Number::GetNumber() const { | |
| 206 return m_bInteger ? static_cast<FX_FLOAT>(m_Integer) : m_Float; | |
| 207 } | |
| 208 | |
| 209 int CPDF_Number::GetInteger() const { | |
| 210 return m_bInteger ? m_Integer : static_cast<int>(m_Float); | |
| 211 } | |
| 212 | |
| 213 bool CPDF_Number::IsNumber() const { | |
| 214 return true; | |
| 215 } | |
| 216 | |
| 217 CPDF_Number* CPDF_Number::AsNumber() { | |
| 218 return this; | |
| 219 } | |
| 220 | |
| 221 const CPDF_Number* CPDF_Number::AsNumber() const { | |
| 222 return this; | |
| 223 } | |
| 224 | |
| 225 void CPDF_Number::SetString(const CFX_ByteString& str) { | |
| 226 FX_atonum(str, m_bInteger, &m_Integer); | |
| 227 } | |
| 228 | |
| 229 CFX_ByteString CPDF_Number::GetString() const { | |
| 230 return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) | |
| 231 : CFX_ByteString::FormatFloat(m_Float); | |
| 232 } | |
| 233 | |
| 234 CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(FALSE) { | |
| 235 m_String = PDF_EncodeText(str); | |
| 236 } | |
| 237 | |
| 238 CPDF_String::~CPDF_String() {} | |
| 239 | |
| 240 CPDF_Object::Type CPDF_String::GetType() const { | |
| 241 return STRING; | |
| 242 } | |
| 243 | |
| 244 CPDF_Object* CPDF_String::Clone(FX_BOOL bDirect) const { | |
| 245 return new CPDF_String(m_String, m_bHex); | |
| 246 } | |
| 247 | |
| 248 CFX_ByteString CPDF_String::GetString() const { | |
| 249 return m_String; | |
| 250 } | |
| 251 | |
| 252 CFX_ByteStringC CPDF_String::GetConstString() const { | |
| 253 return CFX_ByteStringC(m_String); | |
| 254 } | |
| 255 | |
| 256 void CPDF_String::SetString(const CFX_ByteString& str) { | |
| 257 m_String = str; | |
| 258 } | |
| 259 | |
| 260 bool CPDF_String::IsString() const { | |
| 261 return true; | |
| 262 } | |
| 263 | |
| 264 CPDF_String* CPDF_String::AsString() { | |
| 265 return this; | |
| 266 } | |
| 267 | |
| 268 const CPDF_String* CPDF_String::AsString() const { | |
| 269 return this; | |
| 270 } | |
| 271 | |
| 272 CFX_WideString CPDF_String::GetUnicodeText() const { | |
| 273 return PDF_DecodeText(m_String); | |
| 274 } | |
| 275 | |
| 276 CPDF_Name::~CPDF_Name() {} | |
| 277 | |
| 278 CPDF_Object::Type CPDF_Name::GetType() const { | |
| 279 return NAME; | |
| 280 } | |
| 281 | |
| 282 CPDF_Object* CPDF_Name::Clone(FX_BOOL bDirect) const { | |
| 283 return new CPDF_Name(m_Name); | |
| 284 } | |
| 285 | |
| 286 CFX_ByteString CPDF_Name::GetString() const { | |
| 287 return m_Name; | |
| 288 } | |
| 289 | |
| 290 CFX_ByteStringC CPDF_Name::GetConstString() const { | |
| 291 return CFX_ByteStringC(m_Name); | |
| 292 } | |
| 293 | |
| 294 void CPDF_Name::SetString(const CFX_ByteString& str) { | |
| 295 m_Name = str; | |
| 296 } | |
| 297 | |
| 298 bool CPDF_Name::IsName() const { | |
| 299 return true; | |
| 300 } | |
| 301 | |
| 302 CPDF_Name* CPDF_Name::AsName() { | |
| 303 return this; | |
| 304 } | |
| 305 | |
| 306 const CPDF_Name* CPDF_Name::AsName() const { | |
| 307 return this; | |
| 308 } | |
| 309 | |
| 310 CFX_WideString CPDF_Name::GetUnicodeText() const { | |
| 311 return PDF_DecodeText(m_Name); | |
| 312 } | |
| 313 | |
| 314 CPDF_Array::CPDF_Array() {} | |
| 315 | |
| 316 CPDF_Array::~CPDF_Array() { | |
| 317 int size = m_Objects.GetSize(); | |
| 318 CPDF_Object** pList = m_Objects.GetData(); | |
| 319 for (int i = 0; i < size; i++) { | |
| 320 if (pList[i]) | |
| 321 pList[i]->Release(); | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 CPDF_Object::Type CPDF_Array::GetType() const { | |
| 326 return ARRAY; | |
| 327 } | |
| 328 | |
| 329 CPDF_Array* CPDF_Array::GetArray() const { | |
| 330 // The method should be made non-const if we want to not be const. | |
| 331 // See bug #234. | |
| 332 return const_cast<CPDF_Array*>(this); | |
| 333 } | |
| 334 | |
| 335 bool CPDF_Array::IsArray() const { | |
| 336 return true; | |
| 337 } | |
| 338 | |
| 339 CPDF_Array* CPDF_Array::AsArray() { | |
| 340 return this; | |
| 341 } | |
| 342 | |
| 343 const CPDF_Array* CPDF_Array::AsArray() const { | |
| 344 return this; | |
| 345 } | |
| 346 | |
| 347 CPDF_Object* CPDF_Array::Clone(FX_BOOL bDirect) const { | |
| 348 CPDF_Array* pCopy = new CPDF_Array(); | |
| 349 for (int i = 0; i < GetCount(); i++) { | |
| 350 CPDF_Object* value = m_Objects.GetAt(i); | |
| 351 pCopy->m_Objects.Add(value->Clone(bDirect)); | |
| 352 } | |
| 353 return pCopy; | |
| 354 } | |
| 355 | |
| 356 CFX_FloatRect CPDF_Array::GetRect() { | |
| 357 CFX_FloatRect rect; | |
| 358 if (!IsArray() || m_Objects.GetSize() != 4) | |
| 359 return rect; | |
| 360 | |
| 361 rect.left = GetNumberAt(0); | |
| 362 rect.bottom = GetNumberAt(1); | |
| 363 rect.right = GetNumberAt(2); | |
| 364 rect.top = GetNumberAt(3); | |
| 365 return rect; | |
| 366 } | |
| 367 | |
| 368 CFX_Matrix CPDF_Array::GetMatrix() { | |
| 369 CFX_Matrix matrix; | |
| 370 if (!IsArray() || m_Objects.GetSize() != 6) | |
| 371 return matrix; | |
| 372 | |
| 373 matrix.Set(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), GetNumberAt(3), | |
| 374 GetNumberAt(4), GetNumberAt(5)); | |
| 375 return matrix; | |
| 376 } | |
| 377 | |
| 378 CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const { | |
| 379 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 380 return nullptr; | |
| 381 return m_Objects.GetAt(i); | |
| 382 } | |
| 383 | |
| 384 CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const { | |
| 385 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 386 return nullptr; | |
| 387 return m_Objects.GetAt(i)->GetDirect(); | |
| 388 } | |
| 389 | |
| 390 CFX_ByteString CPDF_Array::GetStringAt(FX_DWORD i) const { | |
| 391 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 392 return CFX_ByteString(); | |
| 393 return m_Objects.GetAt(i)->GetString(); | |
| 394 } | |
| 395 | |
| 396 CFX_ByteStringC CPDF_Array::GetConstStringAt(FX_DWORD i) const { | |
| 397 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 398 return CFX_ByteStringC(); | |
| 399 return m_Objects.GetAt(i)->GetConstString(); | |
| 400 } | |
| 401 | |
| 402 int CPDF_Array::GetIntegerAt(FX_DWORD i) const { | |
| 403 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 404 return 0; | |
| 405 return m_Objects.GetAt(i)->GetInteger(); | |
| 406 } | |
| 407 | |
| 408 FX_FLOAT CPDF_Array::GetNumberAt(FX_DWORD i) const { | |
| 409 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 410 return 0; | |
| 411 return m_Objects.GetAt(i)->GetNumber(); | |
| 412 } | |
| 413 | |
| 414 CPDF_Dictionary* CPDF_Array::GetDictAt(FX_DWORD i) const { | |
| 415 CPDF_Object* p = GetElementValue(i); | |
| 416 if (!p) | |
| 417 return NULL; | |
| 418 if (CPDF_Dictionary* pDict = p->AsDictionary()) | |
| 419 return pDict; | |
| 420 if (CPDF_Stream* pStream = p->AsStream()) | |
| 421 return pStream->GetDict(); | |
| 422 return NULL; | |
| 423 } | |
| 424 | |
| 425 CPDF_Stream* CPDF_Array::GetStreamAt(FX_DWORD i) const { | |
| 426 return ToStream(GetElementValue(i)); | |
| 427 } | |
| 428 | |
| 429 CPDF_Array* CPDF_Array::GetArrayAt(FX_DWORD i) const { | |
| 430 return ToArray(GetElementValue(i)); | |
| 431 } | |
| 432 | |
| 433 void CPDF_Array::RemoveAt(FX_DWORD i, int nCount) { | |
| 434 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 435 return; | |
| 436 | |
| 437 if (nCount <= 0 || nCount > m_Objects.GetSize() - i) | |
| 438 return; | |
| 439 | |
| 440 for (int j = 0; j < nCount; ++j) { | |
| 441 if (CPDF_Object* p = m_Objects.GetAt(i + j)) | |
| 442 p->Release(); | |
| 443 } | |
| 444 m_Objects.RemoveAt(i, nCount); | |
| 445 } | |
| 446 | |
| 447 void CPDF_Array::SetAt(FX_DWORD i, | |
| 448 CPDF_Object* pObj, | |
| 449 CPDF_IndirectObjectHolder* pObjs) { | |
| 450 ASSERT(IsArray()); | |
| 451 ASSERT(i < (FX_DWORD)m_Objects.GetSize()); | |
| 452 if (i >= (FX_DWORD)m_Objects.GetSize()) | |
| 453 return; | |
| 454 if (CPDF_Object* pOld = m_Objects.GetAt(i)) | |
| 455 pOld->Release(); | |
| 456 if (pObj->GetObjNum()) { | |
| 457 ASSERT(pObjs); | |
| 458 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); | |
| 459 } | |
| 460 m_Objects.SetAt(i, pObj); | |
| 461 } | |
| 462 | |
| 463 void CPDF_Array::InsertAt(FX_DWORD index, | |
| 464 CPDF_Object* pObj, | |
| 465 CPDF_IndirectObjectHolder* pObjs) { | |
| 466 if (pObj->GetObjNum()) { | |
| 467 ASSERT(pObjs); | |
| 468 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); | |
| 469 } | |
| 470 m_Objects.InsertAt(index, pObj); | |
| 471 } | |
| 472 | |
| 473 void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { | |
| 474 if (pObj->GetObjNum()) { | |
| 475 ASSERT(pObjs); | |
| 476 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); | |
| 477 } | |
| 478 m_Objects.Add(pObj); | |
| 479 } | |
| 480 | |
| 481 void CPDF_Array::AddName(const CFX_ByteString& str) { | |
| 482 ASSERT(IsArray()); | |
| 483 Add(new CPDF_Name(str)); | |
| 484 } | |
| 485 | |
| 486 void CPDF_Array::AddString(const CFX_ByteString& str) { | |
| 487 ASSERT(IsArray()); | |
| 488 Add(new CPDF_String(str, FALSE)); | |
| 489 } | |
| 490 | |
| 491 void CPDF_Array::AddInteger(int i) { | |
| 492 ASSERT(IsArray()); | |
| 493 Add(new CPDF_Number(i)); | |
| 494 } | |
| 495 | |
| 496 void CPDF_Array::AddNumber(FX_FLOAT f) { | |
| 497 ASSERT(IsArray()); | |
| 498 CPDF_Number* pNumber = new CPDF_Number(f); | |
| 499 Add(pNumber); | |
| 500 } | |
| 501 | |
| 502 void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, | |
| 503 FX_DWORD objnum) { | |
| 504 ASSERT(IsArray()); | |
| 505 Add(new CPDF_Reference(pDoc, objnum)); | |
| 506 } | |
| 507 | |
| 508 CPDF_Dictionary::CPDF_Dictionary() {} | |
| 509 | |
| 510 CPDF_Dictionary::~CPDF_Dictionary() { | |
| 511 for (const auto& it : m_Map) { | |
| 512 it.second->Release(); | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 CPDF_Object::Type CPDF_Dictionary::GetType() const { | |
| 517 return DICTIONARY; | |
| 518 } | |
| 519 | |
| 520 CPDF_Dictionary* CPDF_Dictionary::GetDict() const { | |
| 521 // The method should be made non-const if we want to not be const. | |
| 522 // See bug #234. | |
| 523 return const_cast<CPDF_Dictionary*>(this); | |
| 524 } | |
| 525 | |
| 526 bool CPDF_Dictionary::IsDictionary() const { | |
| 527 return true; | |
| 528 } | |
| 529 | |
| 530 CPDF_Dictionary* CPDF_Dictionary::AsDictionary() { | |
| 531 return this; | |
| 532 } | |
| 533 | |
| 534 const CPDF_Dictionary* CPDF_Dictionary::AsDictionary() const { | |
| 535 return this; | |
| 536 } | |
| 537 | |
| 538 CPDF_Object* CPDF_Dictionary::Clone(FX_BOOL bDirect) const { | |
| 539 CPDF_Dictionary* pCopy = new CPDF_Dictionary(); | |
| 540 for (const auto& it : *this) | |
| 541 pCopy->m_Map.insert(std::make_pair(it.first, it.second->Clone(bDirect))); | |
| 542 return pCopy; | |
| 543 } | |
| 544 | |
| 545 CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { | |
| 546 auto it = m_Map.find(key); | |
| 547 if (it == m_Map.end()) | |
| 548 return nullptr; | |
| 549 return it->second; | |
| 550 } | |
| 551 CPDF_Object* CPDF_Dictionary::GetElementValue( | |
| 552 const CFX_ByteStringC& key) const { | |
| 553 CPDF_Object* p = GetElement(key); | |
| 554 return p ? p->GetDirect() : nullptr; | |
| 555 } | |
| 556 | |
| 557 CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key) const { | |
| 558 CPDF_Object* p = GetElement(key); | |
| 559 if (p) { | |
| 560 return p->GetString(); | |
| 561 } | |
| 562 return CFX_ByteString(); | |
| 563 } | |
| 564 | |
| 565 CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( | |
| 566 const CFX_ByteStringC& key) const { | |
| 567 CPDF_Object* p = GetElement(key); | |
| 568 if (p) { | |
| 569 return p->GetConstString(); | |
| 570 } | |
| 571 return CFX_ByteStringC(); | |
| 572 } | |
| 573 | |
| 574 CFX_WideString CPDF_Dictionary::GetUnicodeTextBy( | |
| 575 const CFX_ByteStringC& key) const { | |
| 576 CPDF_Object* p = GetElement(key); | |
| 577 if (CPDF_Reference* pRef = ToReference(p)) | |
| 578 p = pRef->GetDirect(); | |
| 579 return p ? p->GetUnicodeText() : CFX_WideString(); | |
| 580 } | |
| 581 | |
| 582 CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key, | |
| 583 const CFX_ByteStringC& def) const { | |
| 584 CPDF_Object* p = GetElement(key); | |
| 585 if (p) { | |
| 586 return p->GetString(); | |
| 587 } | |
| 588 return CFX_ByteString(def); | |
| 589 } | |
| 590 | |
| 591 CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( | |
| 592 const CFX_ByteStringC& key, | |
| 593 const CFX_ByteStringC& def) const { | |
| 594 CPDF_Object* p = GetElement(key); | |
| 595 if (p) { | |
| 596 return p->GetConstString(); | |
| 597 } | |
| 598 return CFX_ByteStringC(def); | |
| 599 } | |
| 600 | |
| 601 int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key) const { | |
| 602 CPDF_Object* p = GetElement(key); | |
| 603 if (p) { | |
| 604 return p->GetInteger(); | |
| 605 } | |
| 606 return 0; | |
| 607 } | |
| 608 | |
| 609 int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key, int def) const { | |
| 610 CPDF_Object* p = GetElement(key); | |
| 611 if (p) { | |
| 612 return p->GetInteger(); | |
| 613 } | |
| 614 return def; | |
| 615 } | |
| 616 | |
| 617 FX_FLOAT CPDF_Dictionary::GetNumberBy(const CFX_ByteStringC& key) const { | |
| 618 CPDF_Object* p = GetElement(key); | |
| 619 if (p) { | |
| 620 return p->GetNumber(); | |
| 621 } | |
| 622 return 0; | |
| 623 } | |
| 624 | |
| 625 FX_BOOL CPDF_Dictionary::GetBooleanBy(const CFX_ByteStringC& key, | |
| 626 FX_BOOL bDefault) const { | |
| 627 CPDF_Object* p = GetElement(key); | |
| 628 if (ToBoolean(p)) | |
| 629 return p->GetInteger(); | |
| 630 return bDefault; | |
| 631 } | |
| 632 | |
| 633 CPDF_Dictionary* CPDF_Dictionary::GetDictBy(const CFX_ByteStringC& key) const { | |
| 634 CPDF_Object* p = GetElementValue(key); | |
| 635 if (!p) | |
| 636 return nullptr; | |
| 637 if (CPDF_Dictionary* pDict = p->AsDictionary()) | |
| 638 return pDict; | |
| 639 if (CPDF_Stream* pStream = p->AsStream()) | |
| 640 return pStream->GetDict(); | |
| 641 return nullptr; | |
| 642 } | |
| 643 | |
| 644 CPDF_Array* CPDF_Dictionary::GetArrayBy(const CFX_ByteStringC& key) const { | |
| 645 return ToArray(GetElementValue(key)); | |
| 646 } | |
| 647 | |
| 648 CPDF_Stream* CPDF_Dictionary::GetStreamBy(const CFX_ByteStringC& key) const { | |
| 649 return ToStream(GetElementValue(key)); | |
| 650 } | |
| 651 | |
| 652 CFX_FloatRect CPDF_Dictionary::GetRectBy(const CFX_ByteStringC& key) const { | |
| 653 CFX_FloatRect rect; | |
| 654 CPDF_Array* pArray = GetArrayBy(key); | |
| 655 if (pArray) | |
| 656 rect = pArray->GetRect(); | |
| 657 return rect; | |
| 658 } | |
| 659 | |
| 660 CFX_Matrix CPDF_Dictionary::GetMatrixBy(const CFX_ByteStringC& key) const { | |
| 661 CFX_Matrix matrix; | |
| 662 CPDF_Array* pArray = GetArrayBy(key); | |
| 663 if (pArray) | |
| 664 matrix = pArray->GetMatrix(); | |
| 665 return matrix; | |
| 666 } | |
| 667 | |
| 668 FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { | |
| 669 return pdfium::ContainsKey(m_Map, key); | |
| 670 } | |
| 671 | |
| 672 bool CPDF_Dictionary::IsSignatureDict() const { | |
| 673 CPDF_Object* pType = GetElementValue("Type"); | |
| 674 if (!pType) | |
| 675 pType = GetElementValue("FT"); | |
| 676 return pType && pType->GetString() == "Sig"; | |
| 677 } | |
| 678 | |
| 679 void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { | |
| 680 ASSERT(IsDictionary()); | |
| 681 // Avoid 2 constructions of CFX_ByteString. | |
| 682 CFX_ByteString key_bytestring = key; | |
| 683 auto it = m_Map.find(key_bytestring); | |
| 684 if (it == m_Map.end()) { | |
| 685 if (pObj) { | |
| 686 m_Map.insert(std::make_pair(key_bytestring, pObj)); | |
| 687 } | |
| 688 return; | |
| 689 } | |
| 690 | |
| 691 if (it->second == pObj) | |
| 692 return; | |
| 693 it->second->Release(); | |
| 694 | |
| 695 if (pObj) | |
| 696 it->second = pObj; | |
| 697 else | |
| 698 m_Map.erase(it); | |
| 699 } | |
| 700 | |
| 701 void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { | |
| 702 auto it = m_Map.find(key); | |
| 703 if (it == m_Map.end()) | |
| 704 return; | |
| 705 | |
| 706 it->second->Release(); | |
| 707 m_Map.erase(it); | |
| 708 } | |
| 709 | |
| 710 void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, | |
| 711 const CFX_ByteStringC& newkey) { | |
| 712 auto old_it = m_Map.find(oldkey); | |
| 713 if (old_it == m_Map.end()) | |
| 714 return; | |
| 715 | |
| 716 // Avoid 2 constructions of CFX_ByteString. | |
| 717 CFX_ByteString newkey_bytestring = newkey; | |
| 718 auto new_it = m_Map.find(newkey_bytestring); | |
| 719 if (new_it == old_it) | |
| 720 return; | |
| 721 | |
| 722 if (new_it != m_Map.end()) { | |
| 723 new_it->second->Release(); | |
| 724 new_it->second = old_it->second; | |
| 725 } else { | |
| 726 m_Map.insert(std::make_pair(newkey_bytestring, old_it->second)); | |
| 727 } | |
| 728 m_Map.erase(old_it); | |
| 729 } | |
| 730 | |
| 731 void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { | |
| 732 SetAt(key, new CPDF_Number(i)); | |
| 733 } | |
| 734 | |
| 735 void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, | |
| 736 const CFX_ByteString& name) { | |
| 737 SetAt(key, new CPDF_Name(name)); | |
| 738 } | |
| 739 | |
| 740 void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, | |
| 741 const CFX_ByteString& str) { | |
| 742 SetAt(key, new CPDF_String(str, FALSE)); | |
| 743 } | |
| 744 | |
| 745 void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, | |
| 746 CPDF_IndirectObjectHolder* pDoc, | |
| 747 FX_DWORD objnum) { | |
| 748 SetAt(key, new CPDF_Reference(pDoc, objnum)); | |
| 749 } | |
| 750 | |
| 751 void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, | |
| 752 CPDF_IndirectObjectHolder* pDoc, | |
| 753 FX_DWORD objnum) { | |
| 754 SetAt(key, new CPDF_Reference(pDoc, objnum)); | |
| 755 } | |
| 756 | |
| 757 void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { | |
| 758 CPDF_Number* pNumber = new CPDF_Number(f); | |
| 759 SetAt(key, pNumber); | |
| 760 } | |
| 761 | |
| 762 void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { | |
| 763 SetAt(key, new CPDF_Boolean(bValue)); | |
| 764 } | |
| 765 | |
| 766 void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, | |
| 767 const CFX_FloatRect& rect) { | |
| 768 CPDF_Array* pArray = new CPDF_Array; | |
| 769 pArray->AddNumber(rect.left); | |
| 770 pArray->AddNumber(rect.bottom); | |
| 771 pArray->AddNumber(rect.right); | |
| 772 pArray->AddNumber(rect.top); | |
| 773 SetAt(key, pArray); | |
| 774 } | |
| 775 | |
| 776 void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, | |
| 777 const CFX_Matrix& matrix) { | |
| 778 CPDF_Array* pArray = new CPDF_Array; | |
| 779 pArray->AddNumber(matrix.a); | |
| 780 pArray->AddNumber(matrix.b); | |
| 781 pArray->AddNumber(matrix.c); | |
| 782 pArray->AddNumber(matrix.d); | |
| 783 pArray->AddNumber(matrix.e); | |
| 784 pArray->AddNumber(matrix.f); | |
| 785 SetAt(key, pArray); | |
| 786 } | |
| 787 | |
| 788 CPDF_Stream::CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict) | |
| 789 : m_pDict(pDict), | |
| 790 m_dwSize(size), | |
| 791 m_GenNum(kMemoryBasedGenNum), | |
| 792 m_pDataBuf(pData) {} | |
| 793 | |
| 794 CPDF_Stream::~CPDF_Stream() { | |
| 795 if (IsMemoryBased()) | |
| 796 FX_Free(m_pDataBuf); | |
| 797 | |
| 798 if (m_pDict) | |
| 799 m_pDict->Release(); | |
| 800 } | |
| 801 | |
| 802 CPDF_Object::Type CPDF_Stream::GetType() const { | |
| 803 return STREAM; | |
| 804 } | |
| 805 | |
| 806 CPDF_Dictionary* CPDF_Stream::GetDict() const { | |
| 807 return m_pDict; | |
| 808 } | |
| 809 | |
| 810 bool CPDF_Stream::IsStream() const { | |
| 811 return true; | |
| 812 } | |
| 813 | |
| 814 CPDF_Stream* CPDF_Stream::AsStream() { | |
| 815 return this; | |
| 816 } | |
| 817 | |
| 818 const CPDF_Stream* CPDF_Stream::AsStream() const { | |
| 819 return this; | |
| 820 } | |
| 821 | |
| 822 void CPDF_Stream::InitStreamInternal(CPDF_Dictionary* pDict) { | |
| 823 if (pDict) { | |
| 824 if (m_pDict) | |
| 825 m_pDict->Release(); | |
| 826 m_pDict = pDict; | |
| 827 } | |
| 828 if (IsMemoryBased()) | |
| 829 FX_Free(m_pDataBuf); | |
| 830 | |
| 831 m_GenNum = 0; | |
| 832 m_pFile = nullptr; | |
| 833 } | |
| 834 | |
| 835 void CPDF_Stream::InitStream(uint8_t* pData, | |
| 836 FX_DWORD size, | |
| 837 CPDF_Dictionary* pDict) { | |
| 838 InitStreamInternal(pDict); | |
| 839 m_GenNum = kMemoryBasedGenNum; | |
| 840 m_pDataBuf = FX_Alloc(uint8_t, size); | |
| 841 if (pData) { | |
| 842 FXSYS_memcpy(m_pDataBuf, pData, size); | |
| 843 } | |
| 844 m_dwSize = size; | |
| 845 if (m_pDict) { | |
| 846 m_pDict->SetAtInteger("Length", size); | |
| 847 } | |
| 848 } | |
| 849 | |
| 850 CPDF_Object* CPDF_Stream::Clone(FX_BOOL bDirect) const { | |
| 851 CPDF_StreamAcc acc; | |
| 852 acc.LoadAllData(this, TRUE); | |
| 853 FX_DWORD streamSize = acc.GetSize(); | |
| 854 CPDF_Dictionary* pDict = GetDict(); | |
| 855 if (pDict) { | |
| 856 pDict = ToDictionary(pDict->Clone(bDirect)); | |
| 857 } | |
| 858 return new CPDF_Stream(acc.DetachData(), streamSize, pDict); | |
| 859 } | |
| 860 | |
| 861 void CPDF_Stream::SetData(const uint8_t* pData, | |
| 862 FX_DWORD size, | |
| 863 FX_BOOL bCompressed, | |
| 864 FX_BOOL bKeepBuf) { | |
| 865 if (IsMemoryBased()) | |
| 866 FX_Free(m_pDataBuf); | |
| 867 m_GenNum = kMemoryBasedGenNum; | |
| 868 | |
| 869 if (bKeepBuf) { | |
| 870 m_pDataBuf = const_cast<uint8_t*>(pData); | |
| 871 } else { | |
| 872 m_pDataBuf = FX_Alloc(uint8_t, size); | |
| 873 if (pData) { | |
| 874 FXSYS_memcpy(m_pDataBuf, pData, size); | |
| 875 } | |
| 876 } | |
| 877 m_dwSize = size; | |
| 878 if (!m_pDict) | |
| 879 m_pDict = new CPDF_Dictionary; | |
| 880 m_pDict->SetAtInteger("Length", size); | |
| 881 if (!bCompressed) { | |
| 882 m_pDict->RemoveAt("Filter"); | |
| 883 m_pDict->RemoveAt("DecodeParms"); | |
| 884 } | |
| 885 } | |
| 886 | |
| 887 FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, | |
| 888 uint8_t* buf, | |
| 889 FX_DWORD size) const { | |
| 890 if (!IsMemoryBased() && m_pFile) | |
| 891 return m_pFile->ReadBlock(buf, offset, size); | |
| 892 | |
| 893 if (m_pDataBuf) | |
| 894 FXSYS_memcpy(buf, m_pDataBuf + offset, size); | |
| 895 return TRUE; | |
| 896 } | |
| 897 void CPDF_Stream::InitStreamFromFile(IFX_FileRead* pFile, | |
| 898 CPDF_Dictionary* pDict) { | |
| 899 InitStreamInternal(pDict); | |
| 900 m_pFile = pFile; | |
| 901 m_dwSize = (FX_DWORD)pFile->GetSize(); | |
| 902 if (m_pDict) { | |
| 903 m_pDict->SetAtInteger("Length", m_dwSize); | |
| 904 } | |
| 905 } | |
| 906 | |
| 907 CFX_WideString CPDF_Stream::GetUnicodeText() const { | |
| 908 CPDF_StreamAcc stream; | |
| 909 stream.LoadAllData(this, FALSE); | |
| 910 return PDF_DecodeText(stream.GetData(), stream.GetSize()); | |
| 911 } | |
| 912 | |
| 913 CPDF_StreamAcc::CPDF_StreamAcc() { | |
| 914 m_bNewBuf = FALSE; | |
| 915 m_pData = NULL; | |
| 916 m_dwSize = 0; | |
| 917 m_pImageParam = NULL; | |
| 918 m_pStream = NULL; | |
| 919 m_pSrcData = NULL; | |
| 920 } | |
| 921 void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, | |
| 922 FX_BOOL bRawAccess, | |
| 923 FX_DWORD estimated_size, | |
| 924 FX_BOOL bImageAcc) { | |
| 925 if (!pStream) | |
| 926 return; | |
| 927 | |
| 928 m_pStream = pStream; | |
| 929 if (pStream->IsMemoryBased() && | |
| 930 (!pStream->GetDict()->KeyExist("Filter") || bRawAccess)) { | |
| 931 m_dwSize = pStream->GetRawSize(); | |
| 932 m_pData = pStream->GetRawData(); | |
| 933 return; | |
| 934 } | |
| 935 uint8_t* pSrcData; | |
| 936 FX_DWORD dwSrcSize = pStream->GetRawSize(); | |
| 937 if (dwSrcSize == 0) | |
| 938 return; | |
| 939 | |
| 940 if (!pStream->IsMemoryBased()) { | |
| 941 pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize); | |
| 942 if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) | |
| 943 return; | |
| 944 } else { | |
| 945 pSrcData = pStream->GetRawData(); | |
| 946 } | |
| 947 uint8_t* pDecryptedData = pSrcData; | |
| 948 FX_DWORD dwDecryptedSize = dwSrcSize; | |
| 949 if (!pStream->GetDict()->KeyExist("Filter") || bRawAccess) { | |
| 950 m_pData = pDecryptedData; | |
| 951 m_dwSize = dwDecryptedSize; | |
| 952 } else { | |
| 953 FX_BOOL bRet = PDF_DataDecode( | |
| 954 pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), m_pData, | |
| 955 m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc); | |
| 956 if (!bRet) { | |
| 957 m_pData = pDecryptedData; | |
| 958 m_dwSize = dwDecryptedSize; | |
| 959 } | |
| 960 } | |
| 961 if (pSrcData != pStream->GetRawData() && pSrcData != m_pData) { | |
| 962 FX_Free(pSrcData); | |
| 963 } | |
| 964 if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { | |
| 965 FX_Free(pDecryptedData); | |
| 966 } | |
| 967 m_pSrcData = NULL; | |
| 968 m_bNewBuf = m_pData != pStream->GetRawData(); | |
| 969 } | |
| 970 | |
| 971 CPDF_StreamAcc::~CPDF_StreamAcc() { | |
| 972 if (m_bNewBuf) { | |
| 973 FX_Free(m_pData); | |
| 974 } | |
| 975 FX_Free(m_pSrcData); | |
| 976 } | |
| 977 | |
| 978 const uint8_t* CPDF_StreamAcc::GetData() const { | |
| 979 if (m_bNewBuf) { | |
| 980 return m_pData; | |
| 981 } | |
| 982 if (!m_pStream) { | |
| 983 return NULL; | |
| 984 } | |
| 985 return m_pStream->GetRawData(); | |
| 986 } | |
| 987 | |
| 988 FX_DWORD CPDF_StreamAcc::GetSize() const { | |
| 989 if (m_bNewBuf) { | |
| 990 return m_dwSize; | |
| 991 } | |
| 992 if (!m_pStream) { | |
| 993 return 0; | |
| 994 } | |
| 995 return m_pStream->GetRawSize(); | |
| 996 } | |
| 997 | |
| 998 uint8_t* CPDF_StreamAcc::DetachData() { | |
| 999 if (m_bNewBuf) { | |
| 1000 uint8_t* p = m_pData; | |
| 1001 m_pData = NULL; | |
| 1002 m_dwSize = 0; | |
| 1003 return p; | |
| 1004 } | |
| 1005 uint8_t* p = FX_Alloc(uint8_t, m_dwSize); | |
| 1006 FXSYS_memcpy(p, m_pData, m_dwSize); | |
| 1007 return p; | |
| 1008 } | |
| 1009 | |
| 1010 CPDF_Object::Type CPDF_Null::GetType() const { | |
| 1011 return NULLOBJ; | |
| 1012 } | |
| 1013 | |
| 1014 CPDF_Object* CPDF_Null::Clone(FX_BOOL bDirect) const { | |
| 1015 return new CPDF_Null; | |
| 1016 } | |
| 1017 | |
| 1018 CPDF_Reference::~CPDF_Reference() {} | |
| 1019 | |
| 1020 CPDF_Object::Type CPDF_Reference::GetType() const { | |
| 1021 return REFERENCE; | |
| 1022 } | |
| 1023 | |
| 1024 CFX_ByteString CPDF_Reference::GetString() const { | |
| 1025 CPDF_Object* obj = SafeGetDirect(); | |
| 1026 return obj ? obj->GetString() : CFX_ByteString(); | |
| 1027 } | |
| 1028 | |
| 1029 CFX_ByteStringC CPDF_Reference::GetConstString() const { | |
| 1030 CPDF_Object* obj = SafeGetDirect(); | |
| 1031 return obj ? obj->GetConstString() : CFX_ByteStringC(); | |
| 1032 } | |
| 1033 | |
| 1034 FX_FLOAT CPDF_Reference::GetNumber() const { | |
| 1035 CPDF_Object* obj = SafeGetDirect(); | |
| 1036 return obj ? obj->GetNumber() : 0; | |
| 1037 } | |
| 1038 | |
| 1039 int CPDF_Reference::GetInteger() const { | |
| 1040 CPDF_Object* obj = SafeGetDirect(); | |
| 1041 return obj ? obj->GetInteger() : 0; | |
| 1042 } | |
| 1043 | |
| 1044 CPDF_Dictionary* CPDF_Reference::GetDict() const { | |
| 1045 CPDF_Object* obj = SafeGetDirect(); | |
| 1046 return obj ? obj->GetDict() : nullptr; | |
| 1047 } | |
| 1048 | |
| 1049 bool CPDF_Reference::IsReference() const { | |
| 1050 return true; | |
| 1051 } | |
| 1052 | |
| 1053 CPDF_Reference* CPDF_Reference::AsReference() { | |
| 1054 return this; | |
| 1055 } | |
| 1056 | |
| 1057 const CPDF_Reference* CPDF_Reference::AsReference() const { | |
| 1058 return this; | |
| 1059 } | |
| 1060 | |
| 1061 CPDF_Object* CPDF_Reference::Clone(FX_BOOL bDirect) const { | |
| 1062 if (bDirect) { | |
| 1063 auto* pDirect = GetDirect(); | |
| 1064 return pDirect ? pDirect->Clone(TRUE) : nullptr; | |
| 1065 } | |
| 1066 return new CPDF_Reference(m_pObjList, m_RefObjNum); | |
| 1067 } | |
| 1068 | |
| 1069 void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum) { | |
| 1070 m_pObjList = pDoc; | |
| 1071 m_RefObjNum = objnum; | |
| 1072 } | |
| 1073 | |
| 1074 CPDF_Object* CPDF_Reference::GetDirect() const { | |
| 1075 return m_pObjList ? m_pObjList->GetIndirectObject(m_RefObjNum) : nullptr; | |
| 1076 } | |
| 1077 | |
| 1078 CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder(CPDF_Parser* pParser) | |
| 1079 : m_pParser(pParser), m_LastObjNum(0) { | |
| 1080 if (pParser) | |
| 1081 m_LastObjNum = m_pParser->GetLastObjNum(); | |
| 1082 } | |
| 1083 | |
| 1084 CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() { | |
| 1085 for (const auto& pair : m_IndirectObjs) { | |
| 1086 pair.second->Destroy(); | |
| 1087 } | |
| 1088 } | |
| 1089 | |
| 1090 CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(FX_DWORD objnum) { | |
| 1091 if (objnum == 0) | |
| 1092 return nullptr; | |
| 1093 | |
| 1094 auto it = m_IndirectObjs.find(objnum); | |
| 1095 if (it != m_IndirectObjs.end()) | |
| 1096 return it->second->GetObjNum() != -1 ? it->second : nullptr; | |
| 1097 | |
| 1098 if (!m_pParser) | |
| 1099 return nullptr; | |
| 1100 | |
| 1101 CPDF_Object* pObj = m_pParser->ParseIndirectObject(this, objnum); | |
| 1102 if (!pObj) | |
| 1103 return nullptr; | |
| 1104 | |
| 1105 pObj->m_ObjNum = objnum; | |
| 1106 m_LastObjNum = std::max(m_LastObjNum, objnum); | |
| 1107 if (m_IndirectObjs[objnum]) | |
| 1108 m_IndirectObjs[objnum]->Destroy(); | |
| 1109 | |
| 1110 m_IndirectObjs[objnum] = pObj; | |
| 1111 return pObj; | |
| 1112 } | |
| 1113 | |
| 1114 FX_DWORD CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { | |
| 1115 if (pObj->m_ObjNum) { | |
| 1116 return pObj->m_ObjNum; | |
| 1117 } | |
| 1118 m_LastObjNum++; | |
| 1119 m_IndirectObjs[m_LastObjNum] = pObj; | |
| 1120 pObj->m_ObjNum = m_LastObjNum; | |
| 1121 return m_LastObjNum; | |
| 1122 } | |
| 1123 | |
| 1124 void CPDF_IndirectObjectHolder::ReleaseIndirectObject(FX_DWORD objnum) { | |
| 1125 auto it = m_IndirectObjs.find(objnum); | |
| 1126 if (it == m_IndirectObjs.end() || it->second->GetObjNum() == -1) | |
| 1127 return; | |
| 1128 it->second->Destroy(); | |
| 1129 m_IndirectObjs.erase(it); | |
| 1130 } | |
| 1131 | |
| 1132 FX_BOOL CPDF_IndirectObjectHolder::InsertIndirectObject(FX_DWORD objnum, | |
| 1133 CPDF_Object* pObj) { | |
| 1134 if (!objnum || !pObj) | |
| 1135 return FALSE; | |
| 1136 auto it = m_IndirectObjs.find(objnum); | |
| 1137 if (it != m_IndirectObjs.end()) { | |
| 1138 if (pObj->GetGenNum() <= it->second->GetGenNum()) { | |
| 1139 pObj->Destroy(); | |
| 1140 return FALSE; | |
| 1141 } | |
| 1142 it->second->Destroy(); | |
| 1143 } | |
| 1144 pObj->m_ObjNum = objnum; | |
| 1145 m_IndirectObjs[objnum] = pObj; | |
| 1146 m_LastObjNum = std::max(m_LastObjNum, objnum); | |
| 1147 return TRUE; | |
| 1148 } | |
| OLD | NEW |