/*
 * 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-glib/array.hpp>
#include <arrow-glib/basic-data-type.hpp>
#include <arrow-glib/buffer.hpp>
#include <arrow-glib/decimal.hpp>
#include <arrow-glib/error.hpp>
#include <arrow-glib/interval.hpp>
#include <arrow-glib/type.hpp>

#include <arrow/c/bridge.h>

#include <cmath>
#include <sstream>

G_BEGIN_DECLS

/**
 * SECTION: basic-array
 * @section_id: basic-array-classes
 * @title: Basic array classes
 * @include: arrow-glib/arrow-glib.h
 *
 * #GArrowArrayStatistics is a class for statistics of an array.
 *
 * #GArrowArray is a base class for all array classes such as
 * #GArrowBooleanArray.
 *
 * All array classes are immutable. You need to use binary data or
 * array builder to create a new array except #GArrowNullArray. If you
 * have binary data that uses Arrow format data, you can create a new
 * array with the binary data as #GArrowBuffer object. If you don't
 * have binary data, you can use array builder class such as
 * #GArrowBooleanArrayBuilder that creates Arrow format data
 * internally and a new array from the data.
 *
 * #GArrowNullArray is a class for null array. It can store zero or
 * more null values. You need to specify an array length to create a
 * new array.
 *
 * #GArrowBooleanArray is a class for boolean array. It can store zero
 * or more boolean data. If you don't have Arrow format data, you need
 * to use #GArrowBooleanArrayBuilder to create a new array.
 *
 * #GArrowInt8Array is a class for 8-bit integer array. It can store
 * zero or more 8-bit integer data. If you don't have Arrow format
 * data, you need to use #GArrowInt8ArrayBuilder to create a new
 * array.
 *
 * #GArrowUInt8Array is a class for 8-bit unsigned integer array. It
 * can store zero or more 8-bit unsigned integer data. If you don't
 * have Arrow format data, you need to use #GArrowUInt8ArrayBuilder to
 * create a new array.
 *
 * #GArrowInt16Array is a class for 16-bit integer array. It can store
 * zero or more 16-bit integer data. If you don't have Arrow format
 * data, you need to use #GArrowInt16ArrayBuilder to create a new
 * array.
 *
 * #GArrowUInt16Array is a class for 16-bit unsigned integer array. It
 * can store zero or more 16-bit unsigned integer data. If you don't
 * have Arrow format data, you need to use #GArrowUInt16ArrayBuilder
 * to create a new array.
 *
 * #GArrowInt32Array is a class for 32-bit integer array. It can store
 * zero or more 32-bit integer data. If you don't have Arrow format
 * data, you need to use #GArrowInt32ArrayBuilder to create a new
 * array.
 *
 * #GArrowUInt32Array is a class for 32-bit unsigned integer array. It
 * can store zero or more 32-bit unsigned integer data. If you don't
 * have Arrow format data, you need to use #GArrowUInt32ArrayBuilder
 * to create a new array.
 *
 * #GArrowInt64Array is a class for 64-bit integer array. It can store
 * zero or more 64-bit integer data. If you don't have Arrow format
 * data, you need to use #GArrowInt64ArrayBuilder to create a new
 * array.
 *
 * #GArrowUInt64Array is a class for 64-bit unsigned integer array. It
 * can store zero or more 64-bit unsigned integer data. If you don't
 * have Arrow format data, you need to use #GArrowUInt64ArrayBuilder
 * to create a new array.
 *
 * #GArrowFloatArray is a class for 32-bit floating point array. It
 * can store zero or more 32-bit floating data. If you don't have
 * Arrow format data, you need to use #GArrowFloatArrayBuilder to
 * create a new array.
 *
 * #GArrowDoubleArray is a class for 64-bit floating point array. It
 * can store zero or more 64-bit floating data. If you don't have
 * Arrow format data, you need to use #GArrowDoubleArrayBuilder to
 * create a new array.
 *
 * #GArrowBinaryArray is a class for binary array. It can store zero
 * or more binary data. If you don't have Arrow format data, you need
 * to use #GArrowBinaryArrayBuilder to create a new array.
 *
 * #GArrowLargeBinaryArray is a class for 64-bit offsets binary array.
 * It can store zero or more binary data. If you don't have Arrow
 * format data, you need to use #GArrowLargeBinaryArrayBuilder to
 * create a new array.
 *
 * #GArrowStringArray is a class for UTF-8 encoded string array. It
 * can store zero or more UTF-8 encoded string data. If you don't have
 * Arrow format data, you need to use #GArrowStringArrayBuilder to
 * create a new array.
 *
 * #GArrowLargeStringArray is a class for 64-bit offsets UTF-8
 * encoded string array. It can store zero or more UTF-8 encoded
 * string data. If you don't have Arrow format data, you need to
 * use #GArrowLargeStringArrayBuilder to create a new array.
 *
 * #GArrayBinaryViewArray is a class for variable-size binary view array.
 * It can store zero or more binary view data. If you don't have Arrow
 * format data, you need to use #GArrowBinaryViewArrayBuilder to create
 * a new array.
 *
 * #GArrayStringViewArray is a class for variable-size string view array.
 * It can store zero or more string view data. If you don't have Arrow
 * format data, you need to use #GArrowStringViewArrayBuilder to create
 * a new array.
 *
 * #GArrowFixedSizeBinaryArray is a class for fixed size binary array.
 * It can store zero or more fixed size binary data. If you don't have
 * Arrow format data, you need to use
 * #GArrowFixedSizeBinaryArrayBuilder to create a new array.
 *
 * #GArrowDate32Array is a class for the number of days since UNIX
 * epoch in 32-bit signed integer array. It can store zero or more
 * date data. If you don't have Arrow format data, you need to use
 * #GArrowDate32ArrayBuilder to create a new array.
 *
 * #GArrowDate64Array is a class for the number of milliseconds since
 * UNIX epoch in 64-bit signed integer array. It can store zero or
 * more date data. If you don't have Arrow format data, you need to
 * use #GArrowDate64ArrayBuilder to create a new array.
 *
 * #GArrowTimestampArray is a class for the number of
 * seconds/milliseconds/microseconds/nanoseconds since UNIX epoch in
 * 64-bit signed integer array. It can store zero or more timestamp
 * data. If you don't have Arrow format data, you need to use
 * #GArrowTimestampArrayBuilder to create a new array.
 *
 * #GArrowTime32Array is a class for the number of seconds or
 * milliseconds since midnight in 32-bit signed integer array. It can
 * store zero or more time data. If you don't have Arrow format data,
 * you need to use #GArrowTime32ArrayBuilder to create a new array.
 *
 * #GArrowTime64Array is a class for the number of microseconds or
 * nanoseconds since midnight in 64-bit signed integer array. It can
 * store zero or more time data. If you don't have Arrow format data,
 * you need to use #GArrowTime64ArrayBuilder to create a new array.
 *
 * #GArrowMonthIntervalArray is a class for the month intarval array.
 * It can store zero or more date data. If you don't have Arrow format
 * data, you need to use #GArrowMonthIntervalArrayBuilder to create a
 * new array.
 *
 * #GArrowDayTimeIntervalArray is a class for the day time intarval array.
 * It can store zero or more date data. If you don't have Arrow format
 * data, you need to use #GArrowDayTimeIntervalArrayBuilder to create a
 * new array.
 *
 * #GArrowMonthDayNanoIntervalArray is a class for the month day nano
 * intarval array. It can store zero or more date data. If you don't
 * have Arrow format data, you need to use #GArrowMonthDayNanoIntervalArray
 * to create a new array.
 *
 * #GArrowDurationArray is a class for the elapsed time in 64-bit
 * signed integer array. It can store zero or more duration data. If
 * you don't have Arrow format data, you need to use
 * #GArrowDurationArrayBuilder to create a new array.
 *
 * #GArrowDecimal32Array is a class for 32-bit decimal array. It can
 * store zero or more 32-bit decimal data. If you don't have Arrow
 * format data, you need to use #GArrowDecimal32ArrayBuilder to
 * create a new array.
 *
 * #GArrowDecimal64Array is a class for 64-bit decimal array. It can
 * store zero or more 64-bit decimal data. If you don't have Arrow
 * format data, you need to use #GArrowDecimal64ArrayBuilder to
 * create a new array.
 *
 * #GArrowDecimal128Array is a class for 128-bit decimal array. It can
 * store zero or more 128-bit decimal data. If you don't have Arrow
 * format data, you need to use #GArrowDecimal128ArrayBuilder to
 * create a new array.
 *
 * #GArrowDecimal256Array is a class for 256-bit decimal array. It can
 * store zero or more 256-bit decimal data. If you don't have Arrow
 * format data, you need to use #GArrowDecimal256ArrayBuilder to
 * create a new array.
 *
 * #GArrowExtensionArray is a base class for array of user-defined
 * extension types.
 */

typedef struct GArrowEqualOptionsPrivate_
{
  gboolean approx;
  arrow::EqualOptions options;
} GArrowEqualOptionsPrivate;

enum {
  PROP_APPROX = 1,
  PROP_NANS_EQUAL,
  PROP_ABSOLUTE_TOLERANCE,
};

G_DEFINE_TYPE_WITH_PRIVATE(GArrowEqualOptions, garrow_equal_options, G_TYPE_OBJECT)

#define GARROW_EQUAL_OPTIONS_GET_PRIVATE(object)                                         \
  static_cast<GArrowEqualOptionsPrivate *>(                                              \
    garrow_equal_options_get_instance_private(GARROW_EQUAL_OPTIONS(object)))

static void
garrow_equal_options_finalize(GObject *object)
{
  auto priv = GARROW_EQUAL_OPTIONS_GET_PRIVATE(object);
  priv->options.~EqualOptions();
  G_OBJECT_CLASS(garrow_equal_options_parent_class)->finalize(object);
}

static void
garrow_equal_options_set_property(GObject *object,
                                  guint prop_id,
                                  const GValue *value,
                                  GParamSpec *pspec)
{
  auto priv = GARROW_EQUAL_OPTIONS_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_APPROX:
    priv->approx = g_value_get_boolean(value);
    break;
  case PROP_NANS_EQUAL:
    priv->options = priv->options.nans_equal(g_value_get_boolean(value));
    break;
  case PROP_ABSOLUTE_TOLERANCE:
    priv->options = priv->options.atol(g_value_get_double(value));
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_equal_options_get_property(GObject *object,
                                  guint prop_id,
                                  GValue *value,
                                  GParamSpec *pspec)
{
  auto priv = GARROW_EQUAL_OPTIONS_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_APPROX:
    g_value_set_boolean(value, priv->approx);
    break;
  case PROP_NANS_EQUAL:
    g_value_set_boolean(value, priv->options.nans_equal());
    break;
  case PROP_ABSOLUTE_TOLERANCE:
    g_value_set_double(value, priv->options.atol());
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_equal_options_init(GArrowEqualOptions *object)
{
  auto priv = GARROW_EQUAL_OPTIONS_GET_PRIVATE(object);
  priv->approx = FALSE;
  new (&priv->options) arrow::EqualOptions;
  priv->options = arrow::EqualOptions::Defaults();
}

static void
garrow_equal_options_class_init(GArrowEqualOptionsClass *klass)
{
  auto gobject_class = G_OBJECT_CLASS(klass);
  gobject_class->finalize = garrow_equal_options_finalize;
  gobject_class->set_property = garrow_equal_options_set_property;
  gobject_class->get_property = garrow_equal_options_get_property;

  auto options = arrow::EqualOptions::Defaults();
  GParamSpec *spec;
  /**
   * GArrowEqualOptions:approx:
   *
   * Whether or not approximate comparison is used.
   *
   * Since: 5.0.0
   */
  spec = g_param_spec_boolean("approx",
                              "Approx",
                              "Whether or not approximate comparison is used",
                              FALSE,
                              static_cast<GParamFlags>(G_PARAM_READWRITE));
  g_object_class_install_property(gobject_class, PROP_APPROX, spec);

  /**
   * GArrowEqualOptions:nans-equal:
   *
   * Whether or not NaNs are considered equal.
   *
   * Since: 5.0.0
   */
  spec = g_param_spec_boolean("nans-equal",
                              "NaNs equal",
                              "Whether or not NaNs are considered equal",
                              options.nans_equal(),
                              static_cast<GParamFlags>(G_PARAM_READWRITE));
  g_object_class_install_property(gobject_class, PROP_NANS_EQUAL, spec);

  /**
   * GArrowEqualOptions:absolute-tolerance:
   *
   * The absolute tolerance for approximate comparison of
   * floating-point values.
   *
   * Since: 5.0.0
   */
  spec = g_param_spec_double("absolute-tolerance",
                             "Absolute tolerance",
                             "The absolute tolerance for approximate comparison "
                             "of floating-point values",
                             -G_MAXDOUBLE,
                             G_MAXDOUBLE,
                             options.atol(),
                             static_cast<GParamFlags>(G_PARAM_READWRITE));
  g_object_class_install_property(gobject_class, PROP_ABSOLUTE_TOLERANCE, spec);
}

/**
 * garrow_equal_options_new:
 *
 * Returns: A newly created #GArrowEqualOptions.
 *
 * Since: 5.0.0
 */
GArrowEqualOptions *
garrow_equal_options_new(void)
{
  auto equal_options = g_object_new(GARROW_TYPE_EQUAL_OPTIONS, NULL);
  return GARROW_EQUAL_OPTIONS(equal_options);
}

/**
 * garrow_equal_options_is_approx:
 * @options: A #GArrowEqualOptions.
 *
 * Returns: %TRUE if approximate comparison is used, %FALSE otherwise.
 *
 * Since: 5.0.0
 */
gboolean
garrow_equal_options_is_approx(GArrowEqualOptions *options)
{
  auto priv = GARROW_EQUAL_OPTIONS_GET_PRIVATE(options);
  return priv->approx;
}

struct GArrowArrayStatisticsPrivate
{
  arrow::ArrayStatistics statistics;
};

enum {
  PROP_STATISTICS = 1,
};

G_DEFINE_TYPE_WITH_PRIVATE(GArrowArrayStatistics, garrow_array_statistics, G_TYPE_OBJECT)

#define GARROW_ARRAY_STATISTICS_GET_PRIVATE(object)                                      \
  static_cast<GArrowArrayStatisticsPrivate *>(                                           \
    garrow_array_statistics_get_instance_private(GARROW_ARRAY_STATISTICS(object)))

static void
garrow_array_statistics_finalize(GObject *object)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(object);
  priv->statistics.~ArrayStatistics();
  G_OBJECT_CLASS(garrow_array_statistics_parent_class)->finalize(object);
}

static void
garrow_array_statistics_set_property(GObject *object,
                                     guint prop_id,
                                     const GValue *value,
                                     GParamSpec *pspec)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_STATISTICS:
    priv->statistics = *static_cast<arrow::ArrayStatistics *>(g_value_get_pointer(value));
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_array_statistics_init(GArrowArrayStatistics *object)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(object);
  new (&priv->statistics) arrow::ArrayStatistics;
}

