base64.cpp 2.3 KB

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