Spinning Topp Logo BlackTopp Studios
inc
binarybuffer.h
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _binarytool_h
41 #define _binarytool_h
42 
43 #include "datatypes.h"
44 
45 namespace Mezzanine
46 {
47  ///////////////////////////////////////////////////////////////////////////////
48  /// @namespace BinaryTools
49  /// @brief A grouping of utilities for working with binary data more easily.
50  ///////////////////////////////////////
51  namespace BinaryTools
52  {
53  ///////////////////////////////////////////////////////////////////////////////////////////////////
54  /// @brief A way to store and pass binary buffers, for example compiled bytecode.
55  /// @details Originally intended for use with ScriptCompilable as a basic way to store and pass bytecode around.
56  /// This deletes the passed binary on destruction. To prevent this behavior set the Binary pointer to null.
57  /// @n @n
58  /// This is designed to be fairly minimalistic but passing by value causes the buffer to be copied.
59  /// @n @n
60  /// Where possible this class performs no speculative allocation unless explicitly requested to. In other words
61  /// this should have allocated exactly as many bytes are indicated by the member Size, no more and no less.
62  /// This will tend to not allocate memory unless an operation on it is specified that it does so.
63  /// @n @n
64  /// Whenever this needs to allocated memory it will use the Size member for determining the amount to allocate. If that
65  /// is 0 an InvalidStateException exception is thrown. Bounds checking, if performed, only occurs when
66  /// MEZZ_DEBUG is enabled.
67  ///////////////////////////////////////
69  {
70  public:
71  ///////////////////////////////////////////////////////////////////////////////
72  // Public Types
73 
74  /// @brief The type of data this buffer can hold, it is intended to be some type one byte in length, but doesn't have to be
75  typedef Int8 Byte;
76 #ifndef SWIG
77  ///////////////////////////////////////////////////////////////////////////////
78  // Public Data Members
79 
80  /// @brief How many bytes is @ref Binary in size. This is set to 0 if @ref Binary is invalid and should be a null pointer.
82  /// @brief A pointer to the actual binary data.
83  Byte* Binary;
84 #endif
85  ///////////////////////////////////////////////////////////////////////////////
86  // Construction and Destruction
87 
88  /// @brief Default constructor, set everything to zero. Doesn't allocate anything.
89  BinaryBuffer();
90  /// @brief Copy constructor.
91  /// @param Other The buffer to be copied.
92  /// @details Allocates identical amount of memory as other buffer then copies the other buffer into
93  /// the allocated space. Each BinaryBuffer retains ownership of their respective buffers.
94  BinaryBuffer(const BinaryBuffer& Other);
95  /// @brief Terse constructor, set a custom size and allocates space (filled with gibberish).
96  /// @param PredeterminedSize The size to set on creation.
97  explicit BinaryBuffer(const Whole PredeterminedSize);
98  /// @brief Verbose constructor, set everything custom on creation.
99  /// @details If passed a pointer this assumes ownship of that pointer, otherwise this allocates the amount of space requested.
100  /// @param BinaryPointer A pointer to the first byte in memory, if this is null the buffer is created. Ownership of this Pointer will be assumed.
101  /// @param PredeterminedSize The size to set on creation.
102  BinaryBuffer(Byte* BinaryPointer, const Whole PredeterminedSize);
103  /// @brief Base64 decoding Constructor.
104  /// @details Performs exactly one allocation of the amount required to store the decoded base64,
105  /// Then starts filling it. If there is an error with the data as it is beign process the rest of the Buffer will
106  /// be filled with gibberish, and everything before the error will be properly decoded.
107  /// @param DataString A Base64 string to be decode and used as a binary buffer, or a string to be used a buffer if IsBase64 is false.
108  /// @param IsBase64 Is the String passed Base64 encoded.
109  explicit BinaryBuffer(const String& DataString, const Boole IsBase64 = true);
110  /// @brief Virtual deconstructor calls @ref DeleteBuffer() to clean up whatever has been inserted here.
111  /// @details If you do not want the Buffer pointed to by the pointer Binary assign Binary to 0 and
112  /// this deconstructor will delete with erase nothing.
113  ~BinaryBuffer();
114 
115  ///////////////////////////////////////////////////////////////////////////////
116  // Utility
117 
118  /// @brief This will create a buffer with size matching the this->Size and point this->Binary to that Buffer.
119  /// @warning This does not delete an old buffer, delete that before calling this.
120  void CreateBuffer();
121  /// @brief Deletes whatever Binary points at and assigns Size to 0.
122  /// @param NewSize If you don't want to just clear the buffer, but rather want to set size to a value and set a new size, you can do that with this.
123  void DeleteBuffer(const Whole NewSize = 0);
124 
125  /// @brief This calls deallocates any space, allocates fresh space of the size requestedthen the Decodes the passed and repopulates the Buffer.
126  /// @param EncodedBinaryData The Base64 string containing binary data.
127  void CreateFromBase64(const String& EncodedBinaryData);
128  /// @brief Get the binary buffer as a base64 string.
129  /// @return a String contain a base6 encoded version of the binary.
130  String ToBase64String();
131 
132  /// @brief Append another group of arbitrary data onto this one.
133  /// @details Allocates space equal to the size of both buffers, Copies this Buffers data
134  /// into it, then copies the other buffers data, then deallocates any space this buffer
135  /// may have had allocated preivously.
136  /// @param OtherBuffer A pointer to a region of memory to be copied.
137  /// @param ByteSize How big in bytes is the Buffer.
138  void Concatenate(const Byte* OtherBuffer, const Whole ByteSize);
139  /// @brief Concatenate another buffer onto this one.
140  /// @details This calls @ref Concatenate(const Byte*, Whole)
141  /// @param BufferFromAnotherMother A buffer to copy and append onto this one.
142  void Concatenate(const BinaryBuffer BufferFromAnotherMother);
143 
144  /// @brief Get the contents of this crudely converted to a c style string then stuff it in a string.
145  /// @return A String with the value stored in binary copied into it.
146  String ToString();
147  /// @brief Even though this class is intended to have its internals modified directly in some cases, In normal cases accessor are nice to have.
148  /// @return Get the size as a whole.
149  Whole GetSize() const;
150 
151  ///////////////////////////////////////////////////////////////////////////////
152  // Operators
153 
154  /// @brief Assignment Operator.
155  /// @details This deletes the buffer if it is not null, and allocates a fresh one of
156  /// the size in RH, then copies it.
157  /// @param RH The item on the right hand side.
158  /// @return A reference to the newly assigned binary buffer.
159  BinaryBuffer& operator=(const BinaryBuffer& RH);
160  /// @brief Addition Assignment Operator.
161  /// @details An easier way to call @ref Concatenate(const Byte*, const Whole)
162  /// @param RH The other Buffer to copy/append.
163  /// @return A Reference to this buffer to allow operator chaining.
164  BinaryBuffer& operator+=(const BinaryBuffer& RH);
165 
166  /// @brief Access a part of the buffer.
167  /// @param Index How from from the 0 aligned beginning of the buffer would you like to access.
168  /// @return A Reference to the specific Byte the Index passed refers to.
169  /// @note When compiled as Debug this can throw a @ref MemoryOutOfBoundsException if the index is to high (or cast from a negative.
170  Byte& operator[](const Whole Index);
171  };//BinaryBuffer
172 
173  /// @brief Is a character a valid Base64 character.
174  /// @param Char8 a single char to check if it could possibly be valid base64.
175  /// @return True if the character could be part of a valid block of Base64 text, false otherwise.
176  Boole MEZZ_LIB IsBase64(unsigned char Char8);
177  /// @brief Converts the contents of a String into a String containing a base64 encoded String.
178  /// @param Unencoded A String/binary to be encoded.
179  /// @return A string containing base64.
180  String MEZZ_LIB Base64Encode(String const& Unencoded);
181  /// @brief Convert a binary buffer to a base64 String.
182  /// @param Buffer A BinaryBuffer to base64 encode.
183  /// @return A string containing base64.
184  String MEZZ_LIB Base64Encode(BinaryBuffer const& Buffer);
185  /// @brief Convert a binary buffer to a Base64 string.
186  /// @param BytesToEncode A pointer to the beginning of the buffer.
187  /// @param Length The length of the bufferin bytes.
188  /// @return A String containing the base64 encoded binary.
189  String MEZZ_LIB Base64Encode(UInt8 const* BytesToEncode, unsigned int Length);
190  /// @brief Convert Base64 stuff back to binary.
191  /// @param EncodedString The results of a previous function like @ref Base64Encode to be converted back to binary.
192  /// @return A String with the raw bianry.
193  BinaryBuffer MEZZ_LIB Base64Decode(String const& EncodedString);
194  /// @brief From an encoded string get the exact size of the decode binary in 8bit bytes.
195  /// @param EncodedString The base64 encoded string.
196  /// @return This returns the exact length of the result once it is decoded. The binary is about 3/4 of the base64 size, but that can be off by just enough to make memory allocation an issue if not calcualated carefully.
197  Whole MEZZ_LIB PredictBinarySizeFromBase64String(String const& EncodedString);
198  /// @brief From the size of a binary get the exact size in 8bit bytes.
199  /// @param Length The bytelength of the item before Base64 encoding.
200  /// @return This returns the exact length of the result once it is encoded. The Base64 is about 133% of the binary size, but that can be off by just enough to make memory allocation an issue if not calcualated carefully.
201  Whole MEZZ_LIB PredictBase64StringSizeFromBinarySize(Whole Length);
202  }//BinaryTools
203 }//Mezzanine
204 
205 #endif
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
A grouping of utilities for working with binary data more easily.
String ToString(const T &Datum)
Converts whatever to a String as long as a streaming operator is available for it.
Definition: datatypes.h:242
All the definitions for datatypes as well as some basic conversion functions are defined here...
Whole Size
How many bytes is Binary in size. This is set to 0 if Binary is invalid and should be a null pointer...
Definition: binarybuffer.h:81
uint8_t UInt8
An 8-bit unsigned integer.
Definition: datatypes.h:118
char Char8
A datatype to represent one character.
Definition: datatypes.h:169
Int8 Byte
The type of data this buffer can hold, it is intended to be some type one byte in length...
Definition: binarybuffer.h:75
Byte * Binary
A pointer to the actual binary data.
Definition: binarybuffer.h:83
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
A way to store and pass binary buffers, for example compiled bytecode.
Definition: binarybuffer.h:68
int8_t Int8
An 8-bit integer.
Definition: datatypes.h:116
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159