static void
garrow_array_statistics_class_init(GArrowArrayStatisticsClass *klass)
{
  auto gobject_class = G_OBJECT_CLASS(klass);
  gobject_class->finalize = garrow_array_statistics_finalize;
  gobject_class->set_property = garrow_array_statistics_set_property;

  auto spec = g_param_spec_pointer(
    "statistics",
    "Statistics",
    "The raw arrow::ArrayStatistics *",
    static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_STATISTICS, spec);
}

/**
 * garrow_array_statistics_has_null_count:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: %TRUE if @statistics has a valid null count value,
 *   %FALSE otherwise.
 *
 * Since: 20.0.0
 */
gboolean
garrow_array_statistics_has_null_count(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  return priv->statistics.null_count.has_value();
}

/**
 * garrow_array_statistics_is_null_count_exact:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: %TRUE if the null count is available and exact, %FALSE otherwise.
 *
 * Since: 23.0.0
 */
gboolean
garrow_array_statistics_is_null_count_exact(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  return priv->statistics.null_count.has_value() &&
         std::holds_alternative<int64_t>(*priv->statistics.null_count);
}

/**
 * garrow_array_statistics_get_null_count:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: 0 or larger value if @statistics has a valid null count value,
 *   -1 otherwise.
 *
 * Since: 20.0.0
 *
 * Deprecated: 23.0.0. Use garrow_array_statistics_is_null_count_exact(),
 *   garrow_array_statistics_get_null_count_exact() and
 *   garrow_array_statistics_get_null_count_approximate() instead.
 */
gint64
garrow_array_statistics_get_null_count(GArrowArrayStatistics *statistics)
{
  return garrow_array_statistics_get_null_count_exact(statistics);
}

/**
 * garrow_array_statistics_get_null_count_exact:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: 0 or larger value if @statistics has a valid exact null
 *   count value, -1 otherwise.
 *
 * Since: 23.0.0
 */
gint64
garrow_array_statistics_get_null_count_exact(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  const auto &null_count = priv->statistics.null_count;
  if (null_count && std::holds_alternative<int64_t>(*null_count)) {
    return std::get<int64_t>(*null_count);
  } else {
    return -1;
  }
}

/**
 * garrow_array_statistics_get_null_count_approximate:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: Non `NaN` value if @statistics has a valid approximate
 *   null count value, `NaN` otherwise.
 *
 * Since: 23.0.0
 */
gdouble
garrow_array_statistics_get_null_count_approximate(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  const auto &null_count = priv->statistics.null_count;
  if (null_count && std::holds_alternative<double>(*null_count)) {
    return std::get<double>(*null_count);
  } else {
    return std::nan("");
  }
}

/**
 * garrow_array_statistics_has_distinct_count:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: %TRUE if the distinct count is available, %FALSE otherwise.
 *
 * Since: 21.0.0
 */
gboolean
garrow_array_statistics_has_distinct_count(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  return priv->statistics.distinct_count.has_value();
}

/**
 * garrow_array_statistics_is_distinct_count_exact:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: %TRUE if the distinct count is available and exact, %FALSE otherwise.
 *
 * Since: 22.0.0
 */
gboolean
garrow_array_statistics_is_distinct_count_exact(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  return priv->statistics.distinct_count.has_value() &&
         std::holds_alternative<int64_t>(priv->statistics.distinct_count.value());
}

/**
 * garrow_array_statistics_get_distinct_count:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: 0 or larger value if @statistics has a valid distinct count value,
 *   -1 otherwise.
 *
 * Since: 21.0.0
 *
 * Deprecated: 22.0.0. Use garrow_array_statistics_is_distinct_count_exact(),
 *   garrow_array_statistics_get_distinct_count_exact() and
 *   garrow_array_statistics_get_distinct_count_approximate() instead.
 */
gint64
garrow_array_statistics_get_distinct_count(GArrowArrayStatistics *statistics)
{
  return garrow_array_statistics_get_distinct_count_exact(statistics);
}

/**
 * garrow_array_statistics_get_distinct_count_exact:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: 0 or larger value if @statistics has a valid exact distinct count
 *   value, -1 otherwise.
 *
 * Since: 22.0.0
 */
gint64
garrow_array_statistics_get_distinct_count_exact(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  const auto &distinct_count = priv->statistics.distinct_count;
  if (distinct_count && std::holds_alternative<int64_t>(distinct_count.value())) {
    return std::get<int64_t>(distinct_count.value());
  } else {
    return -1;
  }
}

/**
 * garrow_array_statistics_get_distinct_count_approximate:
 * @statistics: A #GArrowArrayStatistics.
 *
 * Returns: Non `NaN` value if @statistics has a valid approximate distinct count
 *   value, `NaN` otherwise.
 *
 * Since: 22.0.0
 */
gdouble
garrow_array_statistics_get_distinct_count_approximate(GArrowArrayStatistics *statistics)
{
  auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
  const auto &distinct_count = priv->statistics.distinct_count;
  if (distinct_count && std::holds_alternative<double>(distinct_count.value())) {
    return std::get<double>(distinct_count.value());
  } else {
    return std::nan("");
  }
}

typedef struct GArrowArrayPrivate_
{
  std::shared_ptr<arrow::Array> array;
  GArrowDataType *value_data_type;
  GArrowBuffer *null_bitmap;
  // Data for primitive array, value offsets for list array, type
  // codes for union array and so on.
  GArrowBuffer *buffer1;
  // Data for binary array, value offsets for dense union array and so
  // on.
  GArrowBuffer *buffer2;
  GArrowArray *parent;
} GArrowArrayPrivate;

enum {
  PROP_ARRAY = 1,
  PROP_VALUE_DATA_TYPE,
  PROP_NULL_BITMAP,
  PROP_BUFFER1,
  PROP_BUFFER2,
  PROP_PARENT,
};

G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GArrowArray, garrow_array, G_TYPE_OBJECT)

#define GARROW_ARRAY_GET_PRIVATE(obj)                                                    \
  static_cast<GArrowArrayPrivate *>(garrow_array_get_instance_private(GARROW_ARRAY(obj)))

G_END_DECLS
template <typename T>
const typename T::c_type *
garrow_array_get_values_raw(std::shared_ptr<arrow::Array> arrow_array, gint64 *length)
{
  auto arrow_specific_array =
    std::static_pointer_cast<typename arrow::TypeTraits<T>::ArrayType>(arrow_array);
  *length = arrow_specific_array->length();
  return arrow_specific_array->raw_values();
};
G_BEGIN_DECLS

static void
garrow_array_dispose(GObject *object)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(object);

  if (priv->value_data_type) {
    g_object_unref(priv->value_data_type);
    priv->value_data_type = NULL;
  }

  if (priv->null_bitmap) {
    g_object_unref(priv->null_bitmap);
    priv->null_bitmap = NULL;
  }

  if (priv->buffer1) {
    g_object_unref(priv->buffer1);
    priv->buffer1 = NULL;
  }

  if (priv->buffer2) {
    g_object_unref(priv->buffer2);
    priv->buffer2 = NULL;
  }

  if (priv->parent) {
    g_object_unref(priv->parent);
    priv->parent = NULL;
  }

  G_OBJECT_CLASS(garrow_array_parent_class)->dispose(object);
}

static void
garrow_array_finalize(GObject *object)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(object);

  priv->array.~shared_ptr();

  G_OBJECT_CLASS(garrow_array_parent_class)->finalize(object);
}

static void
garrow_array_set_property(GObject *object,
                          guint prop_id,
                          const GValue *value,
                          GParamSpec *pspec)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_ARRAY:
    priv->array =
      *static_cast<std::shared_ptr<arrow::Array> *>(g_value_get_pointer(value));
    break;
  case PROP_VALUE_DATA_TYPE:
    priv->value_data_type = GARROW_DATA_TYPE(g_value_dup_object(value));
    break;
  case PROP_NULL_BITMAP:
    priv->null_bitmap = GARROW_BUFFER(g_value_dup_object(value));
    break;
  case PROP_BUFFER1:
    priv->buffer1 = GARROW_BUFFER(g_value_dup_object(value));
    break;
  case PROP_BUFFER2:
    priv->buffer2 = GARROW_BUFFER(g_value_dup_object(value));
    break;
  case PROP_PARENT:
    priv->parent = GARROW_ARRAY(g_value_dup_object(value));
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_array_get_property(GObject *object,
                          guint prop_id,
                          GValue *value,
                          GParamSpec *pspec)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_VALUE_DATA_TYPE:
    g_value_set_object(value, priv->value_data_type);
    break;
  case PROP_NULL_BITMAP:
    g_value_set_object(value, priv->null_bitmap);
    break;
  case PROP_BUFFER1:
    g_value_set_object(value, priv->buffer1);
    break;
  case PROP_BUFFER2:
    g_value_set_object(value, priv->buffer2);
    break;
  case PROP_PARENT:
    g_value_set_object(value, priv->parent);
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_array_init(GArrowArray *object)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(object);
  new (&priv->array) std::shared_ptr<arrow::Array>;
}

static void
garrow_array_class_init(GArrowArrayClass *klass)
{
  auto gobject_class = G_OBJECT_CLASS(klass);

  gobject_class->dispose = garrow_array_dispose;
  gobject_class->finalize = garrow_array_finalize;
  gobject_class->set_property = garrow_array_set_property;
  gobject_class->get_property = garrow_array_get_property;

  GParamSpec *spec;
  spec = g_param_spec_pointer(
    "array",
    "Array",
    "The raw std::shared<arrow::Array> *",
    static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_ARRAY, spec);

  spec = g_param_spec_object(
    "value-data-type",
    "Value data type",
    "The data type of each value",
    GARROW_TYPE_DATA_TYPE,
    static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_VALUE_DATA_TYPE, spec);

  spec = g_param_spec_object(
    "null-bitmap",
    "NULL bitmap",
    "The NULL bitmap",
    GARROW_TYPE_BUFFER,
    static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_NULL_BITMAP, spec);

  spec = g_param_spec_object(
    "buffer1",
    "Buffer1",
    "The first buffer",
    GARROW_TYPE_BUFFER,
    static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_BUFFER1, spec);

  spec = g_param_spec_object(
    "buffer2",
    "Buffer2",
    "The second buffer",
    GARROW_TYPE_BUFFER,
    static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_BUFFER2, spec);

  spec = g_param_spec_object(
    "parent",
    "Parent",
    "The parent array",
    GARROW_TYPE_ARRAY,
    static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_PARENT, spec);
}

/**
 * garrow_array_import:
 * @c_abi_array: (not nullable): A `struct ArrowArray *`.
 * @data_type: A #GArrowDataType of the C ABI array.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: (transfer full) (nullable): An imported #GArrowArray
 *   on success, %NULL on error.
 *
 *   You don't need to release the passed `struct ArrowArray *`,
 *   even if this function reports an error.
 *
 * Since: 6.0.0
 */
GArrowArray *
garrow_array_import(gpointer c_abi_array, GArrowDataType *data_type, GError **error)
{
  auto arrow_data_type = garrow_data_type_get_raw(data_type);
  auto arrow_array_result =
    arrow::ImportArray(static_cast<ArrowArray *>(c_abi_array), arrow_data_type);
  if (garrow::check(error, arrow_array_result, "[array][import]")) {
    return garrow_array_new_raw(&(*arrow_array_result));
  } else {
    return NULL;
  }
}

