Base64Decoder.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //
  2. // Base64Decoder.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/Base64Decoder.cpp#2 $
  5. //
  6. // Library: Foundation
  7. // Package: Streams
  8. // Module: Base64
  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/Base64Decoder.h"
  16. #include "Poco/Base64Encoder.h"
  17. #include "Poco/Exception.h"
  18. #include "Poco/Mutex.h"
  19. namespace Poco {
  20. unsigned char Base64DecoderBuf::IN_ENCODING[256];
  21. bool Base64DecoderBuf::IN_ENCODING_INIT = false;
  22. namespace
  23. {
  24. static FastMutex mutex;
  25. }
  26. Base64DecoderBuf::Base64DecoderBuf(std::istream& istr):
  27. _groupLength(0),
  28. _groupIndex(0),
  29. _buf(*istr.rdbuf())
  30. {
  31. FastMutex::ScopedLock lock(mutex);
  32. if (!IN_ENCODING_INIT)
  33. {
  34. for (unsigned i = 0; i < sizeof(IN_ENCODING); i++)
  35. {
  36. IN_ENCODING[i] = 0xFF;
  37. }
  38. for (unsigned i = 0; i < sizeof(Base64EncoderBuf::OUT_ENCODING); i++)
  39. {
  40. IN_ENCODING[Base64EncoderBuf::OUT_ENCODING[i]] = i;
  41. }
  42. IN_ENCODING[static_cast<unsigned char>('=')] = '\0';
  43. IN_ENCODING_INIT = true;
  44. }
  45. }
  46. Base64DecoderBuf::~Base64DecoderBuf()
  47. {
  48. }
  49. int Base64DecoderBuf::readFromDevice()
  50. {
  51. if (_groupIndex < _groupLength)
  52. {
  53. return _group[_groupIndex++];
  54. }
  55. else
  56. {
  57. unsigned char buffer[4];
  58. int c;
  59. if ((c = readOne()) == -1) return -1;
  60. buffer[0] = (unsigned char) c;
  61. if (IN_ENCODING[buffer[0]] == 0xFF) throw DataFormatException();
  62. if ((c = readOne()) == -1) throw DataFormatException();
  63. buffer[1] = (unsigned char) c;
  64. if (IN_ENCODING[buffer[1]] == 0xFF) throw DataFormatException();
  65. if ((c = readOne()) == -1) throw DataFormatException();
  66. buffer[2] = c;
  67. if (IN_ENCODING[buffer[2]] == 0xFF) throw DataFormatException();
  68. if ((c = readOne()) == -1) throw DataFormatException();
  69. buffer[3] = c;
  70. if (IN_ENCODING[buffer[3]] == 0xFF) throw DataFormatException();
  71. _group[0] = (IN_ENCODING[buffer[0]] << 2) | (IN_ENCODING[buffer[1]] >> 4);
  72. _group[1] = ((IN_ENCODING[buffer[1]] & 0x0F) << 4) | (IN_ENCODING[buffer[2]] >> 2);
  73. _group[2] = (IN_ENCODING[buffer[2]] << 6) | IN_ENCODING[buffer[3]];
  74. if (buffer[2] == '=')
  75. _groupLength = 1;
  76. else if (buffer[3] == '=')
  77. _groupLength = 2;
  78. else
  79. _groupLength = 3;
  80. _groupIndex = 1;
  81. return _group[0];
  82. }
  83. }
  84. int Base64DecoderBuf::readOne()
  85. {
  86. int ch = _buf.sbumpc();
  87. while (ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n')
  88. ch = _buf.sbumpc();
  89. return ch;
  90. }
  91. Base64DecoderIOS::Base64DecoderIOS(std::istream& istr): _buf(istr)
  92. {
  93. poco_ios_init(&_buf);
  94. }
  95. Base64DecoderIOS::~Base64DecoderIOS()
  96. {
  97. }
  98. Base64DecoderBuf* Base64DecoderIOS::rdbuf()
  99. {
  100. return &_buf;
  101. }
  102. Base64Decoder::Base64Decoder(std::istream& istr): Base64DecoderIOS(istr), std::istream(&_buf)
  103. {
  104. }
  105. Base64Decoder::~Base64Decoder()
  106. {
  107. }
  108. } // namespace Poco