This is an automated email from the ASF dual-hosted git repository.

pitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 3deec0b119 GH-50690: [C++] Migrate ObjectWriter users to JsonWriter 
(#50691)
3deec0b119 is described below

commit 3deec0b119a3fc009e86e473242a6b647eea94e8
Author: Aaditya Srinivasan <[email protected]>
AuthorDate: Wed Jul 29 15:05:45 2026 +0530

    GH-50690: [C++] Migrate ObjectWriter users to JsonWriter (#50691)
    
    ### Rationale for this change
    
    This PR continues the simdjson migration by replacing the remaining 
`ObjectWriter` users with `JsonWriter`. With all usages migrated, the obsolete 
`ObjectWriter` implementation and its associated build configuration are 
removed.
    
    ### What changes are included in this PR?
    
    * Replace `ObjectWriter` with `JsonWriter` in:
    
      * `key_material.cc`
      * `key_metadata.cc`
      * `local_wrap_kms_client.cc`
      * `file_system_key_material_store.cc`
    * Remove the unused `ObjectWriter` implementation (`object_writer.cc` and 
`object_writer.h`).
    * Remove `object_writer.h` from the installed headers.
    * Update the Arrow build configuration to stop building `object_writer.cc`.
    * Link Parquet against `simdjson::simdjson` since it now includes 
`json_writer_internal.h`.
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    No.
    
    Closes: #50690
    * GitHub Issue: #50690
    
    Lead-authored-by: Aaditya Srinivasan <[email protected]>
    Co-authored-by: Antoine Pitrou <[email protected]>
    Signed-off-by: Antoine Pitrou <[email protected]>
---
 cpp/src/arrow/CMakeLists.txt                       |  1 -
 cpp/src/arrow/json/json_writer_internal.cc         | 10 +++
 cpp/src/arrow/json/json_writer_internal.h          |  3 +
 cpp/src/arrow/json/meson.build                     |  3 +-
 cpp/src/arrow/json/object_writer.cc                | 81 ----------------------
 cpp/src/arrow/json/object_writer.h                 | 49 -------------
 cpp/src/arrow/meson.build                          |  1 -
 cpp/src/parquet/CMakeLists.txt                     |  6 +-
 .../encryption/file_system_key_material_store.cc   | 10 +--
 cpp/src/parquet/encryption/key_material.cc         | 40 +++++++----
 cpp/src/parquet/encryption/key_metadata.cc         | 19 ++---
 .../parquet/encryption/local_wrap_kms_client.cc    | 16 +++--
 12 files changed, 70 insertions(+), 169 deletions(-)

diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt
index 64fb4d12a5..7211bf5476 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 11fe70a741..49038f26b0 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 e4d6e49885..4173cb4c51 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 a2aa69ecf7..edf92a46fd 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 3277807880..0000000000
--- 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 <rapidjson/document.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-
-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<rj::StringBuffer> 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 cf1ce62194..0000000000
--- 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 <memory>
-#include <string>
-#include <string_view>
-
-#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> impl_;
-};
-
-}  // namespace internal
-}  // namespace json
-}  // namespace arrow
diff --git a/cpp/src/arrow/meson.build b/cpp/src/arrow/meson.build
index ef044f6c42..955ef78973 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 f8a42b5b96..e5860d8919 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 fb8c92ceaf..e5b215a846 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 1cebf5900f..67f838c1df 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 e23a67b6b8..ed6c62955c 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 80543c2932..b2a6872af5 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(

Reply via email to