/**
 * garrow_array_export:
 * @array: A #GArrowArray.
 * @c_abi_array: (out): Return location for a `struct ArrowArray *`.
 *   It should be freed with the `ArrowArray::release` callback then
 *   g_free() when no longer needed.
 * @c_abi_schema: (out) (nullable): Return location for a
 *   `struct ArrowSchema *` or %NULL.
 *   It should be freed with the `ArrowSchema::release` callback then
 *   g_free() when no longer needed.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: %TRUE on success, %FALSE on error.
 *
 * Since: 6.0.0
 */
gboolean
garrow_array_export(GArrowArray *array,
                    gpointer *c_abi_array,
                    gpointer *c_abi_schema,
                    GError **error)
{
  const auto arrow_array = garrow_array_get_raw(array);
  *c_abi_array = g_new(ArrowArray, 1);
  arrow::Status status;
  if (c_abi_schema) {
    *c_abi_schema = g_new(ArrowSchema, 1);
    status = arrow::ExportArray(*arrow_array,
                                static_cast<ArrowArray *>(*c_abi_array),
                                static_cast<ArrowSchema *>(*c_abi_schema));
  } else {
    status = arrow::ExportArray(*arrow_array, static_cast<ArrowArray *>(*c_abi_array));
  }
  if (garrow::check(error, status, "[array][export]")) {
    return true;
  } else {
    g_free(*c_abi_array);
    *c_abi_array = nullptr;
    if (c_abi_schema) {
      g_free(*c_abi_schema);
      *c_abi_schema = nullptr;
    }
    return false;
  }
}

/**
 * garrow_array_equal:
 * @array: A #GArrowArray.
 * @other_array: A #GArrowArray to be compared.
 *
 * Returns: %TRUE if both of them have the same data, %FALSE
 *   otherwise.
 *
 * Since: 0.4.0
 */
gboolean
garrow_array_equal(GArrowArray *array, GArrowArray *other_array)
{
  return garrow_array_equal_options(array, other_array, NULL);
}

/**
 * garrow_array_equal_options:
 * @array: A #GArrowArray.
 * @other_array: A #GArrowArray to be compared.
 * @options: (nullable): A #GArrowEqualOptions to custom how to compare.
 *
 * Returns: %TRUE if both of them have the same data, %FALSE
 *   otherwise.
 *
 * Since: 5.0.0
 */
gboolean
garrow_array_equal_options(GArrowArray *array,
                           GArrowArray *other_array,
                           GArrowEqualOptions *options)
{
  const auto arrow_array = garrow_array_get_raw(array);
  const auto arrow_other_array = garrow_array_get_raw(other_array);
  if (options) {
    auto is_approx = garrow_equal_options_is_approx(options);
    const auto arrow_options = garrow_equal_options_get_raw(options);
    if (is_approx) {
      return arrow_array->ApproxEquals(arrow_other_array, *arrow_options);
    } else {
      return arrow_array->Equals(arrow_other_array, *arrow_options);
    }
  } else {
    return arrow_array->Equals(arrow_other_array);
  }
}

/**
 * garrow_array_equal_approx:
 * @array: A #GArrowArray.
 * @other_array: A #GArrowArray to be compared.
 *
 * Returns: %TRUE if both of them have the approx same data, %FALSE
 *   otherwise.
 *
 * Since: 0.4.0
 */
gboolean
garrow_array_equal_approx(GArrowArray *array, GArrowArray *other_array)
{
  const auto arrow_array = garrow_array_get_raw(array);
  const auto arrow_other_array = garrow_array_get_raw(other_array);
  return arrow_array->ApproxEquals(arrow_other_array);
}

/**
 * garrow_array_equal_range:
 * @array: A #GArrowArray.
 * @start_index: The start index of @array to be used.
 * @other_array: A #GArrowArray to be compared.
 * @other_start_index: The start index of @other_array to be used.
 * @end_index: The end index of @array to be used. The end index of
 *   @other_array is "@other_start_index + (@end_index -
 *   @start_index)".
 * @options: (nullable): A #GArrowEqualOptions to custom how to compare.
 *
 * Returns: %TRUE if both of them have the same data in the range,
 *   %FALSE otherwise.
 *
 * Since: 0.4.0
 */
gboolean
garrow_array_equal_range(GArrowArray *array,
                         gint64 start_index,
                         GArrowArray *other_array,
                         gint64 other_start_index,
                         gint64 end_index,
                         GArrowEqualOptions *options)
{
  const auto arrow_array = garrow_array_get_raw(array);
  const auto arrow_other_array = garrow_array_get_raw(other_array);
  if (options) {
    const auto arrow_options = garrow_equal_options_get_raw(options);
    return arrow_array->RangeEquals(arrow_other_array,
                                    start_index,
                                    end_index,
                                    other_start_index,
                                    *arrow_options);
  } else {
    return arrow_array->RangeEquals(arrow_other_array,
                                    start_index,
                                    end_index,
                                    other_start_index);
  }
}

/**
 * garrow_array_is_null:
 * @array: A #GArrowArray.
 * @i: The index of the target value.
 *
 * Returns: Whether the @i-th value is null or not.
 *
 * Since: 0.3.0
 */
gboolean
garrow_array_is_null(GArrowArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(array);
  return arrow_array->IsNull(i);
}

/**
 * garrow_array_is_valid:
 * @array: A #GArrowArray.
 * @i: The index of the target value.
 *
 * Returns: Whether the @i-th value is valid (not null) or not.
 *
 * Since: 0.8.0
 */
gboolean
garrow_array_is_valid(GArrowArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(array);
  return arrow_array->IsValid(i);
}

/**
 * garrow_array_get_length:
 * @array: A #GArrowArray.
 *
 * Returns: The number of rows in the array.
 */
gint64
garrow_array_get_length(GArrowArray *array)
{
  auto arrow_array = garrow_array_get_raw(array);
  return arrow_array->length();
}

/**
 * garrow_array_get_offset:
 * @array: A #GArrowArray.
 *
 * Returns: The number of values in the array.
 */
gint64
garrow_array_get_offset(GArrowArray *array)
{
  auto arrow_array = garrow_array_get_raw(array);
  return arrow_array->offset();
}

/**
 * garrow_array_get_n_nulls:
 * @array: A #GArrowArray.
 *
 * Returns: The number of NULLs in the array.
 */
gint64
garrow_array_get_n_nulls(GArrowArray *array)
{
  auto arrow_array = garrow_array_get_raw(array);
  return arrow_array->null_count();
}

/**
 * garrow_array_get_null_bitmap:
 * @array: A #GArrowArray.
 *
 * Returns: (transfer full) (nullable): The bitmap that indicates null
 *   value indices for the array as #GArrowBuffer or %NULL when
 *   garrow_array_get_n_nulls() returns 0.
 *
 * Since: 0.3.0
 */
GArrowBuffer *
garrow_array_get_null_bitmap(GArrowArray *array)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
  if (priv->null_bitmap) {
    g_object_ref(priv->null_bitmap);
    return priv->null_bitmap;
  }

  auto arrow_array = garrow_array_get_raw(array);
  auto arrow_null_bitmap = arrow_array->null_bitmap();
  if (arrow_null_bitmap) {
    return garrow_buffer_new_raw(&arrow_null_bitmap);
  } else {
    return nullptr;
  }
}

/**
 * garrow_array_get_value_data_type:
 * @array: A #GArrowArray.
 *
 * Returns: (transfer full): The #GArrowDataType for each value of the
 *   array.
 *
 * Since: 0.3.0
 */
GArrowDataType *
garrow_array_get_value_data_type(GArrowArray *array)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
  if (priv->value_data_type) {
    g_object_ref(priv->value_data_type);
    return priv->value_data_type;
  }

  auto arrow_array = garrow_array_get_raw(array);
  auto arrow_data_type = arrow_array->type();
  return garrow_data_type_new_raw(&arrow_data_type);
}

/**
 * garrow_array_get_value_type:
 * @array: A #GArrowArray.
 *
 * Returns: The #GArrowType for each value of the array.
 *
 * Since: 0.3.0
 */
GArrowType
garrow_array_get_value_type(GArrowArray *array)
{
  auto arrow_array = garrow_array_get_raw(array);
  return garrow_type_from_raw(arrow_array->type_id());
}

/**
 * garrow_array_slice:
 * @array: A #GArrowArray.
 * @offset: The offset of sub #GArrowArray.
 * @length: The length of sub #GArrowArray.
 *
 * Returns: (transfer full): The sub #GArrowArray. It covers only from
 *   `offset` to `offset + length` range. The sub #GArrowArray shares
 *   values with the base #GArrowArray.
 */
GArrowArray *
garrow_array_slice(GArrowArray *array, gint64 offset, gint64 length)
{
  const auto arrow_array = garrow_array_get_raw(array);
  auto arrow_sub_array = arrow_array->Slice(offset, length);
  return garrow_array_new_raw(&arrow_sub_array,
                              "array",
                              &arrow_sub_array,
                              "parent",
                              array,
                              NULL);
}

/**
 * garrow_array_to_string:
 * @array: A #GArrowArray.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: (nullable):
 *   The formatted array content or %NULL on error.
 *
 *   It should be freed with g_free() when no longer needed.
 *
 * Since: 0.4.0
 */
gchar *
garrow_array_to_string(GArrowArray *array, GError **error)
{
  const auto arrow_array = garrow_array_get_raw(array);
  const auto string = arrow_array->ToString();
  return g_strdup(string.c_str());
}

/**
 * garrow_array_view:
 * @array: A #GArrowArray.
 * @return_type: A #GArrowDataType of the returned view.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: (nullable) (transfer full): A zero-copy view of this array
 *   with the given type. This method checks if the `return_type` are
 *   layout-compatible.
 *
 * Since: 0.15.0
 */
GArrowArray *
garrow_array_view(GArrowArray *array, GArrowDataType *return_type, GError **error)
{
  auto arrow_array_raw = garrow_array_get_raw(array);
  auto arrow_return_type = garrow_data_type_get_raw(return_type);
  auto arrow_array = arrow_array_raw->View(arrow_return_type);
  if (garrow::check(error, arrow_array, "[array][view]")) {
    return garrow_array_new_raw(&(*arrow_array));
  } else {
    return NULL;
  }
}

/**
 * garrow_array_diff_unified:
 * @array: A #GArrowArray.
 * @other_array: A #GArrowArray to be compared.
 *
 * Returns: (nullable) (transfer full): The string representation of
 *   the difference between two arrays as unified format. If there is
 *   no difference, the return value is %NULL.
 *
 *   It should be freed with g_free() when no longer needed.
 *
 * Since: 0.15.0
 */
gchar *
garrow_array_diff_unified(GArrowArray *array, GArrowArray *other_array)
{
  const auto arrow_array = garrow_array_get_raw(array);
  const auto arrow_other_array = garrow_array_get_raw(other_array);
  std::stringstream diff;
  arrow_array->Equals(arrow_other_array, arrow::EqualOptions().diff_sink(&diff));
  auto string = diff.str();
  if (string.empty()) {
    return NULL;
  } else {
    return g_strndup(string.data(), string.size());
  }
}

/**
 * garrow_array_concatenate:
 * @array: A #GArrowArray.
 * @other_arrays: (element-type GArrowArray): A #GArrowArray to be
 *   concatenated.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: (nullable) (transfer full): The concatenated array.
 *
 * Since: 4.0.0
 */
GArrowArray *
garrow_array_concatenate(GArrowArray *array, GList *other_arrays, GError **error)
{
  if (!other_arrays) {
    g_object_ref(array);
    return array;
  }
  arrow::ArrayVector arrow_arrays;
  arrow_arrays.push_back(garrow_array_get_raw(array));
  for (auto node = other_arrays; node; node = node->next) {
    auto other_array = GARROW_ARRAY(node->data);
    arrow_arrays.push_back(garrow_array_get_raw(other_array));
  }
  auto arrow_concatenated_array = arrow::Concatenate(arrow_arrays);
  if (garrow::check(error, arrow_concatenated_array, "[array][concatenate]")) {
    return garrow_array_new_raw(&(*arrow_concatenated_array));
  } else {
    return NULL;
  }
}

/**
 * garrow_array_validate:
 * @array: A #GArrowArray.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: %TRUE on success, %FALSE on error.
 *
 * Since: 20.0.0
 */
gboolean
garrow_array_validate(GArrowArray *array, GError **error)
{
  const auto arrow_array = garrow_array_get_raw(array);
  return garrow::check(error, arrow_array->Validate(), "[array][validate]");
}

/**
 * garrow_array_validate_full:
 * @array: A #GArrowArray.
 * @error: (nullable): Return location for a #GError or %NULL.
 *
 * Returns: %TRUE on success, %FALSE on error.
 *
 * Since: 20.0.0
 */
gboolean
garrow_array_validate_full(GArrowArray *array, GError **error)
{
  const auto arrow_array = garrow_array_get_raw(array);
  return garrow::check(error, arrow_array->ValidateFull(), "[array][validate-full]");
}

