36 namespace discord_core_internal {
42 template<
typename return_type> DCA_INLINE return_type ntohsNew(return_type value) {
43 return static_cast<return_type
>(((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8));
46 template<
typename return_type> DCA_INLINE return_type ntohlNew(return_type value) {
47 return static_cast<return_type
>(((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24));
50 template<
typename return_type> DCA_INLINE return_type ntohllNew(return_type value) {
51 return static_cast<return_type
>(((value & 0x00000000000000FFull) << 56) | ((value & 0x000000000000FF00ULL) << 40) | ((value & 0x0000000000FF0000ULL) << 24) |
52 ((value & 0x00000000FF000000ULL) << 8) | ((value & 0x000000FF00000000ULL) >> 8) | ((value & 0x0000FF0000000000ULL) >> 24) |
53 ((value & 0x00FF000000000000ULL) >> 40) | ((value & 0xFF00000000000000ULL) >> 56));
61 if constexpr (std::endian::native == std::endian::little) {
62 switch (
sizeof(return_type)) {
88 template<
typename return_type,
typename value_type> DCA_INLINE
void storeBits(value_type* to, return_type num) {
89 static constexpr uint8_t byteSize{ 8 };
93 for (uint64_t x = 0; x <
sizeof(return_type); ++x) {
94 to[x] =
static_cast<value_type
>(num >> (byteSize * x));
103 DCA_INLINE
explicit etf_parse_error(
const jsonifier::string_view& message, std::source_location location = std::source_location::current())
107 enum class etf_type : int8_t {
109 Small_Integer_Ext = 97,
117 Small_Atom_Ext = 115,
121 constexpr uint8_t formatVersion{ 131 };
124 class DiscordCoreAPI_Dll
etf_parser :
public jsonifier_internal::alloc_wrapper<uint8_t> {
126 friend class websocket_client;
127 using allocator = jsonifier_internal::alloc_wrapper<uint8_t>;
132 DCA_INLINE jsonifier::string_view_base<uint8_t>
parseEtfToJson(jsonifier::string_view_base<uint8_t> dataToParse) {
133 dataBuffer = dataToParse.data();
134 dataSize = dataToParse.size();
138 if (readBitsFromBuffer<uint8_t>() != formatVersion) {
139 throw etf_parse_error{
"etf_parser::parseEtfToJson() error: incorrect format version specified." };
141 singleValueETFToJson();
142 return { finalString.data(), currentSize };
146 jsonifier::string_base<uint8_t> finalString{};
147 const uint8_t* dataBuffer{};
148 uint64_t currentSize{};
156 if (offSet +
sizeof(return_type) > dataSize) {
157 throw etf_parse_error{
"etf_parser::readBitsFromBuffer() error: readBitsFromBuffer() past end of the buffer." };
159 return_type newValue{};
160 std::memcpy(&newValue, dataBuffer + offSet,
sizeof(return_type));
161 offSet +=
sizeof(return_type);
170 if (finalString.size() < currentSize + length) {
171 finalString.resize((finalString.size() + length) * 2);
173 std::memcpy(finalString.data() + currentSize, data, length);
174 currentSize += length;
181 if (finalString.size() < currentSize + size - 1) {
182 finalString.resize((finalString.size() + size - 1) * 2);
184 std::memcpy(finalString.data() + currentSize, data, size - 1);
185 currentSize += size - 1;
192 writeCharacters(
"\"\"");
195 if (offSet +
static_cast<uint64_t
>(length) > dataSize) {
196 throw etf_parse_error{
"erl_packer::writeCharactersFromBuffer() error: read past end of buffer." };
198 if (finalString.size() < currentSize + length) {
199 finalString.resize((finalString.size() + length) * 2);
201 const uint8_t* stringNew = dataBuffer + offSet;
203 if (length >= 3 && length <= 5) {
204 if (length == 3 && stringNew[0] ==
'n' && stringNew[1] ==
'i' && stringNew[2] ==
'l') {
205 writeCharacters(
"null");
207 }
else if (length == 4 && stringNew[0] ==
'n' && stringNew[1] ==
'u' && stringNew[2] ==
'l' && stringNew[3] ==
'l') {
208 writeCharacters(
"null");
210 }
else if (length == 4 && stringNew[0] ==
't' && stringNew[1] ==
'r' && stringNew[2] ==
'u' && stringNew[3] ==
'e') {
211 writeCharacters(
"true");
213 }
else if (length == 5 && stringNew[0] ==
'f' && stringNew[1] ==
'a' && stringNew[2] ==
'l' && stringNew[3] ==
's' && stringNew[4] ==
'e') {
214 writeCharacters(
"false");
218 writeCharacter<
'"'>();
219 for (uint64_t x = 0; x < length; ++x) {
220 switch (stringNew[x]) {
222 switch (stringNew[++x]) {
224 writeCharacter<
'\"'>();
227 writeCharacter<'\\'>();
228 writeCharacter<'\\'>();
231 writeCharacter<'\b'>();
234 writeCharacter<'\f'>();
237 writeCharacter<'\n'>();
240 writeCharacter<'\r'>();
243 writeCharacter<'\t'>();
246 writeCharacter(stringNew[x]);
253 writeCharacter<'\\'>();
254 writeCharacter<
'\"'>();
258 writeCharacter(stringNew[x]);
263 writeCharacter<
'"'>();
268 template<
typename value_type> DCA_INLINE
void writeCharacter(
const value_type value) {
269 if (finalString.size() < currentSize + 1) {
270 finalString.resize((finalString.size() + 1) * 2);
272 allocator::construct(&finalString[currentSize++],
static_cast<uint8_t
>(value));
278 if (finalString.size() < currentSize + 1) {
279 finalString.resize((finalString.size() + 1) * 2);
281 allocator::construct(&finalString[currentSize++],
static_cast<uint8_t
>(charToWrite));
286 if (offSet > dataSize) {
287 throw etf_parse_error{
"erl_packer::singleValueETFToJson() error: read past end of buffer." };
289 uint8_t type = readBitsFromBuffer<uint8_t>();
290 switch (
static_cast<etf_type
>(type)) {
291 case etf_type::New_Float_Ext: {
292 return parseNewFloatExt();
294 case etf_type::Small_Integer_Ext: {
295 return parseSmallIntegerExt();
297 case etf_type::Integer_Ext: {
298 return parseIntegerExt();
300 case etf_type::Atom_Ext: {
301 return parseAtomExt();
303 case etf_type::Nil_Ext: {
304 return parseNilExt();
306 case etf_type::String_Ext: {
307 return parseStringExt();
309 case etf_type::List_Ext: {
310 return parseListExt();
312 case etf_type::Binary_Ext: {
313 return parseBinaryExt();
315 case etf_type::Small_Big_Ext: {
316 return parseSmallBigExt();
318 case etf_type::Small_Atom_Ext: {
319 return parseSmallAtomExt();
321 case etf_type::Map_Ext: {
322 return parseMapExt();
325 throw etf_parse_error{
"etf_parser::singleValueETFToJson() error: unknown data type in etf, the type: " + jsonifier::toString(type) };
332 uint32_t length = readBitsFromBuffer<uint32_t>();
333 writeCharacter<'['>();
334 if (
static_cast<uint64_t
>(offSet) + length > dataSize) {
335 throw etf_parse_error{
"erl_packer::parseListExt() error: read past end of buffer." };
337 for (uint16_t x = 0; x < length; ++x) {
338 singleValueETFToJson();
339 if (x < length - 1) {
340 writeCharacter<','>();
343 readBitsFromBuffer<uint8_t>();
344 writeCharacter<']'>();
349 auto string = jsonifier::toString(readBitsFromBuffer<uint8_t>());
350 writeCharacters(
string.data(),
string.size());
355 auto string = jsonifier::toString(readBitsFromBuffer<uint32_t>());
356 writeCharacters(
string.data(),
string.size());
361 writeCharacter<
'"'>();
362 uint16_t length = readBitsFromBuffer<uint16_t>();
363 if (
static_cast<uint64_t
>(offSet) + length > dataSize) {
364 throw etf_parse_error{
"erl_packer::parseStringExt() error: read past end of buffer." };
366 for (uint16_t x = 0; x < length; ++x) {
367 parseSmallIntegerExt();
369 writeCharacter<
'"'>();
374 uint64_t value = readBitsFromBuffer<uint64_t>();
376 std::memcpy(&newDouble, &value,
sizeof(
double));
377 jsonifier::string valueNew = jsonifier::toString(newDouble);
378 writeCharacters(valueNew.data(), valueNew.size());
383 auto digits = readBitsFromBuffer<uint8_t>();
384 uint8_t sign = readBitsFromBuffer<uint8_t>();
387 throw etf_parse_error{
"etf_parser::parseSmallBigExt() error: big integers larger than 8 bytes not supported." };
392 for (uint8_t x = 0; x < digits; ++x) {
393 uint64_t digit = readBitsFromBuffer<uint8_t>();
394 value += digit * bits;
399 auto string = jsonifier::toString(value);
400 writeCharacters(
string.data(),
string.size());
402 auto string = jsonifier::toString(-(
static_cast<int64_t
>(value)));
403 writeCharacters(
string.data(),
string.size());
409 writeCharactersFromBuffer(readBitsFromBuffer<uint16_t>());
414 writeCharactersFromBuffer(readBitsFromBuffer<uint32_t>());
419 writeCharacters(
"[]");
424 writeCharactersFromBuffer(readBitsFromBuffer<uint8_t>());
429 uint32_t length = readBitsFromBuffer<uint32_t>();
430 writeCharacter<
'{'>();
431 for (uint32_t x = 0; x < length; ++x) {
432 singleValueETFToJson();
433 writeCharacter<':'>();
434 singleValueETFToJson();
435 if (x < length - 1) {
436 writeCharacter<','>();
439 writeCharacter<'}'>();
449 DCA_INLINE
etf_serialize_error(
const jsonifier::string_view& message, std::source_location location = std::source_location::current()) :
dca_exception{ message, location } {};
453 enum class json_type : uint8_t { null_t = 0,
object_t = 1,
array_t = 2, string_t = 3, float_t = 4, uint_t = 5, int_t = 6, bool_t = 7 };
456 template<
typename value_type>
457 concept array_t = jsonifier::concepts::range<value_type> && jsonifier::concepts::has_resize<jsonifier_internal::unwrap_t<value_type>> &&
458 jsonifier::concepts::has_emplace_back<jsonifier_internal::unwrap_t<value_type>> && jsonifier::concepts::vector_subscriptable<jsonifier_internal::unwrap_t<value_type>> &&
459 requires(value_type&& data) {
typename value_type::value_type; };
462 template<
typename value_type>
464 typename value_type::mapped_type;
465 typename value_type::key_type;
466 } && jsonifier::concepts::range<value_type>;
468 class etf_serializer {
470 template<
typename value_type>
using allocator = jsonifier_internal::alloc_wrapper<value_type>;
471 using object_type = unordered_map<jsonifier::string, etf_serializer>;
472 using array_type = jsonifier::vector<etf_serializer>;
473 using string_type = jsonifier::string;
474 using float_type = double;
475 using uint_type = uint64_t;
476 using int_type = int64_t;
477 using bool_type = bool;
479 DCA_INLINE etf_serializer() =
default;
481 DCA_INLINE etf_serializer& operator=(etf_serializer&& data)
noexcept {
483 stringReal = std::move(data.stringReal);
485 data.type = json_type::null_t;
487 case json_type::object_t: {
488 objectValue = data.objectValue;
489 data.objectValue =
nullptr;
492 case json_type::array_t: {
493 arrayValue = data.arrayValue;
494 data.arrayValue =
nullptr;
497 case json_type::string_t: {
498 stringValue = data.stringValue;
499 data.stringValue =
nullptr;
502 case json_type::float_t: {
503 floatValue = data.floatValue;
504 data.floatValue =
nullptr;
507 case json_type::int_t: {
508 intValue = data.intValue;
509 data.intValue =
nullptr;
512 case json_type::uint_t: {
513 uintValue = data.uintValue;
514 data.uintValue =
nullptr;
517 case json_type::bool_t: {
518 boolValue = data.boolValue;
519 data.boolValue =
nullptr;
522 case json_type::null_t: {
529 DCA_INLINE etf_serializer(etf_serializer&& data)
noexcept {
530 *
this = std::move(data);
533 DCA_INLINE etf_serializer& operator=(
const etf_serializer& data) {
536 case json_type::object_t: {
537 setValue<json_type::object_t>(data.getObject());
540 case json_type::array_t: {
541 setValue<json_type::array_t>(data.getArray());
544 case json_type::string_t: {
545 setValue<json_type::string_t>(data.getString());
548 case json_type::float_t: {
549 setValue<json_type::float_t>(data.getFloat());
552 case json_type::uint_t: {
553 setValue<json_type::uint_t>(data.getUint());
556 case json_type::int_t: {
557 setValue<json_type::int_t>(data.getInt());
560 case json_type::bool_t: {
561 setValue<json_type::bool_t>(data.getBool());
564 case json_type::null_t: {
568 stringReal = data.stringReal;
572 DCA_INLINE etf_serializer(
const etf_serializer& data) {
576 template<
object_t value_type> DCA_INLINE etf_serializer& operator=(value_type&& data)
noexcept {
577 setValue<json_type::object_t>(std::forward<value_type>(data));
581 template<
object_t value_type> DCA_INLINE etf_serializer(value_type&& data)
noexcept {
582 *
this = std::forward<value_type>(data);
585 template<array_t value_type> DCA_INLINE etf_serializer& operator=(value_type&& data)
noexcept {
586 setValue<json_type::array_t>(std::forward<value_type>(data));
590 template<array_t value_type> DCA_INLINE etf_serializer(value_type&& data)
noexcept {
591 *
this = std::forward<value_type>(data);
594 template<jsonifier::concepts::
string_t value_type> DCA_INLINE etf_serializer& operator=(value_type&& data)
noexcept {
595 setValue<json_type::string_t>(std::forward<value_type>(data));
599 template<jsonifier::concepts::
string_t value_type> DCA_INLINE etf_serializer(value_type&& data)
noexcept {
600 *
this = std::forward<value_type>(data);
603 template<u
int_type str_length> DCA_INLINE etf_serializer& operator=(
const char (&str)[str_length]) {
604 setValue<json_type::string_t>(str);
608 template<u
int_type str_length> DCA_INLINE etf_serializer(
const char (&str)[str_length]) {
612 template<jsonifier::concepts::
float_type value_type> DCA_INLINE etf_serializer& operator=(value_type&& data) {
613 setValue<json_type::float_t>(std::forward<value_type>(data));
617 template<jsonifier::concepts::
float_type value_type> DCA_INLINE etf_serializer(value_type&& data) {
618 *
this = std::forward<value_type>(data);
621 template<jsonifier::concepts::
integer_t value_type> DCA_INLINE etf_serializer& operator=(value_type&& data) {
622 if constexpr (jsonifier::concepts::signed_type<value_type>) {
623 setValue<json_type::int_t>(std::forward<value_type>(data));
624 }
else if constexpr (jsonifier::concepts::unsigned_type<value_type>) {
625 setValue<json_type::uint_t>(std::forward<value_type>(data));
630 template<jsonifier::concepts::
integer_t value_type> DCA_INLINE etf_serializer(value_type&& data) {
631 *
this = std::forward<value_type>(data);
634 template<jsonifier::concepts::
bool_t value_type> DCA_INLINE etf_serializer& operator=(value_type&& data) {
635 setValue<json_type::bool_t>(std::forward<value_type>(data));
639 template<jsonifier::concepts::
bool_t value_type> DCA_INLINE etf_serializer(value_type&& data) {
640 *
this = std::forward<value_type>(data);
643 template<jsonifier::concepts::enum_t value_type> DCA_INLINE etf_serializer& operator=(value_type&& data)
noexcept {
644 setValue<json_type::int_t>(
static_cast<int_type
>(std::forward<value_type>(data)));
648 template<jsonifier::concepts::enum_t value_type> DCA_INLINE etf_serializer(value_type&& data)
noexcept {
649 *
this = std::forward<value_type>(data);
652 DCA_INLINE etf_serializer& operator=(
json_type data) {
655 case json_type::object_t: {
656 setValue<json_type::object_t>();
659 case json_type::array_t: {
660 setValue<json_type::array_t>();
663 case json_type::string_t: {
664 setValue<json_type::string_t>();
667 case json_type::float_t: {
668 setValue<json_type::float_t>();
671 case json_type::uint_t: {
672 setValue<json_type::uint_t>();
675 case json_type::int_t: {
676 setValue<json_type::int_t>();
679 case json_type::bool_t: {
680 setValue<json_type::bool_t>();
683 case json_type::null_t: {
684 setValue<json_type::null_t>();
691 DCA_INLINE etf_serializer(
json_type data) {
699 DCA_INLINE
operator jsonifier::string_base<uint8_t>() {
702 serializeJsonToEtfString(*
this);
706 DCA_INLINE etf_serializer& operator[](
typename object_type::key_type&& key) {
707 if (type == json_type::null_t) {
708 setValue<json_type::object_t>();
711 if (type == json_type::object_t) {
712 return getObject().operator[](std::forward<typename object_type::key_type>(key));
714 throw etf_serialize_error{
"Sorry, but this value's type is not object." };
717 DCA_INLINE etf_serializer& operator[](uint_type index) {
718 if (type == json_type::null_t) {
719 setValue<json_type::array_t>();
722 if (type == json_type::array_t) {
723 if (index >= getArray().size()) {
724 getArray().resize(index + 1);
727 return getArray().at(index);
729 throw etf_serialize_error{
"Sorry, but this value's type is not array." };
732 DCA_INLINE
void emplaceBack(etf_serializer&& data) {
733 if (type == json_type::null_t) {
734 setValue<json_type::array_t>();
737 if (type == json_type::array_t) {
738 getArray().emplace_back(std::move(data));
741 throw etf_serialize_error{
"Sorry, but this value's type is not array." };
744 DCA_INLINE
void emplaceBack(
const etf_serializer& rhs) {
745 if (type == json_type::null_t) {
746 setValue<json_type::array_t>();
749 if (type == json_type::array_t) {
750 getArray().emplace_back(rhs);
753 throw etf_serialize_error{
"Sorry, but this value's type is not array." };
756 DCA_INLINE bool_type operator==(
const etf_serializer& rhs)
const {
757 if (rhs.type != type) {
761 case json_type::object_t: {
762 return *objectValue == *rhs.objectValue;
764 case json_type::array_t: {
765 return *arrayValue == *rhs.arrayValue;
767 case json_type::string_t: {
768 return *stringValue == *rhs.stringValue;
770 case json_type::float_t: {
771 return *floatValue == *rhs.floatValue;
773 case json_type::uint_t: {
774 return *uintValue == *rhs.uintValue;
776 case json_type::int_t: {
777 return *intValue == *rhs.intValue;
779 case json_type::bool_t: {
780 return *boolValue == *rhs.boolValue;
782 case json_type::null_t: {
789 DCA_INLINE object_type& getObject()
const {
790 if (type != json_type::object_t) {
791 throw etf_serialize_error{
"Sorry, but this value's type is not object!" };
796 DCA_INLINE array_type& getArray()
const {
797 if (type != json_type::array_t) {
798 throw etf_serialize_error{
"Sorry, but this value's type is not array!" };
803 DCA_INLINE string_type& getString()
const {
804 if (type != json_type::string_t) {
805 throw etf_serialize_error{
"Sorry, but this value's type is not string!" };
810 DCA_INLINE float_type& getFloat()
const {
811 if (type != json_type::float_t) {
812 throw etf_serialize_error{
"Sorry, but this value's type is not float!" };
817 DCA_INLINE uint_type& getUint()
const {
818 if (type != json_type::uint_t) {
819 throw etf_serialize_error{
"Sorry, but this value's type is not uint!" };
824 DCA_INLINE int_type& getInt()
const {
825 if (type != json_type::int_t) {
826 throw etf_serialize_error{
"Sorry, but this value's type is not int!" };
831 DCA_INLINE bool_type& getBool()
const {
832 if (type != json_type::bool_t) {
833 throw etf_serialize_error{
"Sorry, but this value's type is not bool!" };
838 DCA_INLINE ~etf_serializer() {
843 jsonifier::string_base<uint8_t> stringReal{};
846 object_type* objectValue;
847 array_type* arrayValue;
848 string_type* stringValue;
849 float_type* floatValue;
850 uint_type* uintValue;
852 bool_type* boolValue;
855 DCA_INLINE
void serializeJsonToEtfString(
const etf_serializer& dataToParse) {
856 switch (dataToParse.type) {
857 case json_type::object_t: {
858 return writeEtfObject(dataToParse.getObject());
860 case json_type::array_t: {
861 return writeEtfArray(dataToParse.getArray());
863 case json_type::string_t: {
864 return writeEtfString(dataToParse.getString());
866 case json_type::float_t: {
867 return writeEtfFloat(dataToParse.getFloat());
869 case json_type::uint_t: {
870 return writeEtfUint(dataToParse.getUint());
872 case json_type::int_t: {
873 return writeEtfInt(dataToParse.getInt());
875 case json_type::bool_t: {
876 return writeEtfBool(dataToParse.getBool());
878 case json_type::null_t: {
879 return writeEtfNull();
884 DCA_INLINE
void writeEtfObject(
const object_type& jsonData) {
885 appendMapHeader(
static_cast<uint32_t
>(jsonData.size()));
886 for (
auto& [key, valueNew]: jsonData) {
887 appendBinaryExt(key,
static_cast<uint32_t
>(key.size()));
888 serializeJsonToEtfString(valueNew);
892 DCA_INLINE
void writeEtfArray(
const array_type& jsonData) {
893 appendListHeader(
static_cast<uint32_t
>(jsonData.size()));
894 for (
auto& valueNew: jsonData) {
895 serializeJsonToEtfString(valueNew);
900 DCA_INLINE
void writeEtfString(
const string_type& jsonData) {
901 appendBinaryExt(jsonData,
static_cast<uint32_t
>(jsonData.size()));
904 DCA_INLINE
void writeEtfUint(
const uint_type jsonData) {
905 if (jsonData <= std::numeric_limits<uint8_t>::max() && jsonData >= std::numeric_limits<uint8_t>::min()) {
906 appendUint8(
static_cast<uint8_t
>(jsonData));
907 }
else if (jsonData <= std::numeric_limits<uint32_t>::max() && jsonData >= std::numeric_limits<uint32_t>::min()) {
908 appendUint32(
static_cast<uint32_t
>(jsonData));
910 appendUint64(jsonData);
914 DCA_INLINE
void writeEtfInt(
const int_type jsonData) {
915 if (jsonData <= std::numeric_limits<int8_t>::max() && jsonData >= std::numeric_limits<int8_t>::min()) {
916 appendInt8(
static_cast<int8_t
>(jsonData));
917 }
else if (jsonData <= std::numeric_limits<int32_t>::max() && jsonData >= std::numeric_limits<int32_t>::min()) {
918 appendInt32(
static_cast<int32_t
>(jsonData));
920 appendInt64(jsonData);
924 DCA_INLINE
void writeEtfFloat(
const float_type jsonData) {
925 appendNewFloatExt(jsonData);
928 DCA_INLINE
void writeEtfBool(
const bool_type jsonData) {
929 appendBool(jsonData);
932 DCA_INLINE
void writeEtfNull() {
936 template<
typename value_type> DCA_INLINE
void writeString(
const value_type* data, uint_type length) {
937 auto oldSize = stringReal.size();
938 stringReal.resize(oldSize + length);
939 std::memcpy(stringReal.data() + oldSize, data, length);
942 DCA_INLINE
void appendBinaryExt(jsonifier::string_view bytes, uint32_t sizeNew) {
943 uint8_t newBuffer[5]{
static_cast<uint8_t
>(etf_type::Binary_Ext) };
945 writeString(newBuffer, std::size(newBuffer));
946 writeString(bytes.data(), bytes.size());
949 DCA_INLINE
void appendNewFloatExt(
const float_type newFloat) {
950 uint8_t newBuffer[9]{
static_cast<uint8_t
>(etf_type::New_Float_Ext) };
951 uint_type newValue{};
952 std::memcpy(&newValue, &newFloat,
sizeof(newFloat));
954 writeString(newBuffer, std::size(newBuffer));
957 DCA_INLINE
void appendListHeader(
const uint32_t sizeNew) {
958 uint8_t newBuffer[5]{
static_cast<uint8_t
>(etf_type::List_Ext) };
960 writeString(newBuffer, std::size(newBuffer));
963 DCA_INLINE
void appendMapHeader(
const uint32_t sizeNew) {
964 uint8_t newBuffer[5]{
static_cast<uint8_t
>(etf_type::Map_Ext) };
966 writeString(newBuffer, std::size(newBuffer));
969 DCA_INLINE
void appendUint64(uint_type valueNew) {
970 uint8_t newBuffer[11]{
static_cast<uint8_t
>(etf_type::Small_Big_Ext) };
971 uint8_t encodedBytes{};
972 while (valueNew > 0) {
973 newBuffer[3 + encodedBytes] =
static_cast<uint8_t
>(valueNew & 0xFF);
977 newBuffer[1] = encodedBytes;
979 writeString(newBuffer, 1ull + 2ull +
static_cast<uint_type
>(encodedBytes));
982 DCA_INLINE
void appendInt64(int_type valueNew) {
983 uint8_t newBuffer[11]{
static_cast<uint8_t
>(etf_type::Small_Big_Ext) };
984 uint8_t encodedBytes{};
985 while (valueNew > 0) {
986 newBuffer[3 + encodedBytes] =
static_cast<uint8_t
>(valueNew & 0xFF);
990 newBuffer[1] = encodedBytes;
996 writeString(newBuffer, 1ull + 2ull +
static_cast<uint_type
>(encodedBytes));
999 DCA_INLINE
void appendUint32(
const uint32_t valueNew) {
1000 uint8_t newBuffer[5]{
static_cast<uint8_t
>(etf_type::Integer_Ext) };
1002 writeString(newBuffer, std::size(newBuffer));
1005 DCA_INLINE
void appendInt32(
const int32_t valueNew) {
1006 uint8_t newBuffer[5]{
static_cast<uint8_t
>(etf_type::Integer_Ext) };
1008 writeString(newBuffer, std::size(newBuffer));
1011 DCA_INLINE
void appendUint8(
const uint8_t valueNew) {
1012 uint8_t newBuffer[2]{
static_cast<uint8_t
>(etf_type::Small_Integer_Ext),
static_cast<uint8_t
>(valueNew) };
1013 writeString(newBuffer, std::size(newBuffer));
1016 DCA_INLINE
void appendInt8(
const int8_t valueNew) {
1017 uint8_t newBuffer[2]{
static_cast<uint8_t
>(etf_type::Small_Integer_Ext),
static_cast<uint8_t
>(valueNew) };
1018 writeString(newBuffer, std::size(newBuffer));
1021 DCA_INLINE
void appendBool(bool_type data) {
1023 uint8_t newBuffer[6]{
static_cast<uint8_t
>(etf_type::Small_Atom_Ext),
static_cast<uint8_t
>(4),
't',
'r',
'u',
'e' };
1024 writeString(newBuffer, std::size(newBuffer));
1027 uint8_t newBuffer[7]{
static_cast<uint8_t
>(etf_type::Small_Atom_Ext),
static_cast<uint8_t
>(5),
'f',
'a',
'l',
's',
'e' };
1028 writeString(newBuffer, std::size(newBuffer));
1032 DCA_INLINE
void appendVersion() {
1033 uint8_t newBuffer[1]{
static_cast<uint8_t
>(formatVersion) };
1034 writeString(newBuffer, std::size(newBuffer));
1037 DCA_INLINE
void appendNilExt() {
1038 uint8_t newBuffer[1]{
static_cast<uint8_t
>(etf_type::Nil_Ext) };
1039 writeString(newBuffer, std::size(newBuffer));
1042 DCA_INLINE
void appendNil() {
1043 uint8_t newBuffer[5]{
static_cast<uint8_t
>(etf_type::Small_Atom_Ext),
static_cast<uint8_t
>(3),
'n',
'i',
'l' };
1044 writeString(newBuffer, std::size(newBuffer));
1047 template<
json_type typeNew,
typename... value_types> DCA_INLINE
void setValue(value_types&&... args) {
1050 if constexpr (typeNew == json_type::object_t) {
1051 allocator<object_type> alloc{};
1052 objectValue = alloc.allocate(1);
1053 alloc.construct(objectValue, std::forward<value_types>(args)...);
1054 }
else if constexpr (typeNew == json_type::array_t) {
1055 allocator<array_type> alloc{};
1056 arrayValue = alloc.allocate(1);
1057 alloc.construct(arrayValue, std::forward<value_types>(args)...);
1058 }
else if constexpr (typeNew == json_type::string_t) {
1059 allocator<string_type> alloc{};
1060 stringValue = alloc.allocate(1);
1061 alloc.construct(stringValue, std::forward<value_types>(args)...);
1062 }
else if constexpr (typeNew == json_type::float_t) {
1063 allocator<float_type> alloc{};
1064 floatValue = alloc.allocate(1);
1065 alloc.construct(floatValue, std::forward<value_types>(args)...);
1066 }
else if constexpr (typeNew == json_type::uint_t) {
1067 allocator<uint_type> alloc{};
1068 uintValue = alloc.allocate(1);
1069 alloc.construct(uintValue, std::forward<value_types>(args)...);
1070 }
else if constexpr (typeNew == json_type::int_t) {
1071 allocator<int_type> alloc{};
1072 intValue = alloc.allocate(1);
1073 alloc.construct(intValue, std::forward<value_types>(args)...);
1074 }
else if constexpr (typeNew == json_type::bool_t) {
1075 allocator<bool_type> alloc{};
1076 boolValue = alloc.allocate(1);
1077 alloc.construct(boolValue, std::forward<value_types>(args)...);
1081 DCA_INLINE
void destroy() {
1083 case json_type::object_t: {
1084 allocator<object_type> alloc{};
1085 alloc.destroy(objectValue);
1086 alloc.deallocate(
static_cast<object_type*
>(objectValue));
1087 objectValue =
nullptr;
1090 case json_type::array_t: {
1091 allocator<array_type> alloc{};
1092 alloc.destroy(arrayValue);
1093 alloc.deallocate(
static_cast<array_type*
>(arrayValue));
1094 arrayValue =
nullptr;
1097 case json_type::string_t: {
1098 allocator<string_type> alloc{};
1099 alloc.destroy(stringValue);
1100 alloc.deallocate(
static_cast<string_type*
>(stringValue));
1101 stringValue =
nullptr;
1104 case json_type::float_t: {
1105 allocator<float_type> alloc{};
1106 alloc.destroy(floatValue);
1107 alloc.deallocate(
static_cast<float_type*
>(floatValue));
1108 floatValue =
nullptr;
1111 case json_type::uint_t: {
1112 allocator<uint_type> alloc{};
1113 alloc.destroy(uintValue);
1114 alloc.deallocate(
static_cast<uint_type*
>(uintValue));
1115 uintValue =
nullptr;
1118 case json_type::int_t: {
1119 allocator<int_type> alloc{};
1120 alloc.destroy(intValue);
1121 alloc.deallocate(
static_cast<int_type*
>(intValue));
1125 case json_type::bool_t: {
1126 allocator<bool_type> alloc{};
1127 alloc.destroy(boolValue);
1128 alloc.deallocate(
static_cast<bool_type*
>(boolValue));
1129 boolValue =
nullptr;
1132 case json_type::null_t: {
1139 type = json_type::null_t;
Class for parsing etf data into json format.
DCA_INLINE void parseAtomExt()
Parse etf data representing an atom and convert to json string.
DCA_INLINE void parseNewFloatExt()
Parse etf data representing a new float and convert to json number.
DCA_INLINE void writeCharacters(const char(&data)[size])
Write characters to the final json string.
DCA_INLINE void parseIntegerExt()
Parse etf data representing an integer and convert to json number.
DCA_INLINE void singleValueETFToJson()
Parse a single etf value and convert to json.
DCA_INLINE void writeCharacter(const value_type value)
Write a character to the final json string.
DCA_INLINE void parseNilExt()
Parse etf data representing a nil value and convert to json null.
DCA_INLINE void parseListExt()
Parse etf data representing a list and convert to json array.
DCA_INLINE void parseMapExt()
Parse etf data representing a map and convert to json object.
DCA_INLINE void writeCharactersFromBuffer(uint32_t length)
Write characters from the buffer to the final json string.
DCA_INLINE jsonifier::string_view_base< uint8_t > parseEtfToJson(jsonifier::string_view_base< uint8_t > dataToParse)
Parse etf data to json format.
DCA_INLINE void parseStringExt()
Parse etf data representing a string and convert to json string.
DCA_INLINE return_type readBitsFromBuffer()
Read bits from the data buffer and convert to return_type.
DCA_INLINE void parseSmallIntegerExt()
Parse etf data representing a small integer and convert to json number.
DCA_INLINE void parseBinaryExt()
Parse etf data representing a binary and convert to json string.
DCA_INLINE void parseSmallBigExt()
Parse etf data representing a small big integer and convert to json number.
DCA_INLINE void parseSmallAtomExt()
Parse etf data representing a small atom and convert to json string.
DCA_INLINE void writeCharacter()
Write a character to the final json string.
DCA_INLINE void writeCharacters(const char *data, uint64_t length)
Write characters to the final json string.
Concept for array types excluding etf_serializer.
Concept for object (associative container) types excluding etf_serializer.
DCA_INLINE void storeBits(value_type *to, return_type num)
Stores the bits of a number into a character array.
json_type
Enumeration for different json value types.
DCA_INLINE void reverseByteOrder(return_type &net)
Reverses the byte order of a value if needed, based on the endianness.
The main namespace for the forward-facing interfaces.
DCA_INLINE dca_exception(jsonifier::string_view error, std::source_location location=std::source_location::current())
Constructor to create a dca_exception with an error message and optional source location.
Exception class for etf parsing errors.
DCA_INLINE etf_parse_error(const jsonifier::string_view &message, std::source_location location=std::source_location::current())
Constructs an etf_parse_error instance with a message and source location.
Custom exception class for etf serialization errors.
DCA_INLINE etf_serialize_error(const jsonifier::string_view &message, std::source_location location=std::source_location::current())
Constructor for etf_serialize_error.