From a54cd537f6b03cadc59d19df86ce7efad0551926 Mon Sep 17 00:00:00 2001 From: Sten Larsson Date: Thu, 4 Dec 2025 16:16:20 +0100 Subject: [PATCH] Add GArrowPadOptions --- c_glib/arrow-glib/compute.cpp | 170 ++++++++++++++++++++++++++++++++ c_glib/arrow-glib/compute.h | 13 +++ c_glib/arrow-glib/compute.hpp | 5 + c_glib/test/test-pad-options.rb | 62 ++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 c_glib/test/test-pad-options.rb diff --git a/c_glib/arrow-glib/compute.cpp b/c_glib/arrow-glib/compute.cpp index 7a216745fc6..8d16b9abee0 100644 --- a/c_glib/arrow-glib/compute.cpp +++ b/c_glib/arrow-glib/compute.cpp @@ -289,6 +289,10 @@ G_BEGIN_DECLS * * #GArrowNullOptions is a class to customize the `is_null` function. * + * #GArrowPadOptions is a class to customize the padding functions such as + * `utf8_lpad`, `utf8_rpad`, `utf8_center`, `ascii_lpad`, `ascii_rpad`, and + * `ascii_center`. + * * There are many functions to compute data on an array. */ @@ -8107,6 +8111,147 @@ garrow_null_options_new(void) return GARROW_NULL_OPTIONS(g_object_new(GARROW_TYPE_NULL_OPTIONS, NULL)); } +enum { + PROP_PAD_OPTIONS_WIDTH = 1, + PROP_PAD_OPTIONS_PADDING, + PROP_PAD_OPTIONS_LEAN_LEFT_ON_ODD_PADDING, +}; + +G_DEFINE_TYPE(GArrowPadOptions, garrow_pad_options, GARROW_TYPE_FUNCTION_OPTIONS) + +static void +garrow_pad_options_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto options = garrow_pad_options_get_raw(GARROW_PAD_OPTIONS(object)); + + switch (prop_id) { + case PROP_PAD_OPTIONS_WIDTH: + options->width = g_value_get_int64(value); + break; + case PROP_PAD_OPTIONS_PADDING: + options->padding = g_value_get_string(value); + break; + case PROP_PAD_OPTIONS_LEAN_LEFT_ON_ODD_PADDING: + options->lean_left_on_odd_padding = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_pad_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto options = garrow_pad_options_get_raw(GARROW_PAD_OPTIONS(object)); + + switch (prop_id) { + case PROP_PAD_OPTIONS_WIDTH: + g_value_set_int64(value, options->width); + break; + case PROP_PAD_OPTIONS_PADDING: + g_value_set_string(value, options->padding.c_str()); + break; + case PROP_PAD_OPTIONS_LEAN_LEFT_ON_ODD_PADDING: + g_value_set_boolean(value, options->lean_left_on_odd_padding); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_pad_options_init(GArrowPadOptions *object) +{ + auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object); + priv->options = + static_cast(new arrow::compute::PadOptions()); +} + +static void +garrow_pad_options_class_init(GArrowPadOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->set_property = garrow_pad_options_set_property; + gobject_class->get_property = garrow_pad_options_get_property; + + arrow::compute::PadOptions options; + + GParamSpec *spec; + /** + * GArrowPadOptions:width: + * + * The desired string length. + * + * Since: 23.0.0 + */ + spec = g_param_spec_int64("width", + "Width", + "The desired string length", + 0, + G_MAXINT64, + options.width, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_PAD_OPTIONS_WIDTH, spec); + + /** + * GArrowPadOptions:padding: + * + * What to pad the string with. Should be one codepoint (Unicode)/byte (ASCII). + * + * Since: 23.0.0 + */ + spec = g_param_spec_string( + "padding", + "Padding", + "What to pad the string with. Should be one codepoint (Unicode)/byte (ASCII)", + options.padding.c_str(), + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_PAD_OPTIONS_PADDING, spec); + + /** + * GArrowPadOptions:lean-left-on-odd-padding: + * + * What to do if there is an odd number of padding characters (in case of centered + * padding). Defaults to aligning on the left (i.e. adding the extra padding character + * on the right). + * + * Since: 23.0.0 + */ + spec = + g_param_spec_boolean("lean-left-on-odd-padding", + "Lean left on odd padding", + "What to do if there is an odd number of padding characters (in " + "case of centered padding). Defaults to aligning on the left " + "(i.e. adding the extra padding character on the right)", + options.lean_left_on_odd_padding, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_PAD_OPTIONS_LEAN_LEFT_ON_ODD_PADDING, + spec); +} + +/** + * garrow_pad_options_new: + * + * Returns: A newly created #GArrowPadOptions. + * + * Since: 23.0.0 + */ +GArrowPadOptions * +garrow_pad_options_new(void) +{ + return GARROW_PAD_OPTIONS(g_object_new(GARROW_TYPE_PAD_OPTIONS, NULL)); +} + G_END_DECLS arrow::Result @@ -8301,6 +8446,11 @@ garrow_function_options_new_raw(const arrow::compute::FunctionOptions *arrow_opt static_cast(arrow_options); auto options = garrow_null_options_new_raw(arrow_null_options); return GARROW_FUNCTION_OPTIONS(options); + } else if (arrow_type_name == "PadOptions") { + const auto arrow_pad_options = + static_cast(arrow_options); + auto options = garrow_pad_options_new_raw(arrow_pad_options); + return GARROW_FUNCTION_OPTIONS(options); } else { auto options = g_object_new(GARROW_TYPE_FUNCTION_OPTIONS, NULL); return GARROW_FUNCTION_OPTIONS(options); @@ -9091,3 +9241,23 @@ garrow_null_options_get_raw(GArrowNullOptions *options) return static_cast( garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); } + +GArrowPadOptions * +garrow_pad_options_new_raw(const arrow::compute::PadOptions *arrow_options) +{ + return GARROW_PAD_OPTIONS(g_object_new(GARROW_TYPE_PAD_OPTIONS, + "width", + arrow_options->width, + "padding", + arrow_options->padding.c_str(), + "lean-left-on-odd-padding", + arrow_options->lean_left_on_odd_padding, + NULL)); +} + +arrow::compute::PadOptions * +garrow_pad_options_get_raw(GArrowPadOptions *options) +{ + return static_cast( + garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); +} diff --git a/c_glib/arrow-glib/compute.h b/c_glib/arrow-glib/compute.h index 1cd4b55242e..14e7e4a7b91 100644 --- a/c_glib/arrow-glib/compute.h +++ b/c_glib/arrow-glib/compute.h @@ -1446,4 +1446,17 @@ GARROW_AVAILABLE_IN_23_0 GArrowNullOptions * garrow_null_options_new(void); +#define GARROW_TYPE_PAD_OPTIONS (garrow_pad_options_get_type()) +GARROW_AVAILABLE_IN_23_0 +G_DECLARE_DERIVABLE_TYPE( + GArrowPadOptions, garrow_pad_options, GARROW, PAD_OPTIONS, GArrowFunctionOptions) +struct _GArrowPadOptionsClass +{ + GArrowFunctionOptionsClass parent_class; +}; + +GARROW_AVAILABLE_IN_23_0 +GArrowPadOptions * +garrow_pad_options_new(void); + G_END_DECLS diff --git a/c_glib/arrow-glib/compute.hpp b/c_glib/arrow-glib/compute.hpp index 47172e38d89..6f9ae390377 100644 --- a/c_glib/arrow-glib/compute.hpp +++ b/c_glib/arrow-glib/compute.hpp @@ -246,3 +246,8 @@ GArrowNullOptions * garrow_null_options_new_raw(const arrow::compute::NullOptions *arrow_options); arrow::compute::NullOptions * garrow_null_options_get_raw(GArrowNullOptions *options); + +GArrowPadOptions * +garrow_pad_options_new_raw(const arrow::compute::PadOptions *arrow_options); +arrow::compute::PadOptions * +garrow_pad_options_get_raw(GArrowPadOptions *options); diff --git a/c_glib/test/test-pad-options.rb b/c_glib/test/test-pad-options.rb new file mode 100644 index 00000000000..56a718234e8 --- /dev/null +++ b/c_glib/test/test-pad-options.rb @@ -0,0 +1,62 @@ +# 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. + +class TestPadOptions < Test::Unit::TestCase + include Helper::Buildable + + def setup + @options = Arrow::PadOptions.new + end + + def test_width_property + assert_equal(0, @options.width) + @options.width = 5 + assert_equal(5, @options.width) + end + + def test_padding_property + assert_equal(" ", @options.padding) + @options.padding = "0" + assert_equal("0", @options.padding) + end + + def test_lean_left_on_odd_padding_property + assert do + @options.lean_left_on_odd_padding? + end + @options.lean_left_on_odd_padding = false + assert do + not @options.lean_left_on_odd_padding? + end + end + + def test_utf8_center_function + args = [ + Arrow::ArrayDatum.new(build_string_array(["a", "ab", "abc"])), + ] + utf8_center_function = Arrow::Function.find("utf8_center") + + @options.width = 5 + @options.padding = " " + result = utf8_center_function.execute(args, @options).value + assert_equal(build_string_array([" a ", " ab ", " abc "]), result) + + @options.lean_left_on_odd_padding = false + result = utf8_center_function.execute(args, @options).value + assert_equal(build_string_array([" a ", " ab ", " abc "]), result) + end +end