/**
 * garrow_array_get_statistics:
 * @array: A #GArrowArray.
 *
 * Returns: (transfer full): The associated #GArrowArrayStatistics of @array,
 *   %NULL if @array doesn't have any associated statistics.
 *
 * Since: 20.0.0
 */
GArrowArrayStatistics *
garrow_array_get_statistics(GArrowArray *array)
{
  const auto arrow_array = garrow_array_get_raw(array);
  const auto &statistics = arrow_array->statistics();
  if (statistics) {
    return garrow_array_statistics_new_raw(statistics.get());
  } else {
    return nullptr;
  }
}

G_DEFINE_TYPE(GArrowNullArray, garrow_null_array, GARROW_TYPE_ARRAY)

static void
garrow_null_array_init(GArrowNullArray *object)
{
}

static void
garrow_null_array_class_init(GArrowNullArrayClass *klass)
{
}

/**
 * garrow_null_array_new:
 * @length: An array length.
 *
 * Returns: A newly created #GArrowNullArray.
 */
GArrowNullArray *
garrow_null_array_new(gint64 length)
{
  auto arrow_null_array = std::make_shared<arrow::NullArray>(length);
  std::shared_ptr<arrow::Array> arrow_array = arrow_null_array;
  auto array = garrow_array_new_raw(&arrow_array);
  return GARROW_NULL_ARRAY(array);
}

G_DEFINE_TYPE(GArrowPrimitiveArray, garrow_primitive_array, GARROW_TYPE_ARRAY)

G_END_DECLS
template <typename T>
GArrowArray *
garrow_primitive_array_new(gint64 length,
                           GArrowBuffer *data,
                           GArrowBuffer *null_bitmap,
                           gint64 n_nulls)
{
  const auto arrow_data = garrow_buffer_get_raw(data);
  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
  auto arrow_specific_array =
    std::make_shared<typename arrow::TypeTraits<T>::ArrayType>(length,
                                                               arrow_data,
                                                               arrow_bitmap,
                                                               n_nulls);
  auto arrow_array = std::static_pointer_cast<arrow::Array>(arrow_specific_array);
  return garrow_array_new_raw(&arrow_array,
                              "array",
                              &arrow_array,
                              "null-bitmap",
                              null_bitmap,
                              "buffer1",
                              data,
                              NULL);
};

template <typename T>
GArrowArray *
garrow_primitive_array_new(GArrowDataType *data_type,
                           gint64 length,
                           GArrowBuffer *data,
                           GArrowBuffer *null_bitmap,
                           gint64 n_nulls)
{
  auto arrow_data_type = garrow_data_type_get_raw(data_type);
  const auto arrow_data = garrow_buffer_get_raw(data);
  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
  auto arrow_specific_array =
    std::make_shared<typename arrow::TypeTraits<T>::ArrayType>(arrow_data_type,
                                                               length,
                                                               arrow_data,
                                                               arrow_bitmap,
                                                               n_nulls);
  auto arrow_array = std::static_pointer_cast<arrow::Array>(arrow_specific_array);
  return garrow_array_new_raw(&arrow_array,
                              "array",
                              &arrow_array,
                              "null-bitmap",
                              null_bitmap,
                              "buffer1",
                              data,
                              NULL);
};
G_BEGIN_DECLS

static void
garrow_primitive_array_init(GArrowPrimitiveArray *object)
{
}

static void
garrow_primitive_array_class_init(GArrowPrimitiveArrayClass *klass)
{
}

/**
 * garrow_primitive_array_get_buffer:
 * @array: A #GArrowPrimitiveArray.
 *
 * Returns: (transfer full): The data of the array as #GArrowBuffer.
 *
 * Deprecated: 1.0.0: Use garrow_primitive_array_get_data_buffer() instead.
 */
GArrowBuffer *
garrow_primitive_array_get_buffer(GArrowPrimitiveArray *array)
{
  return garrow_primitive_array_get_data_buffer(array);
}

/**
 * garrow_primitive_array_get_data_buffer:
 * @array: A #GArrowPrimitiveArray.
 *
 * Returns: (transfer full): The data of the array as #GArrowBuffer.
 *
 * Since: 1.0.0
 */
GArrowBuffer *
garrow_primitive_array_get_data_buffer(GArrowPrimitiveArray *array)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
  if (priv->buffer1) {
    g_object_ref(priv->buffer1);
    return priv->buffer1;
  }

  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_primitive_array =
    std::static_pointer_cast<arrow::PrimitiveArray>(arrow_array);
  auto arrow_data = arrow_primitive_array->values();
  return garrow_buffer_new_raw(&arrow_data);
}

G_DEFINE_TYPE(GArrowBooleanArray, garrow_boolean_array, GARROW_TYPE_PRIMITIVE_ARRAY)

static void
garrow_boolean_array_init(GArrowBooleanArray *object)
{
}

static void
garrow_boolean_array_class_init(GArrowBooleanArrayClass *klass)
{
}

/**
 * garrow_boolean_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowBooleanArray.
 *
 * Since: 0.4.0
 */
GArrowBooleanArray *
garrow_boolean_array_new(gint64 length,
                         GArrowBuffer *data,
                         GArrowBuffer *null_bitmap,
                         gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::BooleanType>(length, data, null_bitmap, n_nulls);
  return GARROW_BOOLEAN_ARRAY(array);
}

/**
 * garrow_boolean_array_get_value:
 * @array: A #GArrowBooleanArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gboolean
garrow_boolean_array_get_value(GArrowBooleanArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::BooleanArray *>(arrow_array.get())->Value(i);
}

/**
 * garrow_boolean_array_get_values:
 * @array: A #GArrowBooleanArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length) (transfer full):
 *   The raw boolean values.
 *
 *   It should be freed with g_free() when no longer needed.
 */
gboolean *
garrow_boolean_array_get_values(GArrowBooleanArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_boolean_array = std::static_pointer_cast<arrow::BooleanArray>(arrow_array);
  *length = arrow_boolean_array->length();
  auto values = static_cast<gboolean *>(g_new(gboolean, *length));
  for (gint64 i = 0; i < *length; ++i) {
    values[i] = arrow_boolean_array->Value(i);
  }
  return values;
}

G_DEFINE_TYPE(GArrowNumericArray, garrow_numeric_array, GARROW_TYPE_PRIMITIVE_ARRAY)

static void
garrow_numeric_array_init(GArrowNumericArray *object)
{
}

static void
garrow_numeric_array_class_init(GArrowNumericArrayClass *klass)
{
}

G_DEFINE_TYPE(GArrowInt8Array, garrow_int8_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_int8_array_init(GArrowInt8Array *object)
{
}

static void
garrow_int8_array_class_init(GArrowInt8ArrayClass *klass)
{
}

/**
 * garrow_int8_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowInt8Array.
 *
 * Since: 0.4.0
 */
GArrowInt8Array *
garrow_int8_array_new(gint64 length,
                      GArrowBuffer *data,
                      GArrowBuffer *null_bitmap,
                      gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::Int8Type>(length, data, null_bitmap, n_nulls);
  return GARROW_INT8_ARRAY(array);
}

/**
 * garrow_int8_array_get_value:
 * @array: A #GArrowInt8Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gint8
garrow_int8_array_get_value(GArrowInt8Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Int8Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_int8_array_get_values:
 * @array: A #GArrowInt8Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const gint8 *
garrow_int8_array_get_values(GArrowInt8Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::Int8Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowUInt8Array, garrow_uint8_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_uint8_array_init(GArrowUInt8Array *object)
{
}

static void
garrow_uint8_array_class_init(GArrowUInt8ArrayClass *klass)
{
}

/**
 * garrow_uint8_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowUInt8Array.
 *
 * Since: 0.4.0
 */
GArrowUInt8Array *
garrow_uint8_array_new(gint64 length,
                       GArrowBuffer *data,
                       GArrowBuffer *null_bitmap,
                       gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::UInt8Type>(length, data, null_bitmap, n_nulls);
  return GARROW_UINT8_ARRAY(array);
}

/**
 * garrow_uint8_array_get_value:
 * @array: A #GArrowUInt8Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
guint8
garrow_uint8_array_get_value(GArrowUInt8Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::UInt8Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_uint8_array_get_values:
 * @array: A #GArrowUInt8Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const guint8 *
garrow_uint8_array_get_values(GArrowUInt8Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::UInt8Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowInt16Array, garrow_int16_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_int16_array_init(GArrowInt16Array *object)
{
}

static void
garrow_int16_array_class_init(GArrowInt16ArrayClass *klass)
{
}

/**
 * garrow_int16_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowInt16Array.
 *
 * Since: 0.4.0
 */
GArrowInt16Array *
garrow_int16_array_new(gint64 length,
                       GArrowBuffer *data,
                       GArrowBuffer *null_bitmap,
                       gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::Int16Type>(length, data, null_bitmap, n_nulls);
  return GARROW_INT16_ARRAY(array);
}

/**
 * garrow_int16_array_get_value:
 * @array: A #GArrowInt16Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gint16
garrow_int16_array_get_value(GArrowInt16Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Int16Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_int16_array_get_values:
 * @array: A #GArrowInt16Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const gint16 *
garrow_int16_array_get_values(GArrowInt16Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::Int16Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowUInt16Array, garrow_uint16_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_uint16_array_init(GArrowUInt16Array *object)
{
}

static void
garrow_uint16_array_class_init(GArrowUInt16ArrayClass *klass)
{
}

/**
 * garrow_uint16_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowUInt16Array.
 *
 * Since: 0.4.0
 */
GArrowUInt16Array *
garrow_uint16_array_new(gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::UInt16Type>(length, data, null_bitmap, n_nulls);
  return GARROW_UINT16_ARRAY(array);
}

/**
 * garrow_uint16_array_get_value:
 * @array: A #GArrowUInt16Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
guint16
garrow_uint16_array_get_value(GArrowUInt16Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::UInt16Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_uint16_array_get_values:
 * @array: A #GArrowUInt16Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const guint16 *
garrow_uint16_array_get_values(GArrowUInt16Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::UInt16Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowInt32Array, garrow_int32_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_int32_array_init(GArrowInt32Array *object)
{
}

static void
garrow_int32_array_class_init(GArrowInt32ArrayClass *klass)
{
}

/**
 * garrow_int32_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowInt32Array.
 *
 * Since: 0.4.0
 */
GArrowInt32Array *
garrow_int32_array_new(gint64 length,
                       GArrowBuffer *data,
                       GArrowBuffer *null_bitmap,
                       gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::Int32Type>(length, data, null_bitmap, n_nulls);
  return GARROW_INT32_ARRAY(array);
}

/**
 * garrow_int32_array_get_value:
 * @array: A #GArrowInt32Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gint32
garrow_int32_array_get_value(GArrowInt32Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Int32Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_int32_array_get_values:
 * @array: A #GArrowInt32Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const gint32 *
garrow_int32_array_get_values(GArrowInt32Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::Int32Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowUInt32Array, garrow_uint32_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_uint32_array_init(GArrowUInt32Array *object)
{
}

static void
garrow_uint32_array_class_init(GArrowUInt32ArrayClass *klass)
{
}

/**
 * garrow_uint32_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowUInt32Array.
 *
 * Since: 0.4.0
 */
GArrowUInt32Array *
garrow_uint32_array_new(gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::UInt32Type>(length, data, null_bitmap, n_nulls);
  return GARROW_UINT32_ARRAY(array);
}

/**
 * garrow_uint32_array_get_value:
 * @array: A #GArrowUInt32Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
guint32
garrow_uint32_array_get_value(GArrowUInt32Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::UInt32Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_uint32_array_get_values:
 * @array: A #GArrowUInt32Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const guint32 *
garrow_uint32_array_get_values(GArrowUInt32Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::UInt32Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowInt64Array, garrow_int64_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_int64_array_init(GArrowInt64Array *object)
{
}

static void
garrow_int64_array_class_init(GArrowInt64ArrayClass *klass)
{
}

/**
 * garrow_int64_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowInt64Array.
 *
 * Since: 0.4.0
 */
GArrowInt64Array *
garrow_int64_array_new(gint64 length,
                       GArrowBuffer *data,
                       GArrowBuffer *null_bitmap,
                       gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::Int64Type>(length, data, null_bitmap, n_nulls);
  return GARROW_INT64_ARRAY(array);
}

/**
 * garrow_int64_array_get_value:
 * @array: A #GArrowInt64Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gint64
garrow_int64_array_get_value(GArrowInt64Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Int64Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_int64_array_get_values:
 * @array: A #GArrowInt64Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const gint64 *
garrow_int64_array_get_values(GArrowInt64Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto values = garrow_array_get_values_raw<arrow::Int64Type>(arrow_array, length);
  return reinterpret_cast<const gint64 *>(values);
}

G_DEFINE_TYPE(GArrowUInt64Array, garrow_uint64_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_uint64_array_init(GArrowUInt64Array *object)
{
}

static void
garrow_uint64_array_class_init(GArrowUInt64ArrayClass *klass)
{
}

/**
 * garrow_uint64_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowUInt64Array.
 *
 * Since: 0.4.0
 */
GArrowUInt64Array *
garrow_uint64_array_new(gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::UInt64Type>(length, data, null_bitmap, n_nulls);
  return GARROW_UINT64_ARRAY(array);
}

/**
 * garrow_uint64_array_get_value:
 * @array: A #GArrowUInt64Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
guint64
garrow_uint64_array_get_value(GArrowUInt64Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::UInt64Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_uint64_array_get_values:
 * @array: A #GArrowUInt64Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const guint64 *
garrow_uint64_array_get_values(GArrowUInt64Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto values = garrow_array_get_values_raw<arrow::UInt64Type>(arrow_array, length);
  return reinterpret_cast<const guint64 *>(values);
}

G_DEFINE_TYPE(GArrowHalfFloatArray, garrow_half_float_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_half_float_array_init(GArrowHalfFloatArray *object)
{
}

static void
garrow_half_float_array_class_init(GArrowHalfFloatArrayClass *klass)
{
}

/**
 * garrow_half_float_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowHalfFloatArray.
 *
 * Since: 11.0.0
 */
GArrowHalfFloatArray *
garrow_half_float_array_new(gint64 length,
                            GArrowBuffer *data,
                            GArrowBuffer *null_bitmap,
                            gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::HalfFloatType>(length, data, null_bitmap, n_nulls);
  return GARROW_HALF_FLOAT_ARRAY(array);
}

/**
 * garrow_half_float_array_get_value:
 * @array: A #GArrowHalfFloatArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 11.0.0
 */
guint16
garrow_half_float_array_get_value(GArrowHalfFloatArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return std::static_pointer_cast<arrow::HalfFloatArray>(arrow_array)->Value(i);
}

/**
 * garrow_half_float_array_get_values:
 * @array: A #GArrowHalfFloatArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 11.0.0
 */
const guint16 *
garrow_half_float_array_get_values(GArrowHalfFloatArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::HalfFloatType>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowFloatArray, garrow_float_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_float_array_init(GArrowFloatArray *object)
{
}

static void
garrow_float_array_class_init(GArrowFloatArrayClass *klass)
{
}

/**
 * garrow_float_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowFloatArray.
 *
 * Since: 0.4.0
 */
GArrowFloatArray *
garrow_float_array_new(gint64 length,
                       GArrowBuffer *data,
                       GArrowBuffer *null_bitmap,
                       gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::FloatType>(length, data, null_bitmap, n_nulls);
  return GARROW_FLOAT_ARRAY(array);
}

/**
 * garrow_float_array_get_value:
 * @array: A #GArrowFloatArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gfloat
garrow_float_array_get_value(GArrowFloatArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::FloatArray *>(arrow_array.get())->Value(i);
}

/**
 * garrow_float_array_get_values:
 * @array: A #GArrowFloatArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const gfloat *
garrow_float_array_get_values(GArrowFloatArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::FloatType>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowDoubleArray, garrow_double_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_double_array_init(GArrowDoubleArray *object)
{
}

static void
garrow_double_array_class_init(GArrowDoubleArrayClass *klass)
{
}

/**
 * garrow_double_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowDoubleArray.
 *
 * Since: 0.4.0
 */
GArrowDoubleArray *
garrow_double_array_new(gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::DoubleType>(length, data, null_bitmap, n_nulls);
  return GARROW_DOUBLE_ARRAY(array);
}

/**
 * garrow_double_array_get_value:
 * @array: A #GArrowDoubleArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 */
gdouble
garrow_double_array_get_value(GArrowDoubleArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::DoubleArray *>(arrow_array.get())->Value(i);
}

/**
 * garrow_double_array_get_values:
 * @array: A #GArrowDoubleArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 */
const gdouble *
garrow_double_array_get_values(GArrowDoubleArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::DoubleType>(arrow_array, length);
}

G_END_DECLS
template <typename BINARY_ARRAY_CLASS>
GArrowArray *
garrow_base_binary_array_new(gint64 length,
                             GArrowBuffer *value_offsets,
                             GArrowBuffer *value_data,
                             GArrowBuffer *null_bitmap,
                             gint64 n_nulls)
{
  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
  const auto arrow_value_data = garrow_buffer_get_raw(value_data);
  const auto arrow_null_bitmap = garrow_buffer_get_raw(null_bitmap);
  auto arrow_binary_array = std::make_shared<BINARY_ARRAY_CLASS>(length,
                                                                 arrow_value_offsets,
                                                                 arrow_value_data,
                                                                 arrow_null_bitmap,
                                                                 n_nulls);
  auto arrow_array = std::static_pointer_cast<arrow::Array>(arrow_binary_array);
  return garrow_array_new_raw(&arrow_array,
                              "array",
                              &arrow_array,
                              "null-bitmap",
                              null_bitmap,
                              "buffer1",
                              value_offsets,
                              "buffer2",
                              value_data,
                              NULL);
};

template <typename BINARY_ARRAY_CLASS>
GBytes *
garrow_base_binary_array_get_value(GArrowArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(array);
  auto arrow_binary_array = std::static_pointer_cast<BINARY_ARRAY_CLASS>(arrow_array);
  auto view = arrow_binary_array->GetView(i);
  return g_bytes_new_static(view.data(), view.length());
};

template <typename BINARY_ARRAY_CLASS>
GArrowBuffer *
garrow_base_binary_array_get_data_buffer(GArrowArray *array)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
  if (priv->buffer2) {
    g_object_ref(priv->buffer2);
    return priv->buffer2;
  }

  auto arrow_array = garrow_array_get_raw(array);
  auto arrow_binary_array = std::static_pointer_cast<BINARY_ARRAY_CLASS>(arrow_array);
  auto arrow_data = arrow_binary_array->value_data();
  return garrow_buffer_new_raw(&arrow_data);
};

template <typename BINARY_ARRAY_CLASS>
GArrowBuffer *
garrow_base_binary_array_get_offsets_buffer(GArrowArray *array)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
  if (priv->buffer1) {
    g_object_ref(priv->buffer1);
    return priv->buffer1;
  }

  auto arrow_array = garrow_array_get_raw(array);
  auto arrow_binary_array = std::static_pointer_cast<BINARY_ARRAY_CLASS>(arrow_array);
  auto arrow_offsets = arrow_binary_array->value_offsets();
  return garrow_buffer_new_raw(&arrow_offsets);
};
G_BEGIN_DECLS

