35 #ifndef OPENMS_FORMAT_BASE64_H
36 #define OPENMS_FORMAT_BASE64_H
38 #ifndef OPENMS_IS_BIG_ENDIAN
39 #if defined OPENMS_BIG_ENDIAN
40 #define OPENMS_IS_BIG_ENDIAN true
42 #define OPENMS_IS_BIG_ENDIAN false
79 BYTEORDER_LITTLEENDIAN
89 template <
typename FromType>
90 void encode(std::vector<FromType> & in, ByteOrder to_byte_order,
String & out,
bool zlib_compression =
false);
99 template <
typename ToType>
100 void decode(
const String & in, ByteOrder from_byte_order, std::vector<ToType> & out,
bool zlib_compression =
false);
109 template <
typename FromType>
110 void encodeIntegers(std::vector<FromType> & in, ByteOrder to_byte_order,
String & out,
bool zlib_compression =
false);
119 template <
typename ToType>
120 void decodeIntegers(
const String & in, ByteOrder from_byte_order, std::vector<ToType> & out,
bool zlib_compression =
false);
129 void encodeStrings(std::vector<String> & in,
String & out,
bool zlib_compression =
false);
138 void decodeStrings(
const String & in, std::vector<String> & out,
bool zlib_compression =
false);
156 static const char encoder_[];
157 static const char decoder_[];
159 template <
typename ToType>
160 void decodeUncompressed_(
const String & in,
ByteOrder from_byte_order, std::vector<ToType> & out);
163 template <
typename ToType>
164 void decodeCompressed_(
const String & in,
ByteOrder from_byte_order, std::vector<ToType> & out);
167 template <
typename ToType>
168 void decodeIntegersUncompressed_(
const String & in,
ByteOrder from_byte_order, std::vector<ToType> & out);
171 template <
typename ToType>
172 void decodeIntegersCompressed_(
const String & in,
ByteOrder from_byte_order, std::vector<ToType> & out);
178 return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24);
184 return ((n & 0x00000000000000ffll) << 56) |
185 ((n & 0x000000000000ff00ll) << 40) |
186 ((n & 0x0000000000ff0000ll) << 24) |
187 ((n & 0x00000000ff000000ll) << 8) |
188 ((n & 0x000000ff00000000ll) >> 8) |
189 ((n & 0x0000ff0000000000ll) >> 24) |
190 ((n & 0x00ff000000000000ll) >> 40) |
191 ((n & 0xff00000000000000ll) >> 56);
194 template <
typename FromType>
202 const Size element_size =
sizeof(FromType);
203 const Size input_bytes = element_size * in.size();
210 if (element_size == 4)
212 for (
Size i = 0; i < in.size(); ++i)
222 for (
Size i = 0; i < in.size(); ++i)
233 if (zlib_compression)
235 unsigned long sourceLen = (
unsigned long)in.size();
236 unsigned long compressed_length =
237 sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
245 compressed.resize(compressed_length);
246 zlib_error = compress(reinterpret_cast<Bytef *>(&compressed[0]), &compressed_length, reinterpret_cast<Bytef *>(&in[0]), (
unsigned long)input_bytes);
255 compressed_length *= 2;
258 while (zlib_error == Z_BUF_ERROR);
260 if (zlib_error != Z_OK)
265 String(compressed).swap(compressed);
266 it =
reinterpret_cast<Byte *
>(&compressed[0]);
267 end = it + compressed_length;
268 out.resize((
Size)ceil(compressed_length / 3.) * 4);
273 out.resize((
Size)ceil(input_bytes / 3.) * 4);
274 it =
reinterpret_cast<Byte *
>(&in[0]);
275 end = it + input_bytes;
278 Byte * to =
reinterpret_cast<Byte *
>(&out[0]);
286 Int padding_count = 0;
289 for (
Size i = 0; i < 3; i++)
293 int_24bit |= *it++ << ((2 - i) * 8);
302 for (
Int i = 3; i >= 0; i--)
309 if (padding_count > 0)
311 if (padding_count > 1)
321 template <
typename ToType>
324 if (zlib_compression)
334 template <
typename ToType>
343 std::vector<unsigned char> binary;
344 const Size element_size =
sizeof(ToType);
348 QByteArray qt_byte_array = QByteArray::fromRawData(in.c_str(), (int) in.size());
349 QByteArray bazip = QByteArray::fromBase64(qt_byte_array);
352 czip[0] = (bazip.size() & 0xff000000) >> 24;
353 czip[1] = (bazip.size() & 0x00ff0000) >> 16;
354 czip[2] = (bazip.size() & 0x0000ff00) >> 8;
355 czip[3] = (bazip.size() & 0x000000ff);
357 QByteArray base64_uncompressed = qUncompress(czip);
359 if (base64_uncompressed.isEmpty())
363 decompressed.resize(base64_uncompressed.size());
365 std::copy(base64_uncompressed.begin(), base64_uncompressed.end(), decompressed.begin());
367 byte_buffer =
reinterpret_cast<void *
>(&decompressed[0]);
368 buffer_size = decompressed.size();
373 if (element_size == 4)
375 const Real * float_buffer =
reinterpret_cast<const Real *
>(byte_buffer);
376 if (buffer_size % element_size != 0)
378 Size float_count = buffer_size / element_size;
379 Int32 * p =
reinterpret_cast<Int32 *
>(byte_buffer);
380 std::transform(p, p + float_count, p,
endianize32);
381 out.assign(float_buffer, float_buffer + float_count);
387 if (buffer_size % element_size != 0)
390 Size float_count = buffer_size / element_size;
392 Int64 * p =
reinterpret_cast<Int64 *
>(byte_buffer);
393 std::transform(p, p + float_count, p,
endianize64);
395 out.resize(float_count);
397 for (
Size i = 0; i < float_count; ++i)
399 out[i] = (ToType) * float_buffer;
406 if (element_size == 4)
408 const Real * float_buffer =
reinterpret_cast<const Real *
>(byte_buffer);
409 if (buffer_size % element_size != 0)
412 Size float_count = buffer_size / element_size;
413 out.assign(float_buffer, float_buffer + float_count);
419 if (buffer_size % element_size != 0)
422 Size float_count = buffer_size / element_size;
423 out.resize(float_count);
425 for (
Size i = 0; i < float_count; ++i)
427 out[i] = (ToType) * float_buffer;
435 template <
typename ToType>
442 Size src_size = in.size();
445 if (in[src_size - 1] ==
'=')
447 if (in[src_size - 2] ==
'=')
459 const Size element_size =
sizeof(ToType);
462 char element[8] =
"\x00\x00\x00\x00\x00\x00\x00";
466 offset = (element_size - 1);
476 out.reserve((
UInt)(std::ceil((4.0 * src_size) / 3.0) + 6.0));
480 for (
Size i = 0; i < src_size; i += 4)
484 b =
decoder_[(int)in[i + 1] - 43] - 62;
485 if (i + 1 >= src_size)
487 element[offset] = (
unsigned char) ((a << 2) | (b >> 4));
489 offset = (offset + inc) % element_size;
491 if (written % element_size == 0)
493 ToType * to_type =
reinterpret_cast<ToType *
>(&element[0]);
494 out.push_back((*to_type));
498 a =
decoder_[(int)in[i + 2] - 43] - 62;
499 if (i + 2 >= src_size)
501 element[offset] = (
unsigned char) (((b & 15) << 4) | (a >> 2));
503 offset = (offset + inc) % element_size;
505 if (written % element_size == 0)
507 ToType * to_type =
reinterpret_cast<ToType *
>(&element[0]);
508 out.push_back((*to_type));
512 b =
decoder_[(int)in[i + 3] - 43] - 62;
513 if (i + 3 >= src_size)
515 element[offset] = (
unsigned char) (((a & 3) << 6) | b);
517 offset = (offset + inc) % element_size;
519 if (written % element_size == 0)
521 ToType * to_type =
reinterpret_cast<ToType *
>(&element[0]);
522 out.push_back((*to_type));
528 template <
typename FromType>
536 const Size element_size =
sizeof(FromType);
537 const Size input_bytes = element_size * in.size();
544 if (element_size == 4)
546 for (
Size i = 0; i < in.size(); ++i)
555 for (
Size i = 0; i < in.size(); ++i)
565 if (zlib_compression)
567 unsigned long sourceLen = (
unsigned long)input_bytes;
568 unsigned long compressed_length =
569 sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
571 compressed.resize(compressed_length);
572 while (compress(reinterpret_cast<Bytef *>(&compressed[0]), &compressed_length, reinterpret_cast<Bytef *>(&in[0]), (
unsigned long)input_bytes) != Z_OK)
574 compressed_length *= 2;
575 compressed.reserve(compressed_length);
579 String(compressed).swap(compressed);
580 it =
reinterpret_cast<Byte *
>(&compressed[0]);
581 end = it + compressed_length;
582 out.resize((
Size)ceil(compressed_length / 3.) * 4);
587 out.resize((
Size)ceil(input_bytes / 3.) * 4);
588 it =
reinterpret_cast<Byte *
>(&in[0]);
589 end = it + input_bytes;
592 Byte * to =
reinterpret_cast<Byte *
>(&out[0]);
600 Int padding_count = 0;
603 for (
Size i = 0; i < 3; i++)
607 int_24bit |= *it++ << ((2 - i) * 8);
616 for (
Int i = 3; i >= 0; i--)
623 if (padding_count > 0)
625 if (padding_count > 1)
635 template <
typename ToType>
638 if (zlib_compression)
648 template <
typename ToType>
657 std::vector<unsigned char> binary;
658 const Size element_size =
sizeof(ToType);
662 QByteArray qt_byte_array = QByteArray::fromRawData(in.c_str(), (int) in.size());
663 QByteArray bazip = QByteArray::fromBase64(qt_byte_array);
666 czip[0] = (bazip.size() & 0xff000000) >> 24;
667 czip[1] = (bazip.size() & 0x00ff0000) >> 16;
668 czip[2] = (bazip.size() | 0x00000800) >> 8;
669 czip[3] = (bazip.size() & 0x000000ff);
671 QByteArray base64_uncompressed = qUncompress(czip);
672 if (base64_uncompressed.isEmpty())
676 decompressed.resize(base64_uncompressed.size());
678 std::copy(base64_uncompressed.begin(), base64_uncompressed.end(), decompressed.begin());
680 byte_buffer =
reinterpret_cast<void *
>(&decompressed[0]);
681 buffer_size = decompressed.size();
686 if (element_size == 4)
688 const Int32 * float_buffer =
reinterpret_cast<const Int32 *
>(byte_buffer);
689 if (buffer_size % element_size != 0)
691 Size float_count = buffer_size / element_size;
692 Int32 * p =
reinterpret_cast<Int32 *
>(byte_buffer);
693 std::transform(p, p + float_count, p,
endianize32);
695 out.resize(float_count);
697 for (
Size i = 0; i < float_count; ++i)
699 out[i] = (ToType) * float_buffer;
705 const Int64 * float_buffer =
reinterpret_cast<const Int64 *
>(byte_buffer);
707 if (buffer_size % element_size != 0)
710 Size float_count = buffer_size / element_size;
712 Int64 * p =
reinterpret_cast<Int64 *
>(byte_buffer);
713 std::transform(p, p + float_count, p,
endianize64);
715 out.resize(float_count);
717 for (
Size i = 0; i < float_count; ++i)
719 out[i] = (ToType) * float_buffer;
726 if (element_size == 4)
728 const Int * float_buffer =
reinterpret_cast<const Int *
>(byte_buffer);
729 if (buffer_size % element_size != 0)
732 Size float_count = buffer_size / element_size;
733 out.resize(float_count);
735 for (
Size i = 0; i < float_count; ++i)
737 out[i] = (ToType) * float_buffer;
743 const Int64 * float_buffer =
reinterpret_cast<const Int64 *
>(byte_buffer);
745 if (buffer_size % element_size != 0)
748 Size float_count = buffer_size / element_size;
749 out.resize(float_count);
751 for (
Size i = 0; i < float_count; ++i)
753 out[i] = (ToType) * float_buffer;
761 template <
typename ToType>
768 Size src_size = in.size();
771 if (in[src_size - 1] ==
'=')
773 if (in[src_size - 2] ==
'=')
785 const Size element_size =
sizeof(ToType);
788 char element[8] =
"\x00\x00\x00\x00\x00\x00\x00";
792 offset = (element_size - 1);
802 out.reserve((
UInt)(std::ceil((4.0 * src_size) / 3.0) + 6.0));
806 for (
Size i = 0; i < src_size; i += 4)
812 b =
decoder_[(int)in[i + 1] - 43] - 62;
813 if (i + 1 >= src_size)
815 element[offset] = (
unsigned char) ((a << 2) | (b >> 4));
818 offset = (offset + inc) % element_size;
820 if (written % element_size == 0)
823 if (element_size == 4)
825 Int32 * value =
reinterpret_cast<Int32 *
>(&element[0]);
826 float_value = (ToType) * value;
830 Int64 * value =
reinterpret_cast<Int64 *
>(&element[0]);
831 float_value = (ToType) * value;
833 out.push_back(float_value);
837 a =
decoder_[(int)in[i + 2] - 43] - 62;
838 if (i + 2 >= src_size)
840 element[offset] = (
unsigned char) (((b & 15) << 4) | (a >> 2));
842 offset = (offset + inc) % element_size;
844 if (written % element_size == 0)
847 if (element_size == 4)
849 Int32 * value =
reinterpret_cast<Int32 *
>(&element[0]);
850 float_value = (ToType) * value;
854 Int64 * value =
reinterpret_cast<Int64 *
>(&element[0]);
855 float_value = (ToType) * value;
857 out.push_back(float_value);
861 b =
decoder_[(int)in[i + 3] - 43] - 62;
862 if (i + 3 >= src_size)
864 element[offset] = (
unsigned char) (((a & 3) << 6) | b);
866 offset = (offset + inc) % element_size;
868 if (written % element_size == 0)
871 if (element_size == 4)
873 Int32 * value =
reinterpret_cast<Int32 *
>(&element[0]);
874 float_value = (ToType) * value;
878 Int64 * value =
reinterpret_cast<Int64 *
>(&element[0]);
879 float_value = (ToType) * value;
881 out.push_back(float_value);
Big endian type.
Definition: Base64.h:78
float Real
Real type.
Definition: Types.h:109
A more convenient string class.
Definition: String.h:56
Class to encode and decode Base64.
Definition: Base64.h:64
Little endian type.
Definition: Base64.h:79
void decodeIntegersUncompressed_(const String &in, ByteOrder from_byte_order, std::vector< ToType > &out)
Decodes a Base64 string to a vector of integer numbers.
Definition: Base64.h:762
Real f
Definition: Base64.h:152
void encodeIntegers(std::vector< FromType > &in, ByteOrder to_byte_order, String &out, bool zlib_compression=false)
Encodes a vector of integer point numbers to a Base64 string.
Definition: Base64.h:529
ByteOrder
Byte order type.
Definition: Base64.h:76
Internal class needed for type-punning.
Definition: Base64.h:150
void decodeIntegers(const String &in, ByteOrder from_byte_order, std::vector< ToType > &out, bool zlib_compression=false)
Decodes a Base64 string to a vector of integer numbers.
Definition: Base64.h:636
OPENMS_INT32_TYPE Int32
Signed integer type (32bit)
Definition: Types.h:61
DoubleReal f
Definition: Base64.h:145
void decodeIntegersCompressed_(const String &in, ByteOrder from_byte_order, std::vector< ToType > &out)
Decodes a compressed Base64 string to a vector of integer numbers.
Definition: Base64.h:649
Int64 i
Definition: Base64.h:146
Invalid conversion exception.
Definition: Exception.h:363
Int32 i
Definition: Base64.h:153
Out of memory exception.
Definition: Exception.h:472
void decodeUncompressed_(const String &in, ByteOrder from_byte_order, std::vector< ToType > &out)
Decodes a Base64 string to a vector of floating point numbers.
Definition: Base64.h:436
#define OPENMS_IS_BIG_ENDIAN
Definition: Base64.h:42
static const char decoder_[]
Definition: Base64.h:157
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:144
static const char encoder_[]
Definition: Base64.h:156
OPENMS_INT64_TYPE Int64
Signed integer type (64bit)
Definition: Types.h:68
OPENMS_BYTE_TYPE Byte
Byte type.
Definition: Types.h:128
void encode(std::vector< FromType > &in, ByteOrder to_byte_order, String &out, bool zlib_compression=false)
Encodes a vector of floating point numbers to a Base64 string.
Definition: Base64.h:195
Int64 endianize64(Int64 &n)
Endianizes a 64 bit type from big endian to little endian and vice versa.
Definition: Base64.h:182
Internal class needed for type-punning.
Definition: Base64.h:143
Int32 endianize32(Int32 &n)
Endianizes a 32 bit type from big endian to little endian and vice versa.
Definition: Base64.h:176
int Int
Signed integer type.
Definition: Types.h:100
void decode(const String &in, ByteOrder from_byte_order, std::vector< ToType > &out, bool zlib_compression=false)
Decodes a Base64 string to a vector of floating point numbers.
Definition: Base64.h:322
void decodeCompressed_(const String &in, ByteOrder from_byte_order, std::vector< ToType > &out)
Decodes a compressed Base64 string to a vector of floating point numbers.
Definition: Base64.h:335