diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index 86f07818e..f50b5e556 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -170,12 +170,14 @@ + + diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index 9d67bed8c..be813db54 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -836,6 +836,12 @@ beast_asio\basics + + beast_core\maths + + + beast_core\memory + diff --git a/Subtrees/beast/modules/beast_core/beast_core.h b/Subtrees/beast/modules/beast_core/beast_core.h index aff325acb..683e845a8 100644 --- a/Subtrees/beast/modules/beast_core/beast_core.h +++ b/Subtrees/beast/modules/beast_core/beast_core.h @@ -230,6 +230,8 @@ namespace beast #include "time/beast_PerformedAtExit.h" #include "diagnostic/beast_LeakChecked.h" #include "memory/beast_ByteOrder.h" +#include "memory/beast_ByteSwap.h" +#include "maths/beast_uint24.h" #include "logging/beast_Logger.h" #include "threads/beast_Thread.h" #include "diagnostic/beast_FPUFlags.h" diff --git a/Subtrees/beast/modules/beast_core/maths/beast_uint24.h b/Subtrees/beast/modules/beast_core/maths/beast_uint24.h new file mode 100644 index 000000000..2181331e6 --- /dev/null +++ b/Subtrees/beast/modules/beast_core/maths/beast_uint24.h @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_UINT24_H_INCLUDED +#define BEAST_UINT24_H_INCLUDED + +/** A 24 bit unsigned integer. + We try to be as compatible as possible with built in types. +*/ +class uint24 : public SafeBool +{ +public: + enum { mask = 0xffffff }; + inline uint24 () noexcept { /* uninitialized */ } + inline uint24 (uint24 const& other) noexcept : m_value (other.m_value) { } + inline uint24& operator= (uint24 const& other) noexcept { m_value = other.m_value; return *this; } + template inline uint24 (IntegralType value) noexcept : m_value (value & mask) { } + template inline uint24& operator= (IntegralType value) noexcept { m_value = value & mask; return *this; } + inline uint32 get () const noexcept { return m_value; } + inline bool asBoolean () const noexcept { return m_value != 0; } + inline operator String () const { return String (m_value); } + inline uint24& operator++ () noexcept { (++m_value) &= mask; return *this; } + inline uint24& operator-- () noexcept { (--m_value) &= mask; return *this; } + inline uint24 operator++ (int) noexcept { return uint24 (m_value + 1); } + inline uint24 operator-- (int) noexcept { return uint24 (m_value - 1); } + inline uint24& operator~ () { m_value = (~ m_value) & mask; return *this; } + inline uint24& operator+= (uint24 const& rhs) { m_value = (m_value + rhs.m_value) & mask; return *this; } + inline uint24& operator-= (uint24 const& rhs) { m_value = (m_value - rhs.m_value) & mask; return *this; } + inline uint24& operator*= (uint24 const& rhs) { m_value = (m_value * rhs.m_value) & mask; return *this; } + inline uint24& operator/= (uint24 const& rhs) { m_value = (m_value / rhs.m_value) & mask; return *this; } + inline uint24& operator|= (uint24 const& rhs) { m_value = (m_value | rhs.m_value) & mask; return *this; } + inline uint24& operator&= (uint24 const& rhs) { m_value = (m_value & rhs.m_value) & mask; return *this; } + inline uint24& operator^= (uint24 const& rhs) { m_value = (m_value ^ rhs.m_value) & mask; return *this; } + template inline uint24& operator+= (IntegralType value) { m_value = (m_value + value) & mask; return *this; } + template inline uint24& operator-= (IntegralType value) { m_value = (m_value - value) & mask; return *this; } + template inline uint24& operator*= (IntegralType value) { m_value = (m_value * value) & mask; return *this; } + template inline uint24& operator/= (IntegralType value) { m_value = (m_value / value) & mask; return *this; } + template inline uint24& operator|= (IntegralType value) { m_value = (m_value | value) & mask; return *this; } + template inline uint24& operator&= (IntegralType value) { m_value = (m_value & value) & mask; return *this; } + template inline uint24& operator^= (IntegralType value) { m_value = (m_value ^ value) & mask; return *this; } + template inline bool operator== (IntegralType value) const noexcept { return m_value == value; } + template inline bool operator!= (IntegralType value) const noexcept { return m_value != value; } + template inline bool operator< (IntegralType value) const noexcept { return m_value < value; } + template inline bool operator> (IntegralType value) const noexcept { return m_value > value; } + template inline bool operator<= (IntegralType value) const noexcept { return m_value <= value; } + template inline bool operator>= (IntegralType value) const noexcept { return m_value >= value; } + + // Construct from raw bytes + static uint24 from3RawBytes (void const* buf) + { + uint24 result; + uint8* const raw (reinterpret_cast (&result.m_value)); + uint8 const* const data (reinterpret_cast (buf)); + +#if BEAST_LITTLE_ENDIAN + raw [0] = data [0]; + raw [1] = data [1]; + raw [2] = data [2]; + raw [3] = 0; +#else + raw [0] = 0; + raw [1] = data [0]; + raw [2] = data [1]; + raw [3] = data [2]; +#endif + return result; + } + +private: + uint24* operator&(); + uint24 const* operator&() const; + + friend struct detail::SwapBytes ; + + inline uint8& operator[] (int index) noexcept { bassert (index >= 0 && index < 3); return raw () [index]; } + inline uint8 operator[] (int index) const noexcept { bassert (index >= 0 && index < 3); return raw () [index]; } + +#if BEAST_LITTLE_ENDIAN + inline uint8* raw () noexcept { return reinterpret_cast (&m_value); } + inline uint8 const* raw () const noexcept { return reinterpret_cast (&m_value); } +#else + inline uint8* raw () noexcept { return reinterpret_cast (&m_value) + 1; } + inline uint8 const* raw () const noexcept { return reinterpret_cast (&m_value) + 1; } +#endif + + uint32 m_value; +}; + +inline uint24 const operator~ (uint24 const& value) noexcept { return uint24 (~value.get ()); } +inline uint24 const operator+ (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () + rhs.get ()); } +inline uint24 const operator- (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () - rhs.get ()); } +inline uint24 const operator/ (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () / rhs.get ()); } +inline uint24 const operator* (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () * rhs.get ()); } +inline uint24 const operator| (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () ^ rhs.get ()); } +inline uint24 const operator& (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () & rhs.get ()); } +inline uint24 const operator^ (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () ^ rhs.get ()); } +inline bool operator== (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () == rhs.get (); } +inline bool operator!= (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () != rhs.get (); } +inline bool operator< (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () < rhs.get (); } +inline bool operator> (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () > rhs.get (); } +inline bool operator<= (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () <= rhs.get (); } +inline bool operator>= (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () >= rhs.get (); } + +/** SwapBytes specialization uint24. */ +namespace detail +{ + +template <> +struct SwapBytes +{ + inline uint24 const operator() (uint24 const& value) const noexcept + { +#if BEAST_LITTLE_ENDIAN + uint24 result; + result [0] = value [2]; + result [1] = value [1]; + result [2] = value [0]; + result [3] = 0; + return result; +#else + return value; +#endif + } +}; + +} + +#endif diff --git a/Subtrees/beast/modules/beast_core/memory/beast_ByteOrder.h b/Subtrees/beast/modules/beast_core/memory/beast_ByteOrder.h index beed17d07..191de0d94 100644 --- a/Subtrees/beast/modules/beast_core/memory/beast_ByteOrder.h +++ b/Subtrees/beast/modules/beast_core/memory/beast_ByteOrder.h @@ -182,4 +182,5 @@ inline int ByteOrder::bigEndian24Bit (const char* const bytes) inline void ByteOrder::littleEndian24BitToChars (const int value, char* const destBytes) { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); } inline void ByteOrder::bigEndian24BitToChars (const int value, char* const destBytes) { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); } -#endif // BEAST_BYTEORDER_BEASTHEADER +#endif + diff --git a/Subtrees/beast/modules/beast_core/memory/beast_ByteSwap.h b/Subtrees/beast/modules/beast_core/memory/beast_ByteSwap.h new file mode 100644 index 000000000..94384eacd --- /dev/null +++ b/Subtrees/beast/modules/beast_core/memory/beast_ByteSwap.h @@ -0,0 +1,126 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_BYTESWAP_H_INCLUDED +#define BEAST_BYTESWAP_H_INCLUDED + +namespace detail +{ + +/** Specialized helper class template for swapping bytes. + + Normally you won't use this directly, use the helper function + byteSwap instead. You can specialize this class for your + own user defined types, as was done for uint24. + + @see swapBytes, uint24 +*/ +template +struct SwapBytes +{ + inline IntegralType operator() (IntegralType value) const noexcept + { + return ByteOrder::swap (value); + } +}; + +// Specializations for signed integers + +template <> +struct SwapBytes +{ + inline int16 operator() (int16 value) const noexcept + { + return static_cast (ByteOrder::swap (static_cast (value))); + } +}; + +template <> +struct SwapBytes +{ + inline int32 operator() (int32 value) const noexcept + { + return static_cast (ByteOrder::swap (static_cast (value))); + } +}; + +template <> +struct SwapBytes +{ + inline int64 operator() (int64 value) const noexcept + { + return static_cast (ByteOrder::swap (static_cast (value))); + } +}; + +} + +//------------------------------------------------------------------------------ + +/** Returns a type with the bytes swapped. + Little endian becomes big endian and vice versa. The underlying + type must be an integral type or behave like one. +*/ +template +inline IntegralType swapBytes (IntegralType value) noexcept +{ + return detail::SwapBytes () (value); +} + +/** Returns the machine byte-order value to little-endian byte order. */ +template +inline IntegralType toLittleEndian (IntegralType value) noexcept +{ +#if BEAST_LITTLE_ENDIAN + return value; +#else + return swapBytes (value); +#endif +} + +/** Returns the machine byte-order value to big-endian byte order. */ +template +inline IntegralType toBigEndian (IntegralType value) noexcept +{ +#if BEAST_LITTLE_ENDIAN + return swapBytes (value); +#else + return value; +#endif +} + +/** Returns the machine byte-order value to network byte order. */ +template +inline IntegralType toNetworkByteOrder (IntegralType value) noexcept +{ + return toBigEndian (value); +} + +/** Converts from network byte order to machine byte order. */ +template +inline IntegralType fromNetworkByteOrder (IntegralType value) noexcept +{ +#if BEAST_LITTLE_ENDIAN + return swapBytes (value); +#else + return value; +#endif +} + +#endif