MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
binarybuffer.h
1 // © Copyright 2010 - 2014 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  /// @brief A grouping of utilities for working with binary data more easily
49  ///////////////////////////////////////
50  namespace BinaryTools
51  {
52  ///////////////////////////////////////////////////////////////////////////////////////////////////
53  /// @brief A way to store and pass binary buffers, for example compiled bytecode.
54  /// @details Originally intended for use with ScriptCompilable as a basic way to store and pass bytecode around.
55  /// This deletes the passed binary on destruction. To prevent this behavior set the Binary pointer to null.
56  /// @n @n
57  /// This is designed to be fairly minimalistic but passing by value causes the buffer to be copied.
58  /// @n @n
59  /// Where possible this class performs no speculative allocation unless explicitly requested to. In other words
60  /// this should have allocated exactly as many bytes are indicated by the member Size, no more and no less.
61  /// This will tend to not allocate memory unless an operation on it is specified that it does so.
62  /// @n @n
63  /// Whenever this needs to allocated memory it will use the Size member for determining the amount to allocate. If that
64  /// is 0 an InvalidStateException exception is thrown. Bounds checking, if performed, only occurs when
65  /// MEZZ_DEBUG is enabled.
67  {
68  public:
69 
70  /// @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
71  typedef Int8 Byte;
72 #ifndef SWIG
73  /// @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.
75 
76  /// @brief A pointer to the actual binary data.
78 #endif
79  /// @brief Default constructor, set everything to zero. Doesn't allocate anything
81  Size(0),
82  Binary(NULL)
83  {}
84 
85  /// @brief Copy constructor.
86  /// @param Other The buffer to copy to make
87  /// @details Allocates identical amount of memory as other buffer then copies the other buffer into
88  /// the allocated space. Each BinaryBuffer retains ownership of their respective buffers.
89  BinaryBuffer(const BinaryBuffer& Other);
90 
91  /// @brief Base64 decoding Constructor
92  /// @details Performs exactly one allocation of the amount required to store the decoded base64,
93  /// Then starts filling it. If there is an error with the data as it is beign process the rest of the Buffer will
94  /// be filled with gibberish, and everything before the error will be properly decoded.
95  /// @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
96  /// @param IsBase64 Is the String passed Base64 encoded
97  explicit BinaryBuffer(const String& DataString, bool IsBase64 = true);
98 
99  /// @brief Assignment Operator
100  /// @details This deletes the buffer if it is not null, and allocates a fresh one of
101  /// the size in RH, then copies it.
102  /// @param RH The item on the right hand side
103  /// @return A reference to the newly assigned binary buffer.
104  BinaryBuffer& operator= (const BinaryBuffer& RH);
105 
106  /// @brief Verbose constructor, set everything custom on creation.
107  /// @details If passed a pointer this assumes ownship of that pointer, otherwise this allocates the amount of space requested.
108  /// @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.
109  /// @param PredeterminedSize The size to set on creation.
110  BinaryBuffer(Byte* BinaryPointer, Integer PredeterminedSize) :
111  Size(PredeterminedSize),
112  Binary(BinaryPointer ? BinaryPointer : new Byte[PredeterminedSize])
113  {}
114 
115  /// @brief Terse constructor, set a custom size and allocates space (filled with gibberish).
116  /// @param PredeterminedSize The size to set on creation.
117  explicit BinaryBuffer(Whole PredeterminedSize) :
118  Size(PredeterminedSize),
119  Binary(new Byte[PredeterminedSize])
120  {}
121 
122  /// @brief Virtual deconstructor calls @ref DeleteBuffer() to clean up whatever has been inserted here
123  /// @details If you do not want the Buffer pointed to by the pointer Binary assign Binary to 0 and
124  /// this deconstructor will delete with erase nothing.
125  virtual ~BinaryBuffer();
126 
127  /// @brief Deletes whatever Binary points at and assigns Size to 0.
128  /// @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
129  void DeleteBuffer(Whole NewSize=0);
130 
131  /// @brief This will create a buffer with size matching the this->Size and point this->Binary to that Buffer
132  /// @warning This does not delete an old buffer, delete that before calling this.
133  void CreateBuffer();
134 
135  /// @brief Get the binary buffer as a base64 string
136  /// @return a String contain a base6 encoded version of the binary
137  String ToBase64String();
138 
139  /// @brief Get the contents of this crudely converted to a c style string then stuff it in a string
140  /// @return A String with the value stored in binary copied into it.
141  String ToString();
142 
143  /// @brief This calls deallocates any space, allocates fresh space of the size requestedthen the Decodes the passed and repopulates the Buffer
144  /// @param EncodedBinaryData The Base64 string containing binary data.
145  void CreateFromBase64(const String &EncodedBinaryData);
146 
147  /// @brief Access a part of the buffer
148  /// @param Index How from from the 0 aligned beginning of the buffer would you like to access.
149  /// @return A Reference to the specific Byte the Index passed refers to
150  /// @note When compiled as Debug this can throw a @ref MemoryOutOfBoundsException if the index is to high (or cast from a negative
151  Byte& operator[] (Whole Index);
152 
153  /// @brief Append another group of arbitrary data onto this one.
154  /// @details Allocates space equal to the size of both buffers, Copies this Buffers data
155  /// into it, then copies the other buffers data, then deallocates any space this buffer
156  /// may have had allocated preivously.
157  /// @param OtherBuffer A pointer to a region of memory to be copied
158  /// @param ByteSize How big in bytes is the Buffer
159  void Concatenate(const Byte* OtherBuffer, Whole ByteSize);
160 
161  /// @brief Concatenate another buffer onto this one
162  /// @details This calls @ref Concatenate(const Byte*, Whole)
163  /// @param BufferFromAnotherMother A buffer to copy and append onto this one.
164  void Concatenate(const BinaryBuffer BufferFromAnotherMother);
165 
166  /// @details An easier way to call @ref Concatenate(const Byte*, Whole)
167  /// @param RH The other Buffer to copy/append.
168  /// @return A Reference to this buffer to allow operator chaining.
169  BinaryBuffer& operator+=(const BinaryBuffer& RH);
170 
171  /// @brief Even though this class is intended to have its internals modifieddirectly in some cases, In normal cases accessor are nice to have.
172  /// @return Get the size as a whole
173  Whole GetSize() const;
174 
175  };
176 
177  /// @brief Is a character a valid Base64 character
178  /// @param Char8 a single char to check if it could possibly be valid base64
179  /// @return True if the character could be part of a valid block of Base64 text, false otherwise
180  bool MEZZ_LIB IsBase64(unsigned char Char8);
181 
182  /// @brief Converts the contents of a String into a String containing a base64 encoded String
183  /// @param Unencoded A String/binary to be encoded
184  /// @return A string containing base64.
185  String MEZZ_LIB Base64Encode(String const& Unencoded);
186 
187  /// @brief Convert a binary buffer to a base64 String.
188  /// @param Buffer A BinaryBuffer to base64 encode.
189  /// @return A string containing base64.
190  String MEZZ_LIB Base64Encode(BinaryBuffer const& Buffer);
191 
192  /// @brief Convert a binary buffer to a Base64 string.
193  /// @param BytesToEncode A pointer to the beginning of the buffer.
194  /// @param Length The length of the bufferin bytes.
195  /// @return A String containing the base64 encoded binary
196  String MEZZ_LIB Base64Encode(UInt8 const* BytesToEncode, unsigned int Length);
197 
198  /// @brief Convert Base64 stuff back to binary
199  /// @param EncodedString The results of a previous function like @ref Base64Encode to be converted back to binary
200  /// @return A String with the raw bianry
201  BinaryBuffer MEZZ_LIB Base64Decode(String const& EncodedString);
202 
203  /// @brief From an encoded string get the exact size of the decode binary in 8bit bytes
204  /// @param EncodedString The base64 encoded string
205  /// @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.
207 
208  /// @brief From the size of a binary get the exact size in 8bit bytes.
209  /// @param Length The bytelength of the item before Base64 encoding.
210  /// @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.
212 
213  } //stringtool
214 }//Mezzanine
215 
216 #endif