// bdljsn_readoptions.h -*-C++-*- #ifndef INCLUDED_BDLJSN_READOPTIONS #define INCLUDED_BDLJSN_READOPTIONS #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide options for reading a JSON document. // //@CLASSES: // bdljsn::ReadOptions: options for reading a JSON document // //@SEE_ALSO: bdljsn_jsonutil, bdljsn_json // //@DESCRIPTION: This component provides a single, simply constrained // (value-semantic) attribute class, 'bdljsn::ReadOptions', that is used to // specify options for reading a JSON document (see {'bdljsn_jsonutil'}). // ///Attributes ///---------- //.. // Name Type Default Simple Constraints // ------------------ ----------- ------- ------------------ // maxNestedDepth int 64 > 0 // allowTrailingText bool false //.. //: o 'maxNestedDepth': the maximum depth to which JSON objects and arrays are //: allowed to be nested before the JSON decoder reports an error. For //: example, if 'maxNestedDepth' is 8, and a JSON text has 9 consecutive open //: brackets ('[') then decoding will return an error. This option can be //: used to prevent poorly formed (or malicious) JSON text from causing a //: stack overflow. //: //: o 'allowTrailingText': whether a read operation will report an error //: if any non-white space text follows a valid JSON document. By default //: this option is 'false', indicating the user expects the input to contain //: a single valid JSON document (without any subsequent text). When //: set to 'true' a 'read' operation will return success if there is text //: following a valid JSON document, assuming that text is separated by //: a delimeter. See {'bdljsn_jsonutil'} for details. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Creating and Populating an Options Object /// - - - - - - - - - - - - - - - - - - - - - - - - - - // This component is designed to be used at a higher level to set the options // for decoding 'Datum' objects in the JSON format. This example shows how to // create and populate an options object. // // First, we default-construct a 'bdljsn::ReadOptions' object: //.. // const int MAX_NESTED_DEPTH = 16; // // bdljsn::ReadOptions options; // assert(64 == options.maxNestedDepth()); // assert(false == options.allowTrailingText()); //.. // Finally, we populate that object to limit the maximum nested depth using a // pre-defined limit: //.. // options.setMaxNestedDepth(MAX_NESTED_DEPTH); // assert(MAX_NESTED_DEPTH == options.maxNestedDepth()); //.. #include <bdlscm_version.h> #include <bsl_iosfwd.h> #include <bsls_assert.h> namespace BloombergLP { namespace bdljsn { // ================= // class ReadOptions // ================= class ReadOptions { // This simply constrained (value-semantic) attribute class specifies // options for reading a JSON document. See the {Attributes} section under // {DESCRIPTION} in the component-level documentation for information on // the class attributes. Note that the class invariants are identically // the constraints on the individual attributes. // INSTANCE DATA bool d_allowTrailingText; // whether to permit text after a valid JSON document int d_maxNestedDepth; // maximum nesting level for JSON objects and arrays public: // CONSTANTS static const bool s_DEFAULT_INITIALIZER_ALLOW_TRAILING_TEXT; static const int s_DEFAULT_INITIALIZER_MAX_NESTED_DEPTH; public: // CREATORS ReadOptions(); // Create an object of type 'ReadOptions' having the (default) // attribute values: //.. // setAllowTrailingText() == false // maxNestedDepth() == 64 //.. ReadOptions(const ReadOptions& original); // Create an object of type 'ReadOptions' having the value of the // specified 'original' object. ~ReadOptions(); // Destroy this object. // MANIPULATORS ReadOptions& operator=(const ReadOptions& rhs); // Assign to this object the value of the specified 'rhs' object and // return a non-'const' reference to this object. void reset(); // Reset this object to the default value (i.e., its value upon default // construction). void setAllowTrailingText(bool value); // Set the 'allowTrailingText' attribute of this object to the // specified 'value'. void setMaxNestedDepth(int value); // Set the 'maxNestedDepth' attribute of this object to the specified // 'value'. The behavior is undefined unless '0 < value'. // ACCESSORS bool allowTrailingText() const; // Return the 'allowTrailingText' attribute of this object. int maxNestedDepth() const; // Return the 'maxNestedDepth' attribute of this object. // Aspects bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const; // Format this object to the specified output 'stream' at the // optionally specified indentation 'level' and return a reference to // the modifiable 'stream'. If 'level' is specified, optionally // specify 'spacesPerLevel', the number of spaces per indentation level // for this and all of its nested objects. Each line is indented by // the absolute value of 'level * spacesPerLevel'. If 'level' is // negative, suppress indentation of the first line. If // 'spacesPerLevel' is negative, suppress line breaks and format the // entire output on one line. If 'stream' is initially invalid, this // operation has no effect. Note that a trailing newline is provided // in multiline mode only. Also note that the format is not fully // specified, and can change without notice. }; // FREE OPERATORS inline bool operator==(const ReadOptions& lhs, const ReadOptions& rhs); // Return 'true' if the specified 'lhs' and 'rhs' attribute objects have // the same value, and 'false' otherwise. Two attribute objects have the // same value if each respective attribute has the same value. inline bool operator!=(const ReadOptions& lhs, const ReadOptions& rhs); // Return 'true' if the specified 'lhs' and 'rhs' attribute objects do not // have the same value, and 'false' otherwise. Two attribute objects do // not have the same value if one or more respective attributes do not // have the same value. inline bsl::ostream& operator<<(bsl::ostream& stream, const ReadOptions& rhs); // Format the specified 'rhs' to the specified output 'stream' in a single // line format and return a non-'const' reference to 'stream'. // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ----------------- // class ReadOptions // ----------------- // CREATORS inline ReadOptions::ReadOptions(const ReadOptions& original) : d_allowTrailingText(original.d_allowTrailingText) , d_maxNestedDepth (original.d_maxNestedDepth) { } inline ReadOptions::~ReadOptions() { BSLS_ASSERT(0 < d_maxNestedDepth); } // MANIPULATORS inline ReadOptions& ReadOptions::operator=(const ReadOptions& rhs) { d_allowTrailingText = rhs.d_allowTrailingText; d_maxNestedDepth = rhs.d_maxNestedDepth; return *this; } inline void ReadOptions::setAllowTrailingText(bool value) { d_allowTrailingText = value; } inline void ReadOptions::setMaxNestedDepth(int value) { BSLS_ASSERT(0 < value); d_maxNestedDepth = value; } // ACCESSORS inline bool ReadOptions::allowTrailingText() const { return d_allowTrailingText; } inline int ReadOptions::maxNestedDepth() const { return d_maxNestedDepth; } } // close package namespace // FREE OPERATORS inline bool bdljsn::operator==(const bdljsn::ReadOptions& lhs, const bdljsn::ReadOptions& rhs) { return lhs.maxNestedDepth() == rhs.maxNestedDepth() && lhs.allowTrailingText() == rhs.allowTrailingText(); } inline bool bdljsn::operator!=(const bdljsn::ReadOptions& lhs, const bdljsn::ReadOptions& rhs) { return lhs.maxNestedDepth() != rhs.maxNestedDepth() || lhs.allowTrailingText() != rhs.allowTrailingText(); } inline bsl::ostream& bdljsn::operator<<(bsl::ostream& stream, const bdljsn::ReadOptions& rhs) { return rhs.print(stream, 0, -1); } } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2022 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------