diff --git a/boost/binary_stream.hpp b/boost/binary_stream.hpp index 1dedebd..78684c8 100644 --- a/boost/binary_stream.hpp +++ b/boost/binary_stream.hpp @@ -12,126 +12,118 @@ #include #include +#include +#include // for strlen +#include // for wcslen namespace boost { - // binary output for built-in types + // binary input and output for built-in types + + // omission of bool and void* is deliberate; any semantics would be questionable - // omission of bool is deliberate; semantics undecided inline std::ostream& operator<=(std::ostream& os, short v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, short& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, unsigned short v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, unsigned short& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, int v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, int& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, unsigned int v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, unsigned int& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, long v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, long& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, unsigned long v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, unsigned long& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, long long v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, long long& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, unsigned long long v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, unsigned long long& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, float v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, float& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, double v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, double& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, long double v) { return os.write( reinterpret_cast(&v), sizeof(v) ); } - inline std::ostream& operator<=(std::ostream& os, const void* p) - { return os.write( static_cast(p), sizeof(p) ); } + inline std::istream& operator>=(std::istream& is, long double& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + inline std::ostream& operator<=(std::ostream& os, char c) { return os.put( c ); } + inline std::istream& operator>=(std::istream& is, char& c) + { return is.get( c ); } + inline std::ostream& operator<=(std::ostream& os, signed char c) { return os.put( c ); } + inline std::istream& operator>=(std::istream& is, signed char& c) + { return is.get( reinterpret_cast(c) ); } + inline std::ostream& operator<=(std::ostream& os, unsigned char c) { return os.put( c ); } + inline std::istream& operator>=(std::istream& is, unsigned char& c) + { return is.get( reinterpret_cast(c) ); } + + inline std::ostream& operator<=(std::ostream& os, wchar_t v) + { return os.write( reinterpret_cast(&v), sizeof(v) ); } + inline std::istream& operator>=(std::istream& is, wchar_t& v) + { return is.read( reinterpret_cast(&v), sizeof(v) ); } + + // binary input and output for strings + inline std::ostream& operator<=(std::ostream& os, const char* p) { return os.write( p, std::strlen(p)+1 ); } + inline std::ostream& operator<=(std::ostream& os, const signed char* p) - { return os.write( static_cast(p), std::strlen(p)+1 ); } + { return os.write( reinterpret_cast(p), std::strlen(reinterpret_cast(p))+1 ); } + inline std::ostream& operator<=(std::ostream& os, const unsigned char* p) - { return os.write( static_cast(p), std::strlen(p)+1 ); } + { return os.write( reinterpret_cast(p), std::strlen(reinterpret_cast(p))+1 ); } + inline std::ostream& operator<=(std::ostream& os, const wchar_t* p) + { return os.write( reinterpret_cast(p), (std::wcslen(p)+1)*sizeof(wchar_t) ); } + + // Caution: note the asymmetry between output and input; a string with embedded + // nulls will be output with the embedded nulls, but input will stop at the first null. + // So it probably isn't a good idea to use these functions for strings with nulls. + inline std::ostream& operator<=(std::ostream& os, const std::string& s) + { return os.write( s.c_str(), s.size()+1 ); } + inline std::istream& operator>=(std::istream& is, std::string& s) + { return getline(is, s, '\0'); } + + inline std::ostream& operator<=(std::ostream& os, const std::wstring& s) + { return os.write( reinterpret_cast(s.c_str()), (s.size()+1)*sizeof(wchar_t) ); } + // TODO: provide input function -//// 27.6.2.6 Formatted output: -//basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&)); -//basic_ostream& operator<<(basic_ios& (*pf)(basic_ios&)); -//basic_ostream& operator<<(ios_base& (*pf)(ios_base&)); -//basic_ostream& operator<<(bool n); -//basic_ostream& operator<<(short n); -//basic_ostream& operator<<(unsigned short n); -//basic_ostream& operator<<(int n); -//basic_ostream& operator<<(unsigned int n); -//basic_ostream& operator<<(long n); -//basic_ostream& operator<<(unsigned long n); -//basic_ostream& operator<<(long long n); -//basic_ostream& operator<<(unsigned long long n); -//basic_ostream& operator<<(float f); -//basic_ostream& operator<<(double f); -//basic_ostream& operator<<(long double f); -//basic_ostream& operator<<(const void* p); -//basic_ostream& operator<<(basic_streambuf* sb); -// -//// 27.6.2.6.4 character inserters -//template -//basic_ostream& operator<<(basic_ostream&, charT); -//template -//basic_ostream& operator<<(basic_ostream&&, charT); -//template -//basic_ostream& operator<<(basic_ostream&, char); -//template -//basic_ostream& operator<<(basic_ostream&&, char); -//template -//basic_ostream& operator<<(basic_ostream&, char); -//template -//basic_ostream& operator<<(basic_ostream&&, char); -// -//// signed and unsigned -//template -//basic_ostream& operator<<(basic_ostream&, signed char); -//template -//basic_ostream& operator<<(basic_ostream&&, signed char); -//template -//basic_ostream& operator<<(basic_ostream&, unsigned char); -//template -//basic_ostream& operator<<(basic_ostream&&, unsigned char); -// -//template -//basic_ostream& operator<<(basic_ostream&, const charT*); -//template -//basic_ostream& operator<<(basic_ostream&&, const charT*); -//template -//basic_ostream& operator<<(basic_ostream&, const char*); -//template -//basic_ostream& operator<<(basic_ostream&&, const char*); -//template -//basic_ostream& operator<<(basic_ostream&, const char*); -//template -//basic_ostream& operator<<(basic_ostream&&, const char*); -// -//// signed and unsigned -//template -//basic_ostream& operator<<(basic_ostream&, const signed char*); -//template -//basic_ostream& operator<<(basic_ostream&&, const signed char*); -//template -//basic_ostream& operator<<(basic_ostream&, const unsigned char*); -//template -//basic_ostream& operator<<(basic_ostream&&, const unsigned char*); -// -//// 21.3.8.9: inserters and extractors -//template -//basic_istream& operator>>(basic_istream&& is, basic_string& str); -//template -//basic_ostream& operator<<(basic_ostream&& os, const basic_string& str); -//template -//basic_istream& getline(basic_istream&& is, basic_string& str, charT delim); -//template -//basic_istream& getline(basic_istream&& is, basic_string& str); } // namespace boost diff --git a/libs/integer/doc/endian.html b/libs/integer/doc/endian.html index 9a8f171..ce4ac14 100644 --- a/libs/integer/doc/endian.html +++ b/libs/integer/doc/endian.html @@ -58,11 +58,13 @@ - <boost/integer/endian.hpp> + <boost/integer/endian.hpp>
+ <boost/integer/endian_io.hpp>

