|  | // Copyright 2018 The PDFium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "fxjs/cfx_globaldata.h" | 
|  |  | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | #include "core/fxcrt/data_vector.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | class TestDelegate : public CFX_GlobalData::Delegate { | 
|  | public: | 
|  | TestDelegate() = default; | 
|  | ~TestDelegate() override = default; | 
|  |  | 
|  | bool StoreBuffer(pdfium::span<const uint8_t> buffer) override { | 
|  | last_buffer_ = DataVector<uint8_t>(buffer.begin(), buffer.end()); | 
|  | return true; | 
|  | } | 
|  | std::optional<pdfium::span<uint8_t>> LoadBuffer() override { | 
|  | return pdfium::span<uint8_t>(last_buffer_); | 
|  | } | 
|  | void BufferDone() override { | 
|  | // Catch misuse after done. | 
|  | last_buffer_ = DataVector<uint8_t>(); | 
|  | } | 
|  |  | 
|  | DataVector<uint8_t> last_buffer_; | 
|  | }; | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | TEST(CFXGlobalData, GetSafety) { | 
|  | CFX_GlobalData* pInstance = CFX_GlobalData::GetRetainedInstance(nullptr); | 
|  | EXPECT_FALSE(pInstance->GetGlobalVariable("nonesuch")); | 
|  | EXPECT_FALSE(pInstance->GetAt(-1)); | 
|  | EXPECT_FALSE(pInstance->GetAt(0)); | 
|  | EXPECT_FALSE(pInstance->GetAt(1)); | 
|  |  | 
|  | pInstance->SetGlobalVariableNumber("double", 2.0); | 
|  | pInstance->SetGlobalVariableString("string", "clams"); | 
|  |  | 
|  | EXPECT_FALSE(pInstance->GetGlobalVariable("nonesuch")); | 
|  | EXPECT_FALSE(pInstance->GetAt(-1)); | 
|  | EXPECT_EQ(pInstance->GetGlobalVariable("double"), pInstance->GetAt(0)); | 
|  | EXPECT_EQ(pInstance->GetGlobalVariable("string"), pInstance->GetAt(1)); | 
|  | EXPECT_FALSE(pInstance->GetAt(2)); | 
|  |  | 
|  | ASSERT_TRUE(pInstance->Release()); | 
|  | } | 
|  |  | 
|  | TEST(CFXGlobalData, StoreReload) { | 
|  | TestDelegate delegate; | 
|  | std::vector<std::unique_ptr<CFX_KeyValue>> array; | 
|  | CFX_GlobalData* pInstance = CFX_GlobalData::GetRetainedInstance(&delegate); | 
|  | pInstance->SetGlobalVariableNumber("double", 2.0); | 
|  | pInstance->SetGlobalVariableString("string", "clams"); | 
|  | pInstance->SetGlobalVariableBoolean("boolean", true); | 
|  | pInstance->SetGlobalVariableNull("null"); | 
|  | pInstance->SetGlobalVariableObject("array", std::move(array)); | 
|  | pInstance->SetGlobalVariablePersistent("double", true); | 
|  | pInstance->SetGlobalVariablePersistent("string", true); | 
|  | pInstance->SetGlobalVariablePersistent("boolean", true); | 
|  | pInstance->SetGlobalVariablePersistent("null", true); | 
|  | pInstance->SetGlobalVariablePersistent("array", true); | 
|  | ASSERT_TRUE(pInstance->Release()); | 
|  |  | 
|  | pInstance = CFX_GlobalData::GetRetainedInstance(&delegate); | 
|  | auto* element = pInstance->GetAt(0); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("double", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kNumber, element->data.nType); | 
|  | EXPECT_EQ(2.0, element->data.dData); | 
|  |  | 
|  | element = pInstance->GetAt(1); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("string", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kString, element->data.nType); | 
|  | EXPECT_EQ("clams", element->data.sData); | 
|  |  | 
|  | element = pInstance->GetAt(2); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("boolean", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kBoolean, element->data.nType); | 
|  | EXPECT_EQ(true, element->data.bData); | 
|  |  | 
|  | element = pInstance->GetAt(3); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("null", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kNull, element->data.nType); | 
|  |  | 
|  | // Arrays don't get persisted. | 
|  | element = pInstance->GetAt(4); | 
|  | ASSERT_FALSE(element); | 
|  |  | 
|  | ASSERT_TRUE(pInstance->Release()); | 
|  | } | 
|  |  | 
|  | TEST(CFXGlobalData, ResetValues) { | 
|  | CFX_GlobalData* pInstance = CFX_GlobalData::GetRetainedInstance(nullptr); | 
|  | pInstance->SetGlobalVariableString("double", "bogus!!!"); | 
|  | pInstance->SetGlobalVariableString("string", "bogus!!!"); | 
|  | pInstance->SetGlobalVariableString("boolean", "bogus!!!"); | 
|  | pInstance->SetGlobalVariableString("null", "bogus!!!"); | 
|  |  | 
|  | pInstance->SetGlobalVariableNumber("double", 2.0); | 
|  | pInstance->SetGlobalVariableString("string", "clams"); | 
|  | pInstance->SetGlobalVariableBoolean("boolean", true); | 
|  | pInstance->SetGlobalVariableNull("null"); | 
|  |  | 
|  | auto* element = pInstance->GetAt(0); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("double", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kNumber, element->data.nType); | 
|  | EXPECT_EQ(2.0, element->data.dData); | 
|  |  | 
|  | element = pInstance->GetAt(1); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("string", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kString, element->data.nType); | 
|  | EXPECT_EQ("clams", element->data.sData); | 
|  |  | 
|  | element = pInstance->GetAt(2); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("boolean", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kBoolean, element->data.nType); | 
|  | EXPECT_EQ(true, element->data.bData); | 
|  |  | 
|  | element = pInstance->GetAt(3); | 
|  | ASSERT_TRUE(element); | 
|  | EXPECT_EQ("null", element->data.sKey); | 
|  | EXPECT_EQ(CFX_Value::DataType::kNull, element->data.nType); | 
|  |  | 
|  | ASSERT_TRUE(pInstance->Release()); | 
|  | } | 
|  |  | 
|  | TEST(CFXGlobalData, DeleteValues) { | 
|  | CFX_GlobalData* pInstance = CFX_GlobalData::GetRetainedInstance(nullptr); | 
|  | pInstance->SetGlobalVariableNumber("double", 2.0); | 
|  | pInstance->SetGlobalVariableString("string", "clams"); | 
|  | pInstance->SetGlobalVariableBoolean("boolean", true); | 
|  | pInstance->SetGlobalVariableNull("null"); | 
|  | EXPECT_EQ(4, pInstance->GetSize()); | 
|  |  | 
|  | pInstance->DeleteGlobalVariable("nonesuch"); | 
|  | EXPECT_EQ(4, pInstance->GetSize()); | 
|  |  | 
|  | pInstance->DeleteGlobalVariable("boolean"); | 
|  | EXPECT_EQ(3, pInstance->GetSize()); | 
|  |  | 
|  | pInstance->DeleteGlobalVariable("string"); | 
|  | EXPECT_EQ(2, pInstance->GetSize()); | 
|  |  | 
|  | pInstance->DeleteGlobalVariable("double"); | 
|  | EXPECT_EQ(1, pInstance->GetSize()); | 
|  |  | 
|  | pInstance->DeleteGlobalVariable("null"); | 
|  | EXPECT_EQ(0, pInstance->GetSize()); | 
|  |  | 
|  | ASSERT_TRUE(pInstance->Release()); | 
|  | } |