Skip to content

Commit

Permalink
Fix 64-bit number to string conversion in some platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
mobizt committed Oct 25, 2024
1 parent 42a91a7 commit 0352ba1
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 11 deletions.
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "FirebaseClient",
"version": "1.4.1",
"version": "1.4.2",
"keywords": "communication, REST, esp32, esp8266, arduino",
"description": "Async Firebase Client library for Arduino.",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name=FirebaseClient

version=1.4.1
version=1.4.2

author=Mobizt

Expand Down
4 changes: 3 additions & 1 deletion src/core/AsyncClient/AsyncClient.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Created October 6, 2024
* Created October 25, 2024
*
* For MCU build target (CORE_ARDUINO_XXXX), see Options.h.
*
Expand Down Expand Up @@ -396,7 +396,9 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
else if (sData->request.base64)
ret = send(sData, reinterpret_cast<const uint8_t *>("\""), 1, totalLen, async_state_send_payload);

#if defined(ENABLE_FS)
exit:
#endif

if (buf)
mem.release(&buf);
Expand Down
90 changes: 86 additions & 4 deletions src/core/AsyncResult/Value.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Created June 12, 2024
* Created October 25, 2024
*
* The MIT License (MIT)
* Copyright (c) 2024 K. Suwatchai (Mobizt)
Expand Down Expand Up @@ -27,6 +27,7 @@
#include <Arduino.h>
#include <string>


enum realtime_database_data_type
{
realtime_database_data_type_undefined = -1,
Expand All @@ -40,6 +41,83 @@ enum realtime_database_data_type
realtime_database_data_type_array = 7
};


// https://github.com/djGrrr/Int64String
#ifdef base16char
#undef base16char
#endif

#define base16char(i) ("0123456789ABCDEF"[i])

class NumToString
{
public:
NumToString() {}

template <typename T = uint64_t>
auto val(T value, bool sign = false) -> typename std::enable_if<(std::is_same<T, uint64_t>::value), String>::type
{

// start at position 64 (65th byte) and work backwards
uint8_t i = 64;
// 66 buffer for 64 characters (binary) + B prefix + \0
char buffer[66] = {0};

if (value == 0)
buffer[i--] = '0';
else
{
uint8_t base_multiplied = 4;
uint16_t multiplier = 10000;

// Five 64 bit devisions max
while (value > multiplier)
{
uint64_t q = value / multiplier;
// get remainder without doing another division with %
uint16_t r = value - q * multiplier;

for (uint8_t j = 0; j < base_multiplied; j++)
{
uint16_t rq = r / 10;
buffer[i--] = base16char(r - rq * 10);
r = rq;
}

value = q;
}

uint16_t remaining = value;
while (remaining > 0)
{
uint16_t q = remaining / 10;
buffer[i--] = base16char(remaining - q * 10);
remaining = q;
}
}

if (sign)
buffer[i--] = '-';

// return String starting at position i + 1
return String(&buffer[i + 1]);
}

template <typename T = int64_t>
auto val(T value) -> typename std::enable_if<(std::is_same<T, int64_t>::value), String>::type
{
// if signed, make it positive
uint64_t uvalue = value < 0 ? -value : value;
return val(uvalue, value < 0);
}

template <typename T = int>
auto val(T value) -> typename std::enable_if<(!std::is_same<T, uint64_t>::value && !std::is_same<T, int64_t>::value), String>::type
{
return String(value);
}
};

struct boolean_t : public Printable
{
private:
Expand All @@ -61,13 +139,14 @@ struct number_t : public Printable
{
private:
String buf;
NumToString num2Str;

public:
number_t() {}
template <typename T1 = int, typename T = int>
explicit number_t(T1 v, T d) : buf(String(v, d)) {}
template <typename T = int>
explicit number_t(T o) : buf(String(o)) {}
explicit number_t(T o) : buf(num2Str.val(o)) {}
const char *c_str() const { return buf.c_str(); }
size_t printTo(Print &p) const override { return p.print(buf.c_str()); }
};
Expand Down Expand Up @@ -165,7 +244,7 @@ struct object_t : public Printable
private:
explicit operator bool() const { return buf.length() > 0; }

template <typename T = const char*>
template <typename T = const char *>
auto operator=(const T &rval) -> typename std::enable_if<!std::is_same<T, object_t>::value && !std::is_same<T, string_t>::value && !std::is_same<T, number_t>::value && !std::is_same<T, boolean_t>::value, object_t &>::type
{
buf = rval;
Expand Down Expand Up @@ -228,7 +307,10 @@ class ValueConverter
{
if (v_sring<T>::value)
buf += '\"';
buf += value;

NumToString num2Str;
buf += num2Str.val(value);

if (v_sring<T>::value)
buf += '\"';
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#undef FIREBASE_CLIENT_VERSION
#endif

#define FIREBASE_CLIENT_VERSION "1.4.1"
#define FIREBASE_CLIENT_VERSION "1.4.2"

static void sys_idle()
{
Expand Down
6 changes: 3 additions & 3 deletions src/firestore/Values.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Created June 26, 2024
* Created October 25, 2024
*
* The MIT License (MIT)
* Copyright (c) 2024 K. Suwatchai (Mobizt)
Expand Down Expand Up @@ -70,7 +70,6 @@ const struct firebase_firestore_const_key_t firestore_const_key[firestore_const_
*/
namespace Values
{

class NullValue : public Printable
{
private:
Expand Down Expand Up @@ -154,14 +153,15 @@ namespace Values
private:
String buf, str;
ObjectWriter owriter;
NumToString num2Str;
const char *getVal() { return owriter.setPair(str, firestore_const_key[firestore_const_key_integerValue].text, buf); }

public:
/**
* A 64-bit signed integer value.
* @param value The 64-bit signed integer value.
*/
explicit IntegerValue(int64_t value) : buf(StringValue(String(value)).c_str()) { getVal(); }
explicit IntegerValue(int64_t value) : buf(StringValue(num2Str.val(value)).c_str()) { getVal(); }
const char *c_str() const { return buf.c_str(); }
const char *val() { return getVal(); }
size_t printTo(Print &p) const override { return p.print(str.c_str()); }
Expand Down

0 comments on commit 0352ba1

Please sign in to comment.