ViniciusSouzaRoque commented on a change in pull request #12306:
URL: https://github.com/apache/arrow/pull/12306#discussion_r798431975



##########
File path: cpp/src/gandiva/gdv_function_stubs.cc
##########
@@ -683,6 +683,215 @@ const char* gdv_fn_upper_utf8(int64_t context, const 
char* data, int32_t data_le
   return out;
 }
 
+GDV_FORCE_INLINE
+uint64_t unsigned_long_div(gdv_int64 x, gdv_int32 m) {
+  if (x >= 0) {
+    return x / m;
+  }
+  return x / m + 2 * (LONG_MAX / m) + 2 / m + (x % m + 2 * (LONG_MAX % m) + 2 
% m) / m;
+}
+
+GDV_FORCE_INLINE
+gdv_int64 encode(gdv_int32 radix, gdv_int32 fromPos, const char* value,
+                 gdv_int32 valueLen) {
+  uint64_t val = 0;
+  uint64_t bound = unsigned_long_div(-1 - radix, radix);
+
+  for (int i = fromPos; i < valueLen && value[i] >= 0; i++) {
+    if (val >= bound) {
+      if (unsigned_long_div(-1 - value[i], radix) < val) {
+        return -1;
+      }
+    }
+    val = val * radix + value[i];
+  }
+  return val;
+}
+
+GDV_FORCE_INLINE
+void decode(gdv_int64 val, gdv_int32 radix, char* value, gdv_int32 valueLen) {
+  for (int i = 0; i < valueLen; i++) {
+    value[i] = static_cast<char>(0);
+  }
+
+  for (int i = valueLen - 1; val != 0; i--) {
+    gdv_int64 q = unsigned_long_div(val, radix);
+    value[i] = static_cast<char>((val - q * radix));
+    val = q;
+  }
+}
+
+// From Decimal to Any Base
+GDV_FORCE_INLINE
+char character_for_digit(gdv_int32 value, gdv_int32 radix) {
+  // This function is similar to Character.forDigit in Java
+  int digit = 0;
+  digit = value % radix;
+  if (digit < 10) {
+    return static_cast<char>(digit + '0');
+  } else {
+    return static_cast<char>(digit + 'A' - 10);
+  }
+}
+
+// From any base to Decimal
+GDV_FORCE_INLINE
+gdv_int64 character_digit(char value, gdv_int32 radix) {
+  // This function is similar to Character.digit in Java
+  if ((radix <= 0) || (radix > 36)) {
+    return -1;
+  }
+
+  if (radix <= 10) {
+    if (value >= '0' && value < '0' + radix) {
+      return value - '0';
+    } else {
+      return -1;
+    }
+  } else if (value >= '0' && value <= '9') {
+    return value - '0';
+  } else if (value >= 'a' && value < 'a' + radix - 10) {
+    return value - 'a' + 10;
+  } else if (value >= 'A' && value < 'A' + radix - 10) {
+    return value - 'A' + 10;
+  }
+
+  return -1;
+}
+
+GDV_FORCE_INLINE
+void byte2char(gdv_int32 radix, gdv_int32 fromPos, char* value, gdv_int32 
valueLen) {
+  for (int i = fromPos; i < valueLen; i++) {
+    value[i] = static_cast<char>(character_for_digit(value[i], radix));
+  }
+}
+
+GDV_FORCE_INLINE
+int32_t char2byte(gdv_int32 radix, gdv_int32 fromPos, char* value, gdv_int32 
valueLen) {
+  for (int i = fromPos; i < valueLen; i++) {
+    value[i] = static_cast<char>(character_digit(value[i], radix));
+    if (value[i] == -1) {
+      return -1;
+    }
+  }
+  return 1;
+}
+
+GANDIVA_EXPORT
+const char* conv_int64_int32_int32(gdv_int64 context, gdv_int64 in, gdv_int32 
from_base,
+                                   gdv_int32 to_base, int32_t* out_len) {
+  std::string to_utf8 = std::to_string(in);
+  char* in_utf8 = &to_utf8[0];
+  gdv_int32 in_utf8_len = to_utf8.length();
+
+  return conv_utf8_int32_int32(context, in_utf8, in_utf8_len, from_base, 
to_base,
+                               out_len);
+}
+
+GANDIVA_EXPORT
+const char* conv_int32_int32_int32(gdv_int64 context, gdv_int32 in, gdv_int32 
from_base,
+                                   gdv_int32 to_base, int32_t* out_len) {
+  std::string to_utf8 = std::to_string(in);
+  char* in_utf8 = &to_utf8[0];
+  gdv_int32 in_utf8_len = to_utf8.length();

Review comment:
       Done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@arrow.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to