/* * 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 #include #include G_BEGIN_DECLS /** * SECTION: ipc-options * @section_id: ipc-options-classes * @title: IPC options classes * @include: arrow-glib/arrow-glib.h * * #GArrowReadOptions provides options for reading data. * * #GArrowWriteOptions provides options for writing data. */ typedef struct GArrowReadOptionsPrivate_ { arrow::ipc::IpcReadOptions options; arrow::ipc::DictionaryMemo dictionary_memo; } GArrowReadOptionsPrivate; enum { PROP_READ_OPTIONS_MAX_RECURSION_DEPTH = 1, PROP_READ_OPTIONS_USE_THREADS, }; G_DEFINE_TYPE_WITH_PRIVATE(GArrowReadOptions, garrow_read_options, G_TYPE_OBJECT); #define GARROW_READ_OPTIONS_GET_PRIVATE(obj) \ static_cast( \ garrow_read_options_get_instance_private( \ GARROW_READ_OPTIONS(obj))) static void garrow_read_options_finalize(GObject *object) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(object); priv->options.~IpcReadOptions(); priv->dictionary_memo.~DictionaryMemo(); G_OBJECT_CLASS(garrow_read_options_parent_class)->finalize(object); } static void garrow_read_options_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(object); switch (prop_id) { case PROP_READ_OPTIONS_MAX_RECURSION_DEPTH: priv->options.max_recursion_depth = g_value_get_int(value); break; case PROP_READ_OPTIONS_USE_THREADS: priv->options.use_threads = g_value_get_boolean(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_read_options_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(object); switch (prop_id) { case PROP_READ_OPTIONS_MAX_RECURSION_DEPTH: g_value_set_int(value, priv->options.max_recursion_depth); break; case PROP_READ_OPTIONS_USE_THREADS: g_value_set_boolean(value, priv->options.use_threads); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_read_options_init(GArrowReadOptions *object) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(object); new(&priv->options) arrow::ipc::IpcReadOptions; priv->options = arrow::ipc::IpcReadOptions::Defaults(); new(&priv->dictionary_memo) arrow::ipc::DictionaryMemo; } static void garrow_read_options_class_init(GArrowReadOptionsClass *klass) { auto gobject_class = G_OBJECT_CLASS(klass); gobject_class->finalize = garrow_read_options_finalize; gobject_class->set_property = garrow_read_options_set_property; gobject_class->get_property = garrow_read_options_get_property; auto options = arrow::ipc::IpcReadOptions::Defaults(); GParamSpec *spec; /** * GArrowReadOptions:max-recursion-depth: * * The maximum permitted schema nesting depth. * * Since: 1.0.0 */ spec = g_param_spec_int("max-recursion-depth", "Max recursion depth", "The maximum permitted schema nesting depth", 0, arrow::ipc::kMaxNestingDepth, options.max_recursion_depth, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_READ_OPTIONS_MAX_RECURSION_DEPTH, spec); /** * GArrowReadOptions:use-threads: * * Whether to use the global CPU thread pool. * * Since: 1.0.0 */ spec = g_param_spec_boolean("use-threads", "Use threads", "Whether to use the global CPU thread pool", options.use_threads, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_READ_OPTIONS_USE_THREADS, spec); } /** * garrow_read_options_new: * * Returns: A newly created #GArrowReadOptions. * * Since: 1.0.0 */ GArrowReadOptions * garrow_read_options_new(void) { auto options = g_object_new(GARROW_TYPE_READ_OPTIONS, NULL); return GARROW_READ_OPTIONS(options); } /** * garrow_read_options_get_included_fields: * @options: A #GArrowReadOptions. * @n_fields: (out): The number of included fields. * * Returns: (array length=n_fields) (transfer full): * Top-level schema fields to include when deserializing * RecordBatch. If empty, return all deserialized fields. * * It should be freed with g_free() when no longer needed. * * Since: 1.0.0 */ int * garrow_read_options_get_included_fields(GArrowReadOptions *options, gsize *n_fields) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(options); if (priv->options.included_fields.empty()) { if (n_fields) { *n_fields = 0; } return NULL; } auto n = priv->options.included_fields.size(); auto fields = g_new(int, n); if (n_fields) { *n_fields = n; } for (size_t i = 0; i < n; ++i) { fields[i] = priv->options.included_fields[i]; } return fields; } /** * garrow_read_options_set_included_fields: * @options: A #GArrowReadOptions. * @fields: (array length=n_fields): Top-level schema fields to * include when deserializing RecordBatch. If empty, return all * deserialized fields. * @n_fields: The number of included fields. * * Since: 1.0.0 */ void garrow_read_options_set_included_fields(GArrowReadOptions *options, int *fields, gsize n_fields) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(options); priv->options.included_fields.resize(n_fields); for (gsize i = 0; i < n_fields; ++i) { priv->options.included_fields[i] = fields[i]; } } typedef struct GArrowWriteOptionsPrivate_ { arrow::ipc::IpcWriteOptions options; GArrowCodec *codec; } GArrowWriteOptionsPrivate; enum { PROP_WRITE_OPTIONS_ALLOW_64BIT = 1, PROP_WRITE_OPTIONS_MAX_RECURSION_DEPTH, PROP_WRITE_OPTIONS_ALIGNMENT, PROP_WRITE_OPTIONS_WRITE_LEGACY_IPC_FORMAT, PROP_WRITE_OPTIONS_CODEC, PROP_WRITE_OPTIONS_USE_THREADS, }; G_DEFINE_TYPE_WITH_PRIVATE(GArrowWriteOptions, garrow_write_options, G_TYPE_OBJECT); #define GARROW_WRITE_OPTIONS_GET_PRIVATE(obj) \ static_cast( \ garrow_write_options_get_instance_private( \ GARROW_WRITE_OPTIONS(obj))) static void garrow_write_options_dispose(GObject *object) { auto priv = GARROW_WRITE_OPTIONS_GET_PRIVATE(object); if (priv->codec) { g_object_unref(priv->codec); priv->codec = NULL; } G_OBJECT_CLASS(garrow_write_options_parent_class)->dispose(object); } static void garrow_write_options_finalize(GObject *object) { auto priv = GARROW_WRITE_OPTIONS_GET_PRIVATE(object); priv->options.~IpcWriteOptions(); G_OBJECT_CLASS(garrow_write_options_parent_class)->finalize(object); } static void garrow_write_options_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { auto priv = GARROW_WRITE_OPTIONS_GET_PRIVATE(object); switch (prop_id) { case PROP_WRITE_OPTIONS_ALLOW_64BIT: priv->options.allow_64bit = g_value_get_boolean(value); break; case PROP_WRITE_OPTIONS_MAX_RECURSION_DEPTH: priv->options.max_recursion_depth = g_value_get_int(value); break; case PROP_WRITE_OPTIONS_ALIGNMENT: priv->options.alignment = g_value_get_int(value); break; case PROP_WRITE_OPTIONS_WRITE_LEGACY_IPC_FORMAT: priv->options.write_legacy_ipc_format = g_value_get_boolean(value); break; case PROP_WRITE_OPTIONS_CODEC: if (priv->codec) { g_object_unref(priv->codec); } priv->codec = GARROW_CODEC(g_value_dup_object(value)); priv->options.codec = garrow_codec_get_raw(priv->codec); break; case PROP_WRITE_OPTIONS_USE_THREADS: priv->options.use_threads = g_value_get_boolean(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_write_options_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { auto priv = GARROW_WRITE_OPTIONS_GET_PRIVATE(object); switch (prop_id) { case PROP_WRITE_OPTIONS_ALLOW_64BIT: g_value_set_boolean(value, priv->options.allow_64bit); break; case PROP_WRITE_OPTIONS_MAX_RECURSION_DEPTH: g_value_set_int(value, priv->options.max_recursion_depth); break; case PROP_WRITE_OPTIONS_ALIGNMENT: g_value_set_int(value, priv->options.alignment); break; case PROP_WRITE_OPTIONS_WRITE_LEGACY_IPC_FORMAT: g_value_set_boolean(value, priv->options.write_legacy_ipc_format); break; case PROP_WRITE_OPTIONS_CODEC: g_value_set_object(value, priv->codec); break; case PROP_WRITE_OPTIONS_USE_THREADS: g_value_set_boolean(value, priv->options.use_threads); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_write_options_init(GArrowWriteOptions *object) { auto priv = GARROW_WRITE_OPTIONS_GET_PRIVATE(object); new(&priv->options) arrow::ipc::IpcWriteOptions; priv->options = arrow::ipc::IpcWriteOptions::Defaults(); if (priv->options.codec) { priv->codec = garrow_codec_new_raw(&(priv->options.codec)); } else { priv->codec = NULL; } } static void garrow_write_options_class_init(GArrowWriteOptionsClass *klass) { auto gobject_class = G_OBJECT_CLASS(klass); gobject_class->dispose = garrow_write_options_dispose; gobject_class->finalize = garrow_write_options_finalize; gobject_class->set_property = garrow_write_options_set_property; gobject_class->get_property = garrow_write_options_get_property; auto options = arrow::ipc::IpcWriteOptions::Defaults(); GParamSpec *spec; /** * GArrowWriteOptions:allow-64bit: * * Whether to allow field lengths that don't fit in a signed 32-bit * int. Some implementations may not be able to parse such streams. * * Since: 1.0.0 */ spec = g_param_spec_boolean("allow-64bit", "Allow 64bit", "Whether to allow signed 64-bit int " "for field length", options.allow_64bit, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_WRITE_OPTIONS_ALLOW_64BIT, spec); /** * GArrowWriteOptions:max-recursion-depth: * * The maximum permitted schema nesting depth. * * Since: 1.0.0 */ spec = g_param_spec_int("max-recursion-depth", "Max recursion depth", "The maximum permitted schema nesting depth", 0, arrow::ipc::kMaxNestingDepth, options.max_recursion_depth, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_WRITE_OPTIONS_MAX_RECURSION_DEPTH, spec); /** * GArrowWriteOptions:alignment: * * Write padding after memory buffers to this multiple of * bytes. Generally 8 or 64. * * Since: 1.0.0 */ spec = g_param_spec_int("alignment", "Alignment", "Write padding " "after memory buffers to this multiple of bytes", 0, G_MAXINT, options.alignment, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_WRITE_OPTIONS_ALIGNMENT, spec); /** * GArrowWriteOptions:write-legacy-ipc-format: * * Whether to write the pre-0.15.0 encapsulated IPC message format * consisting of a 4-byte prefix instead of 8 byte. * * Since: 1.0.0 */ spec = g_param_spec_boolean("write-legacy-ipc-format", "Write legacy IPC format", "Whether to write legacy IPC format", options.write_legacy_ipc_format, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_WRITE_OPTIONS_WRITE_LEGACY_IPC_FORMAT, spec); /** * GArrowWriteOptions:codec: * * Codec to use for compressing and decompressing record batch body * buffers. This is not part of the Arrow IPC protocol and only for * internal use (e.g. Feather files). * * May only be UNCOMPRESSED, LZ4_FRAME and ZSTD. * * Since: 2.0.0 */ spec = g_param_spec_object("codec", "Codec", "Codec to use for " "compressing record batch body buffers.", GARROW_TYPE_CODEC, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_WRITE_OPTIONS_CODEC, spec); /** * GArrowWriteOptions:use-threads: * * Whether to use the global CPU thread pool. * * Since: 1.0.0 */ spec = g_param_spec_boolean("use-threads", "Use threads", "Whether to use the global CPU thread pool", options.use_threads, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_WRITE_OPTIONS_USE_THREADS, spec); } /** * garrow_write_options_new: * * Returns: A newly created #GArrowWriteOptions. * * Since: 1.0.0 */ GArrowWriteOptions * garrow_write_options_new(void) { auto options = g_object_new(GARROW_TYPE_WRITE_OPTIONS, NULL); return GARROW_WRITE_OPTIONS(options); } G_END_DECLS arrow::ipc::IpcReadOptions * garrow_read_options_get_raw(GArrowReadOptions *options) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(options); return &(priv->options); } arrow::ipc::DictionaryMemo * garrow_read_options_get_dictionary_memo_raw(GArrowReadOptions *options) { auto priv = GARROW_READ_OPTIONS_GET_PRIVATE(options); return &(priv->dictionary_memo); } arrow::ipc::IpcWriteOptions * garrow_write_options_get_raw(GArrowWriteOptions *options) { auto priv = GARROW_WRITE_OPTIONS_GET_PRIVATE(options); return &(priv->options); }