22 #include "MCBinaryData.hpp" 24 #include "3rdparty/archives/portable_iarchive.hpp" 25 #include "3rdparty/archives/portable_oarchive.hpp" 29 #ifndef __AIBO_BUILD__ 30 #include <qdatastream.h> 32 #include <qresource.h> 35 #include <boost/archive/binary_oarchive.hpp> 36 #include <boost/archive/binary_iarchive.hpp> 37 #include <boost/archive/iterators/base64_from_binary.hpp> 38 #include <boost/archive/iterators/binary_from_base64.hpp> 39 #if __cplusplus >= 201103L || defined(__MINGW32__) || defined(__MINGW64__) 40 #pragma GCC diagnostic push 41 #pragma GCC diagnostic ignored "-Wreorder" 42 #if !defined(__clang__) 43 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 46 #include <boost/archive/iterators/transform_width.hpp> 47 #if __cplusplus >= 201103L || defined(__MINGW32__) || defined(__MINGW64__) 48 #pragma GCC diagnostic pop 50 #include <boost/serialization/vector.hpp> 75 uint base64_encode(
unsigned char* dest,
const unsigned char* src, uint len)
77 typedef base64_from_binary<transform_width<const char *, 6, 8> > base64_enc;
79 uint one_third_len = len/3;
80 uint len_rounded_down = one_third_len*3;
81 uint j = len_rounded_down + one_third_len;
83 std::copy(base64_enc(src), base64_enc(src + len_rounded_down), dest);
85 if (len_rounded_down != len)
87 char tail[3] = {0, 0, 0};
90 for (; i < len - len_rounded_down; ++i)
92 tail[i] = src[len_rounded_down+i];
94 std::copy(base64_enc(tail), base64_enc(tail + 3), dest + j);
96 for (i = len + one_third_len + 1; i < j+4; ++i)
114 const char* base64_decode(
unsigned char* dest,
const char* src, uint* len)
116 uint output_len = *len;
117 typedef transform_width<binary_from_base64<const char*>, 8, 6> base64_dec;
122 base64_dec src_it(src);
123 for(; i < output_len; ++i)
133 if (src[(
int)*len-1] ==
'=')
136 if (src[(
int)*len-2] ==
'=')
140 return src + (i+2)/3*4;
158 memset(&
Data[0], (
int)value, (
size_t)size);
170 *
this = std::move(other);
176 MCBinaryData::~MCBinaryData()
211 if (size < 0 || size >=
Size)
224 std::vector<unsigned char>(
Data).swap(
Data);
241 for (
int i = 0; i <
Size; ++i)
257 memcpy(&
Data[0], data, size);
284 int Count =
CopyData(target, capacity);
297 int Capacity = capacity < 0 ? target.
Size : capacity;
301 MC_WARNING(
"%d source bytes are needed, but only %d available to write binary data.",
307 MC_WARNING(
"%d target bytes are needed, but only %d available to write binary data.",
319 std::ifstream InputFile(file_name.c_str(), std::ios::in | std::ios::binary);
321 if (!InputFile.is_open())
323 MC_WARNING(
"File does not exist to load binary data: %s", file_name.c_str());
326 InputFile.seekg(0, std::ios::end);
328 InputFile.seekg(0, std::ios::beg);
329 InputFile.read(reinterpret_cast<char*>(&
Data[0]),
Data.size());
330 return InputFile.good();
334 #ifndef __AIBO_BUILD__ 337 QResource XmlResource(resource_str);
338 QFile ClassifierFile(XmlResource.absoluteFilePath());
339 QDataStream InputStream(&ClassifierFile);
342 if (!ClassifierFile.open(QIODevice::ReadOnly))
344 if (InputStream.readRawData((
char*)
GetData(), ClassifierFile.size()) < 0)
346 ClassifierFile.close();
349 ClassifierFile.close();
357 std::ofstream OutputFile(file_name.c_str(), std::ios::out | std::ios::binary);
359 if (!OutputFile.is_open())
361 MC_WARNING(
"Unable to create file to save binary data: %s", file_name.c_str());
364 OutputFile.write(reinterpret_cast<const char*>(&
Data[0]),
Data.size());
366 return OutputFile.good();
383 MC_WARNING(
"Can't encode unsigned char number since no space left.");
395 MC_WARNING(
"Can't encode int16_t number since no space left.");
398 uint16_t TempInt = *
reinterpret_cast<uint16_t*
>(&new_int);
416 MC_WARNING(
"Can't encode int32_t number since no space left.");
419 uint32_t TempInt = *
reinterpret_cast<uint32_t*
>(&new_int);
441 MC_WARNING(
"Can't encode string since no space left.");
445 Position += str.size();
453 MC_WARNING(
"Can't decode unsigned char since no space left.");
467 MC_WARNING(
"Can't decode int16_t number since no space left.");
479 return *
reinterpret_cast<int16_t*
>(&Ret);
487 MC_WARNING(
"Can't decode int32_t number since no space left.");
499 return *
reinterpret_cast<int32_t*
>(&Ret);
514 for (
unsigned int i1 = 0; i1 < additional_chars.size(); ++i1)
516 if (
Data[i] == additional_chars[i1])
524 if (!(
Data[i] >=
'a' &&
Data[i] <=
'z') && !(
Data[i] >=
'A' &&
Data[i] <=
'Z') &&
540 std::string Result(length, 0);
550 return (
unsigned char*)&
Data[0];
608 uint Result = base64_encode(BinaryData->GetData(), &
Data[0],
Size);
610 return std::string((
char*)BinaryData->GetData(), (int)Result);
616 if (base64_str.empty())
619 MC::BinaryDataSPtr BinaryData(
new MCBinaryData(base64_str.size()));
620 uint Result = base64_str.size();
622 base64_decode(BinaryData->GetData(), base64_str.c_str(), &Result);
623 Set(BinaryData->GetData(), (int)Result);
639 Data = std::move(other.Data);
662 for (
int i = 0; i < Size && Ret; ++i)
664 Ret = Ret && (
Data[i] == other.
Data[i]);
672 return !(*
this == other);
676 template<
class Archive>
677 void MCBinaryData::serialize(Archive& archive,
const unsigned int version)
690 template void MCBinaryData::serialize<boost::archive::binary_iarchive>(boost::archive::binary_iarchive&,
692 template void MCBinaryData::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive&,
694 template void MCBinaryData::serialize<eos::portable_iarchive>(eos::portable_iarchive&,
const unsigned int);
695 template void MCBinaryData::serialize<eos::portable_oarchive>(eos::portable_oarchive&,
const unsigned int);
int16_t GetInt16(bool reverse_order=false)
Get a 16 bit integer from the current position.
bool ValidateString(unsigned int length, const std::string &additional_chars="")
Check if a string can be read from the current position.
std::vector< unsigned char > Data
Pointer to the encapsulated data.
bool IsEmpty() const
Check if the binary data is not filled with invalid data.
bool operator!=(const MCBinaryData &other) const
Inequality (!=) operator.
void AddInt16(int16_t new_int, bool reverse_order=false)
Add a 16 bit integer at the current position.
std::string ToBase64() const
Convert the content to base64.
const T MCMin(const U &container)
Get the minimal value of a container.
MCBinaryData GenerateMd5Hash() const
Generate md5 hash.
MCBinaryData & operator=(MCBinaryData &&other)
Move assignment operator.
void AddString(const std::string &str)
Add a string at the current position.
bool SaveToFile(const std::string &file_name) const
Save data to a file.
MCBinaryData()
Class constructor.
unsigned char GetUChar()
Get an unsigned char from the current position.
bool LoadFromQtResource(const QString &resource_str)
Load data from a Qt resource.
void ResetPosition()
Reset the cursor position back to the start position.
#define MC_WARNING(...)
Warning macro.
std::string GetString(unsigned int length, const std::string &additional_chars="")
Get a string from the current position.
void FromBase64(const std::string &base64_str)
Convert back from base64.
void Allocate(int size)
Allocate a certain data size.
void AddInt32(int32_t new_int, bool reverse_order=false)
Add a 32 bit integer at the current position.
unsigned int GetRemainingCapacity(unsigned int capacity) const
Check if the binary data has enough remaining capacity.
bool WriteData(MCBinaryData &target, int capacity=-1)
Write data into a target instance.
void SetPosition(unsigned int position)
Set the cursor position.
int Size
Size of the data.
unsigned int CopyData(MCBinaryData &target, int capacity=-1) const
Copy data into a target instance.
#define MC_UNUSED(a)
Helper macro to avoid compiler warning about unused function parameters.
void Free()
Free the allocated data.
void IncrementPosition(unsigned int position=1)
Increment the cursor position.
void Shrink(int size)
Shrink to a certain data size.
void Set(unsigned char *data, int size)
Set binary data content.
void AddUChar(unsigned char new_char)
Add an unsigned char at the current position.
unsigned char * GetData() const
Get direct access to the binary data.
int32_t GetInt32(bool reverse_order=false)
Get a 32 bit integer from the current position.
bool LoadFromFile(const std::string &file_name)
Load data from a file.
MCBinaryData * Clone()
Clone the binary data.
bool operator==(const MCBinaryData &other) const
Equality (==) operator.
void Clear()
Clear the allocated data.
const std::vector< unsigned char > & GetVectorData() const
Get binary data in vector form.
int GetPosition() const
Get the current position in the binary data.
bool IsPositionAtEnd() const
Check if the current position is at the end of the binary data.
int Position
Internal position index.
int GetSize() const
Get binary data size.