Base32Decoder.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //
  2. // Base32Decoder.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/Base32Decoder.cpp#2 $
  5. //
  6. // Library: Foundation
  7. // Package: Streams
  8. // Module: Base32
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/Base32Decoder.h"
  16. #include "Poco/Base32Encoder.h"
  17. #include "Poco/Exception.h"
  18. #include "Poco/Mutex.h"
  19. #include <cstring>
  20. namespace Poco {
  21. unsigned char Base32DecoderBuf::IN_ENCODING[256];
  22. bool Base32DecoderBuf::IN_ENCODING_INIT = false;
  23. namespace
  24. {
  25. static FastMutex mutex;
  26. }
  27. Base32DecoderBuf::Base32DecoderBuf(std::istream& istr):
  28. _groupLength(0),
  29. _groupIndex(0),
  30. _buf(*istr.rdbuf())
  31. {
  32. FastMutex::ScopedLock lock(mutex);
  33. if (!IN_ENCODING_INIT)
  34. {
  35. for (unsigned i = 0; i < sizeof(IN_ENCODING); i++)
  36. {
  37. IN_ENCODING[i] = 0xFF;
  38. }
  39. for (unsigned i = 0; i < sizeof(Base32EncoderBuf::OUT_ENCODING); i++)
  40. {
  41. IN_ENCODING[Base32EncoderBuf::OUT_ENCODING[i]] = i;
  42. }
  43. IN_ENCODING[static_cast<unsigned char>('=')] = '\0';
  44. IN_ENCODING_INIT = true;
  45. }
  46. }
  47. Base32DecoderBuf::~Base32DecoderBuf()
  48. {
  49. }
  50. int Base32DecoderBuf::readFromDevice()
  51. {
  52. if (_groupIndex < _groupLength)
  53. {
  54. return _group[_groupIndex++];
  55. }
  56. else
  57. {
  58. unsigned char buffer[8];
  59. std::memset(buffer, '=', sizeof(buffer));
  60. int c;
  61. // per RFC-4648, Section 6, permissible block lengths are:
  62. // 2, 4, 5, 7, and 8 bytes. Any other length is malformed.
  63. //
  64. do {
  65. if ((c = readOne()) == -1) return -1;
  66. buffer[0] = (unsigned char) c;
  67. if (IN_ENCODING[buffer[0]] == 0xFF) throw DataFormatException();
  68. if ((c = readOne()) == -1) throw DataFormatException();
  69. buffer[1] = (unsigned char) c;
  70. if (IN_ENCODING[buffer[1]] == 0xFF) throw DataFormatException();
  71. if ((c = readOne()) == -1) break;
  72. buffer[2] = (unsigned char) c;
  73. if (IN_ENCODING[buffer[2]] == 0xFF) throw DataFormatException();
  74. if ((c = readOne()) == -1) throw DataFormatException();
  75. buffer[3] = (unsigned char) c;
  76. if (IN_ENCODING[buffer[3]] == 0xFF) throw DataFormatException();
  77. if ((c = readOne()) == -1) break;
  78. buffer[4] = (unsigned char) c;
  79. if (IN_ENCODING[buffer[4]] == 0xFF) throw DataFormatException();
  80. if ((c = readOne()) == -1) break;
  81. buffer[5] = (unsigned char) c;
  82. if (IN_ENCODING[buffer[5]] == 0xFF) throw DataFormatException();
  83. if ((c = readOne()) == -1) throw DataFormatException();
  84. buffer[6] = (unsigned char) c;
  85. if (IN_ENCODING[buffer[6]] == 0xFF) throw DataFormatException();
  86. if ((c = readOne()) == -1) break;
  87. buffer[7] = (unsigned char) c;
  88. if (IN_ENCODING[buffer[7]] == 0xFF) throw DataFormatException();
  89. } while (false);
  90. _group[0] = (IN_ENCODING[buffer[0]] << 3) | (IN_ENCODING[buffer[1]] >> 2);
  91. _group[1] = ((IN_ENCODING[buffer[1]] & 0x03) << 6) | (IN_ENCODING[buffer[2]] << 1) | (IN_ENCODING[buffer[3]] >> 4);
  92. _group[2] = ((IN_ENCODING[buffer[3]] & 0x0F) << 4) | (IN_ENCODING[buffer[4]] >> 1);
  93. _group[3] = ((IN_ENCODING[buffer[4]] & 0x01) << 7) | (IN_ENCODING[buffer[5]] << 2) | (IN_ENCODING[buffer[6]] >> 3);
  94. _group[4] = ((IN_ENCODING[buffer[6]] & 0x07) << 5) | IN_ENCODING[buffer[7]];
  95. if (buffer[2] == '=')
  96. _groupLength = 1;
  97. else if (buffer[4] == '=')
  98. _groupLength = 2;
  99. else if (buffer[5] == '=')
  100. _groupLength = 3;
  101. else if (buffer[7] == '=')
  102. _groupLength = 4;
  103. else
  104. _groupLength = 5;
  105. _groupIndex = 1;
  106. return _group[0];
  107. }
  108. }
  109. int Base32DecoderBuf::readOne()
  110. {
  111. int ch = _buf.sbumpc();
  112. return ch;
  113. }
  114. Base32DecoderIOS::Base32DecoderIOS(std::istream& istr): _buf(istr)
  115. {
  116. poco_ios_init(&_buf);
  117. }
  118. Base32DecoderIOS::~Base32DecoderIOS()
  119. {
  120. }
  121. Base32DecoderBuf* Base32DecoderIOS::rdbuf()
  122. {
  123. return &_buf;
  124. }
  125. Base32Decoder::Base32Decoder(std::istream& istr): Base32DecoderIOS(istr), std::istream(&_buf)
  126. {
  127. }
  128. Base32Decoder::~Base32Decoder()
  129. {
  130. }
  131. } // namespace Poco