TextConverter.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //
  2. // TextConverter.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/TextConverter.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Text
  8. // Module: TextConverter
  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/TextConverter.h"
  16. #include "Poco/TextIterator.h"
  17. #include "Poco/TextEncoding.h"
  18. namespace {
  19. int nullTransform(int ch)
  20. {
  21. return ch;
  22. }
  23. }
  24. namespace Poco {
  25. TextConverter::TextConverter(const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
  26. _inEncoding(inEncoding),
  27. _outEncoding(outEncoding),
  28. _defaultChar(defaultChar)
  29. {
  30. }
  31. TextConverter::~TextConverter()
  32. {
  33. }
  34. int TextConverter::convert(const std::string& source, std::string& destination, Transform trans)
  35. {
  36. int errors = 0;
  37. TextIterator it(source, _inEncoding);
  38. TextIterator end(source);
  39. unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH];
  40. while (it != end)
  41. {
  42. int c = *it;
  43. if (c == -1) { ++errors; c = _defaultChar; }
  44. c = trans(c);
  45. int n = _outEncoding.convert(c, buffer, sizeof(buffer));
  46. if (n == 0) n = _outEncoding.convert(_defaultChar, buffer, sizeof(buffer));
  47. poco_assert (n <= sizeof(buffer));
  48. destination.append((const char*) buffer, n);
  49. ++it;
  50. }
  51. return errors;
  52. }
  53. int TextConverter::convert(const void* source, int length, std::string& destination, Transform trans)
  54. {
  55. poco_check_ptr (source);
  56. int errors = 0;
  57. const unsigned char* it = (const unsigned char*) source;
  58. const unsigned char* end = (const unsigned char*) source + length;
  59. unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH];
  60. while (it < end)
  61. {
  62. int n = _inEncoding.queryConvert(it, 1);
  63. int uc;
  64. int read = 1;
  65. while (-1 > n && (end - it) >= -n)
  66. {
  67. read = -n;
  68. n = _inEncoding.queryConvert(it, read);
  69. }
  70. if (-1 > n)
  71. {
  72. it = end;
  73. }
  74. else
  75. {
  76. it += read;
  77. }
  78. if (-1 >= n)
  79. {
  80. uc = _defaultChar;
  81. ++errors;
  82. }
  83. else
  84. {
  85. uc = n;
  86. }
  87. uc = trans(uc);
  88. n = _outEncoding.convert(uc, buffer, sizeof(buffer));
  89. if (n == 0) n = _outEncoding.convert(_defaultChar, buffer, sizeof(buffer));
  90. poco_assert (n <= sizeof(buffer));
  91. destination.append((const char*) buffer, n);
  92. }
  93. return errors;
  94. }
  95. int TextConverter::convert(const std::string& source, std::string& destination)
  96. {
  97. return convert(source, destination, nullTransform);
  98. }
  99. int TextConverter::convert(const void* source, int length, std::string& destination)
  100. {
  101. return convert(source, length, destination, nullTransform);
  102. }
  103. } // namespace Poco