// bdld_datumbinaryref.h -*-C++-*- #ifndef INCLUDED_BDLD_DATUMBINARYREF #define INCLUDED_BDLD_DATUMBINARYREF #include <bsls_ident.h> BSLS_IDENT("$Id$ $CSID$") //@PURPOSE: Provide a type to represent binary data and its size. // //@CLASSES: // bdld::DatumBinaryRef: a type representing binary data and its size // //@SEE_ALSO: bdld_datum, bdld_datumerror, bdld_datumudt // //@DESCRIPTION: This component implements a class, 'bdld::DatumBinaryRef', that // represents a pointer to a non-modifiable binary data (as a 'void *') and an // integral size value. Note, that 'bdld::DatumBinaryRef' is nether a // value-semantic type, nor is it an in-core value-semantic type (see // 'bsldoc_glossary'). The 'bdld::DatumBinaryRef' notion of value is expressed // by its equality-operator - two 'bdld::DatumBinaryRef' compare equal if the // binary data they refer to is identical (both by size and by content). // Accessors inside 'Datum' class that need to return a binary data, return an // instance of 'bdld::DatumBinaryRef'. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Basic 'DatumBinaryRef' usage ///- - - - - - - - - - - - - - - - - - - - // Suppose we have three functions. Data are obtained in the first one (with // memory allocation), processed in the second one and released (with memory // deallocation) in the third one. The following code illustrates how to use // 'bdld::DatumBinaryRef' to pass information about memory storage between // them. // // First, we write all three functions: //.. // bdld::DatumBinaryRef obtainData(size_t size) // // Allocate array of the specified 'size' and initialize it with some // // values. // { // if (0 == size) { // return bdld::DatumBinaryRef(); // RETURN // } // int *buffer = new int[size]; // for (size_t i = 0; i < size; ++i) { // buffer[i] = static_cast<int>(i); // } // return bdld::DatumBinaryRef(static_cast<void *>(buffer), size); // } // // int processData(const bdld::DatumBinaryRef& binaryData) // // Process data, held by the specified 'binaryData' object. // { // ostringstream out; // binaryData.print(out); // // if (binaryData == bdld::DatumBinaryRef()) { // return 0; // RETURN // } // // int result = 0; // const int *array = static_cast<const int *>(binaryData.data()); // for (size_t i = 0; i < binaryData.size(); ++i) { // result += array[i]; // } // return result; // } // // void releaseData(const bdld::DatumBinaryRef& binaryData) // // Release memory, held by the specified 'binaryData' object. // { // const int *array = static_cast<const int *>(binaryData.data()); // delete [] array; // } //.. // Next, we call first one to obtain data: //.. // bdld::DatumBinaryRef binaryData = obtainData(5); //.. // Then we verify the results of second one's call: //.. // assert(10 == processData(binaryData)); //.. // Finally, we release allocated memory: //.. // releaseData(binaryData); //.. #include <bdlscm_version.h> #include <bdlb_printmethods.h> #include <bslmf_istriviallycopyable.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsls_assert.h> #include <bsls_review.h> #include <bsls_types.h> #include <bsl_algorithm.h> #include <bsl_cstring.h> #include <bsl_iosfwd.h> namespace BloombergLP { namespace bdld { // ==================== // class DatumBinaryRef // ==================== class DatumBinaryRef { // This class provides a type to represent a pointer to non-modifiable // binary data and an integral size value. public: // TYPES typedef bsls::Types::size_type SizeType; // 'SizeType' is an alias for an unsigned integral value, representing // the length of the binary array. private: // DATA const void *d_data_p; // pointer to the binary data (not owned) SizeType d_size; // size of the binary data public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(DatumBinaryRef, bsl::is_trivially_copyable); BSLMF_NESTED_TRAIT_DECLARATION(DatumBinaryRef, bdlb::HasPrintMethod); // CREATORS DatumBinaryRef(); // Create a 'DatumBinaryRef' object having zero data pointer and size. DatumBinaryRef(const void *data, SizeType size); // Create a 'DatumBinaryRef' object having the specified 'data' and // 'size'. The behavior is undefined unless '0 != data || 0 == size'. // Note that the memory pointed by 'data' is never accessed by a // 'DatumBinaryRef' object. //! DatumBinaryRef(const DatumBinaryRef& origin) = default; //! ~DatumBinaryRef() = default; // MANIPULATORS //! DatumBinaryRef& operator=(const DatumBinaryRef& rhs) = default; // ACCESSORS const void *data() const; // Return the pointer to the non-modifiable binary data. SizeType size() const; // Return the size of the binary data. bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const; // Write the value of this object to the specified output 'stream' in a // human-readable format, and return a reference to the modifyable // 'stream'. Optionally specify an initial indentation 'level', whose // absolute value is incremented recursively for nested objects. If // 'level' is specified, optionally specify 'spacesPerLevel', whose // absolute value indicates the number of spaces per indentation level // for this and all of its nested objects. If 'level' is negative, // suppress indentation of the first line. If 'spacesPerLevel' is // negative, format the entire output on one line, suppressing all but // the initial indentation (as governed by 'level'). If 'stream' is // not valid on entry, this operation has no effect. Note that this // human-readable format is not fully specified, and can change without // notice. }; // FREE OPERATORS bool operator==(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs); // Return 'true' if the specified 'lhs' and 'rhs' have the same value, and // 'false' otherwise. Two 'DatumBinaryRef' objects have the same value if // they refer to arrays of bytes of the same size and having the same // content. bool operator!=(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs); // Return 'true' if the specified 'lhs' and 'rhs' have different values, // and 'true' otherwise. Two 'DatumBinaryRef' objects have different // values if they refer to arrays of bytes of different sizes or having a // different content. bool operator<(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs); // Return 'true' if the specified 'lhs' compares smaller than the specified // 'rhs', and 'false' otherwise. A byte comparision is performed using // memcpy. bool operator>(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs); // Return 'true' if the specified 'lhs' compares larger than the specified // 'rhs', and 'false' otherwise. A byte comparision is performed using // memcpy. bool operator<=(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs); // Return 'true' if the specified 'lhs' compares smaller than or equal to // the specified 'rhs', and 'false' otherwise. A byte comparision is // performed using memcpy. bool operator>=(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs); // Return 'true' if the specified 'lhs' compares larger than or equal to // the specified 'rhs', and 'false' otherwise. A byte comparision is // performed using memcpy. bsl::ostream& operator<<(bsl::ostream& stream, const DatumBinaryRef& rhs); // Write the value of the specified 'rhs' object to the specified output // 'stream' in a single-line format, and return a reference to the // modifyable 'stream'. If 'stream' is not valid on entry, this operation // has no effect. Note that this human-readable format is not fully // specified, can change without notice, and is logically equivalent to: //.. // print(stream, 0, -1); //.. // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // -------------------- // class DatumBinaryRef // -------------------- // CREATORS inline DatumBinaryRef::DatumBinaryRef() : d_data_p(0) , d_size(0) { } inline DatumBinaryRef::DatumBinaryRef(const void *data, SizeType size) : d_data_p(data) , d_size(size) { BSLS_ASSERT(0 != data || 0 == size); } // ACCESSORS inline const void *DatumBinaryRef::data() const { return d_data_p; } inline DatumBinaryRef::SizeType DatumBinaryRef::size() const { return d_size; } } // close package namespace // FREE OPERATORS inline bool bdld::operator==(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs) { return (lhs.size() == rhs.size()) && !bsl::memcmp(lhs.data(), rhs.data(), rhs.size()); } inline bool bdld::operator!=(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs) { return !(lhs == rhs); } inline bool bdld::operator<(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs) { int cmp = bsl::memcmp(lhs.data(), rhs.data(), bsl::min(lhs.size(), rhs.size())); return cmp == 0 ? lhs.size() < rhs.size() : cmp < 0; } inline bool bdld::operator>(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs) { int cmp = bsl::memcmp(lhs.data(), rhs.data(), bsl::min(lhs.size(), rhs.size())); return cmp == 0 ? lhs.size() > rhs.size() : cmp > 0; } inline bool bdld::operator<=(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs) { return !(lhs > rhs); } inline bool bdld::operator>=(const DatumBinaryRef& lhs, const DatumBinaryRef& rhs) { return !(lhs < rhs); } inline bsl::ostream& bdld::operator<<(bsl::ostream& stream, const DatumBinaryRef& rhs) { return rhs.print(stream, 0 , -1); } } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 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 ----------------------------------