Introduction

-

The boost/integer/endian.hpp header provides +

Header + <boost/integer/endian.hpp> provides integer-like byte-holder binary types with explicit control over byte order, value type, size, and alignment. Typedefs provide easy-to-use names for common configurations.

@@ -79,8 +81,7 @@ exploration of endianness, including definitions of big endian and little endian.

Boost endian integers provide the same full set of C++ assignment, arithmetic, and relational operators as C++ standard integral types, with -the standard semantics, plus operators << and >> for -stream insertion and extraction.

+the standard semantics.

Unary arithmetic operators are +, -, ~, !, prefix and postfix -- and ++. Binary arithmetic operators are +, +=, -, @@ -89,7 +90,10 @@ arithmetic operators are +, +=, -, ^, ^=, <<, <<=, >>, >>=. Binary relational operators are ==, !=, <, <=, >, >=.

-

Automatic conversion are provided to and from the underlying integer value type.

+

Automatic conversion is provided to the underlying integer value type.

+

Header <boost/integer/endian_io.hpp> +provides operators << and >> for +stream insertion and extraction.

Limitations

Requires <climits> CHAR_BIT == 8. If CHAR_BIT is some other value, compilation will result in an #error. This @@ -549,7 +553,7 @@ Tomas Puverle, and Yuval Ronen.


Last revised: -11 March, 2009

+12 March, 2009

