00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_FORMAT_BASE64_H
00036 #define OPENMS_FORMAT_BASE64_H
00037
00038 #ifndef OPENMS_IS_BIG_ENDIAN
00039 #if defined OPENMS_BIG_ENDIAN
00040 #define OPENMS_IS_BIG_ENDIAN true
00041 #else
00042 #define OPENMS_IS_BIG_ENDIAN false
00043 #endif
00044 #endif
00045
00046 #include <OpenMS/CONCEPT/Types.h>
00047 #include <OpenMS/CONCEPT/Exception.h>
00048 #include <OpenMS/DATASTRUCTURES/String.h>
00049 #include <algorithm>
00050 #include <iterator>
00051 #include <cmath>
00052 #include <vector>
00053
00054 #include <QByteArray>
00055 #include <zlib.h>
00056
00057 namespace OpenMS
00058 {
00064 class OPENMS_DLLAPI Base64
00065 {
00066
00067 public:
00068
00070 Base64();
00071
00073 virtual ~Base64();
00074
00076 enum ByteOrder
00077 {
00078 BYTEORDER_BIGENDIAN,
00079 BYTEORDER_LITTLEENDIAN
00080 };
00081
00089 template <typename FromType>
00090 void encode(std::vector<FromType> & in, ByteOrder to_byte_order, String & out, bool zlib_compression = false);
00091
00099 template <typename ToType>
00100 void decode(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out, bool zlib_compression = false);
00101
00109 template <typename FromType>
00110 void encodeIntegers(std::vector<FromType> & in, ByteOrder to_byte_order, String & out, bool zlib_compression = false);
00111
00119 template <typename ToType>
00120 void decodeIntegers(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out, bool zlib_compression = false);
00121
00129 void encodeStrings(std::vector<String> & in, String & out, bool zlib_compression = false);
00130
00138 void decodeStrings(const String & in, std::vector<String> & out, bool zlib_compression = false);
00139
00140 private:
00141
00143 union Reinterpreter64_
00144 {
00145 DoubleReal f;
00146 Int64 i;
00147 };
00148
00150 union Reinterpreter32_
00151 {
00152 Real f;
00153 Int32 i;
00154 };
00155
00156 static const char encoder_[];
00157 static const char decoder_[];
00159 template <typename ToType>
00160 void decodeUncompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out);
00161
00163 template <typename ToType>
00164 void decodeCompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out);
00165
00167 template <typename ToType>
00168 void decodeIntegersUncompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out);
00169
00171 template <typename ToType>
00172 void decodeIntegersCompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out);
00173 };
00174
00176 inline Int32 endianize32(Int32 & n)
00177 {
00178 return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24);
00179 }
00180
00182 inline Int64 endianize64(Int64 & n)
00183 {
00184 return ((n & 0x00000000000000ffll) << 56) |
00185 ((n & 0x000000000000ff00ll) << 40) |
00186 ((n & 0x0000000000ff0000ll) << 24) |
00187 ((n & 0x00000000ff000000ll) << 8) |
00188 ((n & 0x000000ff00000000ll) >> 8) |
00189 ((n & 0x0000ff0000000000ll) >> 24) |
00190 ((n & 0x00ff000000000000ll) >> 40) |
00191 ((n & 0xff00000000000000ll) >> 56);
00192 }
00193
00194 template <typename FromType>
00195 void Base64::encode(std::vector<FromType> & in, ByteOrder to_byte_order, String & out, bool zlib_compression)
00196 {
00197 out.clear();
00198 if (in.empty())
00199 return;
00200
00201
00202 const Size element_size = sizeof(FromType);
00203 const Size input_bytes = element_size * in.size();
00204 String compressed;
00205 Byte * it;
00206 Byte * end;
00207
00208 if ((OPENMS_IS_BIG_ENDIAN && to_byte_order == Base64::BYTEORDER_LITTLEENDIAN) || (!OPENMS_IS_BIG_ENDIAN && to_byte_order == Base64::BYTEORDER_BIGENDIAN))
00209 {
00210 if (element_size == 4)
00211 {
00212 for (Size i = 0; i < in.size(); ++i)
00213 {
00214 Reinterpreter32_ tmp;
00215 tmp.f = in[i];
00216 tmp.i = endianize32(tmp.i);
00217 in[i] = tmp.f;
00218 }
00219 }
00220 else
00221 {
00222 for (Size i = 0; i < in.size(); ++i)
00223 {
00224 Reinterpreter64_ tmp;
00225 tmp.f = in[i];
00226 tmp.i = endianize64(tmp.i);
00227 in[i] = tmp.f;
00228 }
00229 }
00230 }
00231
00232
00233 if (zlib_compression)
00234 {
00235 unsigned long sourceLen = (unsigned long)in.size();
00236 unsigned long compressed_length =
00237 sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
00238
00239
00240
00241
00242 int zlib_error;
00243 do
00244 {
00245 compressed.resize(compressed_length);
00246 zlib_error = compress(reinterpret_cast<Bytef *>(&compressed[0]), &compressed_length, reinterpret_cast<Bytef *>(&in[0]), (unsigned long)input_bytes);
00247
00248 switch (zlib_error)
00249 {
00250 case Z_MEM_ERROR:
00251 throw Exception::OutOfMemory(__FILE__, __LINE__, __PRETTY_FUNCTION__, compressed_length);
00252 break;
00253
00254 case Z_BUF_ERROR:
00255 compressed_length *= 2;
00256 }
00257 }
00258 while (zlib_error == Z_BUF_ERROR);
00259
00260 if (zlib_error != Z_OK)
00261 {
00262 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Compression error?");
00263 }
00264
00265 String(compressed).swap(compressed);
00266 it = reinterpret_cast<Byte *>(&compressed[0]);
00267 end = it + compressed_length;
00268 out.resize((Size)ceil(compressed_length / 3.) * 4);
00269 }
00270
00271 else
00272 {
00273 out.resize((Size)ceil(input_bytes / 3.) * 4);
00274 it = reinterpret_cast<Byte *>(&in[0]);
00275 end = it + input_bytes;
00276 }
00277
00278 Byte * to = reinterpret_cast<Byte *>(&out[0]);
00279
00280
00281 Size written = 0;
00282
00283 while (it != end)
00284 {
00285 Int int_24bit = 0;
00286 Int padding_count = 0;
00287
00288
00289 for (Size i = 0; i < 3; i++)
00290 {
00291 if (it != end)
00292 {
00293 int_24bit |= *it++ << ((2 - i) * 8);
00294 }
00295 else
00296 {
00297 padding_count++;
00298 }
00299 }
00300
00301
00302 for (Int i = 3; i >= 0; i--)
00303 {
00304 to[i] = encoder_[int_24bit & 0x3F];
00305 int_24bit >>= 6;
00306 }
00307
00308
00309 if (padding_count > 0)
00310 to[3] = '=';
00311 if (padding_count > 1)
00312 to[2] = '=';
00313
00314 to += 4;
00315 written += 4;
00316 }
00317
00318 out.resize(written);
00319 }
00320
00321 template <typename ToType>
00322 void Base64::decode(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out, bool zlib_compression)
00323 {
00324 if (zlib_compression)
00325 {
00326 decodeCompressed_(in, from_byte_order, out);
00327 }
00328 else
00329 {
00330 decodeUncompressed_(in, from_byte_order, out);
00331 }
00332 }
00333
00334 template <typename ToType>
00335 void Base64::decodeCompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out)
00336 {
00337 out.clear();
00338 if (in == "")
00339 return;
00340
00341 void * byte_buffer;
00342 Size buffer_size;
00343 std::vector<unsigned char> binary;
00344 const Size element_size = sizeof(ToType);
00345
00346 String decompressed;
00347
00348 QByteArray qt_byte_array = QByteArray::fromRawData(in.c_str(), (int) in.size());
00349 QByteArray bazip = QByteArray::fromBase64(qt_byte_array);
00350 QByteArray czip;
00351 czip.resize(4);
00352 czip[0] = (bazip.size() & 0xff000000) >> 24;
00353 czip[1] = (bazip.size() & 0x00ff0000) >> 16;
00354 czip[2] = (bazip.size() & 0x0000ff00) >> 8;
00355 czip[3] = (bazip.size() & 0x000000ff);
00356 czip += bazip;
00357 QByteArray base64_uncompressed = qUncompress(czip);
00358
00359 if (base64_uncompressed.isEmpty())
00360 {
00361 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Decompression error?");
00362 }
00363 decompressed.resize(base64_uncompressed.size());
00364
00365 std::copy(base64_uncompressed.begin(), base64_uncompressed.end(), decompressed.begin());
00366
00367 byte_buffer = reinterpret_cast<void *>(&decompressed[0]);
00368 buffer_size = decompressed.size();
00369
00370
00371 if ((OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_LITTLEENDIAN) || (!OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_BIGENDIAN))
00372 {
00373 if (element_size == 4)
00374 {
00375 const Real * float_buffer = reinterpret_cast<const Real *>(byte_buffer);
00376 if (buffer_size % element_size != 0)
00377 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount?");
00378 Size float_count = buffer_size / element_size;
00379 Int32 * p = reinterpret_cast<Int32 *>(byte_buffer);
00380 std::transform(p, p + float_count, p, endianize32);
00381 out.assign(float_buffer, float_buffer + float_count);
00382 }
00383 else
00384 {
00385 const DoubleReal * float_buffer = reinterpret_cast<const DoubleReal *>(byte_buffer);
00386
00387 if (buffer_size % element_size != 0)
00388 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount?");
00389
00390 Size float_count = buffer_size / element_size;
00391
00392 Int64 * p = reinterpret_cast<Int64 *>(byte_buffer);
00393 std::transform(p, p + float_count, p, endianize64);
00394
00395 out.resize(float_count);
00396
00397 for (Size i = 0; i < float_count; ++i)
00398 {
00399 out[i] = (ToType) * float_buffer;
00400 ++float_buffer;
00401 }
00402 }
00403 }
00404 else
00405 {
00406 if (element_size == 4)
00407 {
00408 const Real * float_buffer = reinterpret_cast<const Real *>(byte_buffer);
00409 if (buffer_size % element_size != 0)
00410 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount while decoding?");
00411
00412 Size float_count = buffer_size / element_size;
00413 out.assign(float_buffer, float_buffer + float_count);
00414 }
00415 else
00416 {
00417 const DoubleReal * float_buffer = reinterpret_cast<const DoubleReal *>(byte_buffer);
00418
00419 if (buffer_size % element_size != 0)
00420 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount while decoding?");
00421
00422 Size float_count = buffer_size / element_size;
00423 out.resize(float_count);
00424
00425 for (Size i = 0; i < float_count; ++i)
00426 {
00427 out[i] = (ToType) * float_buffer;
00428 ++float_buffer;
00429 }
00430 }
00431 }
00432
00433 }
00434
00435 template <typename ToType>
00436 void Base64::decodeUncompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out)
00437 {
00438 out.clear();
00439 if (in == "")
00440 return;
00441
00442 Size src_size = in.size();
00443
00444 int padding = 0;
00445 if (in[src_size - 1] == '=')
00446 padding++;
00447 if (in[src_size - 2] == '=')
00448 padding++;
00449
00450 src_size -= padding;
00451
00452 register UInt a;
00453 register UInt b;
00454
00455 UInt offset = 0;
00456 int inc = 1;
00457 UInt written = 0;
00458
00459 const Size element_size = sizeof(ToType);
00460
00461
00462 char element[8] = "\x00\x00\x00\x00\x00\x00\x00";
00463
00464 if ((OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_LITTLEENDIAN) || (!OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_BIGENDIAN))
00465 {
00466 offset = (element_size - 1);
00467 inc = -1;
00468 }
00469 else
00470 {
00471 offset = 0;
00472 inc = 1;
00473 }
00474
00475
00476 out.reserve((UInt)(std::ceil((4.0 * src_size) / 3.0) + 6.0));
00477
00478
00479
00480 for (Size i = 0; i < src_size; i += 4)
00481 {
00482
00483 a = decoder_[(int)in[i] - 43] - 62;
00484 b = decoder_[(int)in[i + 1] - 43] - 62;
00485 if (i + 1 >= src_size)
00486 b = 0;
00487 element[offset] = (unsigned char) ((a << 2) | (b >> 4));
00488 written++;
00489 offset = (offset + inc) % element_size;
00490
00491 if (written % element_size == 0)
00492 {
00493 ToType * to_type = reinterpret_cast<ToType *>(&element[0]);
00494 out.push_back((*to_type));
00495 strcpy(element, "");
00496 }
00497
00498 a = decoder_[(int)in[i + 2] - 43] - 62;
00499 if (i + 2 >= src_size)
00500 a = 0;
00501 element[offset] = (unsigned char) (((b & 15) << 4) | (a >> 2));
00502 written++;
00503 offset = (offset + inc) % element_size;
00504
00505 if (written % element_size == 0)
00506 {
00507 ToType * to_type = reinterpret_cast<ToType *>(&element[0]);
00508 out.push_back((*to_type));
00509 strcpy(element, "");
00510 }
00511
00512 b = decoder_[(int)in[i + 3] - 43] - 62;
00513 if (i + 3 >= src_size)
00514 b = 0;
00515 element[offset] = (unsigned char) (((a & 3) << 6) | b);
00516 written++;
00517 offset = (offset + inc) % element_size;
00518
00519 if (written % element_size == 0)
00520 {
00521 ToType * to_type = reinterpret_cast<ToType *>(&element[0]);
00522 out.push_back((*to_type));
00523 strcpy(element, "");
00524 }
00525 }
00526 }
00527
00528 template <typename FromType>
00529 void Base64::encodeIntegers(std::vector<FromType> & in, ByteOrder to_byte_order, String & out, bool zlib_compression)
00530 {
00531 out.clear();
00532 if (in.empty())
00533 return;
00534
00535
00536 const Size element_size = sizeof(FromType);
00537 const Size input_bytes = element_size * in.size();
00538 String compressed;
00539 Byte * it;
00540 Byte * end;
00541
00542 if ((OPENMS_IS_BIG_ENDIAN && to_byte_order == Base64::BYTEORDER_LITTLEENDIAN) || (!OPENMS_IS_BIG_ENDIAN && to_byte_order == Base64::BYTEORDER_BIGENDIAN))
00543 {
00544 if (element_size == 4)
00545 {
00546 for (Size i = 0; i < in.size(); ++i)
00547 {
00548 Int32 tmp = in[i];
00549 tmp = endianize32(tmp);
00550 in[i] = tmp;
00551 }
00552 }
00553 else
00554 {
00555 for (Size i = 0; i < in.size(); ++i)
00556 {
00557 Int64 tmp = in[i];
00558 tmp = endianize64(tmp);
00559 in[i] = tmp;
00560 }
00561 }
00562 }
00563
00564
00565 if (zlib_compression)
00566 {
00567 unsigned long sourceLen = (unsigned long)input_bytes;
00568 unsigned long compressed_length =
00569 sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
00570
00571 compressed.resize(compressed_length);
00572 while (compress(reinterpret_cast<Bytef *>(&compressed[0]), &compressed_length, reinterpret_cast<Bytef *>(&in[0]), (unsigned long)input_bytes) != Z_OK)
00573 {
00574 compressed_length *= 2;
00575 compressed.reserve(compressed_length);
00576 }
00577
00578
00579 String(compressed).swap(compressed);
00580 it = reinterpret_cast<Byte *>(&compressed[0]);
00581 end = it + compressed_length;
00582 out.resize((Size)ceil(compressed_length / 3.) * 4);
00583 }
00584
00585 else
00586 {
00587 out.resize((Size)ceil(input_bytes / 3.) * 4);
00588 it = reinterpret_cast<Byte *>(&in[0]);
00589 end = it + input_bytes;
00590 }
00591
00592 Byte * to = reinterpret_cast<Byte *>(&out[0]);
00593
00594
00595 Size written = 0;
00596
00597 while (it != end)
00598 {
00599 Int int_24bit = 0;
00600 Int padding_count = 0;
00601
00602
00603 for (Size i = 0; i < 3; i++)
00604 {
00605 if (it != end)
00606 {
00607 int_24bit |= *it++ << ((2 - i) * 8);
00608 }
00609 else
00610 {
00611 padding_count++;
00612 }
00613 }
00614
00615
00616 for (Int i = 3; i >= 0; i--)
00617 {
00618 to[i] = encoder_[int_24bit & 0x3F];
00619 int_24bit >>= 6;
00620 }
00621
00622
00623 if (padding_count > 0)
00624 to[3] = '=';
00625 if (padding_count > 1)
00626 to[2] = '=';
00627
00628 to += 4;
00629 written += 4;
00630 }
00631
00632 out.resize(written);
00633 }
00634
00635 template <typename ToType>
00636 void Base64::decodeIntegers(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out, bool zlib_compression)
00637 {
00638 if (zlib_compression)
00639 {
00640 decodeIntegersCompressed_(in, from_byte_order, out);
00641 }
00642 else
00643 {
00644 decodeIntegersUncompressed_(in, from_byte_order, out);
00645 }
00646 }
00647
00648 template <typename ToType>
00649 void Base64::decodeIntegersCompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out)
00650 {
00651 out.clear();
00652 if (in == "")
00653 return;
00654
00655 void * byte_buffer;
00656 Size buffer_size;
00657 std::vector<unsigned char> binary;
00658 const Size element_size = sizeof(ToType);
00659
00660 String decompressed;
00661
00662 QByteArray qt_byte_array = QByteArray::fromRawData(in.c_str(), (int) in.size());
00663 QByteArray bazip = QByteArray::fromBase64(qt_byte_array);
00664 QByteArray czip;
00665 czip.resize(4);
00666 czip[0] = (bazip.size() & 0xff000000) >> 24;
00667 czip[1] = (bazip.size() & 0x00ff0000) >> 16;
00668 czip[2] = (bazip.size() | 0x00000800) >> 8;
00669 czip[3] = (bazip.size() & 0x000000ff);
00670 czip += bazip;
00671 QByteArray base64_uncompressed = qUncompress(czip);
00672 if (base64_uncompressed.isEmpty())
00673 {
00674 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Decompression error?");
00675 }
00676 decompressed.resize(base64_uncompressed.size());
00677
00678 std::copy(base64_uncompressed.begin(), base64_uncompressed.end(), decompressed.begin());
00679
00680 byte_buffer = reinterpret_cast<void *>(&decompressed[0]);
00681 buffer_size = decompressed.size();
00682
00683
00684 if ((OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_LITTLEENDIAN) || (!OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_BIGENDIAN))
00685 {
00686 if (element_size == 4)
00687 {
00688 const Int32 * float_buffer = reinterpret_cast<const Int32 *>(byte_buffer);
00689 if (buffer_size % element_size != 0)
00690 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount?");
00691 Size float_count = buffer_size / element_size;
00692 Int32 * p = reinterpret_cast<Int32 *>(byte_buffer);
00693 std::transform(p, p + float_count, p, endianize32);
00694
00695 out.resize(float_count);
00696
00697 for (Size i = 0; i < float_count; ++i)
00698 {
00699 out[i] = (ToType) * float_buffer;
00700 ++float_buffer;
00701 }
00702 }
00703 else
00704 {
00705 const Int64 * float_buffer = reinterpret_cast<const Int64 *>(byte_buffer);
00706
00707 if (buffer_size % element_size != 0)
00708 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount?");
00709
00710 Size float_count = buffer_size / element_size;
00711
00712 Int64 * p = reinterpret_cast<Int64 *>(byte_buffer);
00713 std::transform(p, p + float_count, p, endianize64);
00714
00715 out.resize(float_count);
00716
00717 for (Size i = 0; i < float_count; ++i)
00718 {
00719 out[i] = (ToType) * float_buffer;
00720 ++float_buffer;
00721 }
00722 }
00723 }
00724 else
00725 {
00726 if (element_size == 4)
00727 {
00728 const Int * float_buffer = reinterpret_cast<const Int *>(byte_buffer);
00729 if (buffer_size % element_size != 0)
00730 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount while decoding?");
00731
00732 Size float_count = buffer_size / element_size;
00733 out.resize(float_count);
00734
00735 for (Size i = 0; i < float_count; ++i)
00736 {
00737 out[i] = (ToType) * float_buffer;
00738 ++float_buffer;
00739 }
00740 }
00741 else
00742 {
00743 const Int64 * float_buffer = reinterpret_cast<const Int64 *>(byte_buffer);
00744
00745 if (buffer_size % element_size != 0)
00746 throw Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Bad BufferCount while decoding?");
00747
00748 Size float_count = buffer_size / element_size;
00749 out.resize(float_count);
00750
00751 for (Size i = 0; i < float_count; ++i)
00752 {
00753 out[i] = (ToType) * float_buffer;
00754 ++float_buffer;
00755 }
00756 }
00757 }
00758
00759 }
00760
00761 template <typename ToType>
00762 void Base64::decodeIntegersUncompressed_(const String & in, ByteOrder from_byte_order, std::vector<ToType> & out)
00763 {
00764 out.clear();
00765 if (in == "")
00766 return;
00767
00768 Size src_size = in.size();
00769
00770 int padding = 0;
00771 if (in[src_size - 1] == '=')
00772 padding++;
00773 if (in[src_size - 2] == '=')
00774 padding++;
00775
00776 src_size -= padding;
00777
00778 register UInt a;
00779 register UInt b;
00780
00781 UInt offset = 0;
00782 int inc = 1;
00783 UInt written = 0;
00784
00785 const Size element_size = sizeof(ToType);
00786
00787
00788 char element[8] = "\x00\x00\x00\x00\x00\x00\x00";
00789
00790 if ((OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_LITTLEENDIAN) || (!OPENMS_IS_BIG_ENDIAN && from_byte_order == Base64::BYTEORDER_BIGENDIAN))
00791 {
00792 offset = (element_size - 1);
00793 inc = -1;
00794 }
00795 else
00796 {
00797 offset = 0;
00798 inc = 1;
00799 }
00800
00801
00802 out.reserve((UInt)(std::ceil((4.0 * src_size) / 3.0) + 6.0));
00803
00804
00805
00806 for (Size i = 0; i < src_size; i += 4)
00807 {
00808
00809
00810
00811 a = decoder_[(int)in[i] - 43] - 62;
00812 b = decoder_[(int)in[i + 1] - 43] - 62;
00813 if (i + 1 >= src_size)
00814 b = 0;
00815 element[offset] = (unsigned char) ((a << 2) | (b >> 4));
00816 written++;
00817
00818 offset = (offset + inc) % element_size;
00819
00820 if (written % element_size == 0)
00821 {
00822 ToType float_value;
00823 if (element_size == 4)
00824 {
00825 Int32 * value = reinterpret_cast<Int32 *>(&element[0]);
00826 float_value = (ToType) * value;
00827 }
00828 else
00829 {
00830 Int64 * value = reinterpret_cast<Int64 *>(&element[0]);
00831 float_value = (ToType) * value;
00832 }
00833 out.push_back(float_value);
00834 strcpy(element, "");
00835 }
00836
00837 a = decoder_[(int)in[i + 2] - 43] - 62;
00838 if (i + 2 >= src_size)
00839 a = 0;
00840 element[offset] = (unsigned char) (((b & 15) << 4) | (a >> 2));
00841 written++;
00842 offset = (offset + inc) % element_size;
00843
00844 if (written % element_size == 0)
00845 {
00846 ToType float_value;
00847 if (element_size == 4)
00848 {
00849 Int32 * value = reinterpret_cast<Int32 *>(&element[0]);
00850 float_value = (ToType) * value;
00851 }
00852 else
00853 {
00854 Int64 * value = reinterpret_cast<Int64 *>(&element[0]);
00855 float_value = (ToType) * value;
00856 }
00857 out.push_back(float_value);
00858 strcpy(element, "");
00859 }
00860
00861 b = decoder_[(int)in[i + 3] - 43] - 62;
00862 if (i + 3 >= src_size)
00863 b = 0;
00864 element[offset] = (unsigned char) (((a & 3) << 6) | b);
00865 written++;
00866 offset = (offset + inc) % element_size;
00867
00868 if (written % element_size == 0)
00869 {
00870 ToType float_value;
00871 if (element_size == 4)
00872 {
00873 Int32 * value = reinterpret_cast<Int32 *>(&element[0]);
00874 float_value = (ToType) * value;
00875 }
00876 else
00877 {
00878 Int64 * value = reinterpret_cast<Int64 *>(&element[0]);
00879 float_value = (ToType) * value;
00880 }
00881 out.push_back(float_value);
00882 strcpy(element, "");
00883 }
00884 }
00885 }
00886
00887 }
00888
00889 #endif