StreamConverter.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. //
  2. // StreamConverter.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/StreamConverter.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Text
  8. // Module: StreamConverter
  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/StreamConverter.h"
  16. #include "Poco/TextEncoding.h"
  17. namespace Poco {
  18. StreamConverterBuf::StreamConverterBuf(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  19. _pIstr(&istr),
  20. _pOstr(0),
  21. _inEncoding(inEncoding),
  22. _outEncoding(outEncoding),
  23. _defaultChar(defaultChar),
  24. _sequenceLength(0),
  25. _pos(0),
  26. _errors(0)
  27. {
  28. }
  29. StreamConverterBuf::StreamConverterBuf(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  30. _pIstr(0),
  31. _pOstr(&ostr),
  32. _inEncoding(inEncoding),
  33. _outEncoding(outEncoding),
  34. _defaultChar(defaultChar),
  35. _sequenceLength(0),
  36. _pos(0),
  37. _errors(0)
  38. {
  39. }
  40. StreamConverterBuf::~StreamConverterBuf()
  41. {
  42. }
  43. int StreamConverterBuf::readFromDevice()
  44. {
  45. poco_assert_dbg (_pIstr);
  46. if (_pos < _sequenceLength) return _buffer[_pos++];
  47. _pos = 0;
  48. _sequenceLength = 0;
  49. int c = _pIstr->get();
  50. if (c == -1) return -1;
  51. poco_assert (c < 256);
  52. int uc;
  53. _buffer [0] = (unsigned char) c;
  54. int n = _inEncoding.queryConvert(_buffer, 1);
  55. int read = 1;
  56. while (-1 > n)
  57. {
  58. poco_assert_dbg(-n <= sizeof(_buffer));
  59. _pIstr->read((char*) _buffer + read, -n - read);
  60. read = -n;
  61. n = _inEncoding.queryConvert(_buffer, -n);
  62. }
  63. if (-1 >= n)
  64. {
  65. uc = _defaultChar;
  66. ++_errors;
  67. }
  68. else
  69. {
  70. uc = n;
  71. }
  72. _sequenceLength = _outEncoding.convert(uc, _buffer, sizeof(_buffer));
  73. if (_sequenceLength == 0)
  74. _sequenceLength = _outEncoding.convert(_defaultChar, _buffer, sizeof(_buffer));
  75. if (_sequenceLength == 0)
  76. return -1;
  77. else
  78. return _buffer[_pos++];
  79. }
  80. int StreamConverterBuf::writeToDevice(char c)
  81. {
  82. poco_assert_dbg (_pOstr);
  83. _buffer[_pos++] = (unsigned char) c;
  84. if (_sequenceLength == 0 || _sequenceLength == _pos)
  85. {
  86. int n = _inEncoding.queryConvert(_buffer, _pos);
  87. if (-1 <= n)
  88. {
  89. int uc = n;
  90. if (-1 == n)
  91. {
  92. ++_errors;
  93. return -1;
  94. }
  95. int n = _outEncoding.convert(uc, _buffer, sizeof(_buffer));
  96. if (n == 0) n = _outEncoding.convert(_defaultChar, _buffer, sizeof(_buffer));
  97. poco_assert_dbg (n <= sizeof(_buffer));
  98. _pOstr->write((char*) _buffer, n);
  99. _sequenceLength = 0;
  100. _pos = 0;
  101. }
  102. else
  103. {
  104. _sequenceLength = -n;
  105. }
  106. }
  107. return charToInt(c);
  108. }
  109. int StreamConverterBuf::errors() const
  110. {
  111. return _errors;
  112. }
  113. StreamConverterIOS::StreamConverterIOS(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  114. _buf(istr, inEncoding, outEncoding, defaultChar)
  115. {
  116. poco_ios_init(&_buf);
  117. }
  118. StreamConverterIOS::StreamConverterIOS(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  119. _buf(ostr, inEncoding, outEncoding, defaultChar)
  120. {
  121. poco_ios_init(&_buf);
  122. }
  123. StreamConverterIOS::~StreamConverterIOS()
  124. {
  125. }
  126. StreamConverterBuf* StreamConverterIOS::rdbuf()
  127. {
  128. return &_buf;
  129. }
  130. int StreamConverterIOS::errors() const
  131. {
  132. return _buf.errors();
  133. }
  134. InputStreamConverter::InputStreamConverter(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  135. StreamConverterIOS(istr, inEncoding, outEncoding, defaultChar),
  136. std::istream(&_buf)
  137. {
  138. }
  139. InputStreamConverter::~InputStreamConverter()
  140. {
  141. }
  142. OutputStreamConverter::OutputStreamConverter(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  143. StreamConverterIOS(ostr, inEncoding, outEncoding, defaultChar),
  144. std::ostream(&_buf)
  145. {
  146. }
  147. OutputStreamConverter::~OutputStreamConverter()
  148. {
  149. }
  150. } // namespace Poco