8#ifndef INCLUDED_BALJSN_DECODER
9#define INCLUDED_BALJSN_DECODER
203#include <balscm_version.h>
230#include <bsl_iostream.h>
231#include <bsl_sstream.h>
232#include <bsl_streambuf.h>
233#include <bsl_string.h>
234#include <bsl_string_view.h>
262 bool d_skipUnknownElements;
278 template <
class TYPE>
280 template <
class TYPE>
282 template <
class TYPE>
284 template <
class TYPE>
286 template <
class TYPE>
288 template <
class TYPE>
290 template <
class TYPE>
292 template <
class TYPE>
297 template <
class TYPE,
class ANY_CATEGORY>
298 int decodeImp(TYPE *value, ANY_CATEGORY category);
303 bsl::ostream& logTokenizerError(
const char *alternateString);
335 template <
class TYPE>
336 int decode(bsl::streambuf *streamBuf,
339 template <
class TYPE>
340 int decode(bsl::streambuf *streamBuf,
354 template <
class TYPE>
355 int decode(bsl::istream& stream,
358 template <
class TYPE>
359 int decode(bsl::istream& stream,
369 template <
class TYPE>
370 int decode(bsl::streambuf *streamBuf, TYPE *value);
379 template <
class TYPE>
380 int decode(bsl::istream& stream, TYPE *value);
414 template <
class TYPE>
420 template <
class TYPE,
class INFO>
421 int operator()(TYPE *value,
const INFO& info);
444 template <
class TYPE>
450 template <
class TYPE,
class ANY_CATEGORY>
451 int operator()(TYPE *
object, ANY_CATEGORY category);
480 d_elementName.
data(),
481 static_cast<int>(d_elementName.
length()))) {
487 d_elementName.
data(),
488 static_cast<int>(d_elementName.
length()))) {
489 d_logStream <<
"Could not decode sequence, error decoding "
490 <<
"element or bad element name '"
491 << d_elementName <<
"' \n";
496 if (d_skipUnknownElements) {
497 const int rc = skipUnknownElement(d_elementName);
499 d_logStream <<
"Error reading unknown element '"
500 << d_elementName <<
"' or after it\n";
505 d_logStream <<
"Unknown element '" << d_elementName
512 if (++d_currentDepth > d_maxDepth) {
513 d_logStream <<
"Maximum allowed decoding depth reached: "
514 << d_currentDepth <<
"\n";
519 d_logStream <<
"Could not decode sequence, missing starting '{'\n";
525 d_logStream <<
"Could not decode sequence, ";
526 logTokenizerError(
"error") <<
" reading token after '{'\n";
533 rc = d_tokenizer.
value(&elementName);
535 d_logStream <<
"Error reading attribute name after '{'\n";
542 static_cast<int>(elementName.
length()))) {
543 d_elementName = elementName;
547 logTokenizerError(
"Error") <<
" reading value for"
548 <<
" attribute '" << d_elementName <<
"' \n";
557 d_elementName.
data(),
558 static_cast<int>(d_elementName.
length()))) {
559 d_logStream <<
"Could not decode sequence, error decoding "
560 <<
"element or bad element name '"
561 << d_elementName <<
"' \n";
566 if (d_skipUnknownElements) {
567 rc = skipUnknownElement(elementName);
569 d_logStream <<
"Error reading unknown element '"
570 << elementName <<
"' or after it\n";
575 d_logStream <<
"Unknown element '"
576 << elementName <<
"' found\n";
583 d_logStream <<
"Could not decode sequence, ";
584 logTokenizerError(
"error") <<
" reading token"
585 <<
" after value for attribute '"
586 << d_elementName <<
"' \n";
592 d_logStream <<
"Could not decode sequence, "
593 <<
"missing terminator '}' or seperator ','\n";
603int Decoder::decodeImp(TYPE *value,
616 selectionName.
data(),
617 static_cast<int>(selectionName.
length()))) {
620 selectionName.
data(),
621 static_cast<int>(selectionName.
length()))) {
622 d_logStream <<
"Could not decode choice, bad selection name '"
623 << selectionName <<
"' \n";
631 d_logStream <<
"Could not decode choice, selection "
632 <<
"was not decoded\n";
637 if (d_skipUnknownElements) {
638 const int rc = skipUnknownElement(selectionName);
640 d_logStream <<
"Error reading unknown element '"
641 << selectionName <<
"' or after that "
647 d_logStream <<
"Unknown element '"
648 << selectionName <<
"' found\n";
654 if (++d_currentDepth > d_maxDepth) {
655 d_logStream <<
"Maximum allowed decoding depth reached: "
656 << d_currentDepth <<
"\n";
661 d_logStream <<
"Could not decode choice, missing starting {\n";
667 d_logStream <<
"Could not decode choice, ";
668 logTokenizerError(
"error") <<
" reading token after {\n";
674 rc = d_tokenizer.
value(&selectionName);
676 d_logStream <<
"Error reading selection name after '{'\n";
682 selectionName.
data(),
683 static_cast<int>(selectionName.
length()))) {
686 selectionName.
data(),
687 static_cast<int>(selectionName.
length()))) {
688 d_logStream <<
"Could not decode choice, bad selection "
689 <<
"name '" << selectionName <<
"' \n";
695 d_logStream <<
"Could not decode choice, ";
696 logTokenizerError(
"error") <<
" reading value \n";
704 d_logStream <<
"Could not decode choice, selection "
705 <<
"was not decoded\n";
710 if (d_skipUnknownElements) {
711 rc = skipUnknownElement(selectionName);
713 d_logStream <<
"Error reading unknown element '"
714 << selectionName <<
"' or after that "
720 d_logStream <<
"Unknown element '"
721 << selectionName <<
"' found\n";
728 d_logStream <<
"Could not decode choice, ";
729 logTokenizerError(
"error") <<
" reading token after value for"
737 d_logStream <<
"Could not decode choice, "
738 <<
"missing terminator '}'\n";
750 enum { k_MIN_ENUM_STRING_LENGTH = 2 };
753 d_logStream <<
"Enumeration element value was not found\n";
758 int rc = d_tokenizer.
value(&dataValue);
760 d_logStream <<
"Error reading enumeration value\n";
764 if (dataValue.
length() >= k_MIN_ENUM_STRING_LENGTH &&
765 '"' == dataValue.
front() &&
'"' == dataValue.
back()) {
766 const int kBufSize = 128;
772 d_logStream <<
"Error reading enumeration value\n";
777 value, tmpString.data(),
static_cast<int>(tmpString.size()));
779 d_logStream <<
"Could not decode Enum String, value not allowed \""
780 << dataValue <<
"\"\n";
790 d_logStream <<
"Error reading enumeration value\n";
796 d_logStream <<
"Could not decode int Enum, value " << intValue
807 d_logStream <<
"Customized element value was not found\n";
812 int rc = d_tokenizer.
value(&dataValue);
814 d_logStream <<
"Error reading customized type value\n";
821 BaseType valueBaseType;
831 d_logStream <<
"Could not decode Enum Customized, "
832 <<
"value not allowed \"" << dataValue <<
"\"\n";
839 d_logStream <<
"Could not convert base type to customized type, "
840 <<
"base value disallowed: \"";
842 d_logStream <<
"\"\n";
851 d_logStream <<
"Simple element value was not found\n";
856 int rc = d_tokenizer.
value(&dataValue);
858 d_logStream <<
"Error reading simple value\n";
878 d_logStream <<
"Could not decode vector<char> "
879 <<
"expected as an element value\n";
884 int rc = d_tokenizer.
value(&dataValue);
887 d_logStream <<
"Error reading customized type element value\n";
895int Decoder::decodeImp(TYPE *value,
900 d_logStream <<
"Could not decode vector, missing start token: '['\n";
906 logTokenizerError(
"Error") <<
" reading array.\n";
923 d_logStream <<
"Error adding element '" << i - 1 <<
"'\n";
929 logTokenizerError(
"Error") <<
" reading token after value of"
930 " element '" << i - 1 <<
"'\n";
935 d_logStream <<
"Erroneous token found instead of array element\n";
941 d_logStream <<
"Could not decode vector, missing end token: ']'\n";
949int Decoder::decodeImp(TYPE *value,
953 enum { k_NULL_VALUE_LENGTH = 4 };
957 const int rc = d_tokenizer.
value(&dataValue);
962 if (k_NULL_VALUE_LENGTH == dataValue.
length()
963 &&
'n' == dataValue[0]
964 &&
'u' == dataValue[1]
965 &&
'l' == dataValue[2]
966 &&
'l' == dataValue[3]) {
977template <
class TYPE,
class ANY_CATEGORY>
979int Decoder::decodeImp(TYPE *, ANY_CATEGORY)
989: d_logStream(basicAllocator)
990, d_tokenizer(basicAllocator)
991, d_elementName(basicAllocator)
994, d_skipUnknownElements(false)
1007 d_logStream.clear();
1008 d_logStream.
str(
"");
1016 d_logStream <<
"The object being decoded must be a Sequence, "
1017 <<
"Choice, or Array type\n";
1021 d_tokenizer.
reset(streamBuf);
1036 logTokenizerError(
"Error") <<
" advancing to the first token. "
1037 "Expecting a '{' or '[' as the first character\n";
1046 rc = decodeImp(value, 0, TypeCategory());
1053template <
class TYPE>
1059 return decode(streamBuf, value, options ? *options : localOpts);
1062template <
class TYPE>
1067 if (!stream.good()) {
1069 <<
"Input stream state is not 'good()' ["
1070 << (stream.bad() ?
" 'bad()'" :
"")
1071 << (stream.fail() ?
" 'fail()'" :
"")
1072 << (stream.eof() ?
" 'eof()'" :
"")
1073 <<
" ] - nothing to decode\n";
1077 if (0 !=
decode(stream.rdbuf(), value, options)) {
1078 stream.setstate(bsl::ios_base::failbit);
1085template <
class TYPE>
1091 return decode(stream, value, options ? *options : localOpts);
1094template <
class TYPE>
1098 return decode(streamBuf, value, options);
1101template <
class TYPE>
1105 return decode(stream, value, options);
1112 return d_logStream.
str();
1119template <
class TYPE>
1127template <
class TYPE,
class INFO>
1133 info.formattingMode(),
1142template <
class TYPE>
1151template <
class TYPE,
class ANY_CATEGORY>
1154 ANY_CATEGORY category)
Definition baljsn_decoderoptions.h:153
bool validateInputIsUtf8() const
Definition baljsn_decoderoptions.h:697
bool allowUnescapedControlCharacters() const
Definition baljsn_decoderoptions.h:715
bool skipUnknownElements() const
Definition baljsn_decoderoptions.h:691
bool allowConsecutiveSeparators() const
Definition baljsn_decoderoptions.h:703
bool allowFormFeedAsWhitespace() const
Definition baljsn_decoderoptions.h:709
int maxDepth() const
Return the value of the "MaxDepth" attribute of this object.
Definition baljsn_decoderoptions.h:685
Definition baljsn_decoder.h:254
friend struct Decoder_ElementVisitor
Definition baljsn_decoder.h:266
int decode(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions &options)
Definition baljsn_decoder.h:1000
bsl::string loggedMessages() const
Definition baljsn_decoder.h:1110
Definition bdljsn_tokenizer.h:234
int resetStreamBufGetPointer()
TokenType tokenType() const
Return the token type of the current token.
Definition bdljsn_tokenizer.h:925
Tokenizer & setAllowConsecutiveSeparators(bool value)
Definition bdljsn_tokenizer.h:771
Tokenizer & setAllowHeterogenousArrays(bool value)
Definition bdljsn_tokenizer.h:780
Tokenizer & setAllowStandAloneValues(bool value)
Definition bdljsn_tokenizer.h:807
Tokenizer & setAllowUnescapedControlCharacters(bool value)
Definition bdljsn_tokenizer.h:825
Tokenizer & setAllowTrailingTopLevelComma(bool value)
Definition bdljsn_tokenizer.h:816
Tokenizer & setAllowFormFeedAsWhitespace(bool value)
Definition bdljsn_tokenizer.h:789
void reset(bsl::streambuf *streambuf)
Definition bdljsn_tokenizer.h:753
Tokenizer & setAllowNonUtf8StringLiterals(bool value)
Definition bdljsn_tokenizer.h:798
@ 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_ostringstream.h:175
void str(const StringType &value)
Definition bslstl_ostringstream.h:581
Definition bslstl_stringview.h:441
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference back() const
Definition bslstl_stringview.h:1749
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference front() const
Definition bslstl_stringview.h:1738
Definition bslstl_string.h:1281
size_type length() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6601
iterator end() BSLS_KEYWORD_NOEXCEPT
Return the past-the-end iterator for this modifiable string.
Definition bslstl_string.h:5452
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6477
void swap(basic_string &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:2533
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
Definition bslstl_stringref.h:372
const CHAR_TYPE * data() const
Definition bslstl_stringref.h:936
size_type length() const
Definition bslstl_stringref.h:958
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:821
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1404
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:1856
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition baljsn_datumdecoderoptions.h:113
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:719
Definition baljsn_decoder.h:432
int operator()(TYPE *, bslmf::Nil)
Definition baljsn_decoder.h:1144
int d_mode
Definition baljsn_decoder.h:436
Decoder * d_decoder_p
Definition baljsn_decoder.h:435
Definition baljsn_decoder.h:399
int d_mode
Definition baljsn_decoder.h:403
int operator()(TYPE *value)
Definition baljsn_decoder.h:1121
Decoder * d_decoder_p
Definition baljsn_decoder.h:402
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:329
static int fromStringOrFallbackIfEnabled(TYPE *result, const char *string, int stringLength)
Definition bdlat_enumutil.h:343
TYPE::BaseType Type
Definition bdlat_customizedtypefunctions.h:536
Definition bdlat_typecategory.h:1035
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1037
Definition bdlat_typecategory.h:1034
Definition bdlat_typecategory.h:1038
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1040
Definition bdlat_typecategory.h:1041
Value
Definition bdlat_typecategory.h:1044
@ e_ARRAY_CATEGORY
Definition bdlat_typecategory.h:1046
@ e_CHOICE_CATEGORY
Definition bdlat_typecategory.h:1047
@ e_SEQUENCE_CATEGORY
Definition bdlat_typecategory.h:1051
Definition bslmf_isintegral.h:130
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131