G_DEFINE_TYPE(GArrowBinaryArray, garrow_binary_array, GARROW_TYPE_ARRAY)

static void
garrow_binary_array_init(GArrowBinaryArray *object)
{
}

static void
garrow_binary_array_class_init(GArrowBinaryArrayClass *klass)
{
}

/**
 * garrow_binary_array_new:
 * @length: The number of elements.
 * @value_offsets: The value offsets of @data in Arrow format.
 * @value_data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowBinaryArray.
 *
 * Since: 0.4.0
 */
GArrowBinaryArray *
garrow_binary_array_new(gint64 length,
                        GArrowBuffer *value_offsets,
                        GArrowBuffer *value_data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto binary_array = garrow_base_binary_array_new<arrow::BinaryArray>(length,
                                                                       value_offsets,
                                                                       value_data,
                                                                       null_bitmap,
                                                                       n_nulls);
  return GARROW_BINARY_ARRAY(binary_array);
}

/**
 * garrow_binary_array_get_value:
 * @array: A #GArrowBinaryArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 */
GBytes *
garrow_binary_array_get_value(GArrowBinaryArray *array, gint64 i)
{
  return garrow_base_binary_array_get_value<arrow::BinaryArray>(GARROW_ARRAY(array), i);
}

/**
 * garrow_binary_array_get_buffer:
 * @array: A #GArrowBinaryArray.
 *
 * Returns: (transfer full): The data of the array as #GArrowBuffer.
 *
 * Deprecated: 1.0.0: Use garrow_binary_array_get_data_buffer() instead.
 */
GArrowBuffer *
garrow_binary_array_get_buffer(GArrowBinaryArray *array)
{
  return garrow_binary_array_get_data_buffer(array);
}

/**
 * garrow_binary_array_get_data_buffer:
 * @array: A #GArrowBinaryArray.
 *
 * Returns: (transfer full): The data of the array as #GArrowBuffer.
 *
 * Since: 1.0.0
 */
GArrowBuffer *
garrow_binary_array_get_data_buffer(GArrowBinaryArray *array)
{
  return garrow_base_binary_array_get_data_buffer<arrow::BinaryArray>(
    GARROW_ARRAY(array));
}

/**
 * garrow_binary_array_get_offsets_buffer:
 * @array: A #GArrowBinaryArray.
 *
 * Returns: (transfer full): The offsets of the array as #GArrowBuffer.
 */
GArrowBuffer *
garrow_binary_array_get_offsets_buffer(GArrowBinaryArray *array)
{
  return garrow_base_binary_array_get_offsets_buffer<arrow::BinaryArray>(
    GARROW_ARRAY(array));
}

G_DEFINE_TYPE(GArrowLargeBinaryArray, garrow_large_binary_array, GARROW_TYPE_ARRAY)

static void
garrow_large_binary_array_init(GArrowLargeBinaryArray *object)
{
}

static void
garrow_large_binary_array_class_init(GArrowLargeBinaryArrayClass *klass)
{
}

/**
 * garrow_large_binary_array_new:
 * @length: The number of elements.
 * @value_offsets: The value offsets of @data in Arrow format.
 * @value_data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowLargeBinaryArray.
 *
 * Since: 0.16.0
 */
GArrowLargeBinaryArray *
garrow_large_binary_array_new(gint64 length,
                              GArrowBuffer *value_offsets,
                              GArrowBuffer *value_data,
                              GArrowBuffer *null_bitmap,
                              gint64 n_nulls)
{
  auto large_binary_array =
    garrow_base_binary_array_new<arrow::LargeBinaryArray>(length,
                                                          value_offsets,
                                                          value_data,
                                                          null_bitmap,
                                                          n_nulls);
  return GARROW_LARGE_BINARY_ARRAY(large_binary_array);
}

/**
 * garrow_large_binary_array_get_value:
 * @array: A #GArrowLargeBinaryArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 0.16.0
 */
GBytes *
garrow_large_binary_array_get_value(GArrowLargeBinaryArray *array, gint64 i)
{
  return garrow_base_binary_array_get_value<arrow::LargeBinaryArray>(GARROW_ARRAY(array),
                                                                     i);
}

/**
 * garrow_large_binary_array_get_buffer:
 * @array: A #GArrowLargeBinaryArray.
 *
 * Returns: (transfer full): The data of the array as #GArrowBuffer.
 *
 * Since: 0.16.0
 *
 * Deprecated: 1.0.0: Use garrow_large_binary_array_get_data_buffer() instead.
 */
GArrowBuffer *
garrow_large_binary_array_get_buffer(GArrowLargeBinaryArray *array)
{
  return garrow_large_binary_array_get_data_buffer(array);
}

/**
 * garrow_large_binary_array_get_data_buffer:
 * @array: A #GArrowLargeBinaryArray.
 *
 * Returns: (transfer full): The data of the array as #GArrowBuffer.
 *
 * Since: 1.0.0
 */
GArrowBuffer *
garrow_large_binary_array_get_data_buffer(GArrowLargeBinaryArray *array)
{
  return garrow_base_binary_array_get_data_buffer<arrow::LargeBinaryArray>(
    GARROW_ARRAY(array));
}

/**
 * garrow_large_binary_array_get_offsets_buffer:
 * @array: A #GArrowLargeBinaryArray.
 *
 * Returns: (transfer full): The offsets of the array as #GArrowBuffer.
 *
 * Since: 0.16.0
 */
GArrowBuffer *
garrow_large_binary_array_get_offsets_buffer(GArrowLargeBinaryArray *array)
{
  return garrow_base_binary_array_get_offsets_buffer<arrow::LargeBinaryArray>(
    GARROW_ARRAY(array));
}

G_END_DECLS
template <typename STRING_ARRAY_CLASS>
gchar *
garrow_base_string_array_get_value(GArrowArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(array);
  auto arrow_string_array = std::static_pointer_cast<STRING_ARRAY_CLASS>(arrow_array);
  auto view = arrow_string_array->GetView(i);
  return g_strndup(view.data(), view.length());
};
G_BEGIN_DECLS

G_DEFINE_TYPE(GArrowStringArray, garrow_string_array, GARROW_TYPE_BINARY_ARRAY)

static void
garrow_string_array_init(GArrowStringArray *object)
{
}

static void
garrow_string_array_class_init(GArrowStringArrayClass *klass)
{
}

/**
 * garrow_string_array_new:
 * @length: The number of elements.
 * @value_offsets: The value offsets of @data in Arrow format.
 * @value_data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowStringArray.
 *
 * Since: 0.4.0
 */
GArrowStringArray *
garrow_string_array_new(gint64 length,
                        GArrowBuffer *value_offsets,
                        GArrowBuffer *value_data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto string_array = garrow_base_binary_array_new<arrow::StringArray>(length,
                                                                       value_offsets,
                                                                       value_data,
                                                                       null_bitmap,
                                                                       n_nulls);
  return GARROW_STRING_ARRAY(string_array);
}

