Both sides previous revisionPrevious revisionNext revision | Previous revision |
projects:endian_template [2016/02/24] – [Usage] terence | projects:endian_template [2016/02/26] (current) – [Q & A] terence |
---|
* **Author:** [[mailto:tjgrant@tatewake.com|Terence J. Grant]] | * **Author:** [[mailto:tjgrant@tatewake.com|Terence J. Grant]] |
* **License:** [[http://opensource.org/licenses/MIT|MIT License]] | * **License:** [[http://opensource.org/licenses/MIT|MIT License]] |
* **Last Update:** 2016-02-23 | * **Last Update:** 2016-02-26 |
* **Donate:** [[:donate|Your donations are appreciated!]] | * **Donate:** [[:donate|Your donations are appreciated!]] |
| |
After downloading, make sure to follow the [[#how_to_use|how to use]] instructions below; they're worth reading. | After downloading, make sure to follow the [[#how_to_use|how to use]] instructions below; they're worth reading. |
| |
* Latest version: [[https://github.com/tatewake/endian-template|Endian Template(C++) version 2016-02-23 on GitHub]] | * Latest version: [[https://github.com/tatewake/endian-template|Endian Template(C++) version 2016-02-26 on GitHub]] |
| |
===== About ===== | ===== About ===== |
* First, copy the header ''tEndian.h'' into your project. | * First, copy the header ''tEndian.h'' into your project. |
* Next, include the header somewhere in your project or [[wp>Precompiled_header|precompiled header]] if you use one. | * Next, include the header somewhere in your project or [[wp>Precompiled_header|precompiled header]] if you use one. |
* You will also need to include ''assert.h'' and ''cstdint'' if they're not already included in your project | |
| |
<code c++> | <code c++> |
#include <assert.h> | |
#include <cstdint> | |
#include "tEndian.h" | #include "tEndian.h" |
</code> | </code> |
You'll now have the following typedefs to use in your project: | You'll now have the following typedefs to use in your project: |
| |
* ''leint16_t'', ''leint32_t'', ''leint64_t'' - Little endian signed types | * ''leint16'', ''leint32'', ''leint64'' - Little endian signed types |
* ''leuint16_t'', ''leuint32_t'', ''leuint64_t'' - Little endian unsigned types | * ''leuint16'', ''leuint32'', ''leuint64'' - Little endian unsigned types |
* ''lefloat32_t'', ''lefloat64_t'' - Little endian floating point types | * ''lefloat32'', ''lefloat64'' - Little endian floating point types |
| |
* ''beint16_t'', ''beint32_t'', ''beint64_t'' - Big endian signed types | * ''beint16'', ''beint32'', ''beint64'' - Big endian signed types |
* ''beuint16_t'', ''beuint32_t'', ''beuint64_t'' - Big endian unsigned types | * ''beuint16'', ''beuint32'', ''beuint64'' - Big endian unsigned types |
* ''befloat32_t'', ''befloat64_t'' - Big endian floating point types | * ''befloat32'', ''befloat64'' - Big endian floating point types |
| |
The naming conventions are based on those in C++ standard library header [[http://en.cppreference.com/w/cpp/header/cstdint|cstdint]]; the only addition being a prefix of ''le'' or ''be'' to indicate little endian or big endian, respectively. | The naming conventions are based on those in C++ standard library header [[http://en.cppreference.com/w/cpp/header/cstdint|cstdint]]; the only addition being a prefix of ''le'' or ''be'' to indicate little endian or big endian, respectively. |
| |
<code c++> | <code c++> |
typedef tBigEndian<size_t> besize_t; | typedef tBigEndian<size_t> besize; |
typedef tBigEndian<short> beshort; | typedef tBigEndian<short> beshort; |
typedef tLittleEndian<long long> lelonglong; | typedef tLittleEndian<long long> lelonglong; |
If you read this data into an ''uint32_t'', you're fine as long as you're on a little endian machine (like an x86-based PC.) Not so much if you end up running your code on a PowerPC CPU, which is big endian. | If you read this data into an ''uint32_t'', you're fine as long as you're on a little endian machine (like an x86-based PC.) Not so much if you end up running your code on a PowerPC CPU, which is big endian. |
| |
So take the guesswork out of the equation-- read it into an ''leuint32_t'' instead and it'll always work, regardless of the architecture. | So take the guesswork out of the equation-- read it into an ''leuint32'' instead and it'll always work, regardless of the architecture. |
| |
=== Sending data over a network === | === Sending data over a network === |
If you're familiar with [[http://www.tutorialspoint.com/unix_sockets/network_byte_orders.htm|Network Byte Order]], you'll know that the functions ''htons'', ''htonl'', ''ntohl'', ''ntohs'' are generally suggested to use before sending data over a network. | If you're familiar with [[http://www.tutorialspoint.com/unix_sockets/network_byte_orders.htm|Network Byte Order]], you'll know that the functions ''htons'', ''htonl'', ''ntohl'', ''ntohs'' are generally suggested to use before sending data over a network. |
| |
Since "Network Byte Order" is just "big endian"; instead you can now just define your data as ''beint32_t'', ''beint16_t'', or ''tBigEndian<unsigned short>'' and discard the conversion functions completely. | Since "Network Byte Order" is just "big endian"; instead you can now just define your data as ''beint32'', ''beint16'', or ''tBigEndian<unsigned short>'' and discard the conversion functions completely. |
| |
And regardless of the endian of computer's CPU, the code will always work. | And regardless of the endian of computer's CPU, the code will always work. |
//If you have a question not answered here, please feel free to [[mailto:tjgrant@tatewake.com|contact me]] and ask.// | //If you have a question not answered here, please feel free to [[mailto:tjgrant@tatewake.com|contact me]] and ask.// |
| |
//No questions so far!// | === vs Boost? === |
| |
| * **Q:** What makes this better or different than [[http://www.boost.org/libs/endian/|Boost.Endian]]? |
| * **A:** I can't say for certain if it's better. The Endian Template is small, and only provides a minimum of what's needed to handle automatic endian conversion. |
| |
| As I understand it Boost.Endian provides three different mechanisms for handling endian (one providing swapping functions), whereas my primary philosophy here is "don't use swapping functions." |
| |
| Just for trivia: I originally created this class in 2001 as a proof-of-concept, hoping I could use it in some emulation projects (never got around to those unfortunately.) |
| This predates when Boost.Endian came out, which was around 2002 or 2003. |
| |
| That said, I've used boost (in general) before on a day-to-day basis for a client project. I'm not a boost "hater", but I'm not a regular user of it either. |
===== History ===== | ===== History ===== |
| **February 26, 2016** |
| |
| * Renamed typedefs without ''_t'' postfix notation as this appears to be "reserved" by POSIX (thanks to reddit user "doodle77") |
| * Added required includes directly into ''tEndian.h'' (thanks to reddit user "louiswins") |
| * Changed endian testing method to use reinterpret_cast, as the previous was using "type punning", which in theory can have undefined behavior (thanks to reddit user "NasenSpray") |
| * Removed ::PassThru method as a small optimization |
| |
**February 23, 2016** | **February 23, 2016** |
* First public release | * First public release |
* Created project page | * Created project page |
| |