8#ifndef INCLUDED_BALJSN_JSONCONVERTER
9#define INCLUDED_BALJSN_JSONCONVERTER
180#include <balscm_version.h>
205#include <bsl_iosfwd.h>
206#include <bsl_sstream.h>
207#include <bsl_string.h>
208#include <bsl_vector.h>
213struct JsonConverter_ElementVisitor;
243 bool d_skipUnknownElements;
253 bsl::ostream& logTokenizerError(
const char *alternateString);
270 template <
class TYPE>
272 template <
class TYPE>
274 template <
class TYPE>
276 template <
class TYPE>
278 template <
class TYPE>
280 template <
class TYPE>
282 template <
class TYPE>
284 template <
class TYPE>
289 template <
class TYPE,
class ANY_CATEGORY>
290 int decodeImp(TYPE *value, ANY_CATEGORY category );
320 template <
class TYPE>
330 template <
class TYPE>
379 template <
class TYPE>
385 template <
class TYPE,
class INFO>
386 int operator()(TYPE *value,
const INFO& info);
412 template <
class TYPE>
418 template <
class TYPE,
class ANY_CATEGORY>
419 int operator()(TYPE *
object, ANY_CATEGORY category);
432int JsonConverter::decodeImp(TYPE *value,
441int JsonConverter::decodeImp(TYPE *value,
451 d_elementName.
data(),
452 static_cast<int>(d_elementName.
length()))) {
453 JsonConverter_ElementVisitor visitor = {
this, mode};
458 d_elementName.
data(),
459 static_cast<int>(d_elementName.
length()))) {
460 d_logStream <<
"Could not decode sequence, error decoding "
461 <<
"element or bad element name '"
462 << d_elementName <<
"' \n";
467 if (d_skipUnknownElements) {
468 const int rc = skipUnknownElement(d_elementName);
470 d_logStream <<
"Error reading unknown element '"
471 << d_elementName <<
"' or after it\n";
476 d_logStream <<
"Unknown element '" << d_elementName
483 if (++d_currentDepth > d_maxDepth) {
484 d_logStream <<
"Maximum allowed decoding depth reached: "
485 << d_currentDepth <<
"\n";
490 d_logStream <<
"Could not decode sequence, missing starting '{'\n";
496 d_logStream <<
"Could not decode sequence, ";
497 logTokenizerError(
"error") <<
" reading token after '{'\n";
504 rc = d_tokenizer.
value(&elementName);
506 d_logStream <<
"Error reading attribute name after '{'\n";
513 static_cast<int>(elementName.
length()))) {
514 d_elementName = elementName;
518 logTokenizerError(
"Error")
519 <<
" reading value for"
520 <<
" attribute '" << d_elementName <<
"' \n";
524 JsonConverter_ElementVisitor visitor = {
this, mode};
529 d_elementName.
data(),
530 static_cast<int>(d_elementName.
length()))) {
531 d_logStream <<
"Could not decode sequence, error decoding "
532 <<
"element or bad element name '"
533 << d_elementName <<
"' \n";
538 if (d_skipUnknownElements) {
539 rc = skipUnknownElement(elementName);
541 d_logStream <<
"Error reading unknown element '"
542 << elementName <<
"' or after it\n";
547 d_logStream <<
"Unknown element '" << elementName
555 d_logStream <<
"Could not decode sequence, ";
556 logTokenizerError(
"error") <<
" reading token"
557 <<
" after value for attribute '"
558 << d_elementName <<
"' \n";
564 d_logStream <<
"Could not decode sequence, "
565 <<
"missing terminator '}' or separator ','\n";
575int JsonConverter::decodeImp(TYPE *value,
588 selectionName.
data(),
589 static_cast<int>(selectionName.
length()))) {
592 selectionName.
data(),
593 static_cast<int>(selectionName.
length()))) {
594 d_logStream <<
"Could not decode choice, bad selection name '"
595 << selectionName <<
"' \n";
599 JsonConverter_ElementVisitor visitor = {
this, mode};
603 d_logStream <<
"Could not decode choice, selection "
604 <<
"was not decoded\n";
609 if (d_skipUnknownElements) {
610 const int rc = skipUnknownElement(selectionName);
612 d_logStream <<
"Error reading unknown element '"
613 << selectionName <<
"' or after that "
619 d_logStream <<
"Unknown element '" << selectionName
626 if (++d_currentDepth > d_maxDepth) {
627 d_logStream <<
"Maximum allowed decoding depth reached: "
628 << d_currentDepth <<
"\n";
633 d_logStream <<
"Could not decode choice, missing starting {\n";
639 d_logStream <<
"Could not decode choice, ";
640 logTokenizerError(
"error") <<
" reading token after {\n";
646 rc = d_tokenizer.
value(&selectionName);
648 d_logStream <<
"Error reading selection name after '{'\n";
654 selectionName.
data(),
655 static_cast<int>(selectionName.
length()))) {
658 selectionName.
data(),
659 static_cast<int>(selectionName.
length()))) {
660 d_logStream <<
"Could not decode choice, bad selection "
661 <<
"name '" << selectionName <<
"' \n";
667 d_logStream <<
"Could not decode choice, ";
668 logTokenizerError(
"error") <<
" reading value \n";
672 JsonConverter_ElementVisitor visitor = {
this, mode};
676 d_logStream <<
"Could not decode choice, selection "
677 <<
"was not decoded\n";
682 if (d_skipUnknownElements) {
683 rc = skipUnknownElement(selectionName);
685 d_logStream <<
"Error reading unknown element '"
686 << selectionName <<
"' or after that "
692 d_logStream <<
"Unknown element '" << selectionName
701 d_logStream <<
"Could not decode choice, ";
702 logTokenizerError(
"error") <<
" reading token after value for"
710 d_logStream <<
"Could not decode choice, "
711 <<
"missing terminator '}'\n";
721int JsonConverter::decodeImp(TYPE *value,
725 enum { k_MIN_ENUM_STRING_LENGTH = 2 };
728 d_logStream <<
"Enumeration element value was not found\n";
733 int rc = d_tokenizer.
value(&dataValue);
735 d_logStream <<
"Error reading enumeration value\n";
750 d_logStream <<
"Could not decode Enum String, value not allowed \""
751 << dataValue <<
"\"\n";
761 d_logStream <<
"Error reading enumeration value\n";
769 d_logStream <<
"Could not decode int Enum, value " << intValue
778int JsonConverter::decodeImp(TYPE *value,
783 d_logStream <<
"Customized element value was not found\n";
788 int rc = d_tokenizer.
value(&dataValue);
790 d_logStream <<
"Error reading customized type value\n";
797 BaseType valueBaseType;
807 d_logStream <<
"Could not decode Enum Customized, "
808 <<
"value not allowed \"" << dataValue <<
"\"\n";
815 d_logStream <<
"Could not convert base type to customized type, "
816 <<
"base value disallowed: \"";
818 d_logStream <<
"\"\n";
824int JsonConverter::decodeImp(TYPE *value,
829 d_logStream <<
"Simple element value was not found\n";
834 int rc = d_tokenizer.
value(&dataValue);
836 d_logStream <<
"Error reading simple value\n";
857 d_logStream <<
"Could not decode vector<char> "
858 <<
"expected as an element value\n";
863 int rc = d_tokenizer.
value(&dataValue);
866 d_logStream <<
"Error reading customized type element value\n";
878 int length =
static_cast<int>(base64String.
length());
880 value->
resize(
static_cast<bsl::size_t
>(
883 rc = base64Decoder.convert(value->
begin(),
884 base64String.
begin(),
891 rc = base64Decoder.endConvert(value->
begin() +
892 base64Decoder.outputLength());
898 value->
resize(
static_cast<bsl::size_t
>(base64Decoder.outputLength()));
905int JsonConverter::decodeImp(TYPE *value,
910 d_logStream <<
"Could not decode vector, missing start token: '['\n";
916 logTokenizerError(
"Error") <<
" reading array.\n";
929 JsonConverter_ElementVisitor visitor = {
this, mode};
934 d_logStream <<
"Error adding element '" << i - 1 <<
"'\n";
940 logTokenizerError(
"Error") <<
" reading token after value of"
941 " element '" << i - 1 <<
"'\n";
946 d_logStream <<
"Erroneous token found instead of array element\n";
952 d_logStream <<
"Could not decode vector, missing end token: ']'\n";
960int JsonConverter::decodeImp(TYPE *value,
964 enum { k_NULL_VALUE_LENGTH = 4 };
968 const int rc = d_tokenizer.
value(&dataValue);
973 if (dataValue->
isNull()) {
980 JsonConverter_ElementVisitor visitor = {
this, mode};
985template <
class TYPE,
class ANY_CATEGORY>
987int JsonConverter::decodeImp(TYPE * , ANY_CATEGORY )
1003: d_logStream(
bslma::AllocatorUtil::adapt(allocator))
1008template <
class TYPE>
1015 d_logStream.clear();
1016 d_logStream.str(
"");
1028 <<
"Encoded object must be a Sequence, Choice, or Array type."
1034 static const bool s_FIRST_MEMBER_FLAG =
false;
1046 d_logStream.get_allocator()));
1055 s_FIRST_MEMBER_FLAG);
1059template <
class TYPE>
1066 d_logStream.clear();
1067 d_logStream.str(
"");
1079 <<
"Target object must be a Sequence, Choice, or Array type."
1090 d_tokenizer.
reset(&json);
1095 logTokenizerError(
"Error") <<
" advancing to the first token.\n";
1102 rc = decodeImp(value, 0, TypeCategory());
1110 return d_logStream.str();
1118 return bslma::AATypeUtil::getAllocatorFromSubobject<allocator_type>(
1126template <
class TYPE>
1134template <
class TYPE,
class INFO>
1140 info.formattingMode(),
1149template <
class TYPE>
1158template <
class TYPE,
class ANY_CATEGORY>
1161 ANY_CATEGORY category)
Definition baljsn_convertfromjsonoptions.h:118
int maxDepth() const
Return the value of the maxDepth attribute of this object.
Definition baljsn_convertfromjsonoptions.h:278
bool skipUnknownElements() const
Return the value of the skipUnknownElements attribute of this object.
Definition baljsn_convertfromjsonoptions.h:284
Definition baljsn_converttojsonoptions.h:115
bool convertEmptyArrays() const
Return the value of the convertEmptyArrays attribute of this object.
Definition baljsn_converttojsonoptions.h:273
bool convertNullElements() const
Return the value of the convertNullElements attribute of this object.
Definition baljsn_converttojsonoptions.h:279
Definition baljsn_encoderoptions.h:290
void setEncodeEmptyArrays(bool value)
Definition baljsn_encoderoptions.h:837
void setEncodeNullElements(bool value)
Definition baljsn_encoderoptions.h:843
void setEncodeInfAndNaNAsStrings(bool value)
Definition baljsn_encoderoptions.h:849
Definition baljsn_jsonconverter.h:232
JsonConverter()
Definition baljsn_jsonconverter.h:996
bsl::string loggedMessages() const
Definition baljsn_jsonconverter.h:1108
~JsonConverter()=default
Destroy this object.
allocator_type get_allocator() const
Definition baljsn_jsonconverter.h:1116
int convert(bdljsn::Json *json, const TYPE &value, const ConvertToJsonOptions &options=ConvertToJsonOptions())
Definition baljsn_jsonconverter.h:1009
bsl::allocator allocator_type
Definition baljsn_jsonconverter.h:300
Definition baljsn_jsontokenizer.h:357
@ e_END_OBJECT
Definition baljsn_jsontokenizer.h:367
@ e_START_ARRAY
Definition baljsn_jsontokenizer.h:368
@ e_END_ARRAY
Definition baljsn_jsontokenizer.h:369
@ e_BEGIN
Definition baljsn_jsontokenizer.h:364
@ e_START_OBJECT
Definition baljsn_jsontokenizer.h:366
@ e_ELEMENT_NAME
Definition baljsn_jsontokenizer.h:365
@ e_ELEMENT_VALUE
Definition baljsn_jsontokenizer.h:370
int reset(const bdljsn::Json *json)
TokenType tokenType() const
Return the type of the current token.
Definition baljsn_jsontokenizer.h:652
int value(bsl::string_view *data) const
Definition baljsn_jsontokenizer.h:660
Definition bdlde_base64decoder.h:417
static int maxDecodedLength(int inputLength)
Definition bdlde_base64decoder.h:685
const bsl::string & value() const
Return the textual representation of this JsonNumber.
Definition bdljsn_jsonnumber.h:1010
Definition bdljsn_json.h:1461
bool isNumber() const
Definition bdljsn_json.h:5076
bool isString() const
Definition bdljsn_json.h:5088
JsonNumber & theNumber()
Definition bdljsn_json.h:5112
bool isNull() const
Definition bdljsn_json.h:5070
void makeNull()
Definition bdljsn_json.h:4505
const bsl::string & theString() const
Definition bdljsn_json.h:5320
Definition bslma_bslallocator.h:588
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
size_type length() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7301
size_type size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7292
iterator end() BSLS_KEYWORD_NOEXCEPT
Return the past-the-end iterator for this modifiable string.
Definition bslstl_string.h:6065
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7177
void swap(basic_string &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:2792
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2866
Definition bslstl_vector.h:1120
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1938
void resize(size_type newSize)
Definition bslstl_vector.h:4189
Definition bslstl_stringref.h:374
const CHAR_TYPE * data() const
Definition bslstl_stringref.h:962
size_type length() const
Definition bslstl_stringref.h:984
void assign(const CHAR_TYPE *data, INT_TYPE length, typename bsl::enable_if< bsl::is_integral< INT_TYPE >::value, bslmf::Nil >::type=bslmf::Nil())
Definition bslstl_stringref.h:847
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1414
#define BSLA_FALLTHROUGH
Definition bsla_fallthrough.h:188
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition baljsn_convertfromjsonoptions.h:112
int manipulateElement(TYPE *array, MANIPULATOR &manipulator, int index)
void resize(TYPE *array, int newSize)
bool hasSelection(const TYPE &object, const char *selectionName, int selectionNameLength)
int manipulateSelection(TYPE *object, MANIPULATOR &manipulator)
int makeSelection(TYPE *object, int selectionId)
int convertFromBaseType(TYPE *object, const BASE_TYPE &value)
int manipulateValue(TYPE *object, MANIPULATOR &manipulator)
void makeValue(TYPE *object)
int manipulateAttribute(TYPE *object, MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
bool hasAttribute(const TYPE &object, const char *attributeName, int attributeNameLength)
bdlat_TypeCategory::Value select(const TYPE &object)
void reset(TYPE *object)
Reset the value of the specified object to its default value.
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:725
basic_ostringstream< char, char_traits< char >, allocator< char > > ostringstream
Definition bslstl_iosfwd.h:97
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
Definition baljsn_encoder_testtypes.h:76
static int encode(bsl::ostream *jsonStream, const TYPE &value, const EncoderOptions &options=EncoderOptions())
Definition baljsn_encodeimplutil.h:1237
Definition baljsn_jsonconverter.h:400
int operator()(TYPE *, bslmf::Nil)
Definition baljsn_jsonconverter.h:1151
int d_mode
Definition baljsn_jsonconverter.h:404
JsonConverter * d_decoder_p
Definition baljsn_jsonconverter.h:403
Definition baljsn_jsonconverter.h:364
JsonConverter * d_decoder_p
Definition baljsn_jsonconverter.h:367
int d_mode
Definition baljsn_jsonconverter.h:368
int operator()(TYPE *value)
Definition baljsn_jsonconverter.h:1128
static int getValue(bool *value, const bdljsn::Json &json)
Definition baljsn_jsonparserutil.h:238
static int getValue(bool *value, const bsl::string_view &data)
static int fromIntOrFallbackIfEnabled(TYPE *result, int number)
Definition bdlat_enumutil.h:333
static int fromStringOrFallbackIfEnabled(TYPE *result, const char *string, int stringLength)
Definition bdlat_enumutil.h:347
TYPE::BaseType Type
Definition bdlat_customizedtypefunctions.h:535
Definition bdlat_typecategory.h:1037
Definition bdlat_typecategory.h:1038
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1040
Definition bdlat_typecategory.h:1041
Definition bdlat_typecategory.h:1042
Definition bdlat_typecategory.h:1043
Value
Definition bdlat_typecategory.h:1046
@ e_ARRAY_CATEGORY
Definition bdlat_typecategory.h:1048
@ e_CHOICE_CATEGORY
Definition bdlat_typecategory.h:1049
@ e_SEQUENCE_CATEGORY
Definition bdlat_typecategory.h:1053
Definition bslmf_isintegral.h:140
static bsl::enable_if<!IsDerivedFromBslAllocator< t_ALLOC >::value, t_ALLOC >::type adapt(const t_ALLOC &from)
Definition bslma_allocatorutil.h:871
Definition bslmf_nil.h:133