/**
 * garrow_string_array_get_string:
 * @array: A #GArrowStringArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th UTF-8 encoded string.
 */
gchar *
garrow_string_array_get_string(GArrowStringArray *array, gint64 i)
{
  return garrow_base_string_array_get_value<arrow::StringArray>(GARROW_ARRAY(array), i);
}

G_DEFINE_TYPE(GArrowLargeStringArray,
              garrow_large_string_array,
              GARROW_TYPE_LARGE_BINARY_ARRAY)

static void
garrow_large_string_array_init(GArrowLargeStringArray *object)
{
}

static void
garrow_large_string_array_class_init(GArrowLargeStringArrayClass *klass)
{
}

/**
 * garrow_large_string_array_new:
 * @length: The number of elements.
 * @value_offsets: The value offsets of @data in Arrow format.
 * @value_data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowLargeStringArray.
 *
 * Since: 0.16.0
 */
GArrowLargeStringArray *
garrow_large_string_array_new(gint64 length,
                              GArrowBuffer *value_offsets,
                              GArrowBuffer *value_data,
                              GArrowBuffer *null_bitmap,
                              gint64 n_nulls)
{
  auto large_string_array =
    garrow_base_binary_array_new<arrow::LargeStringArray>(length,
                                                          value_offsets,
                                                          value_data,
                                                          null_bitmap,
                                                          n_nulls);
  return GARROW_LARGE_STRING_ARRAY(large_string_array);
}

/**
 * garrow_large_string_array_get_string:
 * @array: A #GArrowLargeStringArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th UTF-8 encoded string.
 *
 * Since: 0.16.0
 */
gchar *
garrow_large_string_array_get_string(GArrowLargeStringArray *array, gint64 i)
{
  return garrow_base_string_array_get_value<arrow::LargeStringArray>(GARROW_ARRAY(array),
                                                                     i);
}

G_DEFINE_TYPE(GArrowBinaryViewArray, garrow_binary_view_array, GARROW_TYPE_ARRAY)
static void
garrow_binary_view_array_init(GArrowBinaryViewArray *object)
{
}

static void
garrow_binary_view_array_class_init(GArrowBinaryViewArrayClass *klass)
{
}

/**
 * garrow_binary_view_array_new:
 * @length: The number of elements.
 * @views: The view buffer.
 * @data_buffers: (element-type GArrowBuffer): The data buffers.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 * @offset: The position of the first element.
 *
 * Returns: A newly created #GArrowBinaryViewArray.
 *
 * Since: 20.0.0
 */
GArrowBinaryViewArray *
garrow_binary_view_array_new(gint64 length,
                             GArrowBuffer *views,
                             GList *data_buffers,
                             GArrowBuffer *null_bitmap,
                             gint64 n_nulls,
                             gint64 offset)
{
  std::vector<std::shared_ptr<arrow::Buffer>> arrow_data_buffers;
  for (GList *node = data_buffers; node; node = g_list_next(node)) {
    arrow_data_buffers.push_back(garrow_buffer_get_raw(GARROW_BUFFER(node->data)));
  }
  auto binary_view_array =
    std::make_shared<arrow::BinaryViewArray>(arrow::binary_view(),
                                             length,
                                             garrow_buffer_get_raw(views),
                                             std::move(arrow_data_buffers),
                                             garrow_buffer_get_raw(null_bitmap),
                                             n_nulls,
                                             offset);
  return GARROW_BINARY_VIEW_ARRAY(
    g_object_new(GARROW_TYPE_BINARY_VIEW_ARRAY, "array", &binary_view_array, nullptr));
}

/**
 * garrow_binary_view_array_get_value:
 * @array: A #GArrowBinaryViewArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 */
GBytes *
garrow_binary_view_array_get_value(GArrowBinaryViewArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto view = static_cast<arrow::BinaryViewArray *>(arrow_array.get())->GetView(i);
  return g_bytes_new_static(view.data(), view.length());
}

G_DEFINE_TYPE(GArrowStringViewArray,
              garrow_string_view_array,
              GARROW_TYPE_BINARY_VIEW_ARRAY)
static void
garrow_string_view_array_init(GArrowStringViewArray *object)
{
}

static void
garrow_string_view_array_class_init(GArrowStringViewArrayClass *klass)
{
}

/**
 * garrow_string_view_array_new:
 * @length: The number of elements.
 * @views: The view buffer.
 * @data_buffers: (element-type GArrowBuffer): The data buffers.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 * @offset: The position of the first element.
 *
 * Returns: A newly created #GArrowStringViewArray.
 *
 * Since: 20.0.0
 */
GArrowStringViewArray *
garrow_string_view_array_new(gint64 length,
                             GArrowBuffer *views,
                             GList *data_buffers,
                             GArrowBuffer *null_bitmap,
                             gint64 n_nulls,
                             gint64 offset)
{
  std::vector<std::shared_ptr<arrow::Buffer>> arrow_data_buffers;
  for (GList *node = data_buffers; node; node = g_list_next(node)) {
    arrow_data_buffers.push_back(garrow_buffer_get_raw(GARROW_BUFFER(node->data)));
  }
  auto arrow_string_view_array =
    std::make_shared<arrow::StringViewArray>(arrow::utf8_view(),
                                             length,
                                             garrow_buffer_get_raw(views),
                                             std::move(arrow_data_buffers),
                                             garrow_buffer_get_raw(null_bitmap),
                                             n_nulls,
                                             offset);
  return GARROW_STRING_VIEW_ARRAY(g_object_new(GARROW_TYPE_STRING_VIEW_ARRAY,
                                               "array",
                                               &arrow_string_view_array,
                                               nullptr));
}

/**
 * garrow_string_view_array_get_value:
 * @array: A #GArrowStringViewArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 */
GBytes *
garrow_string_view_array_get_value(GArrowStringViewArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto view = static_cast<arrow::StringViewArray *>(arrow_array.get())->GetView(i);
  return g_bytes_new_static(view.data(), view.length());
}

