1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <arrow-glib/arrow-glib.hpp>
21 
22 #include <arrow-flight-glib/common.hpp>
23 
24 G_BEGIN_DECLS
25 
26 /**
27  * SECTION: common
28  * @section_id: common
29  * @title: Classes both for client and server
30  * @include: arrow-flight-glib/arrow-flight-glib.h
31  *
32  * #GAFlightCriteria is a class for criteria.
33  *
34  * #GAFlightLocation is a class for location.
35  *
36  * #GAFlightDescriptor is a base class for all descriptor classes such
37  * as #GAFlightPathDescriptor.
38  *
39  * #GAFlightPathDescriptor is a class for path descriptor.
40  *
41  * #GAFlightCommandDescriptor is a class for command descriptor.
42  *
43  * #GAFlightTicket is a class for ticket.
44  *
45  * #GAFlightEndpoint is a class for endpoint.
46  *
47  * #GAFlightInfo is a class for flight information.
48  *
49  * #GAFlightStreamChunk is a class for a chunk in stream.
50  *
51  * #GAFlightRecordBatchReader is a class for reading record batches.
52  *
53  * Since: 5.0.0
54  */
55 
56 typedef struct GAFlightCriteriaPrivate_ {
57   arrow::flight::Criteria criteria;
58   GBytes *expression;
59 } GAFlightCriteriaPrivate;
60 
61 enum {
62   PROP_EXPRESSION = 1,
63 };
64 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightCriteria,gaflight_criteria,G_TYPE_OBJECT)65 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightCriteria,
66                            gaflight_criteria,
67                            G_TYPE_OBJECT)
68 
69 #define GAFLIGHT_CRITERIA_GET_PRIVATE(obj)            \
70   static_cast<GAFlightCriteriaPrivate *>(             \
71     gaflight_criteria_get_instance_private(           \
72       GAFLIGHT_CRITERIA(obj)))
73 
74 static void
75 gaflight_criteria_dispose(GObject *object)
76 {
77   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object);
78 
79   if (priv->expression) {
80     g_bytes_unref(priv->expression);
81     priv->expression = NULL;
82   }
83 
84   G_OBJECT_CLASS(gaflight_criteria_parent_class)->dispose(object);
85 }
86 
87 static void
gaflight_criteria_finalize(GObject * object)88 gaflight_criteria_finalize(GObject *object)
89 {
90   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object);
91 
92   priv->criteria.~Criteria();
93 
94   G_OBJECT_CLASS(gaflight_criteria_parent_class)->finalize(object);
95 }
96 
97 static void
gaflight_criteria_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)98 gaflight_criteria_set_property(GObject *object,
99                                guint prop_id,
100                                const GValue *value,
101                                GParamSpec *pspec)
102 {
103   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object);
104 
105   switch (prop_id) {
106   case PROP_EXPRESSION:
107     if (priv->expression) {
108       g_bytes_unref(priv->expression);
109     }
110     priv->expression = static_cast<GBytes *>(g_value_dup_boxed(value));
111     {
112       gsize size;
113       auto data = g_bytes_get_data(priv->expression, &size);
114       priv->criteria.expression.assign(static_cast<const char *>(data),
115                                        size);
116     }
117     break;
118   default:
119     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
120     break;
121   }
122 }
123 
124 static void
gaflight_criteria_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)125 gaflight_criteria_get_property(GObject *object,
126                                guint prop_id,
127                                GValue *value,
128                                GParamSpec *pspec)
129 {
130   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object);
131 
132   switch (prop_id) {
133   case PROP_EXPRESSION:
134     g_value_set_boxed(value, priv->expression);
135     break;
136   default:
137     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
138     break;
139   }
140 }
141 
142 static void
gaflight_criteria_init(GAFlightCriteria * object)143 gaflight_criteria_init(GAFlightCriteria *object)
144 {
145   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object);
146   new(&priv->criteria) arrow::flight::Criteria;
147 }
148 
149 static void
gaflight_criteria_class_init(GAFlightCriteriaClass * klass)150 gaflight_criteria_class_init(GAFlightCriteriaClass *klass)
151 {
152   auto gobject_class = G_OBJECT_CLASS(klass);
153 
154   gobject_class->dispose = gaflight_criteria_dispose;
155   gobject_class->finalize = gaflight_criteria_finalize;
156   gobject_class->set_property = gaflight_criteria_set_property;
157   gobject_class->get_property = gaflight_criteria_get_property;
158 
159   GParamSpec *spec;
160   /**
161    * GAFlightCriteria:expression:
162    *
163    * Opaque criteria expression, dependent on server implementation.
164    *
165    * Since: 5.0.0
166    */
167   spec = g_param_spec_boxed("expression",
168                             "Expression",
169                             "Opaque criteria expression, "
170                             "dependent on server implementation",
171                             G_TYPE_BYTES,
172                             static_cast<GParamFlags>(G_PARAM_READWRITE));
173   g_object_class_install_property(gobject_class, PROP_EXPRESSION, spec);
174 }
175 
176 /**
177  * gaflight_criteria_new:
178  * @expression: A #GBytes.
179  *
180  * Returns: The newly created #GAFlightCriteria, %NULL on error.
181  *
182  * Since: 5.0.0
183  */
184 GAFlightCriteria *
gaflight_criteria_new(GBytes * expression)185 gaflight_criteria_new(GBytes *expression)
186 {
187   return GAFLIGHT_CRITERIA(
188     g_object_new(GAFLIGHT_TYPE_CRITERIA,
189                  "expression", expression,
190                  NULL));
191 }
192 
193 
194 typedef struct GAFlightLocationPrivate_ {
195   arrow::flight::Location location;
196 } GAFlightLocationPrivate;
197 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightLocation,gaflight_location,G_TYPE_OBJECT)198 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightLocation,
199                            gaflight_location,
200                            G_TYPE_OBJECT)
201 
202 #define GAFLIGHT_LOCATION_GET_PRIVATE(obj)            \
203   static_cast<GAFlightLocationPrivate *>(             \
204     gaflight_location_get_instance_private(           \
205       GAFLIGHT_LOCATION(obj)))
206 
207 static void
208 gaflight_location_finalize(GObject *object)
209 {
210   auto priv = GAFLIGHT_LOCATION_GET_PRIVATE(object);
211 
212   priv->location.~Location();
213 
214   G_OBJECT_CLASS(gaflight_location_parent_class)->finalize(object);
215 }
216 
217 static void
gaflight_location_init(GAFlightLocation * object)218 gaflight_location_init(GAFlightLocation *object)
219 {
220   auto priv = GAFLIGHT_LOCATION_GET_PRIVATE(object);
221   new(&priv->location) arrow::flight::Location;
222 }
223 
224 static void
gaflight_location_class_init(GAFlightLocationClass * klass)225 gaflight_location_class_init(GAFlightLocationClass *klass)
226 {
227   auto gobject_class = G_OBJECT_CLASS(klass);
228 
229   gobject_class->finalize = gaflight_location_finalize;
230 }
231 
232 /**
233  * gaflight_location_new:
234  * @uri: An URI to specify location.
235  * @error: (nullable): Return location for a #GError or %NULL.
236  *
237  * Returns: (nullable): The newly created location, %NULL on error.
238  *
239  * Since: 5.0.0
240  */
241 GAFlightLocation *
gaflight_location_new(const gchar * uri,GError ** error)242 gaflight_location_new(const gchar *uri,
243                       GError **error)
244 {
245   auto location = GAFLIGHT_LOCATION(g_object_new(GAFLIGHT_TYPE_LOCATION, NULL));
246   auto flight_location = gaflight_location_get_raw(location);
247   if (garrow::check(error,
248                     arrow::flight::Location::Parse(uri, flight_location),
249                     "[flight-location][new]")) {
250     return location;
251   } else {
252     g_object_unref(location);
253     return NULL;
254   }
255 }
256 
257 /**
258  * gaflight_location_to_string:
259  * @location: A #GAFlightLocation.
260  *
261  * Returns: A representation of this URI as a string.
262  *
263  *   It should be freed with g_free() when no longer needed.
264  *
265  * Since: 5.0.0
266  */
267 gchar *
gaflight_location_to_string(GAFlightLocation * location)268 gaflight_location_to_string(GAFlightLocation *location)
269 {
270   const auto flight_location = gaflight_location_get_raw(location);
271   return g_strdup(flight_location->ToString().c_str());
272 }
273 
274 /**
275  * gaflight_location_get_scheme:
276  * @location: A #GAFlightLocation.
277  *
278  * Returns: The scheme of this URI.
279  *
280  *   It should be freed with g_free() when no longer needed.
281  *
282  * Since: 5.0.0
283  */
284 gchar *
gaflight_location_get_scheme(GAFlightLocation * location)285 gaflight_location_get_scheme(GAFlightLocation *location)
286 {
287   const auto flight_location = gaflight_location_get_raw(location);
288   return g_strdup(flight_location->scheme().c_str());
289 }
290 
291 /**
292  * gaflight_location_equal:
293  * @location: A #GAFlightLocation.
294  * @other_location: A #GAFlightLocation to be compared.
295  *
296  * Returns: %TRUE if both of them represents the same URI, %FALSE otherwise.
297  *
298  * Since: 5.0.0
299  */
300 gboolean
gaflight_location_equal(GAFlightLocation * location,GAFlightLocation * other_location)301 gaflight_location_equal(GAFlightLocation *location,
302                         GAFlightLocation *other_location)
303 {
304   const auto flight_location = gaflight_location_get_raw(location);
305   const auto flight_other_location = gaflight_location_get_raw(other_location);
306   return flight_location->Equals(*flight_other_location);
307 }
308 
309 
310 typedef struct GAFlightDescriptorPrivate_ {
311   arrow::flight::FlightDescriptor descriptor;
312 } GAFlightDescriptorPrivate;
313 
314 enum {
315   PROP_DESCRIPTOR = 1,
316 };
317 
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GAFlightDescriptor,gaflight_descriptor,G_TYPE_OBJECT)318 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GAFlightDescriptor,
319                                     gaflight_descriptor,
320                                     G_TYPE_OBJECT)
321 
322 #define GAFLIGHT_DESCRIPTOR_GET_PRIVATE(obj)            \
323   static_cast<GAFlightDescriptorPrivate *>(             \
324     gaflight_descriptor_get_instance_private(           \
325       GAFLIGHT_DESCRIPTOR(obj)))
326 
327 static void
328 gaflight_descriptor_finalize(GObject *object)
329 {
330   auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(object);
331 
332   priv->descriptor.~FlightDescriptor();
333 
334   G_OBJECT_CLASS(gaflight_descriptor_parent_class)->finalize(object);
335 }
336 
337 static void
gaflight_descriptor_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)338 gaflight_descriptor_set_property(GObject *object,
339                                  guint prop_id,
340                                  const GValue *value,
341                                  GParamSpec *pspec)
342 {
343   auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(object);
344 
345   switch (prop_id) {
346   case PROP_DESCRIPTOR:
347     priv->descriptor = *static_cast<arrow::flight::FlightDescriptor *>(
348       g_value_get_pointer(value));
349     break;
350   default:
351     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
352     break;
353   }
354 }
355 
356 static void
gaflight_descriptor_init(GAFlightDescriptor * object)357 gaflight_descriptor_init(GAFlightDescriptor *object)
358 {
359   auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(object);
360   new(&priv->descriptor) arrow::flight::FlightDescriptor;
361 }
362 
363 static void
gaflight_descriptor_class_init(GAFlightDescriptorClass * klass)364 gaflight_descriptor_class_init(GAFlightDescriptorClass *klass)
365 {
366   auto gobject_class = G_OBJECT_CLASS(klass);
367 
368   gobject_class->finalize = gaflight_descriptor_finalize;
369   gobject_class->set_property = gaflight_descriptor_set_property;
370 
371   GParamSpec *spec;
372   spec = g_param_spec_pointer("descriptor",
373                               "Descriptor",
374                               "The raw arrow::flight::FlightDescriptor",
375                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
376                                                        G_PARAM_CONSTRUCT_ONLY));
377   g_object_class_install_property(gobject_class, PROP_EXPRESSION, spec);
378 }
379 
380 /**
381  * gaflight_descriptor_to_string:
382  * @descriptor: A #GAFlightDescriptor.
383  *
384  * Returns: A descriptor as a string.
385  *
386  *   It should be freed with g_free() when no longer needed.
387  *
388  * Since: 5.0.0
389  */
390 gchar *
gaflight_descriptor_to_string(GAFlightDescriptor * descriptor)391 gaflight_descriptor_to_string(GAFlightDescriptor *descriptor)
392 {
393   auto flight_descriptor = gaflight_descriptor_get_raw(descriptor);
394   return g_strdup(flight_descriptor->ToString().c_str());
395 }
396 
397 /**
398  * gaflight_descriptor_equal:
399  * @descriptor: A #GAFlightDescriptor.
400  * @other_descriptor: A #GAFlightDescriptor to be compared.
401  *
402  * Returns: %TRUE if both of them represents the same descriptor,
403  *   %FALSE otherwise.
404  *
405  * Since: 5.0.0
406  */
407 gboolean
gaflight_descriptor_equal(GAFlightDescriptor * descriptor,GAFlightDescriptor * other_descriptor)408 gaflight_descriptor_equal(GAFlightDescriptor *descriptor,
409                           GAFlightDescriptor *other_descriptor)
410 {
411   const auto flight_descriptor =
412     gaflight_descriptor_get_raw(descriptor);
413   const auto flight_other_descriptor =
414     gaflight_descriptor_get_raw(other_descriptor);
415   return flight_descriptor->Equals(*flight_other_descriptor);
416 }
417 
418 
G_DEFINE_TYPE(GAFlightPathDescriptor,gaflight_path_descriptor,GAFLIGHT_TYPE_DESCRIPTOR)419 G_DEFINE_TYPE(GAFlightPathDescriptor,
420               gaflight_path_descriptor,
421               GAFLIGHT_TYPE_DESCRIPTOR)
422 
423 static void
424 gaflight_path_descriptor_init(GAFlightPathDescriptor *object)
425 {
426 }
427 
428 static void
gaflight_path_descriptor_class_init(GAFlightPathDescriptorClass * klass)429 gaflight_path_descriptor_class_init(GAFlightPathDescriptorClass *klass)
430 {
431 }
432 
433 /**
434  * gaflight_path_descriptor_new:
435  * @paths: (array length=n_paths): List of paths identifying a
436  *   particular dataset.
437  * @n_paths: The number of @paths.
438  *
439  * Returns: The newly created #GAFlightPathDescriptor.
440  *
441  * Since: 5.0.0
442  */
443 GAFlightPathDescriptor *
gaflight_path_descriptor_new(const gchar ** paths,gsize n_paths)444 gaflight_path_descriptor_new(const gchar **paths,
445                              gsize n_paths)
446 {
447   std::vector<std::string> flight_paths;
448   for (gsize i = 0; i < n_paths; i++) {
449     flight_paths.push_back(paths[i]);
450   }
451   auto flight_descriptor = arrow::flight::FlightDescriptor::Path(flight_paths);
452   return GAFLIGHT_PATH_DESCRIPTOR(
453     gaflight_descriptor_new_raw(&flight_descriptor));
454 }
455 
456 /**
457  * gaflight_path_descriptor_get_paths:
458  * @descriptor: A #GAFlightPathDescriptor.
459  *
460  * Returns: (nullable) (array zero-terminated=1) (transfer full):
461  *   The paths in this descriptor.
462  *
463  *   It must be freed with g_strfreev() when no longer needed.
464  *
465  * Since: 5.0.0
466  */
467 gchar **
gaflight_path_descriptor_get_paths(GAFlightPathDescriptor * descriptor)468 gaflight_path_descriptor_get_paths(GAFlightPathDescriptor *descriptor)
469 {
470   const auto flight_descriptor =
471     gaflight_descriptor_get_raw(GAFLIGHT_DESCRIPTOR(descriptor));
472   const auto &flight_paths = flight_descriptor->path;
473   if (flight_paths.empty()) {
474     return NULL;
475   } else {
476     auto paths = g_new(gchar *, flight_paths.size() + 1);
477     gsize i = 0;
478     for (const auto &flight_path : flight_paths) {
479       paths[i++] = g_strdup(flight_path.c_str());
480     }
481     paths[i] = NULL;
482     return paths;
483   }
484 }
485 
486 
G_DEFINE_TYPE(GAFlightCommandDescriptor,gaflight_command_descriptor,GAFLIGHT_TYPE_DESCRIPTOR)487 G_DEFINE_TYPE(GAFlightCommandDescriptor,
488               gaflight_command_descriptor,
489               GAFLIGHT_TYPE_DESCRIPTOR)
490 
491 static void
492 gaflight_command_descriptor_init(GAFlightCommandDescriptor *object)
493 {
494 }
495 
496 static void
gaflight_command_descriptor_class_init(GAFlightCommandDescriptorClass * klass)497 gaflight_command_descriptor_class_init(GAFlightCommandDescriptorClass *klass)
498 {
499 }
500 
501 /**
502  * gaflight_command_descriptor_new:
503  * @command: Opaque value used to express a command.
504  *
505  * Returns: The newly created #GAFlightCommandDescriptor.
506  *
507  * Since: 5.0.0
508  */
509 GAFlightCommandDescriptor *
gaflight_command_descriptor_new(const gchar * command)510 gaflight_command_descriptor_new(const gchar *command)
511 {
512   auto flight_descriptor = arrow::flight::FlightDescriptor::Command(command);
513   return GAFLIGHT_COMMAND_DESCRIPTOR(
514     gaflight_descriptor_new_raw(&flight_descriptor));
515 }
516 
517 /**
518  * gaflight_command_descriptor_get_command:
519  * @descriptor: A #GAFlightCommandDescriptor.
520  *
521  * Returns: The opaque value used to express a command.
522  *
523  *   It should be freed with g_free() when no longer needed.
524  *
525  * Since: 5.0.0
526  */
527 gchar *
gaflight_command_descriptor_get_command(GAFlightCommandDescriptor * descriptor)528 gaflight_command_descriptor_get_command(GAFlightCommandDescriptor *descriptor)
529 {
530   const auto flight_descriptor =
531     gaflight_descriptor_get_raw(GAFLIGHT_DESCRIPTOR(descriptor));
532   const auto &flight_command = flight_descriptor->cmd;
533   return g_strdup(flight_command.c_str());
534 }
535 
536 
537 typedef struct GAFlightTicketPrivate_ {
538   arrow::flight::Ticket ticket;
539   GBytes *data;
540 } GAFlightTicketPrivate;
541 
542 enum {
543   PROP_DATA = 1,
544 };
545 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightTicket,gaflight_ticket,G_TYPE_OBJECT)546 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightTicket,
547                            gaflight_ticket,
548                            G_TYPE_OBJECT)
549 
550 #define GAFLIGHT_TICKET_GET_PRIVATE(obj)            \
551   static_cast<GAFlightTicketPrivate *>(             \
552     gaflight_ticket_get_instance_private(           \
553       GAFLIGHT_TICKET(obj)))
554 
555 static void
556 gaflight_ticket_dispose(GObject *object)
557 {
558   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object);
559 
560   if (priv->data) {
561     g_bytes_unref(priv->data);
562     priv->data = NULL;
563   }
564 
565   G_OBJECT_CLASS(gaflight_ticket_parent_class)->dispose(object);
566 }
567 
568 static void
gaflight_ticket_finalize(GObject * object)569 gaflight_ticket_finalize(GObject *object)
570 {
571   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object);
572 
573   priv->ticket.~Ticket();
574 
575   G_OBJECT_CLASS(gaflight_ticket_parent_class)->finalize(object);
576 }
577 
578 static void
gaflight_ticket_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)579 gaflight_ticket_set_property(GObject *object,
580                              guint prop_id,
581                              const GValue *value,
582                              GParamSpec *pspec)
583 {
584   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object);
585 
586   switch (prop_id) {
587   case PROP_DATA:
588     if (priv->data) {
589       g_bytes_unref(priv->data);
590     }
591     priv->data = static_cast<GBytes *>(g_value_dup_boxed(value));
592     {
593       gsize size;
594       auto data = g_bytes_get_data(priv->data, &size);
595       priv->ticket.ticket.assign(static_cast<const char *>(data),
596                                  size);
597     }
598     break;
599   default:
600     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
601     break;
602   }
603 }
604 
605 static void
gaflight_ticket_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)606 gaflight_ticket_get_property(GObject *object,
607                              guint prop_id,
608                              GValue *value,
609                              GParamSpec *pspec)
610 {
611   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object);
612 
613   switch (prop_id) {
614   case PROP_DATA:
615     g_value_set_boxed(value, priv->data);
616     break;
617   default:
618     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
619     break;
620   }
621 }
622 
623 static void
gaflight_ticket_init(GAFlightTicket * object)624 gaflight_ticket_init(GAFlightTicket *object)
625 {
626   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object);
627   new(&priv->ticket) arrow::flight::Ticket;
628 }
629 
630 static void
gaflight_ticket_class_init(GAFlightTicketClass * klass)631 gaflight_ticket_class_init(GAFlightTicketClass *klass)
632 {
633   auto gobject_class = G_OBJECT_CLASS(klass);
634 
635   gobject_class->dispose = gaflight_ticket_dispose;
636   gobject_class->finalize = gaflight_ticket_finalize;
637   gobject_class->set_property = gaflight_ticket_set_property;
638   gobject_class->get_property = gaflight_ticket_get_property;
639 
640   GParamSpec *spec;
641   /**
642    * GAFlightTicket:data:
643    *
644    * Opaque identifier or credential to use when requesting a data
645    * stream with the DoGet RPC.
646    *
647    * Since: 5.0.0
648    */
649   spec = g_param_spec_boxed("data",
650                             "Data",
651                             "Opaque identifier or credential to use "
652                             "when requesting a data stream with the DoGet RPC",
653                             G_TYPE_BYTES,
654                             static_cast<GParamFlags>(G_PARAM_READWRITE));
655   g_object_class_install_property(gobject_class, PROP_DATA, spec);
656 }
657 
658 /**
659  * gaflight_ticket_new:
660  * @data: A #GBytes.
661  *
662  * Returns: The newly created #GAFlightTicket, %NULL on error.
663  *
664  * Since: 5.0.0
665  */
666 GAFlightTicket *
gaflight_ticket_new(GBytes * data)667 gaflight_ticket_new(GBytes *data)
668 {
669   return GAFLIGHT_TICKET(
670     g_object_new(GAFLIGHT_TYPE_TICKET,
671                  "data", data,
672                  NULL));
673 }
674 
675 /**
676  * gaflight_ticket_equal:
677  * @ticket: A #GAFlightTicket.
678  * @other_ticket: A #GAFlightTicket to be compared.
679  *
680  * Returns: %TRUE if both of them represents the same ticket, %FALSE otherwise.
681  *
682  * Since: 5.0.0
683  */
684 gboolean
gaflight_ticket_equal(GAFlightTicket * ticket,GAFlightTicket * other_ticket)685 gaflight_ticket_equal(GAFlightTicket *ticket,
686                       GAFlightTicket *other_ticket)
687 {
688   const auto flight_ticket = gaflight_ticket_get_raw(ticket);
689   const auto flight_other_ticket = gaflight_ticket_get_raw(other_ticket);
690   return flight_ticket->Equals(*flight_other_ticket);
691 }
692 
693 
694 typedef struct GAFlightEndpointPrivate_ {
695   arrow::flight::FlightEndpoint endpoint;
696   GAFlightTicket *ticket;
697   GList *locations;
698 } GAFlightEndpointPrivate;
699 
700 enum {
701   PROP_TICKET = 1,
702 };
703 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightEndpoint,gaflight_endpoint,G_TYPE_OBJECT)704 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightEndpoint,
705                            gaflight_endpoint,
706                            G_TYPE_OBJECT)
707 
708 #define GAFLIGHT_ENDPOINT_GET_PRIVATE(obj)            \
709   static_cast<GAFlightEndpointPrivate *>(             \
710     gaflight_endpoint_get_instance_private(           \
711       GAFLIGHT_ENDPOINT(obj)))
712 
713 static void
714 gaflight_endpoint_dispose(GObject *object)
715 {
716   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object);
717 
718   if (priv->ticket) {
719     g_object_unref(priv->ticket);
720     priv->ticket = NULL;
721   }
722 
723   if (priv->locations) {
724     g_list_free_full(priv->locations, g_object_unref);
725     priv->locations = NULL;
726   }
727 
728   G_OBJECT_CLASS(gaflight_endpoint_parent_class)->dispose(object);
729 }
730 
731 static void
gaflight_endpoint_finalize(GObject * object)732 gaflight_endpoint_finalize(GObject *object)
733 {
734   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object);
735 
736   priv->endpoint.~FlightEndpoint();
737 
738   G_OBJECT_CLASS(gaflight_endpoint_parent_class)->finalize(object);
739 }
740 
741 static void
gaflight_endpoint_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)742 gaflight_endpoint_get_property(GObject *object,
743                                guint prop_id,
744                                GValue *value,
745                                GParamSpec *pspec)
746 {
747   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object);
748 
749   switch (prop_id) {
750   case PROP_TICKET:
751     g_value_set_object(value, priv->ticket);
752     break;
753   default:
754     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
755     break;
756   }
757 }
758 
759 static void
gaflight_endpoint_init(GAFlightEndpoint * object)760 gaflight_endpoint_init(GAFlightEndpoint *object)
761 {
762   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object);
763   new(&priv->endpoint) arrow::flight::FlightEndpoint;
764 }
765 
766 static void
gaflight_endpoint_class_init(GAFlightEndpointClass * klass)767 gaflight_endpoint_class_init(GAFlightEndpointClass *klass)
768 {
769   auto gobject_class = G_OBJECT_CLASS(klass);
770 
771   gobject_class->dispose = gaflight_endpoint_dispose;
772   gobject_class->finalize = gaflight_endpoint_finalize;
773   gobject_class->get_property = gaflight_endpoint_get_property;
774 
775   GParamSpec *spec;
776   /**
777    * GAFlightEndpoint:ticket:
778    *
779    * Opaque ticket identify; use with DoGet RPC.
780    *
781    * Since: 5.0.0
782    */
783   spec = g_param_spec_object("ticket",
784                              "Ticket",
785                              "Opaque ticket identify; use with DoGet RPC",
786                              GAFLIGHT_TYPE_TICKET,
787                              static_cast<GParamFlags>(G_PARAM_READABLE));
788   g_object_class_install_property(gobject_class, PROP_TICKET, spec);
789 }
790 
791 /**
792  * gaflight_endpoint_new:
793  * @ticket: A #GAFlightTicket.
794  * @locations: (element-type GAFlightLocation): A list of #GAFlightLocation.
795  *
796  * Returns: The newly created #GAFlightEndpoint, %NULL on error.
797  *
798  * Since: 5.0.0
799  */
800 GAFlightEndpoint *
gaflight_endpoint_new(GAFlightTicket * ticket,GList * locations)801 gaflight_endpoint_new(GAFlightTicket *ticket,
802                       GList *locations)
803 {
804   auto endpoint = gaflight_endpoint_new_raw(nullptr, ticket);
805   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(endpoint);
806   for (auto node = locations; node; node = node->next) {
807     auto location = GAFLIGHT_LOCATION(node->data);
808     priv->endpoint.locations.push_back(*gaflight_location_get_raw(location));
809   }
810   return endpoint;
811 }
812 
813 /**
814  * gaflight_endpoint_equal:
815  * @endpoint: A #GAFlightEndpoint.
816  * @other_endpoint: A #GAFlightEndpoint to be compared.
817  *
818  * Returns: %TRUE if both of them represents the same endpoint,
819  *   %FALSE otherwise.
820  *
821  * Since: 5.0.0
822  */
823 gboolean
gaflight_endpoint_equal(GAFlightEndpoint * endpoint,GAFlightEndpoint * other_endpoint)824 gaflight_endpoint_equal(GAFlightEndpoint *endpoint,
825                         GAFlightEndpoint *other_endpoint)
826 {
827   const auto flight_endpoint = gaflight_endpoint_get_raw(endpoint);
828   const auto flight_other_endpoint = gaflight_endpoint_get_raw(other_endpoint);
829   return flight_endpoint->Equals(*flight_other_endpoint);
830 }
831 
832 /**
833  * gaflight_endpoint_get_locations:
834  * @endpoint: A #GAFlightEndpoint.
835  *
836  * Returns: (nullable) (element-type GAFlightLocation) (transfer full):
837  *   The locations in this endpoint.
838  *
839  *   It must be freed with g_list_free() and g_object_unref() when no
840  *   longer needed. You can use `g_list_free_full(locations,
841  *   g_object_unref)`.
842  *
843  * Since: 5.0.0
844  */
845 GList *
gaflight_endpoint_get_locations(GAFlightEndpoint * endpoint)846 gaflight_endpoint_get_locations(GAFlightEndpoint *endpoint)
847 {
848   const auto flight_endpoint = gaflight_endpoint_get_raw(endpoint);
849   GList *locations = NULL;
850   for (const auto &flight_location : flight_endpoint->locations) {
851     auto location = gaflight_location_new(flight_location.ToString().c_str(),
852                                           nullptr);
853     locations = g_list_prepend(locations, location);
854   }
855   return g_list_reverse(locations);
856 }
857 
858 
859 typedef struct GAFlightInfoPrivate_ {
860   arrow::flight::FlightInfo info;
861 } GAFlightInfoPrivate;
862 
863 enum {
864   PROP_INFO = 1,
865 };
866 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightInfo,gaflight_info,G_TYPE_OBJECT)867 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightInfo,
868                            gaflight_info,
869                            G_TYPE_OBJECT)
870 
871 #define GAFLIGHT_INFO_GET_PRIVATE(obj)            \
872   static_cast<GAFlightInfoPrivate *>(             \
873     gaflight_info_get_instance_private(           \
874       GAFLIGHT_INFO(obj)))
875 
876 static void
877 gaflight_info_finalize(GObject *object)
878 {
879   auto priv = GAFLIGHT_INFO_GET_PRIVATE(object);
880 
881   priv->info.~FlightInfo();
882 
883   G_OBJECT_CLASS(gaflight_info_parent_class)->finalize(object);
884 }
885 
886 static void
gaflight_info_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)887 gaflight_info_set_property(GObject *object,
888                            guint prop_id,
889                            const GValue *value,
890                            GParamSpec *pspec)
891 {
892   auto priv = GAFLIGHT_INFO_GET_PRIVATE(object);
893 
894   switch (prop_id) {
895   case PROP_INFO:
896     {
897       auto info =
898         static_cast<arrow::flight::FlightInfo *>(g_value_get_pointer(value));
899       new(&(priv->info)) arrow::flight::FlightInfo(*info);
900     }
901     break;
902   default:
903     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
904     break;
905   }
906 }
907 
908 static void
gaflight_info_init(GAFlightInfo * object)909 gaflight_info_init(GAFlightInfo *object)
910 {
911 }
912 
913 static void
gaflight_info_class_init(GAFlightInfoClass * klass)914 gaflight_info_class_init(GAFlightInfoClass *klass)
915 {
916   auto gobject_class = G_OBJECT_CLASS(klass);
917 
918   gobject_class->finalize = gaflight_info_finalize;
919   gobject_class->set_property = gaflight_info_set_property;
920 
921   GParamSpec *spec;
922   spec = g_param_spec_pointer("info",
923                               "Info",
924                               "The raw arrow::flight::FlightInfo *",
925                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
926                                                        G_PARAM_CONSTRUCT_ONLY));
927   g_object_class_install_property(gobject_class, PROP_INFO, spec);
928 }
929 
930 /**
931  * gaflight_info_new:
932  * @schema: A #GArrowSchema.
933  * @descriptor: A #GAFlightDescriptor.
934  * @endpoints: (element-type GAFlightEndpoint): A list of #GAFlightEndpoint.
935  * @total_records: The number of total records.
936  * @total_bytes: The number of total bytes.
937  * @error: (nullable): Return location for a #GError or %NULL.
938  *
939  * Returns: (nullable): The newly created #GAFlightInfo, %NULL on error.
940  *
941  * Since: 5.0.0
942  */
943 GAFlightInfo *
gaflight_info_new(GArrowSchema * schema,GAFlightDescriptor * descriptor,GList * endpoints,gint64 total_records,gint64 total_bytes,GError ** error)944 gaflight_info_new(GArrowSchema *schema,
945                   GAFlightDescriptor *descriptor,
946                   GList *endpoints,
947                   gint64 total_records,
948                   gint64 total_bytes,
949                   GError **error)
950 {
951   auto arrow_schema = garrow_schema_get_raw(schema);
952   auto flight_descriptor = gaflight_descriptor_get_raw(descriptor);
953   std::vector<arrow::flight::FlightEndpoint> flight_endpoints;
954   for (auto node = endpoints; node; node = node->next) {
955     auto endpoint = GAFLIGHT_ENDPOINT(node->data);
956     flight_endpoints.push_back(*gaflight_endpoint_get_raw(endpoint));
957   }
958   auto flight_info_result =
959     arrow::flight::FlightInfo::Make(*arrow_schema,
960                                     *flight_descriptor,
961                                     flight_endpoints,
962                                     total_records,
963                                     total_bytes);
964   if (!garrow::check(error,
965                      flight_info_result,
966                      "[flight-info][new]")) {
967     return NULL;
968   }
969   return gaflight_info_new_raw(&(*flight_info_result));
970 }
971 
972 /**
973  * gaflight_info_equal:
974  * @info: A #GAFlightInfo.
975  * @other_info: A #GAFlightInfo to be compared.
976  *
977  * Returns: %TRUE if both of them represents the same information,
978  *   %FALSE otherwise.
979  *
980  * Since: 5.0.0
981  */
982 gboolean
gaflight_info_equal(GAFlightInfo * info,GAFlightInfo * other_info)983 gaflight_info_equal(GAFlightInfo *info,
984                     GAFlightInfo *other_info)
985 {
986   const auto flight_info = gaflight_info_get_raw(info);
987   const auto flight_other_info = gaflight_info_get_raw(other_info);
988   return
989     (flight_info->serialized_schema() ==
990      flight_other_info->serialized_schema()) &&
991     (flight_info->descriptor() ==
992      flight_other_info->descriptor()) &&
993     (flight_info->endpoints() ==
994      flight_other_info->endpoints()) &&
995     (flight_info->total_records() ==
996      flight_other_info->total_records()) &&
997     (flight_info->total_bytes() ==
998      flight_other_info->total_bytes());
999 }
1000 
1001 /**
1002  * gaflight_info_get_schema:
1003  * @info: A #GAFlightInfo.
1004  * @options: (nullable): A #GArrowReadOptions.
1005  * @error: (nullable): Return location for a #GError or %NULL.
1006  *
1007  * Returns: (transfer full): Deserialized #GArrowSchema, %NULL on error.
1008  *
1009  * Since: 5.0.0
1010  */
1011 GArrowSchema *
gaflight_info_get_schema(GAFlightInfo * info,GArrowReadOptions * options,GError ** error)1012 gaflight_info_get_schema(GAFlightInfo *info,
1013                          GArrowReadOptions *options,
1014                          GError **error)
1015 {
1016   const auto flight_info = gaflight_info_get_raw(info);
1017   arrow::Status status;
1018   std::shared_ptr<arrow::Schema> arrow_schema;
1019   if (options) {
1020     auto arrow_memo = garrow_read_options_get_dictionary_memo_raw(options);
1021     status = flight_info->GetSchema(arrow_memo, &arrow_schema);
1022   } else {
1023     arrow::ipc::DictionaryMemo arrow_memo;
1024     status = flight_info->GetSchema(&arrow_memo, &arrow_schema);
1025   }
1026   if (garrow::check(error, status, "[flight-info][get-schema]")) {
1027     return garrow_schema_new_raw(&arrow_schema);
1028   } else {
1029     return NULL;
1030   }
1031 }
1032 
1033 /**
1034  * gaflight_info_get_descriptor:
1035  * @info: A #GAFlightInfo.
1036  *
1037  * Returns: (transfer full): The #GAFlightDescriptor of the information.
1038  *
1039  * Since: 5.0.0
1040  */
1041 GAFlightDescriptor *
gaflight_info_get_descriptor(GAFlightInfo * info)1042 gaflight_info_get_descriptor(GAFlightInfo *info)
1043 {
1044   const auto flight_info = gaflight_info_get_raw(info);
1045   return gaflight_descriptor_new_raw(&(flight_info->descriptor()));
1046 }
1047 
1048 /**
1049  * gaflight_info_get_endpoints:
1050  * @info: A #GAFlightInfo.
1051  *
1052  * Returns: (element-type GAFlightEndpoint) (transfer full):
1053  *   The list of #GAFlightEndpoint of the information.
1054  *
1055  * Since: 5.0.0
1056  */
1057 GList *
gaflight_info_get_endpoints(GAFlightInfo * info)1058 gaflight_info_get_endpoints(GAFlightInfo *info)
1059 {
1060   const auto flight_info = gaflight_info_get_raw(info);
1061   GList *endpoints = NULL;
1062   for (const auto &flight_endpoint : flight_info->endpoints()) {
1063     auto endpoint = gaflight_endpoint_new_raw(&flight_endpoint, nullptr);
1064     endpoints = g_list_prepend(endpoints, endpoint);
1065   }
1066   return g_list_reverse(endpoints);
1067 }
1068 
1069 /**
1070  * gaflight_info_get_total_records:
1071  * @info: A #GAFlightInfo.
1072  *
1073  * Returns: The number of total records of the information.
1074  *
1075  * Since: 5.0.0
1076  */
1077 gint64
gaflight_info_get_total_records(GAFlightInfo * info)1078 gaflight_info_get_total_records(GAFlightInfo *info)
1079 {
1080   const auto flight_info = gaflight_info_get_raw(info);
1081   return flight_info->total_records();
1082 }
1083 
1084 /**
1085  * gaflight_info_get_total_bytes:
1086  * @info: A #GAFlightInfo.
1087  *
1088  * Returns: The number of total bytes of the information.
1089  *
1090  * Since: 5.0.0
1091  */
1092 gint64
gaflight_info_get_total_bytes(GAFlightInfo * info)1093 gaflight_info_get_total_bytes(GAFlightInfo *info)
1094 {
1095   const auto flight_info = gaflight_info_get_raw(info);
1096   return flight_info->total_bytes();
1097 }
1098 
1099 typedef struct GAFlightStreamChunkPrivate_ {
1100   arrow::flight::FlightStreamChunk chunk;
1101 } GAFlightStreamChunkPrivate;
1102 
1103 enum {
1104   PROP_CHUNK = 1,
1105 };
1106 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightStreamChunk,gaflight_stream_chunk,G_TYPE_OBJECT)1107 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightStreamChunk,
1108                            gaflight_stream_chunk,
1109                            G_TYPE_OBJECT)
1110 
1111 #define GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(obj)            \
1112   static_cast<GAFlightStreamChunkPrivate *>(             \
1113     gaflight_stream_chunk_get_instance_private(           \
1114       GAFLIGHT_STREAM_CHUNK(obj)))
1115 
1116 static void
1117 gaflight_stream_chunk_finalize(GObject *object)
1118 {
1119   auto priv = GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(object);
1120 
1121   priv->chunk.~FlightStreamChunk();
1122 
1123   G_OBJECT_CLASS(gaflight_info_parent_class)->finalize(object);
1124 }
1125 
1126 static void
gaflight_stream_chunk_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1127 gaflight_stream_chunk_set_property(GObject *object,
1128                                    guint prop_id,
1129                                    const GValue *value,
1130                                    GParamSpec *pspec)
1131 {
1132   auto priv = GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(object);
1133 
1134   switch (prop_id) {
1135   case PROP_CHUNK:
1136     priv->chunk =
1137       *static_cast<arrow::flight::FlightStreamChunk *>(
1138         g_value_get_pointer(value));
1139     break;
1140   default:
1141     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1142     break;
1143   }
1144 }
1145 
1146 static void
gaflight_stream_chunk_init(GAFlightStreamChunk * object)1147 gaflight_stream_chunk_init(GAFlightStreamChunk *object)
1148 {
1149 }
1150 
1151 static void
gaflight_stream_chunk_class_init(GAFlightStreamChunkClass * klass)1152 gaflight_stream_chunk_class_init(GAFlightStreamChunkClass *klass)
1153 {
1154   auto gobject_class = G_OBJECT_CLASS(klass);
1155 
1156   gobject_class->finalize = gaflight_stream_chunk_finalize;
1157   gobject_class->set_property = gaflight_stream_chunk_set_property;
1158 
1159   GParamSpec *spec;
1160   spec = g_param_spec_pointer("chunk",
1161                               "Stream chunk",
1162                               "The raw arrow::flight::FlightStreamChunk *",
1163                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
1164                                                        G_PARAM_CONSTRUCT_ONLY));
1165   g_object_class_install_property(gobject_class, PROP_CHUNK, spec);
1166 }
1167 
1168 /**
1169  * gaflight_stream_chunk_get_data:
1170  * @chunk: A #GAFlightStreamChunk.
1171  *
1172  * Returns: (transfer full): The data of the chunk.
1173  *
1174  * Since: 6.0.0
1175  */
1176 GArrowRecordBatch *
gaflight_stream_chunk_get_data(GAFlightStreamChunk * chunk)1177 gaflight_stream_chunk_get_data(GAFlightStreamChunk *chunk)
1178 {
1179   auto flight_chunk = gaflight_stream_chunk_get_raw(chunk);
1180   return garrow_record_batch_new_raw(&(flight_chunk->data));
1181 }
1182 
1183 /**
1184  * gaflight_stream_chunk_get_metadata:
1185  * @chunk: A #GAFlightStreamChunk.
1186  *
1187  * Returns: (nullable) (transfer full): The metadata of the chunk.
1188  *
1189  *   The metadata may be NULL.
1190  *
1191  * Since: 6.0.0
1192  */
1193 GArrowBuffer *
gaflight_stream_chunk_get_metadata(GAFlightStreamChunk * chunk)1194 gaflight_stream_chunk_get_metadata(GAFlightStreamChunk *chunk)
1195 {
1196   auto flight_chunk = gaflight_stream_chunk_get_raw(chunk);
1197   if (flight_chunk->app_metadata) {
1198     return garrow_buffer_new_raw(&(flight_chunk->app_metadata));
1199   } else {
1200     return NULL;
1201   }
1202 }
1203 
1204 
1205 typedef struct GAFlightRecordBatchReaderPrivate_ {
1206   arrow::flight::MetadataRecordBatchReader *reader;
1207 } GAFlightRecordBatchReaderPrivate;
1208 
1209 enum {
1210   PROP_READER = 1,
1211 };
1212 
G_DEFINE_TYPE_WITH_PRIVATE(GAFlightRecordBatchReader,gaflight_record_batch_reader,G_TYPE_OBJECT)1213 G_DEFINE_TYPE_WITH_PRIVATE(GAFlightRecordBatchReader,
1214                            gaflight_record_batch_reader,
1215                            G_TYPE_OBJECT)
1216 
1217 #define GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(obj)            \
1218   static_cast<GAFlightRecordBatchReaderPrivate *>(               \
1219     gaflight_record_batch_reader_get_instance_private(           \
1220       GAFLIGHT_RECORD_BATCH_READER(obj)))
1221 
1222 static void
1223 gaflight_record_batch_reader_finalize(GObject *object)
1224 {
1225   auto priv = GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(object);
1226 
1227   delete priv->reader;
1228 
1229   G_OBJECT_CLASS(gaflight_info_parent_class)->finalize(object);
1230 }
1231 
1232 static void
gaflight_record_batch_reader_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1233 gaflight_record_batch_reader_set_property(GObject *object,
1234                                           guint prop_id,
1235                                           const GValue *value,
1236                                           GParamSpec *pspec)
1237 {
1238   auto priv = GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(object);
1239 
1240   switch (prop_id) {
1241   case PROP_READER:
1242     priv->reader =
1243       static_cast<arrow::flight::MetadataRecordBatchReader *>(
1244         g_value_get_pointer(value));
1245     break;
1246   default:
1247     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1248     break;
1249   }
1250 }
1251 
1252 static void
gaflight_record_batch_reader_init(GAFlightRecordBatchReader * object)1253 gaflight_record_batch_reader_init(GAFlightRecordBatchReader *object)
1254 {
1255 }
1256 
1257 static void
gaflight_record_batch_reader_class_init(GAFlightRecordBatchReaderClass * klass)1258 gaflight_record_batch_reader_class_init(GAFlightRecordBatchReaderClass *klass)
1259 {
1260   auto gobject_class = G_OBJECT_CLASS(klass);
1261 
1262   gobject_class->finalize = gaflight_record_batch_reader_finalize;
1263   gobject_class->set_property = gaflight_record_batch_reader_set_property;
1264 
1265   GParamSpec *spec;
1266   spec = g_param_spec_pointer("reader",
1267                               "Reader",
1268                               "The raw arrow::flight::MetadataRecordBatchReader *",
1269                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
1270                                                        G_PARAM_CONSTRUCT_ONLY));
1271   g_object_class_install_property(gobject_class, PROP_READER, spec);
1272 }
1273 
1274 /**
1275  * gaflight_record_batch_reader_read_next:
1276  * @reader: A #GAFlightRecordBatchReader.
1277  * @error: (nullable): Return location for a #GError or %NULL.
1278  *
1279  * Returns: (transfer full): The next chunk on success, %NULL on end
1280  *   of stream, %NULL on error.
1281  *
1282  * Since: 6.0.0
1283  */
1284 GAFlightStreamChunk *
gaflight_record_batch_reader_read_next(GAFlightRecordBatchReader * reader,GError ** error)1285 gaflight_record_batch_reader_read_next(GAFlightRecordBatchReader *reader,
1286                                        GError **error)
1287 {
1288   auto flight_reader = gaflight_record_batch_reader_get_raw(reader);
1289   arrow::flight::FlightStreamChunk flight_chunk;
1290   auto status = flight_reader->Next(&flight_chunk);
1291   if (garrow::check(error, status, "[flight-record-batch-reader][read-next]")) {
1292     if (flight_chunk.data) {
1293       return gaflight_stream_chunk_new_raw(&flight_chunk);
1294     } else {
1295       return NULL;
1296     }
1297   } else {
1298     return NULL;
1299   }
1300 }
1301 
1302 /**
1303  * gaflight_record_batch_reader_read_all:
1304  * @reader: A #GAFlightRecordBatchReader.
1305  * @error: (nullable): Return location for a #GError or %NULL.
1306  *
1307  * Returns: (transfer full): The all data on success, %NULL on error.
1308  *
1309  * Since: 6.0.0
1310  */
1311 GArrowTable *
gaflight_record_batch_reader_read_all(GAFlightRecordBatchReader * reader,GError ** error)1312 gaflight_record_batch_reader_read_all(GAFlightRecordBatchReader *reader,
1313                                       GError **error)
1314 {
1315   auto flight_reader = gaflight_record_batch_reader_get_raw(reader);
1316   std::shared_ptr<arrow::Table> arrow_table;
1317   auto status = flight_reader->ReadAll(&arrow_table);
1318   if (garrow::check(error, status, "[flight-record-batch-reader][read-all]")) {
1319     return garrow_table_new_raw(&arrow_table);
1320   } else {
1321     return NULL;
1322   }
1323 }
1324 
1325 
1326 G_END_DECLS
1327 
1328 
1329 GAFlightCriteria *
gaflight_criteria_new_raw(const arrow::flight::Criteria * flight_criteria)1330 gaflight_criteria_new_raw(const arrow::flight::Criteria *flight_criteria)
1331 {
1332   auto criteria = g_object_new(GAFLIGHT_TYPE_CRITERIA, NULL);
1333   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(criteria);
1334   priv->criteria = *flight_criteria;
1335   priv->expression = g_bytes_new(priv->criteria.expression.data(),
1336                                  priv->criteria.expression.size());
1337   return GAFLIGHT_CRITERIA(criteria);
1338 }
1339 
1340 arrow::flight::Criteria *
gaflight_criteria_get_raw(GAFlightCriteria * criteria)1341 gaflight_criteria_get_raw(GAFlightCriteria *criteria)
1342 {
1343   auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(criteria);
1344   return &(priv->criteria);
1345 }
1346 
1347 arrow::flight::Location *
gaflight_location_get_raw(GAFlightLocation * location)1348 gaflight_location_get_raw(GAFlightLocation *location)
1349 {
1350   auto priv = GAFLIGHT_LOCATION_GET_PRIVATE(location);
1351   return &(priv->location);
1352 }
1353 
1354 GAFlightDescriptor *
gaflight_descriptor_new_raw(const arrow::flight::FlightDescriptor * flight_descriptor)1355 gaflight_descriptor_new_raw(
1356   const arrow::flight::FlightDescriptor *flight_descriptor)
1357 {
1358   GType gtype = GAFLIGHT_TYPE_DESCRIPTOR;
1359   switch (flight_descriptor->type) {
1360   case arrow::flight::FlightDescriptor::DescriptorType::PATH:
1361     gtype = GAFLIGHT_TYPE_PATH_DESCRIPTOR;
1362     break;
1363   case arrow::flight::FlightDescriptor::DescriptorType::CMD:
1364     gtype = GAFLIGHT_TYPE_COMMAND_DESCRIPTOR;
1365     break;
1366   default:
1367     break;
1368   }
1369   return GAFLIGHT_DESCRIPTOR(g_object_new(gtype,
1370                                           "descriptor", flight_descriptor,
1371                                           NULL));
1372 }
1373 
1374 arrow::flight::FlightDescriptor *
gaflight_descriptor_get_raw(GAFlightDescriptor * descriptor)1375 gaflight_descriptor_get_raw(GAFlightDescriptor *descriptor)
1376 {
1377   auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(descriptor);
1378   return &(priv->descriptor);
1379 }
1380 
1381 GAFlightTicket *
gaflight_ticket_new_raw(const arrow::flight::Ticket * flight_ticket)1382 gaflight_ticket_new_raw(const arrow::flight::Ticket *flight_ticket)
1383 {
1384   auto ticket = g_object_new(GAFLIGHT_TYPE_TICKET, NULL);
1385   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(ticket);
1386   priv->ticket = *flight_ticket;
1387   priv->data = g_bytes_new(priv->ticket.ticket.data(),
1388                            priv->ticket.ticket.size());
1389   return GAFLIGHT_TICKET(ticket);
1390 }
1391 
1392 arrow::flight::Ticket *
gaflight_ticket_get_raw(GAFlightTicket * ticket)1393 gaflight_ticket_get_raw(GAFlightTicket *ticket)
1394 {
1395   auto priv = GAFLIGHT_TICKET_GET_PRIVATE(ticket);
1396   return &(priv->ticket);
1397 }
1398 
1399 GAFlightEndpoint *
gaflight_endpoint_new_raw(const arrow::flight::FlightEndpoint * flight_endpoint,GAFlightTicket * ticket)1400 gaflight_endpoint_new_raw(const arrow::flight::FlightEndpoint *flight_endpoint,
1401                           GAFlightTicket *ticket)
1402 {
1403   auto endpoint = GAFLIGHT_ENDPOINT(g_object_new(GAFLIGHT_TYPE_ENDPOINT,
1404                                                  NULL));
1405   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(endpoint);
1406   if (ticket) {
1407     priv->ticket = ticket;
1408     g_object_ref(priv->ticket);
1409     priv->endpoint.ticket = *gaflight_ticket_get_raw(priv->ticket);
1410   } else {
1411     auto data = g_bytes_new(flight_endpoint->ticket.ticket.data(),
1412                             flight_endpoint->ticket.ticket.length());
1413     auto ticket = gaflight_ticket_new(data);
1414     g_bytes_unref(data);
1415     priv->ticket = ticket;
1416     priv->endpoint.ticket.ticket = flight_endpoint->ticket.ticket;
1417   }
1418   if (flight_endpoint) {
1419     priv->endpoint.locations = flight_endpoint->locations;
1420   }
1421   return endpoint;
1422 }
1423 
1424 arrow::flight::FlightEndpoint *
gaflight_endpoint_get_raw(GAFlightEndpoint * endpoint)1425 gaflight_endpoint_get_raw(GAFlightEndpoint *endpoint)
1426 {
1427   auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(endpoint);
1428   return &(priv->endpoint);
1429 }
1430 
1431 GAFlightInfo *
gaflight_info_new_raw(arrow::flight::FlightInfo * flight_info)1432 gaflight_info_new_raw(arrow::flight::FlightInfo *flight_info)
1433 {
1434   return GAFLIGHT_INFO(g_object_new(GAFLIGHT_TYPE_INFO,
1435                                     "info", flight_info,
1436                                     NULL));
1437 }
1438 
1439 arrow::flight::FlightInfo *
gaflight_info_get_raw(GAFlightInfo * info)1440 gaflight_info_get_raw(GAFlightInfo *info)
1441 {
1442   auto priv = GAFLIGHT_INFO_GET_PRIVATE(info);
1443   return &(priv->info);
1444 }
1445 
1446 GAFlightStreamChunk *
gaflight_stream_chunk_new_raw(arrow::flight::FlightStreamChunk * flight_chunk)1447 gaflight_stream_chunk_new_raw(arrow::flight::FlightStreamChunk *flight_chunk)
1448 {
1449   return GAFLIGHT_STREAM_CHUNK(
1450     g_object_new(GAFLIGHT_TYPE_STREAM_CHUNK,
1451                  "chunk", flight_chunk,
1452                  NULL));
1453 }
1454 
1455 arrow::flight::FlightStreamChunk *
gaflight_stream_chunk_get_raw(GAFlightStreamChunk * chunk)1456 gaflight_stream_chunk_get_raw(GAFlightStreamChunk *chunk)
1457 {
1458   auto priv = GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(chunk);
1459   return &(priv->chunk);
1460 }
1461 
1462 arrow::flight::MetadataRecordBatchReader *
gaflight_record_batch_reader_get_raw(GAFlightRecordBatchReader * reader)1463 gaflight_record_batch_reader_get_raw(GAFlightRecordBatchReader *reader)
1464 {
1465   auto priv = GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(reader);
1466   return priv->reader;
1467 }
1468