© Copyright Beman Dawes, 2006

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/libs/integer/example/endian_hello_world.cpp b/libs/integer/example/endian_hello_world.cpp index f68eb36..67605e0 100644 --- a/libs/integer/example/endian_hello_world.cpp +++ b/libs/integer/example/endian_hello_world.cpp @@ -7,6 +7,7 @@ // See library home page at http://www.boost.org/libs/endian +#include #include #include @@ -15,10 +16,14 @@ using namespace boost::integer; int main() { - long value = 3224115L; // integer value of ASCII { '1', '2', '3' } - big24_t big( value ); - little24_t little( value ); + int_least32_t value = 0x313233L; // = 3224115 = ASCII { '1', '2', '3' } + big24_t big( value ); + little24_t little( value ); - std::cout << "Hello, endian world "<< value << ' ' << big << ' ' << little << '\n'; + std::cout << "Hello, endian world!\n"; + std::cout << " cout << value--: " << value << " sizeof(value): " << sizeof(value) + << "\n cout << big----: " << big << " sizeof(big): " << sizeof(big) + << "\n cout << little-: " << little << " sizeof(little): " << sizeof(little) + << '\n'; } diff --git a/libs/integer/test/binary_stream_test.cpp b/libs/integer/test/binary_stream_test.cpp new file mode 100644 index 0000000..4770e0c --- /dev/null +++ b/libs/integer/test/binary_stream_test.cpp @@ -0,0 +1,122 @@ +// binary_test.cpp -------------------------------------------------------------------// + +// Copyright Beman Dawes, 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +using namespace boost; +using namespace std; + +namespace +{ + int errors = 0; + + void verify( bool x, const char * file, int line ) + { + if ( x ) return; + ++errors; + cout << file << "(" << line << ") : error: predicate is false\n" << endl; + } + +} + +#define BOOST_VERIFY(predicate) verify( predicate, __FILE__, __LINE__ ) + + +int main() +{ + std::stringstream ss( std::ios_base::in | std::ios_base::out | std::ios_base::binary ); + + short short_1(0x0102), short_2; + ss <= short_1; + ss >= short_2; + BOOST_VERIFY( short_1 == short_2 ); + + unsigned short ushort_1(0x0102), ushort_2; + ss <= ushort_1; + ss >= ushort_2; + BOOST_VERIFY( ushort_1 == ushort_2 ); + + int int_1(0x01020304), int_2; + ss <= int_1; + ss >= int_2; + BOOST_VERIFY( int_1 == int_2 ); + + unsigned int uint_1(0x01020304), uint_2; + ss <= uint_1; + ss >= uint_2; + BOOST_VERIFY( uint_1 == uint_2 ); + + long long_1(0x01020304L), long_2; + ss <= long_1; + ss >= long_2; + BOOST_VERIFY( long_1 == long_2 ); + + unsigned long ulong_1(0x01020304UL), ulong_2; + ss <= ulong_1; + ss >= ulong_2; + BOOST_VERIFY( ulong_1 == ulong_2 ); + + long long long_long_1(0x0102030405060708LL), long_long_2; + ss <= long_long_1; + ss >= long_long_2; + BOOST_VERIFY( long_long_1 == long_long_2 ); + + unsigned long long ulong_long_1(0x0102030405060708ULL), ulong_long_2; + ss <= ulong_long_1; + ss >= ulong_long_2; + BOOST_VERIFY( ulong_long_1 == ulong_long_2 ); + + float float_1(1.2F), float_2; + ss <= float_1; + ss >= float_2; + BOOST_VERIFY( float_1 == float_2 ); + + double double_1(1.2), double_2; + ss <= double_1; + ss >= double_2; + BOOST_VERIFY( double_1 == double_2 ); + + long double long_double_1(1.2), long_double_2; + ss <= long_double_1; + ss >= long_double_2; + BOOST_VERIFY( long_double_1 == long_double_2 ); + + char char_1(0x01), char_2; + ss <= char_1; + ss >= char_2; + BOOST_VERIFY( char_1 == char_2 ); + + signed char schar_1(0x01), schar_2; + ss <= schar_1; + ss >= schar_2; + BOOST_VERIFY( schar_1 == schar_2 ); + + unsigned char uchar_1(0x01), uchar_2; + ss <= uchar_1; + ss >= uchar_2; + BOOST_VERIFY( uchar_1 == uchar_2 ); + + wchar_t wchar_t_1(L'1'), wchar_t_2; + ss <= wchar_t_1; + ss >= wchar_t_2; + BOOST_VERIFY( wchar_t_1 == wchar_t_2 ); + + string string_1("foobar"), string_2; + ss <= string_1.c_str(); + ss >= string_2; + BOOST_VERIFY( string_1 == string_2 ); + ss <= string_1; + ss >= string_2; + BOOST_VERIFY( string_1 == string_2 ); + + cout << errors << " error(s) detected\n"; + return errors; +} diff --git a/libs/integer/test/endian-in-sandbox/binary_stream_test/binary_stream_test.vcproj b/libs/integer/test/endian-in-sandbox/binary_stream_test/binary_stream_test.vcproj new file mode 100644 index 0000000..e3c0fa9 --- /dev/null +++ b/libs/integer/test/endian-in-sandbox/binary_stream_test/binary_stream_test.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln b/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln index a2492d3..d79c670 100644 --- a/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln +++ b/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln @@ -13,6 +13,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endian_example", "endian_ex EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endian_hello_world", "endian_hello_world\endian_hello_world.vcproj", "{1AAEBB4E-501E-417E-9531-04469AF5DD8B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binary_stream_test", "binary_stream_test\binary_stream_test.vcproj", "{1382D085-FF3F-4573-8709-E10D3D74D620}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -43,6 +45,10 @@ Global {1AAEBB4E-501E-417E-9531-04469AF5DD8B}.Debug|Win32.Build.0 = Debug|Win32 {1AAEBB4E-501E-417E-9531-04469AF5DD8B}.Release|Win32.ActiveCfg = Release|Win32 {1AAEBB4E-501E-417E-9531-04469AF5DD8B}.Release|Win32.Build.0 = Release|Win32 + {1382D085-FF3F-4573-8709-E10D3D74D620}.Debug|Win32.ActiveCfg = Debug|Win32 + {1382D085-FF3F-4573-8709-E10D3D74D620}.Debug|Win32.Build.0 = Debug|Win32 + {1382D085-FF3F-4573-8709-E10D3D74D620}.Release|Win32.ActiveCfg = Release|Win32 + {1382D085-FF3F-4573-8709-E10D3D74D620}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/libs/integer/test/endian_test.cpp b/libs/integer/test/endian_test.cpp index 5dd411d..4d027c7 100644 --- a/libs/integer/test/endian_test.cpp +++ b/libs/integer/test/endian_test.cpp @@ -2,8 +2,8 @@ // Copyright Beman Dawes, 1999-2008 -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// 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