G_DEFINE_TYPE(GArrowDate32Array, garrow_date32_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_date32_array_init(GArrowDate32Array *object)
{
}

static void
garrow_date32_array_class_init(GArrowDate32ArrayClass *klass)
{
}

/**
 * garrow_date32_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowDate32Array.
 *
 * Since: 0.7.0
 */
GArrowDate32Array *
garrow_date32_array_new(gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::Date32Type>(length, data, null_bitmap, n_nulls);
  return GARROW_DATE32_ARRAY(array);
}

/**
 * garrow_date32_array_get_value:
 * @array: A #GArrowDate32Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 0.7.0
 */
gint32
garrow_date32_array_get_value(GArrowDate32Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Date32Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_date32_array_get_values:
 * @array: A #GArrowDate32Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 0.7.0
 */
const gint32 *
garrow_date32_array_get_values(GArrowDate32Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::Date32Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowDate64Array, garrow_date64_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_date64_array_init(GArrowDate64Array *object)
{
}

static void
garrow_date64_array_class_init(GArrowDate64ArrayClass *klass)
{
}

/**
 * garrow_date64_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowDate64Array.
 *
 * Since: 0.7.0
 */
GArrowDate64Array *
garrow_date64_array_new(gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::Date64Type>(length, data, null_bitmap, n_nulls);
  return GARROW_DATE64_ARRAY(array);
}

/**
 * garrow_date64_array_get_value:
 * @array: A #GArrowDate64Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 0.7.0
 */
gint64
garrow_date64_array_get_value(GArrowDate64Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Date64Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_date64_array_get_values:
 * @array: A #GArrowDate64Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 0.7.0
 */
const gint64 *
garrow_date64_array_get_values(GArrowDate64Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto values = garrow_array_get_values_raw<arrow::Date64Type>(arrow_array, length);
  return reinterpret_cast<const gint64 *>(values);
}

G_DEFINE_TYPE(GArrowTimestampArray, garrow_timestamp_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_timestamp_array_init(GArrowTimestampArray *object)
{
}

static void
garrow_timestamp_array_class_init(GArrowTimestampArrayClass *klass)
{
}

/**
 * garrow_timestamp_array_new:
 * @data_type: The #GArrowTimestampDataType.
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowTimestampArray.
 *
 * Since: 0.7.0
 */
GArrowTimestampArray *
garrow_timestamp_array_new(GArrowTimestampDataType *data_type,
                           gint64 length,
                           GArrowBuffer *data,
                           GArrowBuffer *null_bitmap,
                           gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::TimestampType>(GARROW_DATA_TYPE(data_type),
                                                     length,
                                                     data,
                                                     null_bitmap,
                                                     n_nulls);
  return GARROW_TIMESTAMP_ARRAY(array);
}

/**
 * garrow_timestamp_array_get_value:
 * @array: A #GArrowTimestampArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 0.7.0
 */
gint64
garrow_timestamp_array_get_value(GArrowTimestampArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::TimestampArray *>(arrow_array.get())->Value(i);
}

/**
 * garrow_timestamp_array_get_values:
 * @array: A #GArrowTimestampArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 0.7.0
 */
const gint64 *
garrow_timestamp_array_get_values(GArrowTimestampArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto values = garrow_array_get_values_raw<arrow::TimestampType>(arrow_array, length);
  return reinterpret_cast<const gint64 *>(values);
}

G_DEFINE_TYPE(GArrowTime32Array, garrow_time32_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_time32_array_init(GArrowTime32Array *object)
{
}

static void
garrow_time32_array_class_init(GArrowTime32ArrayClass *klass)
{
}

/**
 * garrow_time32_array_new:
 * @data_type: The #GArrowTime32DataType.
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowTime32Array.
 *
 * Since: 0.7.0
 */
GArrowTime32Array *
garrow_time32_array_new(GArrowTime32DataType *data_type,
                        gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array = garrow_primitive_array_new<arrow::Time32Type>(GARROW_DATA_TYPE(data_type),
                                                             length,
                                                             data,
                                                             null_bitmap,
                                                             n_nulls);
  return GARROW_TIME32_ARRAY(array);
}

/**
 * garrow_time32_array_get_value:
 * @array: A #GArrowTime32Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 0.7.0
 */
gint32
garrow_time32_array_get_value(GArrowTime32Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Time32Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_time32_array_get_values:
 * @array: A #GArrowTime32Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 0.7.0
 */
const gint32 *
garrow_time32_array_get_values(GArrowTime32Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::Time32Type>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowTime64Array, garrow_time64_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_time64_array_init(GArrowTime64Array *object)
{
}

static void
garrow_time64_array_class_init(GArrowTime64ArrayClass *klass)
{
}

/**
 * garrow_time64_array_new:
 * @data_type: The #GArrowTime64DataType.
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowTime64Array.
 *
 * Since: 0.7.0
 */
GArrowTime64Array *
garrow_time64_array_new(GArrowTime64DataType *data_type,
                        gint64 length,
                        GArrowBuffer *data,
                        GArrowBuffer *null_bitmap,
                        gint64 n_nulls)
{
  auto array = garrow_primitive_array_new<arrow::Time64Type>(GARROW_DATA_TYPE(data_type),
                                                             length,
                                                             data,
                                                             null_bitmap,
                                                             n_nulls);
  return GARROW_TIME64_ARRAY(array);
}

/**
 * garrow_time64_array_get_value:
 * @array: A #GArrowTime64Array.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 0.7.0
 */
gint64
garrow_time64_array_get_value(GArrowTime64Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::Time64Array *>(arrow_array.get())->Value(i);
}

/**
 * garrow_time64_array_get_values:
 * @array: A #GArrowTime64Array.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 0.7.0
 */
const gint64 *
garrow_time64_array_get_values(GArrowTime64Array *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto values = garrow_array_get_values_raw<arrow::Time64Type>(arrow_array, length);
  return reinterpret_cast<const gint64 *>(values);
}

G_DEFINE_TYPE(GArrowMonthIntervalArray,
              garrow_month_interval_array,
              GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_month_interval_array_init(GArrowMonthIntervalArray *object)
{
}

static void
garrow_month_interval_array_class_init(GArrowMonthIntervalArrayClass *klass)
{
}

/**
 * garrow_month_interval_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowMonthIntervalArray.
 *
 * Since: 8.0.0
 */
GArrowMonthIntervalArray *
garrow_month_interval_array_new(gint64 length,
                                GArrowBuffer *data,
                                GArrowBuffer *null_bitmap,
                                gint64 n_nulls)
{
  auto array = garrow_primitive_array_new<arrow::MonthIntervalType>(length,
                                                                    data,
                                                                    null_bitmap,
                                                                    n_nulls);
  return GARROW_MONTH_INTERVAL_ARRAY(array);
}

/**
 * garrow_month_interval_array_get_value:
 * @array: A #GArrowMonthIntervalArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 8.0.0
 */
gint32
garrow_month_interval_array_get_value(GArrowMonthIntervalArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::MonthIntervalArray *>(arrow_array.get())->Value(i);
}

/**
 * garrow_month_interval_array_get_values:
 * @array: A #GArrowMonthIntervalArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 8.0.0
 */
const gint32 *
garrow_month_interval_array_get_values(GArrowMonthIntervalArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return garrow_array_get_values_raw<arrow::MonthIntervalType>(arrow_array, length);
}

G_DEFINE_TYPE(GArrowDayTimeIntervalArray,
              garrow_day_time_interval_array,
              GARROW_TYPE_PRIMITIVE_ARRAY)

static void
garrow_day_time_interval_array_init(GArrowDayTimeIntervalArray *object)
{
}

static void
garrow_day_time_interval_array_class_init(GArrowDayTimeIntervalArrayClass *klass)
{
}

/**
 * garrow_day_time_interval_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowDayTimeIntervalArray.
 *
 * Since: 8.0.0
 */
GArrowDayTimeIntervalArray *
garrow_day_time_interval_array_new(gint64 length,
                                   GArrowBuffer *data,
                                   GArrowBuffer *null_bitmap,
                                   gint64 n_nulls)
{
  auto array = garrow_primitive_array_new<arrow::DayTimeIntervalType>(length,
                                                                      data,
                                                                      null_bitmap,
                                                                      n_nulls);
  return GARROW_DAY_TIME_INTERVAL_ARRAY(array);
}

/**
 * garrow_day_time_interval_array_get_value:
 * @array: A #GArrowDayTimeIntervalArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 8.0.0
 */
GArrowDayMillisecond *
garrow_day_time_interval_array_get_value(GArrowDayTimeIntervalArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_day_time_interval_array =
    std::static_pointer_cast<arrow::DayTimeIntervalArray>(arrow_array);
  auto arrow_day_time_interval = arrow_day_time_interval_array->GetValue(i);
  return garrow_day_millisecond_new_raw(&arrow_day_time_interval);
}

/**
 * garrow_day_time_interval_array_get_values:
 * @array: A #GArrowDayTimeIntervalArray.
 *
 * Returns: (nullable) (element-type GArrowDayMillisecond) (transfer full):
 *   The list of #GArrowDayMillisecond.
 *
 * Since: 8.0.0
 */
GList *
garrow_day_time_interval_array_get_values(GArrowDayTimeIntervalArray *array)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_day_time_interval_array =
    std::static_pointer_cast<arrow::DayTimeIntervalArray>(arrow_array);
  auto length = arrow_day_time_interval_array->length();
  GList *values = NULL;
  for (gint64 i = 0; i < length; ++i) {
    if (arrow_day_time_interval_array->IsValid(i)) {
      auto arrow_value = arrow_day_time_interval_array->GetValue(i);
      auto value = garrow_day_millisecond_new_raw(&arrow_value);
      values = g_list_prepend(values, value);
    } else {
      values = g_list_prepend(values, NULL);
    }
  }
  return g_list_reverse(values);
}

G_DEFINE_TYPE(GArrowMonthDayNanoIntervalArray,
              garrow_month_day_nano_interval_array,
              GARROW_TYPE_PRIMITIVE_ARRAY)

static void
garrow_month_day_nano_interval_array_init(GArrowMonthDayNanoIntervalArray *object)
{
}

static void
garrow_month_day_nano_interval_array_class_init(
  GArrowMonthDayNanoIntervalArrayClass *klass)
{
}

/**
 * garrow_month_day_nano_interval_array_new:
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowMonthDayNanoIntervalArray.
 *
 * Since: 8.0.0
 */
GArrowMonthDayNanoIntervalArray *
garrow_month_day_nano_interval_array_new(gint64 length,
                                         GArrowBuffer *data,
                                         GArrowBuffer *null_bitmap,
                                         gint64 n_nulls)
{
  auto array = garrow_primitive_array_new<arrow::MonthDayNanoIntervalType>(length,
                                                                           data,
                                                                           null_bitmap,
                                                                           n_nulls);
  return GARROW_MONTH_DAY_NANO_INTERVAL_ARRAY(array);
}

/**
 * garrow_month_day_nano_interval_array_get_value:
 * @array: A #GArrowMonthDayNanoIntervalArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 8.0.0
 */
GArrowMonthDayNano *
garrow_month_day_nano_interval_array_get_value(GArrowMonthDayNanoIntervalArray *array,
                                               gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_month_day_nano_interval_array =
    std::static_pointer_cast<arrow::MonthDayNanoIntervalArray>(arrow_array);
  auto arrow_value = arrow_month_day_nano_interval_array->GetValue(i);
  return garrow_month_day_nano_new_raw(&arrow_value);
}

/**
 * garrow_month_day_nano_interval_array_get_values:
 * @array: A #GArrowMonthDayNanoIntervalArray.
 *
 * Returns: (nullable) (element-type GArrowMonthDayNano) (transfer full):
 *   The list of #GArrowMonthDayNano.
 *
 * Since: 8.0.0
 */
GList *
garrow_month_day_nano_interval_array_get_values(GArrowMonthDayNanoIntervalArray *array)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_month_day_nano_interval_array =
    std::static_pointer_cast<arrow::MonthDayNanoIntervalArray>(arrow_array);
  auto length = arrow_month_day_nano_interval_array->length();
  GList *values = NULL;
  for (gint64 i = 0; i < length; ++i) {
    if (arrow_month_day_nano_interval_array->IsValid(i)) {
      auto arrow_value = arrow_month_day_nano_interval_array->GetValue(i);
      auto value = garrow_month_day_nano_new_raw(&arrow_value);
      values = g_list_prepend(values, value);
    } else {
      values = g_list_prepend(values, NULL);
    }
  }
  return g_list_reverse(values);
}

G_DEFINE_TYPE(GArrowDurationArray, garrow_duration_array, GARROW_TYPE_NUMERIC_ARRAY)

static void
garrow_duration_array_init(GArrowDurationArray *object)
{
}

static void
garrow_duration_array_class_init(GArrowDurationArrayClass *klass)
{
}

/**
 * garrow_duration_array_new:
 * @data_type: The #GArrowDurationDataType.
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowDurationArray.
 *
 * Since: 23.0.0
 */
GArrowDurationArray *
garrow_duration_array_new(GArrowDurationDataType *data_type,
                          gint64 length,
                          GArrowBuffer *data,
                          GArrowBuffer *null_bitmap,
                          gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::DurationType>(GARROW_DATA_TYPE(data_type),
                                                    length,
                                                    data,
                                                    null_bitmap,
                                                    n_nulls);
  return GARROW_DURATION_ARRAY(array);
}

/**
 * garrow_duration_array_get_value:
 * @array: A #GArrowDurationArray.
 * @i: The index of the target value.
 *
 * Returns: The @i-th value.
 *
 * Since: 23.0.0
 */
gint64
garrow_duration_array_get_value(GArrowDurationArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  return static_cast<arrow::DurationArray *>(arrow_array.get())->Value(i);
}

/**
 * garrow_duration_array_get_values:
 * @array: A #GArrowDurationArray.
 * @length: (out): The number of values.
 *
 * Returns: (array length=length): The raw values.
 *
 * Since: 23.0.0
 */
const gint64 *
garrow_duration_array_get_values(GArrowDurationArray *array, gint64 *length)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto values = garrow_array_get_values_raw<arrow::DurationType>(arrow_array, length);
  return reinterpret_cast<const gint64 *>(values);
}

G_DEFINE_TYPE(GArrowFixedSizeBinaryArray,
              garrow_fixed_size_binary_array,
              GARROW_TYPE_PRIMITIVE_ARRAY)
static void
garrow_fixed_size_binary_array_init(GArrowFixedSizeBinaryArray *object)
{
}

static void
garrow_fixed_size_binary_array_class_init(GArrowFixedSizeBinaryArrayClass *klass)
{
}

/**
 * garrow_fixed_size_binary_array_new:
 * @data_type: A #GArrowFixedSizeBinaryDataType for the array.
 * @length: The number of elements.
 * @data: The binary data in Arrow format of the array.
 * @null_bitmap: (nullable): The bitmap that shows null elements. The
 *   N-th element is null when the N-th bit is 0, not null otherwise.
 *   If the array has no null elements, the bitmap must be %NULL and
 *   @n_nulls is 0.
 * @n_nulls: The number of null elements. If -1 is specified, the
 *   number of nulls are computed from @null_bitmap.
 *
 * Returns: A newly created #GArrowFixedSizeBinaryArray.
 *
 * Since: 3.0.0
 */
GArrowFixedSizeBinaryArray *
garrow_fixed_size_binary_array_new(GArrowFixedSizeBinaryDataType *data_type,
                                   gint64 length,
                                   GArrowBuffer *data,
                                   GArrowBuffer *null_bitmap,
                                   gint64 n_nulls)
{
  auto array =
    garrow_primitive_array_new<arrow::FixedSizeBinaryType>(GARROW_DATA_TYPE(data_type),
                                                           length,
                                                           data,
                                                           null_bitmap,
                                                           n_nulls);
  return GARROW_FIXED_SIZE_BINARY_ARRAY(array);
}

/**
 * garrow_fixed_size_binary_array_get_byte_width:
 * @array: A #GArrowFixedSizeBinaryArray.
 *
 * Returns: The number of bytes of each value.
 *
 * Since: 3.0.0
 */
gint32
garrow_fixed_size_binary_array_get_byte_width(GArrowFixedSizeBinaryArray *array)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_binary_array =
    std::static_pointer_cast<arrow::FixedSizeBinaryArray>(arrow_array);
  return arrow_binary_array->byte_width();
}

/**
 * garrow_fixed_size_binary_array_get_value:
 * @array: A #GArrowFixedSizeBinaryArray.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 3.0.0
 */
GBytes *
garrow_fixed_size_binary_array_get_value(GArrowFixedSizeBinaryArray *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_binary_array =
    std::static_pointer_cast<arrow::FixedSizeBinaryArray>(arrow_array);
  auto value = arrow_binary_array->GetValue(i);
  return g_bytes_new_static(value, arrow_binary_array->byte_width());
}

/**
 * garrow_fixed_size_binary_array_get_values_bytes:
 * @array: A #GArrowFixedSizeBinaryArray.
 *
 * Returns: (transfer full): All values as a #GBytes.
 *
 * Since: 3.0.0
 */
GBytes *
garrow_fixed_size_binary_array_get_values_bytes(GArrowFixedSizeBinaryArray *array)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_binary_array =
    std::static_pointer_cast<arrow::FixedSizeBinaryArray>(arrow_array);
  auto value = arrow_binary_array->raw_values();
  return g_bytes_new_static(value,
                            arrow_binary_array->byte_width() * arrow_array->length());
}

G_DEFINE_TYPE(GArrowDecimal32Array,
              garrow_decimal32_array,
              GARROW_TYPE_FIXED_SIZE_BINARY_ARRAY)
static void
garrow_decimal32_array_init(GArrowDecimal32Array *object)
{
}

static void
garrow_decimal32_array_class_init(GArrowDecimal32ArrayClass *klass)
{
}

/**
 * garrow_decimal32_array_format_value:
 * @array: A #GArrowDecimal32Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The formatted @i-th value.
 *
 *   It should be freed with g_free() when no longer needed.
 *
 * Since: 19.0.0
 */
gchar *
garrow_decimal32_array_format_value(GArrowDecimal32Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal32_array =
    std::static_pointer_cast<arrow::Decimal32Array>(arrow_array);
  auto value = arrow_decimal32_array->FormatValue(i);
  return g_strndup(value.data(), value.size());
}

/**
 * garrow_decimal32_array_get_value:
 * @array: A #GArrowDecimal32Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 19.0.0
 */
GArrowDecimal32 *
garrow_decimal32_array_get_value(GArrowDecimal32Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal32_array =
    std::static_pointer_cast<arrow::Decimal32Array>(arrow_array);
  auto arrow_decimal32 =
    std::make_shared<arrow::Decimal32>(arrow_decimal32_array->GetValue(i));
  return garrow_decimal32_new_raw(&arrow_decimal32);
}

G_DEFINE_TYPE(GArrowDecimal64Array,
              garrow_decimal64_array,
              GARROW_TYPE_FIXED_SIZE_BINARY_ARRAY)
static void
garrow_decimal64_array_init(GArrowDecimal64Array *object)
{
}

static void
garrow_decimal64_array_class_init(GArrowDecimal64ArrayClass *klass)
{
}

/**
 * garrow_decimal64_array_format_value:
 * @array: A #GArrowDecimal64Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The formatted @i-th value.
 *
 *   It should be freed with g_free() when no longer needed.
 *
 * Since: 19.0.0
 */
gchar *
garrow_decimal64_array_format_value(GArrowDecimal64Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal64_array =
    std::static_pointer_cast<arrow::Decimal64Array>(arrow_array);
  auto value = arrow_decimal64_array->FormatValue(i);
  return g_strndup(value.data(), value.size());
}

/**
 * garrow_decimal64_array_get_value:
 * @array: A #GArrowDecimal64Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 19.0.0
 */
GArrowDecimal64 *
garrow_decimal64_array_get_value(GArrowDecimal64Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal64_array =
    std::static_pointer_cast<arrow::Decimal64Array>(arrow_array);
  auto arrow_decimal64 =
    std::make_shared<arrow::Decimal64>(arrow_decimal64_array->GetValue(i));
  return garrow_decimal64_new_raw(&arrow_decimal64);
}

G_DEFINE_TYPE(GArrowDecimal128Array,
              garrow_decimal128_array,
              GARROW_TYPE_FIXED_SIZE_BINARY_ARRAY)
static void
garrow_decimal128_array_init(GArrowDecimal128Array *object)
{
}

static void
garrow_decimal128_array_class_init(GArrowDecimal128ArrayClass *klass)
{
}

/**
 * garrow_decimal128_array_format_value:
 * @array: A #GArrowDecimal128Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The formatted @i-th value.
 *
 *   It should be freed with g_free() when no longer needed.
 *
 * Since: 0.10.0
 */
gchar *
garrow_decimal128_array_format_value(GArrowDecimal128Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal128_array =
    std::static_pointer_cast<arrow::Decimal128Array>(arrow_array);
  auto value = arrow_decimal128_array->FormatValue(i);
  return g_strndup(value.data(), value.size());
}

/**
 * garrow_decimal128_array_get_value:
 * @array: A #GArrowDecimal128Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 0.10.0
 */
GArrowDecimal128 *
garrow_decimal128_array_get_value(GArrowDecimal128Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal128_array =
    std::static_pointer_cast<arrow::Decimal128Array>(arrow_array);
  auto arrow_decimal128 =
    std::make_shared<arrow::Decimal128>(arrow_decimal128_array->GetValue(i));
  return garrow_decimal128_new_raw(&arrow_decimal128);
}

G_DEFINE_TYPE(GArrowDecimal256Array,
              garrow_decimal256_array,
              GARROW_TYPE_FIXED_SIZE_BINARY_ARRAY)
static void
garrow_decimal256_array_init(GArrowDecimal256Array *object)
{
}

static void
garrow_decimal256_array_class_init(GArrowDecimal256ArrayClass *klass)
{
}

/**
 * garrow_decimal256_array_format_value:
 * @array: A #GArrowDecimal256Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The formatted @i-th value.
 *
 *   It should be freed with g_free() when no longer needed.
 *
 * Since: 3.0.0
 */
gchar *
garrow_decimal256_array_format_value(GArrowDecimal256Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal256_array =
    std::static_pointer_cast<arrow::Decimal256Array>(arrow_array);
  auto value = arrow_decimal256_array->FormatValue(i);
  return g_strndup(value.data(), value.size());
}

/**
 * garrow_decimal256_array_get_value:
 * @array: A #GArrowDecimal256Array.
 * @i: The index of the target value.
 *
 * Returns: (transfer full): The @i-th value.
 *
 * Since: 3.0.0
 */
GArrowDecimal256 *
garrow_decimal256_array_get_value(GArrowDecimal256Array *array, gint64 i)
{
  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
  auto arrow_decimal256_array =
    std::static_pointer_cast<arrow::Decimal256Array>(arrow_array);
  auto arrow_decimal256 =
    std::make_shared<arrow::Decimal256>(arrow_decimal256_array->GetValue(i));
  return garrow_decimal256_new_raw(&arrow_decimal256);
}

typedef struct GArrowExtensionArrayPrivate_
{
  GArrowArray *storage;
} GArrowExtensionArrayPrivate;

enum {
  PROP_STORAGE = 1
};

G_DEFINE_TYPE_WITH_PRIVATE(GArrowExtensionArray,
                           garrow_extension_array,
                           GARROW_TYPE_ARRAY)

#define GARROW_EXTENSION_ARRAY_GET_PRIVATE(obj)                                          \
  static_cast<GArrowExtensionArrayPrivate *>(                                            \
    garrow_extension_array_get_instance_private(GARROW_EXTENSION_ARRAY(obj)))

static void
garrow_extension_array_dispose(GObject *object)
{
  auto priv = GARROW_EXTENSION_ARRAY_GET_PRIVATE(object);

  if (priv->storage) {
    g_object_unref(priv->storage);
    priv->storage = NULL;
  }

  G_OBJECT_CLASS(garrow_extension_array_parent_class)->dispose(object);
}

static void
garrow_extension_array_set_property(GObject *object,
                                    guint prop_id,
                                    const GValue *value,
                                    GParamSpec *pspec)
{
  auto priv = GARROW_EXTENSION_ARRAY_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_STORAGE:
    priv->storage = GARROW_ARRAY(g_value_dup_object(value));
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_extension_array_get_property(GObject *object,
                                    guint prop_id,
                                    GValue *value,
                                    GParamSpec *pspec)
{
  auto priv = GARROW_EXTENSION_ARRAY_GET_PRIVATE(object);

  switch (prop_id) {
  case PROP_STORAGE:
    g_value_set_object(value, priv->storage);
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}

static void
garrow_extension_array_init(GArrowExtensionArray *object)
{
}

static void
garrow_extension_array_class_init(GArrowExtensionArrayClass *klass)
{
  auto gobject_class = G_OBJECT_CLASS(klass);

  gobject_class->dispose = garrow_extension_array_dispose;
  gobject_class->set_property = garrow_extension_array_set_property;
  gobject_class->get_property = garrow_extension_array_get_property;

  GParamSpec *spec;
  spec = g_param_spec_object(
    "storage",
    "storage",
    "The storage array",
    GARROW_TYPE_ARRAY,
    static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property(gobject_class, PROP_STORAGE, spec);
}

/**
 * garrow_extension_array_get_storage:
 * @array: A #GArrowExtensionArray.
 *
 * Returns: (transfer full): The underlying storage of the array.
 *
 * Since: 3.0.0
 */
GArrowArray *
garrow_extension_array_get_storage(GArrowExtensionArray *array)
{
  auto priv = GARROW_EXTENSION_ARRAY_GET_PRIVATE(array);
  if (priv->storage) {
    g_object_ref(priv->storage);
    return priv->storage;
  }

  auto array_priv = GARROW_ARRAY_GET_PRIVATE(array);
  return garrow_array_new_raw(&(array_priv->array));
}

G_END_DECLS

arrow::EqualOptions *
garrow_equal_options_get_raw(GArrowEqualOptions *equal_options)
{
  auto priv = GARROW_EQUAL_OPTIONS_GET_PRIVATE(equal_options);
  return &(priv->options);
}

GArrowArrayStatistics *
garrow_array_statistics_new_raw(arrow::ArrayStatistics *arrow_statistics)
{
  return GARROW_ARRAY_STATISTICS(
    g_object_new(GARROW_TYPE_ARRAY_STATISTICS, "statistics", arrow_statistics, nullptr));
}

GArrowArray *
garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array)
{
  return garrow_array_new_raw(arrow_array, "array", arrow_array, NULL);
}

GArrowArray *
garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array,
                     const gchar *first_property_name,
                     ...)
{
  va_list args;
  va_start(args, first_property_name);
  auto array = garrow_array_new_raw_valist(arrow_array, first_property_name, args);
  va_end(args);
  return array;
}

GArrowArray *
garrow_array_new_raw_valist(std::shared_ptr<arrow::Array> *arrow_array,
                            const gchar *first_property_name,
                            va_list args)
{
  GType type;

  switch ((*arrow_array)->type_id()) {
  case arrow::Type::type::NA:
    type = GARROW_TYPE_NULL_ARRAY;
    break;
  case arrow::Type::type::BOOL:
    type = GARROW_TYPE_BOOLEAN_ARRAY;
    break;
  case arrow::Type::type::UINT8:
    type = GARROW_TYPE_UINT8_ARRAY;
    break;
  case arrow::Type::type::INT8:
    type = GARROW_TYPE_INT8_ARRAY;
    break;
  case arrow::Type::type::UINT16:
    type = GARROW_TYPE_UINT16_ARRAY;
    break;
  case arrow::Type::type::INT16:
    type = GARROW_TYPE_INT16_ARRAY;
    break;
  case arrow::Type::type::UINT32:
    type = GARROW_TYPE_UINT32_ARRAY;
    break;
  case arrow::Type::type::INT32:
    type = GARROW_TYPE_INT32_ARRAY;
    break;
  case arrow::Type::type::UINT64:
    type = GARROW_TYPE_UINT64_ARRAY;
    break;
  case arrow::Type::type::INT64:
    type = GARROW_TYPE_INT64_ARRAY;
    break;
  case arrow::Type::type::HALF_FLOAT:
    type = GARROW_TYPE_HALF_FLOAT_ARRAY;
    break;
  case arrow::Type::type::FLOAT:
    type = GARROW_TYPE_FLOAT_ARRAY;
    break;
  case arrow::Type::type::DOUBLE:
    type = GARROW_TYPE_DOUBLE_ARRAY;
    break;
  case arrow::Type::type::BINARY:
    type = GARROW_TYPE_BINARY_ARRAY;
    break;
  case arrow::Type::type::LARGE_BINARY:
    type = GARROW_TYPE_LARGE_BINARY_ARRAY;
    break;
  case arrow::Type::type::STRING:
    type = GARROW_TYPE_STRING_ARRAY;
    break;
  case arrow::Type::type::LARGE_STRING:
    type = GARROW_TYPE_LARGE_STRING_ARRAY;
    break;
  case arrow::Type::type::FIXED_SIZE_BINARY:
    type = GARROW_TYPE_FIXED_SIZE_BINARY_ARRAY;
    break;
  case arrow::Type::type::DATE32:
    type = GARROW_TYPE_DATE32_ARRAY;
    break;
  case arrow::Type::type::DATE64:
    type = GARROW_TYPE_DATE64_ARRAY;
    break;
  case arrow::Type::type::TIMESTAMP:
    type = GARROW_TYPE_TIMESTAMP_ARRAY;
    break;
  case arrow::Type::type::TIME32:
    type = GARROW_TYPE_TIME32_ARRAY;
    break;
  case arrow::Type::type::TIME64:
    type = GARROW_TYPE_TIME64_ARRAY;
    break;
  case arrow::Type::type::INTERVAL_MONTHS:
    type = GARROW_TYPE_MONTH_INTERVAL_ARRAY;
    break;
  case arrow::Type::type::INTERVAL_DAY_TIME:
    type = GARROW_TYPE_DAY_TIME_INTERVAL_ARRAY;
    break;
  case arrow::Type::type::INTERVAL_MONTH_DAY_NANO:
    type = GARROW_TYPE_MONTH_DAY_NANO_INTERVAL_ARRAY;
    break;
  case arrow::Type::type::DURATION:
    type = GARROW_TYPE_DURATION_ARRAY;
    break;
  case arrow::Type::type::LIST:
    type = GARROW_TYPE_LIST_ARRAY;
    break;
  case arrow::Type::type::LARGE_LIST:
    type = GARROW_TYPE_LARGE_LIST_ARRAY;
    break;
  case arrow::Type::type::FIXED_SIZE_LIST:
    type = GARROW_TYPE_FIXED_SIZE_LIST_ARRAY;
    break;
  case arrow::Type::type::STRUCT:
    type = GARROW_TYPE_STRUCT_ARRAY;
    break;
  case arrow::Type::type::MAP:
    type = GARROW_TYPE_MAP_ARRAY;
    break;
  case arrow::Type::type::SPARSE_UNION:
    type = GARROW_TYPE_SPARSE_UNION_ARRAY;
    break;
  case arrow::Type::type::DENSE_UNION:
    type = GARROW_TYPE_DENSE_UNION_ARRAY;
    break;
  case arrow::Type::type::DICTIONARY:
    type = GARROW_TYPE_DICTIONARY_ARRAY;
    break;
  case arrow::Type::type::DECIMAL32:
    type = GARROW_TYPE_DECIMAL32_ARRAY;
    break;
  case arrow::Type::type::DECIMAL64:
    type = GARROW_TYPE_DECIMAL64_ARRAY;
    break;
  case arrow::Type::type::DECIMAL128:
    type = GARROW_TYPE_DECIMAL128_ARRAY;
    break;
  case arrow::Type::type::DECIMAL256:
    type = GARROW_TYPE_DECIMAL256_ARRAY;
    break;
  case arrow::Type::type::EXTENSION:
    {
      auto arrow_data_type = (*arrow_array)->type();
      auto arrow_gextension_data_type =
        std::static_pointer_cast<garrow::GExtensionType>(arrow_data_type);
      if (arrow_gextension_data_type) {
        type = arrow_gextension_data_type->array_gtype();
      } else {
        type = GARROW_TYPE_EXTENSION_ARRAY;
      }
    }
    break;
  case arrow::Type::type::RUN_END_ENCODED:
    type = GARROW_TYPE_RUN_END_ENCODED_ARRAY;
    break;
  case arrow::Type::type::BINARY_VIEW:
    type = GARROW_TYPE_BINARY_VIEW_ARRAY;
    break;
  default:
    type = GARROW_TYPE_ARRAY;
    break;
  }
  return GARROW_ARRAY(g_object_new_valist(type, first_property_name, args));
}

GArrowExtensionArray *
garrow_extension_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array,
                               GArrowArray *storage)
{
  auto array =
    garrow_array_new_raw(arrow_array, "array", arrow_array, "storage", storage, NULL);
  return GARROW_EXTENSION_ARRAY(array);
}

std::shared_ptr<arrow::Array>
garrow_array_get_raw(GArrowArray *array)
{
  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
  return priv->array;
}
