diff options
Diffstat (limited to 'libxsde/xsde/cxx/serializer/validating/base64-binary.cxx')
-rw-r--r-- | libxsde/xsde/cxx/serializer/validating/base64-binary.cxx | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx b/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx new file mode 100644 index 0000000..a649433 --- /dev/null +++ b/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx @@ -0,0 +1,166 @@ +// file : xsde/cxx/serializer/validating/base64-binary.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsde/cxx/serializer/validating/base64-binary.hxx> + +namespace xsde +{ + namespace cxx + { + namespace serializer + { + namespace validating + { + base64_binary_simpl:: + ~base64_binary_simpl () + { + if (free_) + delete const_cast<buffer*> (value_); + } + + void base64_binary_simpl:: + pre (const buffer* value) + { + value_ = value; + } + + static const char base64_tab[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/', '\0' + }; + + inline void + split_1 (char b, unsigned char& b1, unsigned char& b2) + { + unsigned char ub = static_cast<unsigned char> (b); + b1 = ub >> 2; + b2 = (ub & 0x3) << 4; + } + + inline void + split_2 (char b, unsigned char& b2, unsigned char& b3) + { + unsigned char ub = static_cast<unsigned char> (b); + b2 |= ub >> 4; + b3 = (ub & 0x0F) << 2; + } + + inline void + split_3 (char b, unsigned char& b3, unsigned char& b4) + { + unsigned char ub = static_cast<unsigned char> (b); + b3 |= ub >> 6; + b4 = ( ub & 0x3F ); + } + + void base64_binary_simpl:: + _serialize_content () + { + // Maximum 76 characters per line, 76/4 = 19 + // + const size_t quads_per_line = 19; + char buf[quads_per_line * 4 + 1]; + + if (size_t size = value_->size ()) + { + const char* data = value_->data (); + size_t quads = (size + 2) / 3; + + // Process all quadruplets except the last, one line at a time. + // + size_t i = 0; + size_t j = 0; + unsigned char b1, b2, b3, b4; + + for (; j < (quads - 1);) + { + for (; i < quads_per_line && j < (quads - 1); ++i, ++j) + { + split_1 (*data++, b1, b2); + split_2 (*data++, b2, b3); + split_3 (*data++, b3, b4); + + buf[i * 4] = base64_tab[b1]; + buf[i * 4 + 1] = base64_tab[b2]; + buf[i * 4 + 2] = base64_tab[b3]; + buf[i * 4 + 3] = base64_tab[b4]; + } + + if (i == quads_per_line) + { + buf[i * 4] = '\n'; + +#ifdef XSDE_EXCEPTIONS + _characters (buf, i * 4 + 1); +#else + if (!_characters (buf, i * 4 + 1)) + break; +#endif + i = 0; + } + } + +#ifndef XSDE_EXCEPTIONS + if (j == (quads - 1)) + { +#endif + // Process last quadruplet. The first byte is always present. + // + split_1 (*data++, b1, b2); + buf[i * 4] = base64_tab[b1]; + + if (data != value_->end ()) + { + // Second byte is present. + // + split_2 (*data++, b2, b3); + buf[i * 4 + 1] = base64_tab[b2]; + + if(data != value_->end ()) + { + // Third byte is present. + // + split_3 (*data++, b3, b4); + buf[i * 4 + 2] = base64_tab[b3]; + buf[i * 4 + 3] = base64_tab[b4]; + } + else + { + buf[i * 4 + 2] = base64_tab[b3]; + buf[i * 4 + 3] = '='; + } + } + else + { + buf[i * 4 + 1] = base64_tab[b2]; + buf[i * 4 + 2] = '='; + buf[i * 4 + 3] = '='; + } + + i++; + + buf[i * 4] = '\n'; + _characters (buf, i * 4 + 1); + +#ifndef XSDE_EXCEPTIONS + } +#endif + } + + if (free_) + { + delete const_cast<buffer*> (value_); + value_ = 0; + } + } + } + } + } +} |