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/decimal.hpp>
21 #include <arrow-glib/error.hpp>
22 
23 template <typename Decimal>
24 struct DecimalConverter {
25 };
26 
27 template <>
28 struct DecimalConverter<arrow::Decimal128> {
29   using ArrowType = arrow::Decimal128;
30   using GArrowType = GArrowDecimal128;
31 
32   GArrowType *
new_rawDecimalConverter33   new_raw(std::shared_ptr<ArrowType> *arrow_decimal128)
34   {
35     return garrow_decimal128_new_raw(arrow_decimal128);
36   }
37 
38   std::shared_ptr<ArrowType>
get_rawDecimalConverter39   get_raw(GArrowType *decimal128)
40   {
41     return garrow_decimal128_get_raw(decimal128);
42   }
43 };
44 
45 template <>
46 struct DecimalConverter<arrow::Decimal256> {
47   using ArrowType = arrow::Decimal256;
48   using GArrowType = GArrowDecimal256;
49 
50   GArrowType *
new_rawDecimalConverter51   new_raw(std::shared_ptr<ArrowType> *arrow_decimal256) {
52     return garrow_decimal256_new_raw(arrow_decimal256);
53   }
54 
55   std::shared_ptr<ArrowType>
get_rawDecimalConverter56   get_raw(GArrowType *decimal256) {
57     return garrow_decimal256_get_raw(decimal256);
58   }
59 };
60 
61 template <typename Decimal>
62 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_new_string(const gchar * data)63 garrow_decimal_new_string(const gchar *data)
64 {
65   auto arrow_decimal = std::make_shared<Decimal>(data);
66   DecimalConverter<Decimal> converter;
67   return converter.new_raw(&arrow_decimal);
68 }
69 
70 template <typename Decimal>
71 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_new_integer(const gint64 data)72 garrow_decimal_new_integer(const gint64 data)
73 {
74   auto arrow_decimal = std::make_shared<Decimal>(data);
75   DecimalConverter<Decimal> converter;
76   return converter.new_raw(&arrow_decimal);
77 }
78 
79 template <typename Decimal>
80 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_copy(typename DecimalConverter<Decimal>::GArrowType * decimal)81 garrow_decimal_copy(typename DecimalConverter<Decimal>::GArrowType *decimal)
82 {
83   DecimalConverter<Decimal> converter;
84   const auto arrow_decimal = converter.get_raw(decimal);
85   auto arrow_copied_decimal = std::make_shared<Decimal>(*arrow_decimal);
86   return converter.new_raw(&arrow_copied_decimal);
87 }
88 
89 template <typename Decimal>
90 gboolean
garrow_decimal_equal(typename DecimalConverter<Decimal>::GArrowType * decimal,typename DecimalConverter<Decimal>::GArrowType * other_decimal)91 garrow_decimal_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
92                      typename DecimalConverter<Decimal>::GArrowType *other_decimal)
93 {
94   DecimalConverter<Decimal> converter;
95   const auto arrow_decimal = converter.get_raw(decimal);
96   const auto arrow_other_decimal = converter.get_raw(other_decimal);
97   return *arrow_decimal == *arrow_other_decimal;
98 }
99 
100 template <typename Decimal>
101 gboolean
garrow_decimal_not_equal(typename DecimalConverter<Decimal>::GArrowType * decimal,typename DecimalConverter<Decimal>::GArrowType * other_decimal)102 garrow_decimal_not_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
103                          typename DecimalConverter<Decimal>::GArrowType *other_decimal)
104 {
105   DecimalConverter<Decimal> converter;
106   const auto arrow_decimal = converter.get_raw(decimal);
107   const auto arrow_other_decimal = converter.get_raw(other_decimal);
108   return *arrow_decimal != *arrow_other_decimal;
109 }
110 
111 template <typename Decimal>
112 gboolean
garrow_decimal_less_than(typename DecimalConverter<Decimal>::GArrowType * decimal,typename DecimalConverter<Decimal>::GArrowType * other_decimal)113 garrow_decimal_less_than(typename DecimalConverter<Decimal>::GArrowType *decimal,
114                          typename DecimalConverter<Decimal>::GArrowType *other_decimal)
115 {
116   DecimalConverter<Decimal> converter;
117   const auto arrow_decimal = converter.get_raw(decimal);
118   const auto arrow_other_decimal = converter.get_raw(other_decimal);
119   return *arrow_decimal < *arrow_other_decimal;
120 }
121 
122 template <typename Decimal>
123 gboolean
garrow_decimal_less_than_or_equal(typename DecimalConverter<Decimal>::GArrowType * decimal,typename DecimalConverter<Decimal>::GArrowType * other_decimal)124 garrow_decimal_less_than_or_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
125                                   typename DecimalConverter<Decimal>::GArrowType *other_decimal)
126 {
127   DecimalConverter<Decimal> converter;
128   const auto arrow_decimal = converter.get_raw(decimal);
129   const auto arrow_other_decimal = converter.get_raw(other_decimal);
130   return *arrow_decimal <= *arrow_other_decimal;
131 }
132 
133 template <typename Decimal>
134 gboolean
garrow_decimal_greater_than(typename DecimalConverter<Decimal>::GArrowType * decimal,typename DecimalConverter<Decimal>::GArrowType * other_decimal)135 garrow_decimal_greater_than(typename DecimalConverter<Decimal>::GArrowType *decimal,
136                             typename DecimalConverter<Decimal>::GArrowType *other_decimal)
137 {
138   DecimalConverter<Decimal> converter;
139   const auto arrow_decimal = converter.get_raw(decimal);
140   const auto arrow_other_decimal = converter.get_raw(other_decimal);
141   return *arrow_decimal > *arrow_other_decimal;
142 }
143 
144 template <typename Decimal>
145 gboolean
garrow_decimal_greater_than_or_equal(typename DecimalConverter<Decimal>::GArrowType * decimal,typename DecimalConverter<Decimal>::GArrowType * other_decimal)146 garrow_decimal_greater_than_or_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
147                                      typename DecimalConverter<Decimal>::GArrowType *other_decimal)
148 {
149   DecimalConverter<Decimal> converter;
150   const auto arrow_decimal = converter.get_raw(decimal);
151   const auto arrow_other_decimal = converter.get_raw(other_decimal);
152   return *arrow_decimal >= *arrow_other_decimal;
153 }
154 
155 template <typename Decimal>
156 gchar *
garrow_decimal_to_string_scale(typename DecimalConverter<Decimal>::GArrowType * decimal,gint32 scale)157 garrow_decimal_to_string_scale(typename DecimalConverter<Decimal>::GArrowType *decimal,
158                                gint32 scale)
159 {
160   DecimalConverter<Decimal> converter;
161   const auto arrow_decimal = converter.get_raw(decimal);
162   return g_strdup(arrow_decimal->ToString(scale).c_str());
163 }
164 
165 template <typename Decimal>
166 gchar *
garrow_decimal_to_string(typename DecimalConverter<Decimal>::GArrowType * decimal)167 garrow_decimal_to_string(typename DecimalConverter<Decimal>::GArrowType *decimal)
168 {
169   DecimalConverter<Decimal> converter;
170   const auto arrow_decimal = converter.get_raw(decimal);
171   return g_strdup(arrow_decimal->ToIntegerString().c_str());
172 }
173 
174 template <typename Decimal>
175 GBytes *
garrow_decimal_to_bytes(typename DecimalConverter<Decimal>::GArrowType * decimal)176 garrow_decimal_to_bytes(typename DecimalConverter<Decimal>::GArrowType *decimal)
177 {
178   DecimalConverter<Decimal> converter;
179   const auto arrow_decimal = converter.get_raw(decimal);
180   uint8_t data[DecimalConverter<Decimal>::ArrowType::kBitWidth / 8];
181   arrow_decimal->ToBytes(data);
182   return g_bytes_new(data, sizeof(data));
183 }
184 
185 template <typename Decimal>
186 void
garrow_decimal_abs(typename DecimalConverter<Decimal>::GArrowType * decimal)187 garrow_decimal_abs(typename DecimalConverter<Decimal>::GArrowType *decimal)
188 {
189   DecimalConverter<Decimal> converter;
190   auto arrow_decimal = converter.get_raw(decimal);
191   arrow_decimal->Abs();
192 }
193 
194 template <typename Decimal>
195 void
garrow_decimal_negate(typename DecimalConverter<Decimal>::GArrowType * decimal)196 garrow_decimal_negate(typename DecimalConverter<Decimal>::GArrowType *decimal)
197 {
198   DecimalConverter<Decimal> converter;
199   auto arrow_decimal = converter.get_raw(decimal);
200   arrow_decimal->Negate();
201 }
202 
203 template <typename Decimal>
204 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_plus(typename DecimalConverter<Decimal>::GArrowType * left,typename DecimalConverter<Decimal>::GArrowType * right)205 garrow_decimal_plus(typename DecimalConverter<Decimal>::GArrowType *left,
206                     typename DecimalConverter<Decimal>::GArrowType *right)
207 {
208   DecimalConverter<Decimal> converter;
209   auto arrow_left = converter.get_raw(left);
210   auto arrow_right = converter.get_raw(right);
211   auto arrow_decimal = std::make_shared<Decimal>(*arrow_left + *arrow_right);
212   return converter.new_raw(&arrow_decimal);
213 }
214 
215 template <typename Decimal>
216 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_minus(typename DecimalConverter<Decimal>::GArrowType * left,typename DecimalConverter<Decimal>::GArrowType * right)217 garrow_decimal_minus(typename DecimalConverter<Decimal>::GArrowType *left,
218                      typename DecimalConverter<Decimal>::GArrowType *right)
219 {
220   DecimalConverter<Decimal> converter;
221   auto arrow_left = converter.get_raw(left);
222   auto arrow_right = converter.get_raw(right);
223   auto arrow_decimal = std::make_shared<Decimal>(*arrow_left - *arrow_right);
224   return converter.new_raw(&arrow_decimal);
225 }
226 
227 template <typename Decimal>
228 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_multiply(typename DecimalConverter<Decimal>::GArrowType * left,typename DecimalConverter<Decimal>::GArrowType * right)229 garrow_decimal_multiply(typename DecimalConverter<Decimal>::GArrowType *left,
230                         typename DecimalConverter<Decimal>::GArrowType *right)
231 {
232   DecimalConverter<Decimal> converter;
233   auto arrow_left = converter.get_raw(left);
234   auto arrow_right = converter.get_raw(right);
235   auto arrow_decimal = std::make_shared<Decimal>(*arrow_left * *arrow_right);
236   return converter.new_raw(&arrow_decimal);
237 }
238 
239 template <typename Decimal>
240 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_divide(typename DecimalConverter<Decimal>::GArrowType * left,typename DecimalConverter<Decimal>::GArrowType * right,typename DecimalConverter<Decimal>::GArrowType ** remainder,GError ** error,const gchar * tag)241 garrow_decimal_divide(typename DecimalConverter<Decimal>::GArrowType *left,
242                       typename DecimalConverter<Decimal>::GArrowType *right,
243                       typename DecimalConverter<Decimal>::GArrowType **remainder,
244                       GError **error,
245                       const gchar *tag)
246 {
247   DecimalConverter<Decimal> converter;
248   auto arrow_left = converter.get_raw(left);
249   auto arrow_right = converter.get_raw(right);
250   auto arrow_result = arrow_left->Divide(*arrow_right);
251   if (garrow::check(error, arrow_result, tag)) {
252     Decimal arrow_quotient_raw;
253     Decimal arrow_remainder_raw;
254     std::tie(arrow_quotient_raw, arrow_remainder_raw) = *arrow_result;
255     if (remainder) {
256       auto arrow_remainder = std::make_shared<Decimal>(arrow_remainder_raw);
257       *remainder = converter.new_raw(&arrow_remainder);
258     }
259     auto arrow_quotient = std::make_shared<Decimal>(arrow_quotient_raw);
260     return converter.new_raw(&arrow_quotient);
261   } else {
262     if (remainder) {
263       *remainder = NULL;
264     }
265     return NULL;
266   }
267 }
268 
269 template <typename Decimal>
270 typename DecimalConverter<Decimal>::GArrowType *
garrow_decimal_rescale(typename DecimalConverter<Decimal>::GArrowType * decimal,gint32 original_scale,gint32 new_scale,GError ** error,const gchar * tag)271 garrow_decimal_rescale(typename DecimalConverter<Decimal>::GArrowType *decimal,
272                        gint32 original_scale,
273                        gint32 new_scale,
274                        GError **error,
275                        const gchar *tag)
276 {
277   DecimalConverter<Decimal> converter;
278   auto arrow_decimal = converter.get_raw(decimal);
279   auto arrow_result = arrow_decimal->Rescale(original_scale, new_scale);
280   if (garrow::check(error, arrow_result, tag)) {
281     auto arrow_rescaled_decimal = std::make_shared<Decimal>(*arrow_result);
282     return converter.new_raw(&arrow_rescaled_decimal);
283   } else {
284     return NULL;
285   }
286 }
287 
288 
289 G_BEGIN_DECLS
290 
291 /**
292  * SECTION: decimal
293  * @section_id: decimal
294  * @title: 128-bit and 256-bit decimal classes
295  * @include: arrow-glib/arrow-glib.h
296  *
297  * #GArrowDecimal128 is a 128-bit decimal class.
298  *
299  * #GArrowDecimal256 is a 256-bit decimal class.
300  *
301  * Since: 0.10.0
302  */
303 
304 typedef struct GArrowDecimal128Private_ {
305   std::shared_ptr<arrow::Decimal128> decimal128;
306 } GArrowDecimal128Private;
307 
308 enum {
309   PROP_DECIMAL128 = 1
310 };
311 
G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal128,garrow_decimal128,G_TYPE_OBJECT)312 G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal128,
313                            garrow_decimal128,
314                            G_TYPE_OBJECT)
315 
316 #define GARROW_DECIMAL128_GET_PRIVATE(obj)         \
317   static_cast<GArrowDecimal128Private *>(          \
318      garrow_decimal128_get_instance_private(       \
319        GARROW_DECIMAL128(obj)))
320 
321 static void
322 garrow_decimal128_finalize(GObject *object)
323 {
324   auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
325 
326   priv->decimal128.~shared_ptr();
327 
328   G_OBJECT_CLASS(garrow_decimal128_parent_class)->finalize(object);
329 }
330 
331 static void
garrow_decimal128_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)332 garrow_decimal128_set_property(GObject *object,
333                                guint prop_id,
334                                const GValue *value,
335                                GParamSpec *pspec)
336 {
337   auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
338 
339   switch (prop_id) {
340   case PROP_DECIMAL128:
341     priv->decimal128 =
342       *static_cast<std::shared_ptr<arrow::Decimal128> *>(g_value_get_pointer(value));
343     break;
344   default:
345     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
346     break;
347   }
348 }
349 
350 static void
garrow_decimal128_init(GArrowDecimal128 * object)351 garrow_decimal128_init(GArrowDecimal128 *object)
352 {
353   auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
354   new(&priv->decimal128) std::shared_ptr<arrow::Decimal128>;
355 }
356 
357 static void
garrow_decimal128_class_init(GArrowDecimal128Class * klass)358 garrow_decimal128_class_init(GArrowDecimal128Class *klass)
359 {
360   GParamSpec *spec;
361 
362   auto gobject_class = G_OBJECT_CLASS(klass);
363 
364   gobject_class->finalize     = garrow_decimal128_finalize;
365   gobject_class->set_property = garrow_decimal128_set_property;
366 
367   spec = g_param_spec_pointer("decimal128",
368                               "Decimal128",
369                               "The raw std::shared<arrow::Decimal128> *",
370                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
371                                                        G_PARAM_CONSTRUCT_ONLY));
372   g_object_class_install_property(gobject_class, PROP_DECIMAL128, spec);
373 }
374 
375 /**
376  * garrow_decimal128_new_string:
377  * @data: The data of the decimal.
378  *
379  * Returns: A newly created #GArrowDecimal128.
380  *
381  * Since: 0.10.0
382  */
383 GArrowDecimal128 *
garrow_decimal128_new_string(const gchar * data)384 garrow_decimal128_new_string(const gchar *data)
385 {
386   return garrow_decimal_new_string<arrow::Decimal128>(data);
387 }
388 
389 /**
390  * garrow_decimal128_new_integer:
391  * @data: The data of the decimal.
392  *
393  * Returns: A newly created #GArrowDecimal128.
394  *
395  * Since: 0.10.0
396  */
397 GArrowDecimal128 *
garrow_decimal128_new_integer(const gint64 data)398 garrow_decimal128_new_integer(const gint64 data)
399 {
400   return garrow_decimal_new_integer<arrow::Decimal128>(data);
401 }
402 
403 /**
404  * garrow_decimal128_copy:
405  * @decimal: The decimal to be copied.
406  *
407  * Returns: (transfer full): A copied #GArrowDecimal128.
408  *
409  * Since: 3.0.0
410  */
411 GArrowDecimal128 *
garrow_decimal128_copy(GArrowDecimal128 * decimal)412 garrow_decimal128_copy(GArrowDecimal128 *decimal)
413 {
414   return garrow_decimal_copy<arrow::Decimal128>(decimal);
415 }
416 
417 /**
418  * garrow_decimal128_equal:
419  * @decimal: A #GArrowDecimal128.
420  * @other_decimal: A #GArrowDecimal128 to be compared.
421  *
422  * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
423  *   otherwise.
424  *
425  * Since: 0.12.0
426  */
427 gboolean
garrow_decimal128_equal(GArrowDecimal128 * decimal,GArrowDecimal128 * other_decimal)428 garrow_decimal128_equal(GArrowDecimal128 *decimal,
429                         GArrowDecimal128 *other_decimal)
430 {
431   return garrow_decimal_equal<arrow::Decimal128>(decimal, other_decimal);
432 }
433 
434 /**
435  * garrow_decimal128_not_equal:
436  * @decimal: A #GArrowDecimal128.
437  * @other_decimal: A #GArrowDecimal128 to be compared.
438  *
439  * Returns: %TRUE if the decimal isn't equal to the other decimal,
440  *   %FALSE otherwise.
441  *
442  * Since: 0.12.0
443  */
444 gboolean
garrow_decimal128_not_equal(GArrowDecimal128 * decimal,GArrowDecimal128 * other_decimal)445 garrow_decimal128_not_equal(GArrowDecimal128 *decimal,
446                             GArrowDecimal128 *other_decimal)
447 {
448   return garrow_decimal_not_equal<arrow::Decimal128>(decimal, other_decimal);
449 }
450 
451 /**
452  * garrow_decimal128_less_than:
453  * @decimal: A #GArrowDecimal128.
454  * @other_decimal: A #GArrowDecimal128 to be compared.
455  *
456  * Returns: %TRUE if the decimal is less than the other decimal,
457  *   %FALSE otherwise.
458  *
459  * Since: 0.12.0
460  */
461 gboolean
garrow_decimal128_less_than(GArrowDecimal128 * decimal,GArrowDecimal128 * other_decimal)462 garrow_decimal128_less_than(GArrowDecimal128 *decimal,
463                             GArrowDecimal128 *other_decimal)
464 {
465   return garrow_decimal_less_than<arrow::Decimal128>(decimal, other_decimal);
466 }
467 
468 /**
469  * garrow_decimal128_less_than_or_equal:
470  * @decimal: A #GArrowDecimal128.
471  * @other_decimal: A #GArrowDecimal128 to be compared.
472  *
473  * Returns: %TRUE if the decimal is less than the other decimal
474  *   or equal to the other decimal, %FALSE otherwise.
475  *
476  * Since: 0.12.0
477  */
478 gboolean
garrow_decimal128_less_than_or_equal(GArrowDecimal128 * decimal,GArrowDecimal128 * other_decimal)479 garrow_decimal128_less_than_or_equal(GArrowDecimal128 *decimal,
480                                      GArrowDecimal128 *other_decimal)
481 {
482   return garrow_decimal_less_than_or_equal<arrow::Decimal128>(decimal, other_decimal);
483 }
484 
485 /**
486  * garrow_decimal128_greater_than:
487  * @decimal: A #GArrowDecimal128.
488  * @other_decimal: A #GArrowDecimal128 to be compared.
489  *
490  * Returns: %TRUE if the decimal is greater than the other decimal,
491  *   %FALSE otherwise.
492  *
493  * Since: 0.12.0
494  */
495 gboolean
garrow_decimal128_greater_than(GArrowDecimal128 * decimal,GArrowDecimal128 * other_decimal)496 garrow_decimal128_greater_than(GArrowDecimal128 *decimal,
497                                GArrowDecimal128 *other_decimal)
498 {
499   return garrow_decimal_greater_than<arrow::Decimal128>(decimal, other_decimal);
500 }
501 
502 /**
503  * garrow_decimal128_greater_than_or_equal:
504  * @decimal: A #GArrowDecimal128.
505  * @other_decimal: A #GArrowDecimal128 to be compared.
506  *
507  * Returns: %TRUE if the decimal is greater than the other decimal
508  *   or equal to the other decimal, %FALSE otherwise.
509  *
510  * Since: 0.12.0
511  */
512 gboolean
garrow_decimal128_greater_than_or_equal(GArrowDecimal128 * decimal,GArrowDecimal128 * other_decimal)513 garrow_decimal128_greater_than_or_equal(GArrowDecimal128 *decimal,
514                                         GArrowDecimal128 *other_decimal)
515 {
516   return garrow_decimal_greater_than_or_equal<arrow::Decimal128>(decimal, other_decimal);
517 }
518 
519 /**
520  * garrow_decimal128_to_string_scale:
521  * @decimal: A #GArrowDecimal128.
522  * @scale: The scale of the decimal.
523  *
524  * Returns: The string representation of the decimal.
525  *
526  *   It should be freed with g_free() when no longer needed.
527  *
528  * Since: 0.10.0
529  */
530 gchar *
garrow_decimal128_to_string_scale(GArrowDecimal128 * decimal,gint32 scale)531 garrow_decimal128_to_string_scale(GArrowDecimal128 *decimal, gint32 scale)
532 {
533   return garrow_decimal_to_string_scale<arrow::Decimal128>(decimal, scale);
534 }
535 
536 /**
537  * garrow_decimal128_to_string:
538  * @decimal: A #GArrowDecimal128.
539  *
540  * Returns: The string representation of the decimal.
541  *
542  *   It should be freed with g_free() when no longer needed.
543  *
544  * Since: 0.10.0
545  */
546 gchar *
garrow_decimal128_to_string(GArrowDecimal128 * decimal)547 garrow_decimal128_to_string(GArrowDecimal128 *decimal)
548 {
549   return garrow_decimal_to_string<arrow::Decimal128>(decimal);
550 }
551 
552 /**
553  * garrow_decimal128_to_bytes:
554  * @decimal: A #GArrowDecimal128.
555  *
556  * Returns: (transfer full): The binary representation of the decimal.
557  *
558  * Since: 3.0.0
559  */
560 GBytes *
garrow_decimal128_to_bytes(GArrowDecimal128 * decimal)561 garrow_decimal128_to_bytes(GArrowDecimal128 *decimal)
562 {
563   return garrow_decimal_to_bytes<arrow::Decimal128>(decimal);
564 }
565 
566 /**
567  * garrow_decimal128_abs:
568  * @decimal: A #GArrowDecimal128.
569  *
570  * Computes the absolute value of the @decimal destructively.
571  *
572  * Since: 0.10.0
573  */
574 void
garrow_decimal128_abs(GArrowDecimal128 * decimal)575 garrow_decimal128_abs(GArrowDecimal128 *decimal)
576 {
577   garrow_decimal_abs<arrow::Decimal128>(decimal);
578 }
579 
580 /**
581  * garrow_decimal128_negate:
582  * @decimal: A #GArrowDecimal128.
583  *
584  * Negate the current value of the @decimal destructively.
585  *
586  * Since: 0.10.0
587  */
588 void
garrow_decimal128_negate(GArrowDecimal128 * decimal)589 garrow_decimal128_negate(GArrowDecimal128 *decimal)
590 {
591   garrow_decimal_negate<arrow::Decimal128>(decimal);
592 }
593 
594 /**
595  * garrow_decimal128_to_integer:
596  * @decimal: A #GArrowDecimal128.
597  *
598  * Returns: The 64-bit integer representation of the decimal.
599  *
600  * Since: 0.10.0
601  */
602 gint64
garrow_decimal128_to_integer(GArrowDecimal128 * decimal)603 garrow_decimal128_to_integer(GArrowDecimal128 *decimal)
604 {
605   auto arrow_decimal = garrow_decimal128_get_raw(decimal);
606   return static_cast<int64_t>(*arrow_decimal);
607 }
608 
609 /**
610  * garrow_decimal128_plus:
611  * @left: A #GArrowDecimal128.
612  * @right: A #GArrowDecimal128.
613  *
614  * Returns: (transfer full): The added value of these decimals.
615  *
616  * Since: 0.11.0
617  */
618 GArrowDecimal128 *
garrow_decimal128_plus(GArrowDecimal128 * left,GArrowDecimal128 * right)619 garrow_decimal128_plus(GArrowDecimal128 *left,
620                        GArrowDecimal128 *right)
621 {
622   return garrow_decimal_plus<arrow::Decimal128>(left, right);
623 }
624 
625 /**
626  * garrow_decimal128_minus:
627  * @left: A #GArrowDecimal128.
628  * @right: A #GArrowDecimal128.
629  *
630  * Returns: (transfer full): The subtracted value of these decimals.
631  *
632  * Since: 0.11.0
633  */
634 GArrowDecimal128 *
garrow_decimal128_minus(GArrowDecimal128 * left,GArrowDecimal128 * right)635 garrow_decimal128_minus(GArrowDecimal128 *left,
636                         GArrowDecimal128 *right)
637 {
638   return garrow_decimal_minus<arrow::Decimal128>(left, right);
639 }
640 
641 /**
642  * garrow_decimal128_multiply:
643  * @left: A #GArrowDecimal128.
644  * @right: A #GArrowDecimal128.
645  *
646  * Returns: (transfer full): The multiplied value of these decimals.
647  *
648  * Since: 0.11.0
649  */
650 GArrowDecimal128 *
garrow_decimal128_multiply(GArrowDecimal128 * left,GArrowDecimal128 * right)651 garrow_decimal128_multiply(GArrowDecimal128 *left,
652                            GArrowDecimal128 *right)
653 {
654   return garrow_decimal_multiply<arrow::Decimal128>(left, right);
655 }
656 
657 /**
658  * garrow_decimal128_divide:
659  * @left: A #GArrowDecimal128.
660  * @right: A #GArrowDecimal128.
661  * @remainder: (out) (nullable): A return location for the remainder
662  *   value of these decimals. The returned #GArrowDecimal128 be
663  *   unreferred with g_object_unref() when no longer needed.
664  * @error: (nullable): Return location for a #GError or %NULL.
665  *
666  * Returns: (nullable) (transfer full): The divided value of
667  *   these decimals or %NULL on error.
668  *
669  * Since: 0.11.0
670  */
671 GArrowDecimal128 *
garrow_decimal128_divide(GArrowDecimal128 * left,GArrowDecimal128 * right,GArrowDecimal128 ** remainder,GError ** error)672 garrow_decimal128_divide(GArrowDecimal128 *left,
673                          GArrowDecimal128 *right,
674                          GArrowDecimal128 **remainder,
675                          GError **error)
676 {
677   return garrow_decimal_divide<arrow::Decimal128>(left,
678                                                   right,
679                                                   remainder,
680                                                   error,
681                                                   "[decimal128][divide]");
682 }
683 
684 /**
685  * garrow_decimal128_rescale:
686  * @decimal: A #GArrowDecimal128.
687  * @original_scale: A scale to be converted from.
688  * @new_scale: A scale to be converted to.
689  * @error: (nullable): Return location for a #GError or %NULL.
690  *
691  * Returns: (nullable) (transfer full): The rescaled decimal or %NULL on error.
692  *
693  * Since: 0.15.0
694  */
695 GArrowDecimal128 *
garrow_decimal128_rescale(GArrowDecimal128 * decimal,gint32 original_scale,gint32 new_scale,GError ** error)696 garrow_decimal128_rescale(GArrowDecimal128 *decimal,
697                           gint32 original_scale,
698                           gint32 new_scale,
699                           GError **error)
700 {
701   return garrow_decimal_rescale<arrow::Decimal128>(decimal,
702                                                    original_scale,
703                                                    new_scale,
704                                                    error,
705                                                    "[decimal128][rescale]");
706 }
707 
708 
709 typedef struct GArrowDecimal256Private_ {
710   std::shared_ptr<arrow::Decimal256> decimal256;
711 } GArrowDecimal256Private;
712 
713 enum {
714   PROP_DECIMAL256 = 1
715 };
716 
G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal256,garrow_decimal256,G_TYPE_OBJECT)717 G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal256,
718                            garrow_decimal256,
719                            G_TYPE_OBJECT)
720 
721 #define GARROW_DECIMAL256_GET_PRIVATE(obj)         \
722   static_cast<GArrowDecimal256Private *>(          \
723      garrow_decimal256_get_instance_private(       \
724        GARROW_DECIMAL256(obj)))
725 
726 static void
727 garrow_decimal256_finalize(GObject *object)
728 {
729   auto priv = GARROW_DECIMAL256_GET_PRIVATE(object);
730 
731   priv->decimal256.~shared_ptr();
732 
733   G_OBJECT_CLASS(garrow_decimal256_parent_class)->finalize(object);
734 }
735 
736 static void
garrow_decimal256_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)737 garrow_decimal256_set_property(GObject *object,
738                                guint prop_id,
739                                const GValue *value,
740                                GParamSpec *pspec)
741 {
742   auto priv = GARROW_DECIMAL256_GET_PRIVATE(object);
743 
744   switch (prop_id) {
745   case PROP_DECIMAL256:
746     priv->decimal256 =
747       *static_cast<std::shared_ptr<arrow::Decimal256> *>(g_value_get_pointer(value));
748     break;
749   default:
750     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
751     break;
752   }
753 }
754 
755 static void
garrow_decimal256_init(GArrowDecimal256 * object)756 garrow_decimal256_init(GArrowDecimal256 *object)
757 {
758   auto priv = GARROW_DECIMAL256_GET_PRIVATE(object);
759   new(&priv->decimal256) std::shared_ptr<arrow::Decimal256>;
760 }
761 
762 static void
garrow_decimal256_class_init(GArrowDecimal256Class * klass)763 garrow_decimal256_class_init(GArrowDecimal256Class *klass)
764 {
765   GParamSpec *spec;
766 
767   auto gobject_class = G_OBJECT_CLASS(klass);
768 
769   gobject_class->finalize     = garrow_decimal256_finalize;
770   gobject_class->set_property = garrow_decimal256_set_property;
771 
772   spec = g_param_spec_pointer("decimal256",
773                               "Decimal256",
774                               "The raw std::shared<arrow::Decimal256> *",
775                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
776                                                        G_PARAM_CONSTRUCT_ONLY));
777   g_object_class_install_property(gobject_class, PROP_DECIMAL256, spec);
778 }
779 
780 /**
781  * garrow_decimal256_new_string:
782  * @data: The data of the decimal.
783  *
784  * Returns: A newly created #GArrowDecimal256.
785  *
786  * Since: 3.0.0
787  */
788 GArrowDecimal256 *
garrow_decimal256_new_string(const gchar * data)789 garrow_decimal256_new_string(const gchar *data)
790 {
791   return garrow_decimal_new_string<arrow::Decimal256>(data);
792 }
793 
794 /**
795  * garrow_decimal256_new_integer:
796  * @data: The data of the decimal.
797  *
798  * Returns: A newly created #GArrowDecimal256.
799  *
800  * Since: 3.0.0
801  */
802 GArrowDecimal256 *
garrow_decimal256_new_integer(const gint64 data)803 garrow_decimal256_new_integer(const gint64 data)
804 {
805   return garrow_decimal_new_integer<arrow::Decimal256>(data);
806 }
807 
808 /**
809  * garrow_decimal256_copy:
810  * @decimal: The decimal to be copied.
811  *
812  * Returns: (transfer full): A copied #GArrowDecimal256.
813  *
814  * Since: 3.0.0
815  */
816 GArrowDecimal256 *
garrow_decimal256_copy(GArrowDecimal256 * decimal)817 garrow_decimal256_copy(GArrowDecimal256 *decimal)
818 {
819   return garrow_decimal_copy<arrow::Decimal256>(decimal);
820 }
821 
822 /**
823  * garrow_decimal256_equal:
824  * @decimal: A #GArrowDecimal256.
825  * @other_decimal: A #GArrowDecimal256 to be compared.
826  *
827  * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
828  *   otherwise.
829  *
830  * Since: 3.0.0
831  */
832 gboolean
garrow_decimal256_equal(GArrowDecimal256 * decimal,GArrowDecimal256 * other_decimal)833 garrow_decimal256_equal(GArrowDecimal256 *decimal,
834                         GArrowDecimal256 *other_decimal)
835 {
836   return garrow_decimal_equal<arrow::Decimal256>(decimal, other_decimal);
837 }
838 
839 /**
840  * garrow_decimal256_not_equal:
841  * @decimal: A #GArrowDecimal256.
842  * @other_decimal: A #GArrowDecimal256 to be compared.
843  *
844  * Returns: %TRUE if the decimal isn't equal to the other decimal,
845  *   %FALSE otherwise.
846  *
847  * Since: 3.0.0
848  */
849 gboolean
garrow_decimal256_not_equal(GArrowDecimal256 * decimal,GArrowDecimal256 * other_decimal)850 garrow_decimal256_not_equal(GArrowDecimal256 *decimal,
851                             GArrowDecimal256 *other_decimal)
852 {
853   return garrow_decimal_not_equal<arrow::Decimal256>(decimal, other_decimal);
854 }
855 
856 /**
857  * garrow_decimal256_less_than:
858  * @decimal: A #GArrowDecimal256.
859  * @other_decimal: A #GArrowDecimal256 to be compared.
860  *
861  * Returns: %TRUE if the decimal is less than the other decimal,
862  *   %FALSE otherwise.
863  *
864  * Since: 3.0.0
865  */
866 gboolean
garrow_decimal256_less_than(GArrowDecimal256 * decimal,GArrowDecimal256 * other_decimal)867 garrow_decimal256_less_than(GArrowDecimal256 *decimal,
868                             GArrowDecimal256 *other_decimal)
869 {
870   return garrow_decimal_less_than<arrow::Decimal256>(decimal, other_decimal);
871 }
872 
873 /**
874  * garrow_decimal256_less_than_or_equal:
875  * @decimal: A #GArrowDecimal256.
876  * @other_decimal: A #GArrowDecimal256 to be compared.
877  *
878  * Returns: %TRUE if the decimal is less than the other decimal
879  *   or equal to the other decimal, %FALSE otherwise.
880  *
881  * Since: 3.0.0
882  */
883 gboolean
garrow_decimal256_less_than_or_equal(GArrowDecimal256 * decimal,GArrowDecimal256 * other_decimal)884 garrow_decimal256_less_than_or_equal(GArrowDecimal256 *decimal,
885                                      GArrowDecimal256 *other_decimal)
886 {
887   return garrow_decimal_less_than_or_equal<arrow::Decimal256>(decimal, other_decimal);
888 }
889 
890 /**
891  * garrow_decimal256_greater_than:
892  * @decimal: A #GArrowDecimal256.
893  * @other_decimal: A #GArrowDecimal256 to be compared.
894  *
895  * Returns: %TRUE if the decimal is greater than the other decimal,
896  *   %FALSE otherwise.
897  *
898  * Since: 3.0.0
899  */
900 gboolean
garrow_decimal256_greater_than(GArrowDecimal256 * decimal,GArrowDecimal256 * other_decimal)901 garrow_decimal256_greater_than(GArrowDecimal256 *decimal,
902                                GArrowDecimal256 *other_decimal)
903 {
904   return garrow_decimal_greater_than<arrow::Decimal256>(decimal, other_decimal);
905 }
906 
907 /**
908  * garrow_decimal256_greater_than_or_equal:
909  * @decimal: A #GArrowDecimal256.
910  * @other_decimal: A #GArrowDecimal256 to be compared.
911  *
912  * Returns: %TRUE if the decimal is greater than the other decimal
913  *   or equal to the other decimal, %FALSE otherwise.
914  *
915  * Since: 3.0.0
916  */
917 gboolean
garrow_decimal256_greater_than_or_equal(GArrowDecimal256 * decimal,GArrowDecimal256 * other_decimal)918 garrow_decimal256_greater_than_or_equal(GArrowDecimal256 *decimal,
919                                         GArrowDecimal256 *other_decimal)
920 {
921   return garrow_decimal_greater_than_or_equal<arrow::Decimal256>(decimal, other_decimal);
922 }
923 
924 /**
925  * garrow_decimal256_to_string_scale:
926  * @decimal: A #GArrowDecimal256.
927  * @scale: The scale of the decimal.
928  *
929  * Returns: The string representation of the decimal.
930  *
931  *   It should be freed with g_free() when no longer needed.
932  *
933  * Since: 3.0.0
934  */
935 gchar *
garrow_decimal256_to_string_scale(GArrowDecimal256 * decimal,gint32 scale)936 garrow_decimal256_to_string_scale(GArrowDecimal256 *decimal, gint32 scale)
937 {
938   return garrow_decimal_to_string_scale<arrow::Decimal256>(decimal, scale);
939 }
940 
941 /**
942  * garrow_decimal256_to_string:
943  * @decimal: A #GArrowDecimal256.
944  *
945  * Returns: The string representation of the decimal.
946  *
947  *   It should be freed with g_free() when no longer needed.
948  *
949  * Since: 3.0.0
950  */
951 gchar *
garrow_decimal256_to_string(GArrowDecimal256 * decimal)952 garrow_decimal256_to_string(GArrowDecimal256 *decimal)
953 {
954   return garrow_decimal_to_string<arrow::Decimal256>(decimal);
955 }
956 
957 /**
958  * garrow_decimal256_to_bytes:
959  * @decimal: A #GArrowDecimal256.
960  *
961  * Returns: (transfer full): The binary representation of the decimal.
962  *
963  * Since: 3.0.0
964  */
965 GBytes *
garrow_decimal256_to_bytes(GArrowDecimal256 * decimal)966 garrow_decimal256_to_bytes(GArrowDecimal256 *decimal)
967 {
968   return garrow_decimal_to_bytes<arrow::Decimal256>(decimal);
969 }
970 
971 /**
972  * garrow_decimal256_abs:
973  * @decimal: A #GArrowDecimal256.
974  *
975  * Computes the absolute value of the @decimal destructively.
976  *
977  * Since: 3.0.0
978  */
979 void
garrow_decimal256_abs(GArrowDecimal256 * decimal)980 garrow_decimal256_abs(GArrowDecimal256 *decimal)
981 {
982   garrow_decimal_abs<arrow::Decimal256>(decimal);
983 }
984 
985 /**
986  * garrow_decimal256_negate:
987  * @decimal: A #GArrowDecimal256.
988  *
989  * Negate the current value of the @decimal destructively.
990  *
991  * Since: 3.0.0
992  */
993 void
garrow_decimal256_negate(GArrowDecimal256 * decimal)994 garrow_decimal256_negate(GArrowDecimal256 *decimal)
995 {
996   garrow_decimal_negate<arrow::Decimal256>(decimal);
997 }
998 
999 /**
1000  * garrow_decimal256_plus:
1001  * @left: A #GArrowDecimal256.
1002  * @right: A #GArrowDecimal256.
1003  *
1004  * Returns: (transfer full): The added value of these decimals.
1005  *
1006  * Since: 3.0.0
1007  */
1008 GArrowDecimal256 *
garrow_decimal256_plus(GArrowDecimal256 * left,GArrowDecimal256 * right)1009 garrow_decimal256_plus(GArrowDecimal256 *left,
1010                        GArrowDecimal256 *right)
1011 {
1012   return garrow_decimal_plus<arrow::Decimal256>(left, right);
1013 }
1014 
1015 /**
1016  * garrow_decimal256_multiply:
1017  * @left: A #GArrowDecimal256.
1018  * @right: A #GArrowDecimal256.
1019  *
1020  * Returns: (transfer full): The multiplied value of these decimals.
1021  *
1022  * Since: 3.0.0
1023  */
1024 GArrowDecimal256 *
garrow_decimal256_multiply(GArrowDecimal256 * left,GArrowDecimal256 * right)1025 garrow_decimal256_multiply(GArrowDecimal256 *left,
1026                            GArrowDecimal256 *right)
1027 {
1028   return garrow_decimal_multiply<arrow::Decimal256>(left, right);
1029 }
1030 
1031 /**
1032  * garrow_decimal256_divide:
1033  * @left: A #GArrowDecimal256.
1034  * @right: A #GArrowDecimal256.
1035  * @remainder: (out) (nullable): A return location for the remainder
1036  *   value of these decimals. The returned #GArrowDecimal256 be
1037  *   unreferred with g_object_unref() when no longer needed.
1038  * @error: (nullable): Return location for a #GError or %NULL.
1039  *
1040  * Returns: (nullable) (transfer full): The divided value of
1041  *   these decimals or %NULL on error.
1042  *
1043  * Since: 3.0.0
1044  */
1045 GArrowDecimal256 *
garrow_decimal256_divide(GArrowDecimal256 * left,GArrowDecimal256 * right,GArrowDecimal256 ** remainder,GError ** error)1046 garrow_decimal256_divide(GArrowDecimal256 *left,
1047                          GArrowDecimal256 *right,
1048                          GArrowDecimal256 **remainder,
1049                          GError **error)
1050 {
1051   return garrow_decimal_divide<arrow::Decimal256>(left,
1052                                                   right,
1053                                                   remainder,
1054                                                   error,
1055                                                   "[decimal256][divide]");
1056 }
1057 
1058 /**
1059  * garrow_decimal256_rescale:
1060  * @decimal: A #GArrowDecimal256.
1061  * @original_scale: A scale to be converted from.
1062  * @new_scale: A scale to be converted to.
1063  * @error: (nullable): Return location for a #GError or %NULL.
1064  *
1065  * Returns: (nullable) (transfer full): The rescaled decimal or %NULL on error.
1066  *
1067  * Since: 3.0.0
1068  */
1069 GArrowDecimal256 *
garrow_decimal256_rescale(GArrowDecimal256 * decimal,gint32 original_scale,gint32 new_scale,GError ** error)1070 garrow_decimal256_rescale(GArrowDecimal256 *decimal,
1071                           gint32 original_scale,
1072                           gint32 new_scale,
1073                           GError **error)
1074 {
1075   return garrow_decimal_rescale<arrow::Decimal256>(decimal,
1076                                                    original_scale,
1077                                                    new_scale,
1078                                                    error,
1079                                                    "[decimal256][rescale]");
1080 }
1081 
1082 
1083 G_END_DECLS
1084 
1085 GArrowDecimal128 *
garrow_decimal128_new_raw(std::shared_ptr<arrow::Decimal128> * arrow_decimal128)1086 garrow_decimal128_new_raw(std::shared_ptr<arrow::Decimal128> *arrow_decimal128)
1087 {
1088   auto decimal128 = g_object_new(garrow_decimal128_get_type(),
1089                                  "decimal128", arrow_decimal128,
1090                                  NULL);
1091   return GARROW_DECIMAL128(decimal128);
1092 }
1093 
1094 std::shared_ptr<arrow::Decimal128>
garrow_decimal128_get_raw(GArrowDecimal128 * decimal128)1095 garrow_decimal128_get_raw(GArrowDecimal128 *decimal128)
1096 {
1097   auto priv = GARROW_DECIMAL128_GET_PRIVATE(decimal128);
1098   return priv->decimal128;
1099 }
1100 
1101 GArrowDecimal256 *
garrow_decimal256_new_raw(std::shared_ptr<arrow::Decimal256> * arrow_decimal256)1102 garrow_decimal256_new_raw(std::shared_ptr<arrow::Decimal256> *arrow_decimal256)
1103 {
1104   auto decimal256 = g_object_new(garrow_decimal256_get_type(),
1105                                  "decimal256", arrow_decimal256,
1106                                  NULL);
1107   return GARROW_DECIMAL256(decimal256);
1108 }
1109 
1110 std::shared_ptr<arrow::Decimal256>
garrow_decimal256_get_raw(GArrowDecimal256 * decimal256)1111 garrow_decimal256_get_raw(GArrowDecimal256 *decimal256)
1112 {
1113   auto priv = GARROW_DECIMAL256_GET_PRIVATE(decimal256);
1114   return priv->decimal256;
1115 }
1116