diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt index 64fb4d12a546..7211bf5476dc 100644 --- a/cpp/src/arrow/CMakeLists.txt +++ b/cpp/src/arrow/CMakeLists.txt @@ -1042,7 +1042,6 @@ if(ARROW_JSON) json/from_string.cc json/json_writer_internal.cc json/object_parser.cc - json/object_writer.cc json/parser.cc json/reader.cc) foreach(ARROW_JSON_TARGET ${ARROW_JSON_TARGETS}) diff --git a/cpp/src/arrow/json/json_writer_internal.cc b/cpp/src/arrow/json/json_writer_internal.cc index 11fe70a7415e..49038f26b073 100644 --- a/cpp/src/arrow/json/json_writer_internal.cc +++ b/cpp/src/arrow/json/json_writer_internal.cc @@ -115,4 +115,14 @@ void JsonWriter::MaybeComma() { } } +void JsonWriter::StringField(std::string_view key, std::string_view value) { + Key(key); + String(value); +} + +void JsonWriter::BoolField(std::string_view key, bool value) { + Key(key); + Bool(value); +} + } // namespace arrow::json diff --git a/cpp/src/arrow/json/json_writer_internal.h b/cpp/src/arrow/json/json_writer_internal.h index e4d6e49885f8..4173cb4c512c 100644 --- a/cpp/src/arrow/json/json_writer_internal.h +++ b/cpp/src/arrow/json/json_writer_internal.h @@ -52,6 +52,9 @@ class ARROW_EXPORT JsonWriter { void Null(); + void StringField(std::string_view key, std::string_view value); + void BoolField(std::string_view key, bool value); + std::string_view GetString() const; void Clear(); diff --git a/cpp/src/arrow/json/meson.build b/cpp/src/arrow/json/meson.build index a2aa69ecf789..edf92a46fdd2 100644 --- a/cpp/src/arrow/json/meson.build +++ b/cpp/src/arrow/json/meson.build @@ -22,9 +22,9 @@ exc = executable( 'chunker_test.cc', 'converter_test.cc', 'from_string_test.cc', + 'json_writer_internal_test.cc', 'parser_test.cc', 'reader_test.cc', - 'json_writer_internal_test.cc', ], dependencies: [arrow_test_dep, rapidjson_dep], ) @@ -45,7 +45,6 @@ install_headers( 'converter.h', 'from_string.h', 'object_parser.h', - 'object_writer.h', 'options.h', 'parser.h', 'rapidjson_defs.h', diff --git a/cpp/src/arrow/json/object_writer.cc b/cpp/src/arrow/json/object_writer.cc deleted file mode 100644 index 3277807880ce..000000000000 --- a/cpp/src/arrow/json/object_writer.cc +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#include "arrow/json/object_writer.h" -#include "arrow/json/rapidjson_defs.h" // IWYU pragma: keep - -#include -#include -#include - -namespace rj = arrow::rapidjson; - -namespace arrow { -namespace json { -namespace internal { - -class ObjectWriter::Impl { - public: - Impl() : root_(rj::kObjectType) {} - - void SetString(std::string_view key, std::string_view value) { - rj::Document::AllocatorType& allocator = document_.GetAllocator(); - - rj::Value str_key(key.data(), allocator); - rj::Value str_value(value.data(), allocator); - - root_.AddMember(str_key, str_value, allocator); - } - - void SetBool(std::string_view key, bool value) { - rj::Document::AllocatorType& allocator = document_.GetAllocator(); - - rj::Value str_key(key.data(), allocator); - - root_.AddMember(str_key, value, allocator); - } - - std::string Serialize() { - rj::StringBuffer buffer; - rj::Writer writer(buffer); - root_.Accept(writer); - - return buffer.GetString(); - } - - private: - rj::Document document_; - rj::Value root_; -}; - -ObjectWriter::ObjectWriter() : impl_(new ObjectWriter::Impl()) {} - -ObjectWriter::~ObjectWriter() = default; - -void ObjectWriter::SetString(std::string_view key, std::string_view value) { - impl_->SetString(key, value); -} - -void ObjectWriter::SetBool(std::string_view key, bool value) { - impl_->SetBool(key, value); -} - -std::string ObjectWriter::Serialize() { return impl_->Serialize(); } - -} // namespace internal -} // namespace json -} // namespace arrow diff --git a/cpp/src/arrow/json/object_writer.h b/cpp/src/arrow/json/object_writer.h deleted file mode 100644 index cf1ce62194fb..000000000000 --- a/cpp/src/arrow/json/object_writer.h +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#pragma once - -#include -#include -#include - -#include "arrow/util/visibility.h" - -namespace arrow { -namespace json { -namespace internal { - -/// This class is a helper to serialize a json object to a string. -/// It uses rapidjson in implementation. -class ARROW_EXPORT ObjectWriter { - public: - ObjectWriter(); - ~ObjectWriter(); - - void SetString(std::string_view key, std::string_view value); - void SetBool(std::string_view key, bool value); - - std::string Serialize(); - - private: - class Impl; - std::unique_ptr impl_; -}; - -} // namespace internal -} // namespace json -} // namespace arrow diff --git a/cpp/src/arrow/meson.build b/cpp/src/arrow/meson.build index ef044f6c4227..955ef78973ed 100644 --- a/cpp/src/arrow/meson.build +++ b/cpp/src/arrow/meson.build @@ -516,7 +516,6 @@ if needs_json 'json/from_string.cc', 'json/json_writer_internal.cc', 'json/object_parser.cc', - 'json/object_writer.cc', 'json/options.cc', 'json/parser.cc', 'json/reader.cc', diff --git a/cpp/src/parquet/CMakeLists.txt b/cpp/src/parquet/CMakeLists.txt index f8a42b5b96bf..e5860d891964 100644 --- a/cpp/src/parquet/CMakeLists.txt +++ b/cpp/src/parquet/CMakeLists.txt @@ -263,9 +263,9 @@ endif() list(APPEND PARQUET_SHARED_LINK_LIBS arrow_shared) -# Add RapidJSON libraries -list(APPEND PARQUET_SHARED_PRIVATE_LINK_LIBS RapidJSON) -list(APPEND PARQUET_STATIC_LINK_LIBS RapidJSON) +# Add RapidJSON & simdjson libraries +list(APPEND PARQUET_SHARED_PRIVATE_LINK_LIBS RapidJSON simdjson::simdjson) +list(APPEND PARQUET_STATIC_LINK_LIBS RapidJSON simdjson::simdjson) # These are libraries that we will link privately with parquet_shared (as they # do not need to be linked transitively by other linkers) diff --git a/cpp/src/parquet/encryption/file_system_key_material_store.cc b/cpp/src/parquet/encryption/file_system_key_material_store.cc index fb8c92ceafee..e5b215a84609 100644 --- a/cpp/src/parquet/encryption/file_system_key_material_store.cc +++ b/cpp/src/parquet/encryption/file_system_key_material_store.cc @@ -20,8 +20,8 @@ #include "arrow/buffer.h" #include "arrow/filesystem/filesystem.h" #include "arrow/filesystem/path_util.h" +#include "arrow/json/json_writer_internal.h" #include "arrow/json/object_parser.h" -#include "arrow/json/object_writer.h" #include "arrow/result.h" #include "parquet/encryption/file_system_key_material_store.h" @@ -81,11 +81,13 @@ void FileSystemKeyMaterialStore::LoadKeyMaterialMap() { } std::string FileSystemKeyMaterialStore::BuildKeyMaterialMapJson() { - ::arrow::json::internal::ObjectWriter writer; + ::arrow::json::JsonWriter writer; + writer.StartObject(); for (const auto& it : key_material_map_) { - writer.SetString(it.first, it.second); + writer.StringField(it.first, it.second); } - return writer.Serialize(); + writer.EndObject(); + return std::string(writer.GetString()); } void FileSystemKeyMaterialStore::SaveMaterial() { diff --git a/cpp/src/parquet/encryption/key_material.cc b/cpp/src/parquet/encryption/key_material.cc index 1cebf5900f31..67f838c1df1b 100644 --- a/cpp/src/parquet/encryption/key_material.cc +++ b/cpp/src/parquet/encryption/key_material.cc @@ -15,15 +15,15 @@ // specific language governing permissions and limitations // under the License. +#include "arrow/json/json_writer_internal.h" #include "arrow/json/object_parser.h" -#include "arrow/json/object_writer.h" #include "parquet/encryption/key_material.h" #include "parquet/encryption/key_metadata.h" #include "parquet/exception.h" +using ::arrow::json::JsonWriter; using ::arrow::json::internal::ObjectParser; -using ::arrow::json::internal::ObjectWriter; namespace parquet::encryption { @@ -122,36 +122,48 @@ std::string KeyMaterial::SerializeToJson( bool is_double_wrapped, const std::string& kek_id, const std::string& encoded_wrapped_kek, const std::string& encoded_wrapped_dek, bool is_internal_storage) { - ObjectWriter json_writer; - json_writer.SetString(kKeyMaterialTypeField, kKeyMaterialType1); + JsonWriter json_writer; + + json_writer.StartObject(); + + json_writer.StringField(kKeyMaterialTypeField, kKeyMaterialType1); if (is_internal_storage) { // 1. for internal storage, key material and key metadata are the same. // adding the "internalStorage" field that belongs to KeyMetadata. - json_writer.SetBool(KeyMetadata::kKeyMaterialInternalStorageField, true); + json_writer.BoolField(KeyMetadata::kKeyMaterialInternalStorageField, true); } + // 2. Write isFooterKey - json_writer.SetBool(kIsFooterKeyField, is_footer_key); + json_writer.BoolField(kIsFooterKeyField, is_footer_key); + if (is_footer_key) { // 3. For footer key, write KMS Instance ID - json_writer.SetString(kKmsInstanceIdField, kms_instance_id); + json_writer.StringField(kKmsInstanceIdField, kms_instance_id); + // 4. For footer key, write KMS Instance URL - json_writer.SetString(kKmsInstanceUrlField, kms_instance_url); + json_writer.StringField(kKmsInstanceUrlField, kms_instance_url); } + // 5. Write master key ID - json_writer.SetString(kMasterKeyIdField, master_key_id); + json_writer.StringField(kMasterKeyIdField, master_key_id); + // 6. Write wrapped DEK - json_writer.SetString(kWrappedDataEncryptionKeyField, encoded_wrapped_dek); + json_writer.StringField(kWrappedDataEncryptionKeyField, encoded_wrapped_dek); + // 7. Write isDoubleWrapped - json_writer.SetBool(kDoubleWrappingField, is_double_wrapped); + json_writer.BoolField(kDoubleWrappingField, is_double_wrapped); + if (is_double_wrapped) { // 8. In double wrapping mode, write KEK ID - json_writer.SetString(kKeyEncryptionKeyIdField, kek_id); + json_writer.StringField(kKeyEncryptionKeyIdField, kek_id); + // 9. In double wrapping mode, write wrapped KEK - json_writer.SetString(kWrappedKeyEncryptionKeyField, encoded_wrapped_kek); + json_writer.StringField(kWrappedKeyEncryptionKeyField, encoded_wrapped_kek); } - return json_writer.Serialize(); + json_writer.EndObject(); + return std::string(json_writer.GetString()); } } // namespace parquet::encryption diff --git a/cpp/src/parquet/encryption/key_metadata.cc b/cpp/src/parquet/encryption/key_metadata.cc index e23a67b6b86e..ed6c62955cf2 100644 --- a/cpp/src/parquet/encryption/key_metadata.cc +++ b/cpp/src/parquet/encryption/key_metadata.cc @@ -15,14 +15,14 @@ // specific language governing permissions and limitations // under the License. +#include "arrow/json/json_writer_internal.h" #include "arrow/json/object_parser.h" -#include "arrow/json/object_writer.h" #include "parquet/encryption/key_metadata.h" #include "parquet/exception.h" +using ::arrow::json::JsonWriter; using ::arrow::json::internal::ObjectParser; -using ::arrow::json::internal::ObjectWriter; namespace parquet::encryption { @@ -73,15 +73,18 @@ KeyMetadata KeyMetadata::Parse(const std::string& key_metadata) { // directly std::string KeyMetadata::CreateSerializedForExternalMaterial( const std::string& key_reference) { - ObjectWriter json_writer; + JsonWriter json_writer; - json_writer.SetString(KeyMaterial::kKeyMaterialTypeField, - KeyMaterial::kKeyMaterialType1); - json_writer.SetBool(kKeyMaterialInternalStorageField, false); + json_writer.StartObject(); - json_writer.SetString(kKeyReferenceField, key_reference); + json_writer.StringField(KeyMaterial::kKeyMaterialTypeField, + KeyMaterial::kKeyMaterialType1); + json_writer.BoolField(kKeyMaterialInternalStorageField, false); + json_writer.StringField(kKeyReferenceField, key_reference); - return json_writer.Serialize(); + json_writer.EndObject(); + + return std::string(json_writer.GetString()); } } // namespace parquet::encryption diff --git a/cpp/src/parquet/encryption/local_wrap_kms_client.cc b/cpp/src/parquet/encryption/local_wrap_kms_client.cc index 80543c2932aa..b2a6872af5bd 100644 --- a/cpp/src/parquet/encryption/local_wrap_kms_client.cc +++ b/cpp/src/parquet/encryption/local_wrap_kms_client.cc @@ -15,16 +15,16 @@ // specific language governing permissions and limitations // under the License. +#include "arrow/json/json_writer_internal.h" #include "arrow/json/object_parser.h" -#include "arrow/json/object_writer.h" #include "arrow/util/secure_string.h" #include "parquet/encryption/key_toolkit_internal.h" #include "parquet/encryption/local_wrap_kms_client.h" #include "parquet/exception.h" +using ::arrow::json::JsonWriter; using ::arrow::json::internal::ObjectParser; -using ::arrow::json::internal::ObjectWriter; using ::arrow::util::SecureString; namespace parquet::encryption { @@ -41,12 +41,16 @@ LocalWrapKmsClient::LocalKeyWrap::LocalKeyWrap(std::string master_key_version, std::string LocalWrapKmsClient::LocalKeyWrap::CreateSerialized( const std::string& encrypted_encoded_key) { - ObjectWriter json_writer; + JsonWriter json_writer; - json_writer.SetString(kLocalWrapKeyVersionField, kLocalWrapNoKeyVersion); - json_writer.SetString(kLocalWrapEncryptedKeyField, encrypted_encoded_key); + json_writer.StartObject(); - return json_writer.Serialize(); + json_writer.StringField(kLocalWrapKeyVersionField, kLocalWrapNoKeyVersion); + json_writer.StringField(kLocalWrapEncryptedKeyField, encrypted_encoded_key); + + json_writer.EndObject(); + + return std::string(json_writer.GetString()); } LocalWrapKmsClient::LocalKeyWrap LocalWrapKmsClient::LocalKeyWrap::Parse(