8#ifndef INCLUDED_BALJSN_DECODER
9#define INCLUDED_BALJSN_DECODER
203#include <balscm_version.h>
235#include <bsl_iostream.h>
236#include <bsl_sstream.h>
237#include <bsl_streambuf.h>
238#include <bsl_string.h>
239#include <bsl_string_view.h>
240#include <bsl_unordered_set.h>
268 bool d_skipUnknownElements;
269 int d_numUnknownElementsSkipped;
271 bool d_allowMissingRequiredAttributes;
293 template <
class TYPE>
295 template <
class TYPE>
297 template <
class TYPE>
299 template <
class TYPE>
301 template <
class TYPE>
303 template <
class TYPE>
305 template <
class TYPE>
307 template <
class TYPE>
312 template <
class TYPE,
class ANY_CATEGORY>
313 int decodeImp(TYPE *value, ANY_CATEGORY category);
318 bsl::ostream& logTokenizerError(
const char *alternateString);
351 template <
class TYPE>
352 int decode(bsl::streambuf *streamBuf,
355 template <
class TYPE>
356 int decode(bsl::streambuf *streamBuf,
371 template <
class TYPE>
372 int decode(bsl::istream& stream,
375 template <
class TYPE>
376 int decode(bsl::istream& stream,
386 template <
class TYPE>
387 int decode(bsl::streambuf *streamBuf, TYPE *value);
397 template <
class TYPE>
398 int decode(bsl::istream& stream, TYPE *value);
411 template <
class TYPE>
415 template <
class TYPE>
434 template <
class TYPE>
438 template <
class TYPE>
487 template <
class TYPE>
493 template <
class TYPE,
class INFO>
494 int operator()(TYPE *value,
const INFO& info);
520 template <
class TYPE>
526 template <
class TYPE,
class ANY_CATEGORY>
527 int operator()(TYPE *
object, ANY_CATEGORY category);
544 template <
class TYPE,
class INFO>
545 int operator()(TYPE *value,
const INFO& info);
564 template <
class t_BASE_TYPE>
575 d_logStream <<
"Could not decode Enum Customized, "
576 <<
"value not allowed \"" <<
d_dataValue <<
"\"\n";
584 template <
class t_REF>
609 d_elementName.
data(),
610 static_cast<int>(d_elementName.
length()))) {
616 d_elementName.
data(),
617 static_cast<int>(d_elementName.
length()))) {
618 d_logStream <<
"Could not decode sequence, error decoding "
619 <<
"element or bad element name '"
620 << d_elementName <<
"' \n";
625 if (d_skipUnknownElements) {
626 const int rc = skipUnknownElement(d_elementName);
628 d_logStream <<
"Error reading unknown element '"
629 << d_elementName <<
"' or after it\n";
634 d_logStream <<
"Unknown element '" << d_elementName
641 if (++d_currentDepth > d_maxDepth) {
642 d_logStream <<
"Maximum allowed decoding depth reached: "
643 << d_currentDepth <<
"\n";
648 d_logStream <<
"Could not decode sequence, missing starting '{'\n";
654 d_logStream <<
"Could not decode sequence, ";
655 logTokenizerError(
"error") <<
" reading token after '{'\n";
661 if (!d_allowMissingRequiredAttributes) {
663 Decoder_RequiredAttrsVisitor visitor = {&requiredAttributes,
664 ::BloombergLP::bdlat_UsesDefaultValueFlag<TYPE>::value};
671 rc = d_tokenizer.
value(&elementName);
673 d_logStream <<
"Error reading attribute name after '{'\n";
680 static_cast<int>(elementName.
length()))) {
681 d_elementName = elementName;
685 logTokenizerError(
"Error") <<
" reading value for"
686 <<
" attribute '" << d_elementName <<
"' \n";
695 d_elementName.
data(),
696 static_cast<int>(d_elementName.
length()))) {
697 d_logStream <<
"Could not decode sequence, error decoding "
698 <<
"element or bad element name '"
699 << d_elementName <<
"' \n";
703 if (!requiredAttributes.empty()) {
704 requiredAttributes.
erase(elementName);
708 if (d_skipUnknownElements) {
709 rc = skipUnknownElement(elementName);
711 d_logStream <<
"Error reading unknown element '"
712 << elementName <<
"' or after it\n";
717 d_logStream <<
"Unknown element '"
718 << elementName <<
"' found\n";
725 d_logStream <<
"Could not decode sequence, ";
726 logTokenizerError(
"error") <<
" reading token"
727 <<
" after value for attribute '"
728 << d_elementName <<
"' \n";
734 d_logStream <<
"Could not decode sequence, "
735 <<
"missing terminator '}' or seperator ','\n";
739 if (!requiredAttributes.empty()) {
742 d_logStream <<
"Could not decode sequence, "
743 <<
"missing required attribute \""
744 << *requiredAttributes.begin() <<
"\"\n";
754int Decoder::decodeImp(TYPE *value,
767 selectionName.
data(),
768 static_cast<int>(selectionName.
length()))) {
771 selectionName.
data(),
772 static_cast<int>(selectionName.
length()))) {
773 d_logStream <<
"Could not decode choice, bad selection name '"
774 << selectionName <<
"' \n";
782 d_logStream <<
"Could not decode choice, selection "
783 <<
"was not decoded\n";
788 if (d_skipUnknownElements) {
789 const int rc = skipUnknownElement(selectionName);
791 d_logStream <<
"Error reading unknown element '"
792 << selectionName <<
"' or after that "
798 d_logStream <<
"Unknown element '"
799 << selectionName <<
"' found\n";
805 if (++d_currentDepth > d_maxDepth) {
806 d_logStream <<
"Maximum allowed decoding depth reached: "
807 << d_currentDepth <<
"\n";
812 d_logStream <<
"Could not decode choice, missing starting {\n";
818 d_logStream <<
"Could not decode choice, ";
819 logTokenizerError(
"error") <<
" reading token after {\n";
825 rc = d_tokenizer.
value(&selectionName);
827 d_logStream <<
"Error reading selection name after '{'\n";
833 selectionName.
data(),
834 static_cast<int>(selectionName.
length()))) {
837 selectionName.
data(),
838 static_cast<int>(selectionName.
length()))) {
839 d_logStream <<
"Could not decode choice, bad selection "
840 <<
"name '" << selectionName <<
"' \n";
846 d_logStream <<
"Could not decode choice, ";
847 logTokenizerError(
"error") <<
" reading value \n";
855 d_logStream <<
"Could not decode choice, selection "
856 <<
"was not decoded\n";
861 if (d_skipUnknownElements) {
862 rc = skipUnknownElement(selectionName);
864 d_logStream <<
"Error reading unknown element '"
865 << selectionName <<
"' or after that "
871 d_logStream <<
"Unknown element '"
872 << selectionName <<
"' found\n";
879 d_logStream <<
"Could not decode choice, ";
880 logTokenizerError(
"error") <<
" reading token after value for"
888 d_logStream <<
"Could not decode choice, "
889 <<
"missing terminator '}'\n";
901 enum { k_MIN_ENUM_STRING_LENGTH = 2 };
904 d_logStream <<
"Enumeration element value was not found\n";
909 int rc = d_tokenizer.
value(&dataValue);
911 d_logStream <<
"Error reading enumeration value\n";
915 if (dataValue.
length() >= k_MIN_ENUM_STRING_LENGTH &&
916 '"' == dataValue.
front() &&
'"' == dataValue.
back()) {
917 const int kBufSize = 128;
923 d_logStream <<
"Error reading enumeration value\n";
928 value, tmpString.data(),
static_cast<int>(tmpString.size()));
930 d_logStream <<
"Could not decode Enum String, value not allowed \""
931 << dataValue <<
"\"\n";
941 d_logStream <<
"Error reading enumeration value\n";
947 d_logStream <<
"Could not decode int Enum, value " << intValue
958 d_logStream <<
"Customized element value was not found\n";
963 int rc = d_tokenizer.
value(&dataValue);
965 d_logStream <<
"Error reading customized type value\n";
969 CustomizedManipulator baseManipulator = {d_logStream, dataValue,
false};
973 if (rc && baseManipulator.d_convertCalled) {
974 d_logStream <<
"Could not convert base type to customized type, "
975 <<
"base value disallowed: \"";
977 d_logStream <<
"\"\n";
986 d_logStream <<
"Simple element value was not found\n";
991 int rc = d_tokenizer.
value(&dataValue);
993 d_logStream <<
"Error reading simple value\n";
1013 d_logStream <<
"Could not decode vector<char> "
1014 <<
"expected as an element value\n";
1019 int rc = d_tokenizer.
value(&dataValue);
1022 d_logStream <<
"Error reading customized type element value\n";
1029template <
class TYPE>
1030int Decoder::decodeImp(TYPE *value,
1035 d_logStream <<
"Could not decode vector, missing start token: '['\n";
1041 logTokenizerError(
"Error") <<
" reading array.\n";
1058 d_logStream <<
"Error adding element '" << i - 1 <<
"'\n";
1064 logTokenizerError(
"Error") <<
" reading token after value of"
1065 " element '" << i - 1 <<
"'\n";
1070 d_logStream <<
"Erroneous token found instead of array element\n";
1076 d_logStream <<
"Could not decode vector, missing end token: ']'\n";
1083template <
class TYPE>
1084int Decoder::decodeImp(TYPE *value,
1088 enum { k_NULL_VALUE_LENGTH = 4 };
1092 const int rc = d_tokenizer.
value(&dataValue);
1097 if (k_NULL_VALUE_LENGTH == dataValue.
length()
1098 &&
'n' == dataValue[0]
1099 &&
'u' == dataValue[1]
1100 &&
'l' == dataValue[2]
1101 &&
'l' == dataValue[3]) {
1112template <
class TYPE,
class ANY_CATEGORY>
1114int Decoder::decodeImp(TYPE *, ANY_CATEGORY)
1124: d_logStream(basicAllocator)
1125, d_tokenizer(basicAllocator)
1126, d_elementName(basicAllocator)
1129, d_skipUnknownElements(false)
1130, d_numUnknownElementsSkipped(0)
1131, d_allowMissingRequiredAttributes(
1132 DecoderOptions::DEFAULT_INITIALIZER_ALLOW_MISSING_REQUIRED_ATTRIBUTES)
1137template <
class TYPE>
1145 d_logStream.clear();
1146 d_logStream.str(
"");
1151 d_numUnknownElementsSkipped = 0;
1153 d_allowMissingRequiredAttributes =
1162 d_logStream <<
"The object being decoded must be a Sequence, "
1163 <<
"Choice, or Array type\n";
1167 d_tokenizer.
reset(streamBuf);
1182 logTokenizerError(
"Error") <<
" advancing to the first token. "
1183 "Expecting a '{' or '[' as the first character\n";
1189 rc = decodeImp(value, 0, TypeCategory());
1196template <
class TYPE>
1202 return decode(streamBuf, value, options ? *options : localOpts);
1205template <
class TYPE>
1210 if (!stream.good()) {
1212 <<
"Input stream state is not 'good()' ["
1213 << (stream.bad() ?
" 'bad()'" :
"")
1214 << (stream.fail() ?
" 'fail()'" :
"")
1215 << (stream.eof() ?
" 'eof()'" :
"")
1216 <<
" ] - nothing to decode\n";
1220 if (0 !=
decode(stream.rdbuf(), value, options)) {
1221 stream.setstate(bsl::ios_base::failbit);
1228template <
class TYPE>
1234 return decode(stream, value, options ? *options : localOpts);
1237template <
class TYPE>
1241 return decode(streamBuf, value, options);
1244template <
class TYPE>
1248 return decode(stream, value, options);
1251template <
class TYPE>
1258 return decodeAny(streamBuf, &any, options);
1261template <
class TYPE>
1270template <
class TYPE>
1277 return decodeAny(stream, &any, options);
1280template <
class TYPE>
1293 return d_logStream.str();
1299 return d_numUnknownElementsSkipped;
1306template <
class TYPE>
1314template <
class TYPE,
class INFO>
1320 info.formattingMode(),
1329template <
class TYPE>
1338template <
class TYPE,
class ANY_CATEGORY>
1341 ANY_CATEGORY category)
1351template <
class TYPE,
class INFO>
Definition baljsn_decoderoptions.h:155
bool validateInputIsUtf8() const
Definition baljsn_decoderoptions.h:739
bool allowUnescapedControlCharacters() const
Definition baljsn_decoderoptions.h:757
bool allowMissingRequiredAttributes() const
Definition baljsn_decoderoptions.h:763
bool skipUnknownElements() const
Definition baljsn_decoderoptions.h:733
bool allowConsecutiveSeparators() const
Definition baljsn_decoderoptions.h:745
bool allowFormFeedAsWhitespace() const
Definition baljsn_decoderoptions.h:751
int maxDepth() const
Return the value of the "MaxDepth" attribute of this object.
Definition baljsn_decoderoptions.h:727
Definition baljsn_decoder.h:260
friend struct Decoder_ElementVisitor
Definition baljsn_decoder.h:276
int decodeAny(bsl::streambuf *streamBuf, bdlar::AnyRef *value, const DecoderOptions &options)
int decodeAny(bsl::istream &stream, bdlar::AnyRef *value, const DecoderOptions &options)
int numUnknownElementsSkipped() const
Definition baljsn_decoder.h:1297
int decode(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions &options)
Definition baljsn_decoder.h:1138
bsl::string loggedMessages() const
Definition baljsn_decoder.h:1291
int decodeAny(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions &options)
Definition baljsn_decoder.h:1253
Definition bdlar_anyref.h:85
static bsl::enable_if<!IsDynamic< t_TYPE >::value, AnyRef >::type makeAnyRef(t_TYPE &object)
Make AnyRef to the specified object.
Definition bdlar_refutil.h:209
Definition bdljsn_tokenizer.h:234
int resetStreamBufGetPointer()
TokenType tokenType() const
Return the token type of the current token.
Definition bdljsn_tokenizer.h:944
Tokenizer & setAllowConsecutiveSeparators(bool value)
Definition bdljsn_tokenizer.h:790
Tokenizer & setAllowHeterogenousArrays(bool value)
Definition bdljsn_tokenizer.h:799
Tokenizer & setAllowStandAloneValues(bool value)
Definition bdljsn_tokenizer.h:826
Tokenizer & setAllowUnescapedControlCharacters(bool value)
Definition bdljsn_tokenizer.h:844
Tokenizer & setAllowTrailingTopLevelComma(bool value)
Definition bdljsn_tokenizer.h:835
Tokenizer & setAllowFormFeedAsWhitespace(bool value)
Definition bdljsn_tokenizer.h:808
void reset(bsl::streambuf *streambuf)
Definition bdljsn_tokenizer.h:772
Tokenizer & setAllowNonUtf8StringLiterals(bool value)
Definition bdljsn_tokenizer.h:817
@ e_ELEMENT_NAME
Definition bdljsn_tokenizer.h:245
@ e_END_OBJECT
Definition bdljsn_tokenizer.h:247
@ e_END_ARRAY
Definition bdljsn_tokenizer.h:249
@ e_ELEMENT_VALUE
Definition bdljsn_tokenizer.h:250
@ e_START_ARRAY
Definition bdljsn_tokenizer.h:248
@ e_START_OBJECT
Definition bdljsn_tokenizer.h:246
int value(bsl::string_view *data) const
Definition bdlma_localsequentialallocator.h:230
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference back() const
Definition bslstl_stringview.h:1977
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference front() const
Definition bslstl_stringview.h:1966
Definition bslstl_string.h:1252
size_type length() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7301
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
basic_string & erase(size_type position=0, size_type numChars=npos)
Definition bslstl_string.h:6740
Definition bslstl_unorderedset.h:733
Definition bslstl_vector.h:1120
Definition bslma_allocator.h:545
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_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 createBaseAndConvert(t_TYPE *object, t_MANIPULATOR &baseManipulator)
int manipulateValue(TYPE *object, MANIPULATOR &manipulator)
void makeValue(TYPE *object)
int manipulateAttribute(TYPE *object, MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
int manipulateAttributes(TYPE *object, MANIPULATOR &manipulator)
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
Definition baljsn_decoder.h:557
bool d_convertCalled
Definition baljsn_decoder.h:561
bsl::enable_if< bdlar::IsRef< t_REF >::value, int >::type operator()(t_REF *)
Stub for the bdlar ref types.
Definition baljsn_decoder.h:586
bslstl::StringRef d_dataValue
Definition baljsn_decoder.h:560
bsl::ostringstream & d_logStream
Definition baljsn_decoder.h:559
bsl::enable_if<!bdlar::IsRef< t_BASE_TYPE >::value, int >::type operator()(t_BASE_TYPE *value)
Definition baljsn_decoder.h:566
Definition baljsn_decoder.h:508
int operator()(TYPE *, bslmf::Nil)
Definition baljsn_decoder.h:1331
int d_mode
Definition baljsn_decoder.h:512
Decoder * d_decoder_p
Definition baljsn_decoder.h:511
Definition baljsn_decoder.h:472
int d_mode
Definition baljsn_decoder.h:476
int operator()(TYPE *value)
Definition baljsn_decoder.h:1308
Decoder * d_decoder_p
Definition baljsn_decoder.h:475
Definition baljsn_decoder.h:538
bsl::unordered_set< bsl::string > * d_requiredAttributes_p
Definition baljsn_decoder.h:540
int operator()(TYPE *value, const INFO &info)
Definition baljsn_decoder.h:1353
bool d_usesDefaultValueFlag
Definition baljsn_decoder.h:541
static int getValue(bool *value, const bsl::string_view &data)
static bool stripQuotes(bsl::string_view *str)
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
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
@ e_SIMPLE_CATEGORY
Definition bdlat_typecategory.h:1054
@ e_CUSTOMIZED_TYPE_CATEGORY
Definition bdlat_typecategory.h:1050
@ e_NULLABLE_VALUE_CATEGORY
Definition bdlat_typecategory.h:1052
@ e_ENUMERATION_CATEGORY
Definition bdlat_typecategory.h:1051
Definition bslmf_enableif.h:530
Definition bslmf_isintegral.h:140
Definition bslmf_nil.h:133