base64.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include<__vic/base64.h>
  2. #include<__vic/readers/string.h>
  3. #include<__vic/writers/string.h>
  4. #include<__vic/ascii.h>
  5. #include<iostream>
  6. #include<exception>
  7. #include<cassert>
  8. #include<string>
  9. namespace tests {
  10. typedef std::string bytes;
  11. typedef __vic::string_reader bytes_reader;
  12. typedef __vic::string_writer bytes_writer;
  13. template<class Reader>
  14. class skip_ws_reader
  15. {
  16. Reader r;
  17. public:
  18. template<class Arg>
  19. explicit skip_ws_reader(Arg &arg) : r(arg) {}
  20. bool read(char &res)
  21. {
  22. for(;;)
  23. {
  24. char ch;
  25. if(!r.read(ch)) return false;
  26. if(__vic::ascii::isspace(ch)) continue;
  27. res = ch;
  28. return true;
  29. }
  30. }
  31. };
  32. std::string encode(const bytes &s)
  33. {
  34. std::string res;
  35. size_t enc_len = __vic::base64::encoded_length(s.length());
  36. res.reserve(enc_len);
  37. __vic::base64::encode(bytes_reader(s), __vic::string_writer(res));
  38. assert(res.length() == enc_len);
  39. return res;
  40. }
  41. bytes decode(const std::string &s)
  42. {
  43. bytes res;
  44. size_t max_dec_len = __vic::base64::max_decoded_length(s.length());
  45. res.reserve(max_dec_len);
  46. __vic::base64::decode(__vic::string_reader(s), bytes_writer(res));
  47. assert(res.length() <= max_dec_len);
  48. return res;
  49. }
  50. bytes decode_ignore_ws(const std::string &s)
  51. {
  52. bytes res;
  53. size_t max_dec_len = __vic::base64::max_decoded_length(s.length());
  54. res.reserve(max_dec_len);
  55. __vic::base64::decode(
  56. skip_ws_reader<__vic::string_reader>(s), bytes_writer(res));
  57. assert(res.length() <= max_dec_len);
  58. return res;
  59. }
  60. void run()
  61. {
  62. assert(encode("Hello") == "SGVsbG8=");
  63. assert(decode("SGVsbG8=") == "Hello");
  64. assert(decode_ignore_ws(" S G Vs bG8 = ") == "Hello");
  65. try
  66. {
  67. decode("!SGVsbG8="); // non-BASE64 digit
  68. assert(false);
  69. }
  70. catch(const __vic::base64::bad_digit & ) {} // OK
  71. try
  72. {
  73. decode("SGVsbG8"); // bad length
  74. assert(false);
  75. }
  76. catch(const __vic::base64::bad_length & ) {} // OK
  77. }
  78. } // namespace
  79. int main()
  80. {
  81. try
  82. {
  83. tests::run();
  84. return 0;
  85. }
  86. catch(const std::exception &ex)
  87. {
  88. std::cerr << ex.what() << '\n';
  89. }
  90. return 1;
  91. }