Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/include/fpdfapi/fpdf_objects.h" | 7 #include "core/include/fpdfapi/fpdf_objects.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 #include "core/include/fpdfapi/fpdf_parser.h" | 11 #include "core/include/fpdfapi/fpdf_parser.h" |
| 12 #include "core/include/fxcrt/fx_string.h" | 12 #include "core/include/fxcrt/fx_string.h" |
| 13 #include "third_party/base/stl_util.h" | 13 #include "third_party/base/stl_util.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 const FX_DWORD kBlockSize = 1024; | 17 const FX_DWORD kBlockSize = 1024; |
| 18 | 18 |
| 19 } // namespace | 19 } // namespace |
| 20 | 20 |
| 21 // static | |
| 22 int CPDF_Object::s_nCurRefDepth = 0; | |
| 23 | |
| 24 void CPDF_Object::Release() { | 21 void CPDF_Object::Release() { |
| 25 if (m_ObjNum) { | 22 if (m_ObjNum) { |
| 26 return; | 23 return; |
| 27 } | 24 } |
| 28 Destroy(); | 25 Destroy(); |
| 29 } | 26 } |
| 30 void CPDF_Object::Destroy() { | 27 void CPDF_Object::Destroy() { |
| 31 switch (m_Type) { | 28 switch (m_Type) { |
| 32 case PDFOBJ_STRING: | 29 case PDFOBJ_STRING: |
| 33 delete AsString(); | 30 delete AsString(); |
| 34 break; | 31 break; |
| 35 case PDFOBJ_NAME: | 32 case PDFOBJ_NAME: |
| 36 delete AsName(); | 33 delete AsName(); |
| 37 break; | 34 break; |
| 38 case PDFOBJ_ARRAY: | 35 case PDFOBJ_ARRAY: |
| 39 delete AsArray(); | 36 delete AsArray(); |
| 40 break; | 37 break; |
| 41 case PDFOBJ_DICTIONARY: | 38 case PDFOBJ_DICTIONARY: |
| 42 delete AsDictionary(); | 39 delete AsDictionary(); |
| 43 break; | 40 break; |
| 44 case PDFOBJ_STREAM: | 41 case PDFOBJ_STREAM: |
| 45 delete AsStream(); | 42 delete AsStream(); |
| 46 break; | 43 break; |
| 47 default: | 44 default: |
| 48 delete this; | 45 delete this; |
| 49 } | 46 } |
| 50 } | 47 } |
| 48 | |
| 49 const CPDF_Object* const CPDF_Object::GetBasicObject() const { | |
| 50 if (m_Type != PDFOBJ_REFERENCE) | |
|
Lei Zhang
2016/01/16 00:51:57
You can just call AsReference() and omit this chec
Wei Li
2016/01/19 20:16:24
Done.
| |
| 51 return this; | |
| 52 | |
| 53 const CPDF_Reference* pRef = AsReference(); | |
| 54 if (!pRef->m_pObjList) | |
| 55 return nullptr; | |
| 56 return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 57 } | |
| 58 | |
| 51 CFX_ByteString CPDF_Object::GetString() const { | 59 CFX_ByteString CPDF_Object::GetString() const { |
| 52 switch (m_Type) { | 60 const CPDF_Object* obj = GetBasicObject(); |
| 53 case PDFOBJ_BOOLEAN: | 61 if (obj) { |
| 54 return AsBoolean()->m_bValue ? "true" : "false"; | 62 switch (obj->GetType()) { |
| 55 case PDFOBJ_NUMBER: | 63 case PDFOBJ_BOOLEAN: |
| 56 return AsNumber()->GetString(); | 64 return obj->AsBoolean()->GetString(); |
| 57 case PDFOBJ_STRING: | 65 case PDFOBJ_NUMBER: |
| 58 return AsString()->m_String; | 66 return obj->AsNumber()->GetString(); |
| 59 case PDFOBJ_NAME: | 67 case PDFOBJ_STRING: |
| 60 return AsName()->m_Name; | 68 return obj->AsString()->GetString(); |
| 61 case PDFOBJ_REFERENCE: { | 69 case PDFOBJ_NAME: |
| 62 const CPDF_Reference* pRef = AsReference(); | 70 return obj->AsName()->GetString(); |
| 63 if (!pRef->m_pObjList) | |
| 64 break; | |
| 65 | |
| 66 CPDF_Object* pObj = | |
| 67 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 68 return pObj ? pObj->GetString() : CFX_ByteString(); | |
| 69 } | 71 } |
| 70 } | 72 } |
| 71 return CFX_ByteString(); | 73 return CFX_ByteString(); |
| 72 } | 74 } |
| 75 | |
| 73 CFX_ByteStringC CPDF_Object::GetConstString() const { | 76 CFX_ByteStringC CPDF_Object::GetConstString() const { |
| 74 switch (m_Type) { | 77 const CPDF_Object* obj = GetBasicObject(); |
| 75 case PDFOBJ_STRING: { | 78 if (obj) { |
| 76 CFX_ByteString str = AsString()->m_String; | 79 FX_DWORD type = obj->GetType(); |
| 77 return CFX_ByteStringC((const uint8_t*)str, str.GetLength()); | 80 if (type == PDFOBJ_STRING) { |
| 81 CFX_ByteString str = obj->AsString()->GetString(); | |
| 82 return CFX_ByteStringC(str); | |
| 78 } | 83 } |
| 79 case PDFOBJ_NAME: { | 84 if (type == PDFOBJ_NAME) { |
| 80 CFX_ByteString name = AsName()->m_Name; | 85 CFX_ByteString name = obj->AsName()->GetString(); |
| 81 return CFX_ByteStringC((const uint8_t*)name, name.GetLength()); | 86 return CFX_ByteStringC(name); |
| 82 } | |
| 83 case PDFOBJ_REFERENCE: { | |
| 84 const CPDF_Reference* pRef = AsReference(); | |
| 85 if (!pRef->m_pObjList) | |
| 86 break; | |
| 87 | |
| 88 CPDF_Object* pObj = | |
| 89 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 90 return pObj ? pObj->GetConstString() : CFX_ByteStringC(); | |
| 91 } | 87 } |
| 92 } | 88 } |
| 93 return CFX_ByteStringC(); | 89 return CFX_ByteStringC(); |
| 94 } | 90 } |
| 95 | 91 |
| 96 FX_FLOAT CPDF_Object::GetNumber() const { | 92 FX_FLOAT CPDF_Object::GetNumber() const { |
| 97 switch (m_Type) { | 93 const CPDF_Object* obj = GetBasicObject(); |
| 98 case PDFOBJ_NUMBER: | 94 if (obj && obj->GetType() == PDFOBJ_NUMBER) |
| 99 return AsNumber()->GetNumber(); | 95 return AsNumber()->GetNumber(); |
| 100 case PDFOBJ_REFERENCE: { | |
| 101 const CPDF_Reference* pRef = AsReference(); | |
| 102 if (!pRef->m_pObjList) | |
| 103 break; | |
| 104 | |
| 105 CPDF_Object* pObj = | |
| 106 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 107 return pObj ? pObj->GetNumber() : 0; | |
| 108 } | |
| 109 } | |
| 110 return 0; | 96 return 0; |
| 111 } | 97 } |
| 112 | 98 |
| 113 FX_FLOAT CPDF_Object::GetNumber16() const { | 99 FX_FLOAT CPDF_Object::GetNumber16() const { |
| 114 return GetNumber(); | 100 return GetNumber(); |
| 115 } | 101 } |
| 116 | 102 |
| 117 int CPDF_Object::GetInteger() const { | 103 int CPDF_Object::GetInteger() const { |
| 118 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); | 104 const CPDF_Object* obj = GetBasicObject(); |
| 119 if (++s_nCurRefDepth > kObjectRefMaxDepth) | 105 if (obj) { |
| 120 return 0; | 106 FX_DWORD type = obj->GetType(); |
| 121 | 107 if (type == PDFOBJ_BOOLEAN) |
| 122 switch (m_Type) { | 108 return obj->AsBoolean()->GetValue(); |
| 123 case PDFOBJ_BOOLEAN: | 109 if (type == PDFOBJ_NUMBER) |
| 124 return AsBoolean()->m_bValue; | 110 return obj->AsNumber()->GetInteger(); |
| 125 case PDFOBJ_NUMBER: | |
| 126 return AsNumber()->GetInteger(); | |
| 127 case PDFOBJ_REFERENCE: { | |
| 128 const CPDF_Reference* pRef = AsReference(); | |
| 129 PARSE_CONTEXT context; | |
| 130 FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); | |
| 131 if (!pRef->m_pObjList) | |
| 132 return 0; | |
| 133 | |
| 134 CPDF_Object* pObj = | |
| 135 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), &context); | |
| 136 return pObj ? pObj->GetInteger() : 0; | |
| 137 } | |
| 138 } | 111 } |
| 139 return 0; | 112 return 0; |
| 140 } | 113 } |
| 141 | 114 |
| 142 CPDF_Dictionary* CPDF_Object::GetDict() const { | 115 CPDF_Dictionary* CPDF_Object::GetDict() const { |
| 143 switch (m_Type) { | 116 const CPDF_Object* obj = GetBasicObject(); |
| 144 case PDFOBJ_DICTIONARY: | 117 if (obj) { |
| 118 FX_DWORD type = obj->GetType(); | |
| 119 if (type == PDFOBJ_DICTIONARY) { | |
| 145 // The method should be made non-const if we want to not be const. | 120 // The method should be made non-const if we want to not be const. |
| 146 // See bug #234. | 121 // See bug #234. |
| 147 return const_cast<CPDF_Dictionary*>(AsDictionary()); | 122 return const_cast<CPDF_Dictionary*>(AsDictionary()); |
| 148 case PDFOBJ_STREAM: | 123 } |
| 124 if (type == PDFOBJ_STREAM) | |
| 149 return AsStream()->GetDict(); | 125 return AsStream()->GetDict(); |
| 150 case PDFOBJ_REFERENCE: { | |
| 151 const CPDF_Reference* pRef = AsReference(); | |
| 152 CPDF_IndirectObjectHolder* pIndirect = pRef->GetObjList(); | |
| 153 if (!pIndirect) | |
| 154 return nullptr; | |
| 155 CPDF_Object* pObj = | |
| 156 pIndirect->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 157 if (!pObj || (pObj == this)) | |
| 158 return nullptr; | |
| 159 return pObj->GetDict(); | |
| 160 } | |
| 161 default: | |
| 162 return nullptr; | |
| 163 } | 126 } |
| 127 return nullptr; | |
| 164 } | 128 } |
| 165 | 129 |
| 166 CPDF_Array* CPDF_Object::GetArray() const { | 130 CPDF_Array* CPDF_Object::GetArray() const { |
| 167 // The method should be made non-const if we want to not be const. | 131 // The method should be made non-const if we want to not be const. |
| 168 // See bug #234. | 132 // See bug #234. |
| 169 return const_cast<CPDF_Array*>(AsArray()); | 133 return const_cast<CPDF_Array*>(AsArray()); |
| 170 } | 134 } |
| 171 | 135 |
| 172 void CPDF_Object::SetString(const CFX_ByteString& str) { | 136 void CPDF_Object::SetString(const CFX_ByteString& str) { |
| 173 switch (m_Type) { | 137 switch (m_Type) { |
| (...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 pObj->Destroy(); | 1097 pObj->Destroy(); |
| 1134 return FALSE; | 1098 return FALSE; |
| 1135 } | 1099 } |
| 1136 it->second->Destroy(); | 1100 it->second->Destroy(); |
| 1137 } | 1101 } |
| 1138 pObj->m_ObjNum = objnum; | 1102 pObj->m_ObjNum = objnum; |
| 1139 m_IndirectObjs[objnum] = pObj; | 1103 m_IndirectObjs[objnum] = pObj; |
| 1140 m_LastObjNum = std::max(m_LastObjNum, objnum); | 1104 m_LastObjNum = std::max(m_LastObjNum, objnum); |
| 1141 return TRUE; | 1105 return TRUE; |
| 1142 } | 1106 } |
| OLD | NEW |