Move CFXA_MapModule to CFXJSE_MapModule and add tests
Change-Id: Ib1bf4c0394d435658e11a2237442b2e13c46280f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/74832
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index 0526f21..1c7c3e3 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -124,6 +124,8 @@
"xfa/cfxjse_formcalc_context.h",
"xfa/cfxjse_isolatetracker.cpp",
"xfa/cfxjse_isolatetracker.h",
+ "xfa/cfxjse_mapmodule.cpp",
+ "xfa/cfxjse_mapmodule.h",
"xfa/cfxjse_nodehelper.cpp",
"xfa/cfxjse_nodehelper.h",
"xfa/cfxjse_resolveprocessor.cpp",
@@ -253,8 +255,12 @@
"gc/gced_tree_node_unittest.cpp",
"gc/heap_unittest.cpp",
"gc/move_unittest.cpp",
+ "xfa/cfxjse_mapmodule_unittest.cpp",
]
- deps += [ ":gc" ]
+ deps += [
+ ":gc",
+ "../xfa/fxfa/parser",
+ ]
}
}
diff --git a/fxjs/xfa/cfxjse_mapmodule.cpp b/fxjs/xfa/cfxjse_mapmodule.cpp
new file mode 100644
index 0000000..669ce21
--- /dev/null
+++ b/fxjs/xfa/cfxjse_mapmodule.cpp
@@ -0,0 +1,78 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/xfa/cfxjse_mapmodule.h"
+
+#include "third_party/base/stl_util.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+
+CFXJSE_MapModule::CFXJSE_MapModule() = default;
+
+CFXJSE_MapModule::~CFXJSE_MapModule() = default;
+
+void CFXJSE_MapModule::SetValue(uint32_t key, int32_t value) {
+ m_StringMap.erase(key);
+ m_MeasurementMap.erase(key);
+ m_ValueMap[key] = value;
+}
+
+void CFXJSE_MapModule::SetString(uint32_t key, const WideString& wsString) {
+ m_ValueMap.erase(key);
+ m_MeasurementMap.erase(key);
+ m_StringMap[key] = wsString;
+}
+
+void CFXJSE_MapModule::SetMeasurement(uint32_t key,
+ const CXFA_Measurement& measurement) {
+ m_ValueMap.erase(key);
+ m_StringMap.erase(key);
+ m_MeasurementMap[key] = measurement;
+}
+
+Optional<int32_t> CFXJSE_MapModule::GetValue(uint32_t key) const {
+ auto it = m_ValueMap.find(key);
+ if (it == m_ValueMap.end())
+ return pdfium::nullopt;
+ return it->second;
+}
+
+Optional<WideString> CFXJSE_MapModule::GetString(uint32_t key) const {
+ auto it = m_StringMap.find(key);
+ if (it == m_StringMap.end())
+ return pdfium::nullopt;
+ return it->second;
+}
+
+Optional<CXFA_Measurement> CFXJSE_MapModule::GetMeasurement(
+ uint32_t key) const {
+ auto it = m_MeasurementMap.find(key);
+ if (it == m_MeasurementMap.end())
+ return pdfium::nullopt;
+ return it->second;
+}
+
+bool CFXJSE_MapModule::HasKey(uint32_t key) const {
+ return pdfium::Contains(m_ValueMap, key) ||
+ pdfium::Contains(m_StringMap, key) ||
+ pdfium::Contains(m_MeasurementMap, key);
+}
+
+void CFXJSE_MapModule::RemoveKey(uint32_t key) {
+ m_ValueMap.erase(key);
+ m_StringMap.erase(key);
+ m_MeasurementMap.erase(key);
+}
+
+void CFXJSE_MapModule::MergeDataFrom(const CFXJSE_MapModule* pSrc) {
+ for (const auto& pair : pSrc->m_ValueMap)
+ SetValue(pair.first, pair.second);
+
+ for (const auto& pair : pSrc->m_StringMap)
+ SetString(pair.first, pair.second);
+
+ for (const auto& pair : pSrc->m_MeasurementMap)
+ SetMeasurement(pair.first, pair.second);
+}
diff --git a/fxjs/xfa/cfxjse_mapmodule.h b/fxjs/xfa/cfxjse_mapmodule.h
new file mode 100644
index 0000000..ce8fa07
--- /dev/null
+++ b/fxjs/xfa/cfxjse_mapmodule.h
@@ -0,0 +1,44 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJS_XFA_CFXJSE_MAPMODULE_H_
+#define FXJS_XFA_CFXJSE_MAPMODULE_H_
+
+#include <stdint.h>
+
+#include <map>
+
+#include "core/fxcrt/fx_string.h"
+#include "third_party/base/optional.h"
+
+class CXFA_Measurement;
+
+class CFXJSE_MapModule {
+ public:
+ CFXJSE_MapModule();
+ ~CFXJSE_MapModule();
+
+ CFXJSE_MapModule(const CFXJSE_MapModule& that) = delete;
+ CFXJSE_MapModule& operator=(const CFXJSE_MapModule& that) = delete;
+
+ void SetValue(uint32_t key, int32_t value);
+ void SetString(uint32_t key, const WideString& wsString);
+ void SetMeasurement(uint32_t key, const CXFA_Measurement& measurement);
+ Optional<int32_t> GetValue(uint32_t key) const;
+ Optional<WideString> GetString(uint32_t key) const;
+ Optional<CXFA_Measurement> GetMeasurement(uint32_t key) const;
+ bool HasKey(uint32_t key) const;
+ void RemoveKey(uint32_t key);
+ void MergeDataFrom(const CFXJSE_MapModule* pSrc);
+
+ private:
+ // keyed by result of GetMapKey_*().
+ std::map<uint32_t, int32_t> m_ValueMap;
+ std::map<uint32_t, WideString> m_StringMap;
+ std::map<uint32_t, CXFA_Measurement> m_MeasurementMap;
+};
+
+#endif // FXJS_XFA_CFXJSE_MAPMODULE_H_
diff --git a/fxjs/xfa/cfxjse_mapmodule_unittest.cpp b/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
new file mode 100644
index 0000000..894b209
--- /dev/null
+++ b/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
@@ -0,0 +1,124 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/xfa/cfxjse_mapmodule.h"
+
+#include "core/fxcrt/fx_string.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/base/optional.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+
+TEST(CFXJSEMapModule, EmptyModule) {
+ CFXJSE_MapModule module;
+ EXPECT_FALSE(module.HasKey(1));
+ EXPECT_FALSE(module.HasKey(2));
+ EXPECT_FALSE(module.HasKey(3));
+ EXPECT_FALSE(module.GetValue(1).has_value());
+ EXPECT_FALSE(module.GetString(2).has_value());
+ EXPECT_FALSE(module.GetMeasurement(3).has_value());
+}
+
+TEST(CFXJSEMapModule, InsertDelete) {
+ const int value = 101;
+ WideString string(L"foo");
+ CXFA_Measurement measure(L"1 pt");
+ CFXJSE_MapModule module;
+
+ module.SetValue(100, value);
+ module.SetString(200, string);
+ module.SetMeasurement(300, measure);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_TRUE(module.HasKey(200));
+ EXPECT_TRUE(module.HasKey(300));
+
+ EXPECT_EQ(module.GetValue(100).value(), value);
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+
+ EXPECT_FALSE(module.GetValue(200).has_value());
+ EXPECT_EQ(module.GetString(200).value(), string);
+ EXPECT_FALSE(module.GetMeasurement(200).has_value());
+
+ EXPECT_FALSE(module.GetValue(300).has_value());
+ EXPECT_FALSE(module.GetString(300).has_value());
+ EXPECT_EQ(module.GetMeasurement(300).value().GetUnit(), measure.GetUnit());
+ EXPECT_EQ(module.GetMeasurement(300).value().GetValue(), measure.GetValue());
+
+ module.RemoveKey(100);
+ module.RemoveKey(200);
+ module.RemoveKey(300);
+ EXPECT_FALSE(module.HasKey(100));
+ EXPECT_FALSE(module.HasKey(200));
+ EXPECT_FALSE(module.HasKey(300));
+ EXPECT_FALSE(module.GetValue(100).has_value());
+ EXPECT_FALSE(module.GetString(200).has_value());
+ EXPECT_FALSE(module.GetMeasurement(200).has_value());
+}
+
+TEST(CFXJSEMapModule, KeyCollision) {
+ const int value = 37;
+ WideString string(L"foo");
+ CXFA_Measurement measure(L"1 pt");
+ CFXJSE_MapModule module;
+
+ module.SetValue(100, value);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_EQ(module.GetValue(100).value(), value);
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+
+ module.SetString(100, string);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_FALSE(module.GetValue(100).has_value());
+ EXPECT_EQ(module.GetString(100).value(), string);
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+
+ module.SetMeasurement(100, measure);
+ EXPECT_FALSE(module.GetValue(100).has_value());
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_EQ(module.GetMeasurement(100).value().GetUnit(), measure.GetUnit());
+
+ module.SetValue(100, value);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_EQ(module.GetValue(100).value(), value);
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+}
+
+TEST(CFXJSEMapModule, MergeData) {
+ const int value1 = 42;
+ const int value2 = -1999;
+ WideString string1(L"foo");
+ WideString string2(L"foo");
+ CXFA_Measurement measure1(L"1 pt");
+ CXFA_Measurement measure2(L"2 mm");
+ CFXJSE_MapModule module1;
+ CFXJSE_MapModule module2;
+
+ module1.SetValue(100, value1);
+ module1.SetValue(101, value1);
+ module1.SetString(200, string1);
+ module1.SetString(201, string1);
+ module1.SetMeasurement(300, measure1);
+ module1.SetMeasurement(301, measure1);
+
+ module2.SetString(100, string2);
+ module2.SetMeasurement(200, measure2);
+ module2.SetValue(300, value2);
+
+ module1.MergeDataFrom(&module2);
+ EXPECT_EQ(module1.GetString(100).value(), string2);
+ EXPECT_EQ(module1.GetValue(101).value(), value1);
+ EXPECT_EQ(module1.GetMeasurement(200).value().GetUnit(), measure2.GetUnit());
+ EXPECT_EQ(module1.GetString(201).value(), string1);
+ EXPECT_EQ(module1.GetValue(300).value(), value2);
+ EXPECT_EQ(module1.GetMeasurement(301).value().GetUnit(), measure1.GetUnit());
+
+ // module2 is undisturbed.
+ EXPECT_EQ(module2.GetString(100).value(), string2);
+ EXPECT_EQ(module2.GetMeasurement(200).value().GetUnit(), measure2.GetUnit());
+ EXPECT_EQ(module2.GetValue(300).value(), value2);
+}
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index db7deeb..eb975b1 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -16,6 +16,7 @@
#include "fxjs/cjs_result.h"
#include "fxjs/gc/container_trace.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cfxjse_mapmodule.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_boolean.h"
#include "fxjs/xfa/cjx_draw.h"
@@ -93,80 +94,6 @@
} // namespace
-class CXFA_MapModule {
- public:
- CXFA_MapModule() = default;
- ~CXFA_MapModule() = default;
-
- void SetValue(uint32_t key, int32_t value) {
- m_StringMap.erase(key);
- m_MeasurementMap.erase(key);
- m_ValueMap[key] = value;
- }
-
- void SetString(uint32_t key, const WideString& wsString) {
- m_ValueMap.erase(key);
- m_MeasurementMap.erase(key);
- m_StringMap[key] = wsString;
- }
-
- void SetMeasurement(uint32_t key, const CXFA_Measurement& measurement) {
- m_ValueMap.erase(key);
- m_StringMap.erase(key);
- m_MeasurementMap[key] = measurement;
- }
-
- Optional<int32_t> GetValue(uint32_t key) const {
- auto it = m_ValueMap.find(key);
- if (it == m_ValueMap.end())
- return pdfium::nullopt;
- return it->second;
- }
-
- Optional<WideString> GetString(uint32_t key) const {
- auto it = m_StringMap.find(key);
- if (it == m_StringMap.end())
- return pdfium::nullopt;
- return it->second;
- }
-
- Optional<CXFA_Measurement> GetMeasurement(uint32_t key) const {
- auto it = m_MeasurementMap.find(key);
- if (it == m_MeasurementMap.end())
- return pdfium::nullopt;
- return it->second;
- }
-
- bool HasKey(uint32_t key) const {
- return pdfium::Contains(m_ValueMap, key) ||
- pdfium::Contains(m_StringMap, key) ||
- pdfium::Contains(m_MeasurementMap, key);
- }
-
- void RemoveKey(uint32_t key) {
- m_ValueMap.erase(key);
- m_StringMap.erase(key);
- m_MeasurementMap.erase(key);
- }
-
- void MergeDataFrom(const CXFA_MapModule* pSrc) {
- for (const auto& pair : pSrc->m_ValueMap)
- SetValue(pair.first, pair.second);
-
- for (const auto& pair : pSrc->m_StringMap)
- SetString(pair.first, pair.second);
-
- for (const auto& pair : pSrc->m_MeasurementMap)
- SetMeasurement(pair.first, pair.second);
- }
-
- private:
- // keyed by result of GetMapKey_*().
- std::map<uint32_t, int32_t> m_ValueMap;
- std::map<uint32_t, WideString> m_StringMap;
- std::map<uint32_t, CXFA_Measurement> m_MeasurementMap;
-};
-
CJX_Object::CJX_Object(CXFA_Object* obj) : object_(obj) {}
CJX_Object::~CJX_Object() = default;
@@ -832,13 +759,13 @@
return GetXFANode()->GetOrCreateProperty(index, eProperty);
}
-CXFA_MapModule* CJX_Object::CreateMapModule() {
+CFXJSE_MapModule* CJX_Object::CreateMapModule() {
if (!map_module_)
- map_module_ = std::make_unique<CXFA_MapModule>();
+ map_module_ = std::make_unique<CFXJSE_MapModule>();
return map_module_.get();
}
-CXFA_MapModule* CJX_Object::GetMapModule() const {
+CFXJSE_MapModule* CJX_Object::GetMapModule() const {
return map_module_.get();
}
@@ -856,14 +783,14 @@
}
Optional<int32_t> CJX_Object::GetMapModuleValue(uint32_t key) const {
- CXFA_MapModule* pModule = GetMapModule();
+ CFXJSE_MapModule* pModule = GetMapModule();
if (!pModule)
return pdfium::nullopt;
return pModule->GetValue(key);
}
Optional<WideString> CJX_Object::GetMapModuleString(uint32_t key) const {
- CXFA_MapModule* pModule = GetMapModule();
+ CFXJSE_MapModule* pModule = GetMapModule();
if (!pModule)
return pdfium::nullopt;
return pModule->GetString(key);
@@ -871,7 +798,7 @@
Optional<CXFA_Measurement> CJX_Object::GetMapModuleMeasurement(
uint32_t key) const {
- CXFA_MapModule* pModule = GetMapModule();
+ CFXJSE_MapModule* pModule = GetMapModule();
if (!pModule)
return pdfium::nullopt;
return pModule->GetMeasurement(key);
@@ -933,19 +860,19 @@
}
bool CJX_Object::HasMapModuleKey(uint32_t key) {
- CXFA_MapModule* pModule = GetMapModule();
+ CFXJSE_MapModule* pModule = GetMapModule();
return pModule && pModule->HasKey(key);
}
void CJX_Object::RemoveMapModuleKey(uint32_t key) {
- CXFA_MapModule* pModule = GetMapModule();
+ CFXJSE_MapModule* pModule = GetMapModule();
if (pModule)
pModule->RemoveKey(key);
}
void CJX_Object::MergeAllData(CXFA_Object* pDstObj) {
- CXFA_MapModule* pDstModule = ToNode(pDstObj)->JSObject()->CreateMapModule();
- CXFA_MapModule* pSrcModule = GetMapModule();
+ CFXJSE_MapModule* pDstModule = ToNode(pDstObj)->JSObject()->CreateMapModule();
+ CFXJSE_MapModule* pSrcModule = GetMapModule();
if (!pSrcModule)
return;
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index 9a01b76..8cd5ab0 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -21,15 +21,15 @@
#include "v8/include/cppgc/garbage-collected.h"
#include "v8/include/cppgc/member.h"
#include "xfa/fxfa/fxfa_basic.h"
-#include "xfa/fxfa/parser/cxfa_measurement.h"
+class CFXJSE_MapModule;
class CFXJSE_Value;
class CFX_V8;
class CFX_XMLElement;
class CJX_Object;
class CXFA_Document;
class CXFA_LayoutItem;
-class CXFA_MapModule;
+class CXFA_Measurement;
class CXFA_Node;
class CXFA_Object;
@@ -255,8 +255,8 @@
CFX_XMLElement* SetValue(XFA_Attribute eAttr, int32_t value, bool bNotify);
int32_t Subform_and_SubformSet_InstanceIndex();
- CXFA_MapModule* CreateMapModule();
- CXFA_MapModule* GetMapModule() const;
+ CFXJSE_MapModule* CreateMapModule();
+ CFXJSE_MapModule* GetMapModule() const;
void SetMapModuleValue(uint32_t key, int32_t value);
void SetMapModuleString(uint32_t key, const WideString& wsValue);
void SetMapModuleMeasurement(uint32_t key, const CXFA_Measurement& value);
@@ -274,7 +274,7 @@
cppgc::Member<CXFA_Object> object_;
cppgc::Member<CXFA_LayoutItem> layout_item_;
cppgc::Member<CalcData> calc_data_;
- std::unique_ptr<CXFA_MapModule> map_module_;
+ std::unique_ptr<CFXJSE_MapModule> map_module_;
std::map<ByteString, CJX_MethodCall> method_specs_;
size_t calc_recursion_count_ = 0;
};