diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/endian/example | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/endian/example')
-rw-r--r-- | src/boost/libs/endian/example/conversion_use_case.cpp | 51 | ||||
-rw-r--r-- | src/boost/libs/endian/example/endian_example.cpp | 75 | ||||
-rw-r--r-- | src/boost/libs/endian/example/third_party_format.hpp | 19 | ||||
-rw-r--r-- | src/boost/libs/endian/example/udt_conversion_example.cpp | 79 | ||||
-rw-r--r-- | src/boost/libs/endian/example/use_cases.cpp | 152 |
5 files changed, 376 insertions, 0 deletions
diff --git a/src/boost/libs/endian/example/conversion_use_case.cpp b/src/boost/libs/endian/example/conversion_use_case.cpp new file mode 100644 index 00000000..544b0c0b --- /dev/null +++ b/src/boost/libs/endian/example/conversion_use_case.cpp @@ -0,0 +1,51 @@ +// endian/example/conversion_use_case.cpp + +// Copyright Beman Dawes 2014 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// This program reads a binary file of fixed length records, with a format defined +// in a header file supplied by a third-party. The records inserted into a vector, +// and the vector is sorted. The sorted records are then written to an output file. + +// Full I/O error testing omitted for brevity, So don't try this at home. + +#include "third_party_format.hpp" +#include <boost/endian/conversion.hpp> +#include <vector> +#include <fstream> +#include <algorithm> +#include <iostream> + +using third_party::record; + +int main() +{ + std::ifstream in("data.bin", std::ios::binary); + if (!in) { std::cout << "Could not open data.bin\n"; return 1; } + + std::ofstream out("sorted-data.bin", std::ios::binary); + if (!out) { std::cout << "Could not open sorted-data.bin\n"; return 1; } + + record rec; + std::vector<record> recs; + + while (!in.eof()) // read each record + { + in.read((char*)&rec, sizeof(rec)); + rec.balance = boost::endian::big_to_native(rec.balance); // reverse if needed + recs.push_back(rec); + } + + std::sort(recs.begin(), recs.end(), // decending sort by balance + [](const record& lhs, const record& rhs) -> bool + { return lhs.balance > rhs.balance; }); + + for (auto &out_rec : recs) // write each record + { + out_rec.balance = boost::endian::native_to_big(out_rec.balance); // reverse if needed + out.write((const char*)&out_rec, sizeof(out_rec)); + } + +} diff --git a/src/boost/libs/endian/example/endian_example.cpp b/src/boost/libs/endian/example/endian_example.cpp new file mode 100644 index 00000000..fcab6580 --- /dev/null +++ b/src/boost/libs/endian/example/endian_example.cpp @@ -0,0 +1,75 @@ +// endian_example.cpp -------------------------------------------------------// + +// Copyright Beman Dawes, 2006 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See library home page at http://www.boost.org/libs/endian + +//----------------------------------------------------------------------------// + +#include <boost/endian/detail/disable_warnings.hpp> + +#include <iostream> +#include <cstdio> +#include <boost/endian/buffers.hpp> +#include <boost/static_assert.hpp> + +using namespace boost::endian; + +namespace +{ + // This is an extract from a very widely used GIS file format. Why the designer + // decided to mix big and little endians in the same file is not known. But + // this is a real-world format and users wishing to write low level code + // manipulating these files have to deal with the mixed endianness. + + struct header + { + big_int32_buf_at file_code; + big_int32_buf_at file_length; + little_int32_buf_at version; + little_int32_buf_at shape_type; + }; + + const char* filename = "test.dat"; +} + +int main(int, char* []) +{ + header h; + + BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check + + h.file_code = 0x01020304; + h.file_length = sizeof(header); + h.version = 1; + h.shape_type = 0x01020304; + + // Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is sometimes + // used for binary file operations when ultimate efficiency is important. + // Such I/O is often performed in some C++ wrapper class, but to drive home the + // point that endian integers are often used in fairly low-level code that + // does bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example. + + std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY + + if (!fi) + { + std::cout << "could not open " << filename << '\n'; + return 1; + } + + if (std::fwrite(&h, sizeof(header), 1, fi)!= 1) + { + std::cout << "write failure for " << filename << '\n'; + return 1; + } + + std::fclose(fi); + + std::cout << "created file " << filename << '\n'; + + return 0; +} diff --git a/src/boost/libs/endian/example/third_party_format.hpp b/src/boost/libs/endian/example/third_party_format.hpp new file mode 100644 index 00000000..d6472837 --- /dev/null +++ b/src/boost/libs/endian/example/third_party_format.hpp @@ -0,0 +1,19 @@ +// endian/example/third_party_format.hpp + +// Copyright Beman Dawes 2014 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <cstdint> + +namespace third_party +{ + struct record + { + uint32_t id; // big endian + int32_t balance; // big endian + + // ... data members whose endianness is not a concern + }; +} diff --git a/src/boost/libs/endian/example/udt_conversion_example.cpp b/src/boost/libs/endian/example/udt_conversion_example.cpp new file mode 100644 index 00000000..b0a6d088 --- /dev/null +++ b/src/boost/libs/endian/example/udt_conversion_example.cpp @@ -0,0 +1,79 @@ +// udt_conversion_example.cpp --------------------------------------------------------// + +// Copyright Beman Dawes 2013 + +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +//--------------------------------------------------------------------------------------// + +#include <boost/endian/detail/disable_warnings.hpp> + +#include <boost/endian/conversion.hpp> +#include <iostream> +#include <cstring> + +using namespace boost::endian; +using std::cout; +using std::endl; +using boost::int32_t; +using boost::int64_t; + +namespace user +{ + class UDT + { + public: + UDT() : id_(0), value_(0) {desc_[0] = '\0';} + UDT(int32_t id, int64_t value, const char* desc) : id_(id), value_(value) + { + std::strncpy(desc_, desc, sizeof(desc_)-1); + desc_[sizeof(desc_)-1] = '\0'; + } + int32_t id() const {return id_;} + int64_t value() const {return value_;} + const char* desc() const {return desc_;} + void id(int32_t x) {id_ = x;} + void value(int64_t v) {value_ = v;} + void desc(const char* s) + { + std::strncpy(desc_, s, sizeof(desc_)-1); + desc_[sizeof(desc_-1)] = '\0'; + } + + friend void endian_reverse_inplace(UDT&); + + private: + int32_t id_; + int64_t value_; + char desc_[56]; // '/0' + }; + + void endian_reverse_inplace(UDT& x) + { + boost::endian::endian_reverse_inplace(x.id_); + boost::endian::endian_reverse_inplace(x.value_); + } +} + +int main(int, char* []) +{ + user::UDT x(1, 123456789012345LL, "Bingo!"); + + //cout << std::hex; + cout << "(1) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; + + user::endian_reverse_inplace(x); + cout << "(2) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; + + endian_reverse_inplace(x); + cout << "(3) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; + + conditional_reverse_inplace<order::little, order::big>(x); + cout << "(4) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; + + conditional_reverse_inplace(x, order::big, order::little); + cout << "(5) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; +} + +#include <boost/endian/detail/disable_warnings_pop.hpp> diff --git a/src/boost/libs/endian/example/use_cases.cpp b/src/boost/libs/endian/example/use_cases.cpp new file mode 100644 index 00000000..7bbe9b28 --- /dev/null +++ b/src/boost/libs/endian/example/use_cases.cpp @@ -0,0 +1,152 @@ +// endian/example/uses_cases.cpp -----------------------------------------------------// + +// Copyright Beman Dawes 2014 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//--------------------------------------------------------------------------------------// + +#ifndef _SCL_SECURE_NO_WARNINGS +# define _SCL_SECURE_NO_WARNINGS +#endif + +#ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +#endif + + +#include <boost/endian/conversion.hpp> +#include <boost/endian/buffers.hpp> +#include <boost/endian/arithmetic.hpp> +#include <iostream> + +using namespace boost::endian; + +using std::cout; +using std::endl; + + + + + { // Use case 2 - Endian buffer types + + struct Record + { + big_ubuf32_t count; // big endian + big_buf32_t value; // big endian + }; + + Record rec; + + read(&rec, sizeof(Record)); + + uint32_t count = rec.count.value(); + int32_t value = rec.value.value(); + + ++count; + value += fee; + + rec.count = count; + rec.value = value; + + write(&rec, sizeof(Record)); + } + + { // Use case 3a - Endian arithmetic types + + struct Record + { + big_uint32_t count; // big endian + big_int32_t value; // big endian + }; + + Record rec; + + read(&rec, sizeof(Record)); + + ++rec.count; + rec.value += fee; + + write(&rec, sizeof(Record)); + } + + { // Use case 3b - Endian arithmetic types + + struct Record + { + big_uint32_t count; // big endian + big_int32_t value; // big endian + }; + + Record rec; + + read(&rec, sizeof(Record)); + + uint32_t count = rec.count; + int32_t value = rec.value; + + ++count; + value += fee; + + rec.count = count; + rec.value = value; + + write(&rec, sizeof(Record)); + } + + // Recommended approach when conversion time is not a concern + // + // Conversion time is not a concert with this application because the minimum + // possible number of conversions is performed and because I/O time will be + // much greater than conversion time. + + { + struct Record + { + big_uint32_t count; // big endian + big_int32_t value; // big endian + }; + + Record rec; + + read(&rec, sizeof(Record)); + + ++rec.count; + rec.value += fee; + + write(&rec, sizeof(Record)); + } + +// Recommended approach when conversion time is a concern + // + // Conversion time is a concert with this application because (1) any conversions + // performed in the loop will consume a great deal of time and because (2) + // computation time will be much greater than I/O time. + + { + struct Record + { + big_uint32_t count; // big endian + big_int32_t value; // big endian + }; + + Record rec; + + read(&rec, sizeof(Record)); + + uint32_t count = rec.count; + int32_t value = rec.value; + + for (long long i = 0; i < several_gazillion; ++i) // (1) + { + ... immensely complex computation using rec variables many times // (2) + } + + rec.count = count; + rec.value = value; + + write(&rec, sizeof(Record)); + } + +} |