QuotedPrintable.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: QuotedPrintable.cpp /////////////////////////////////////////////////////////
  24. // Author: Matt Campbell, February 2002
  25. // Description: Quoted-printable encode/decode
  26. ////////////////////////////////////////////////////////////////////////////
  27. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  28. #include "Common/QuotedPrintable.h"
  29. #define MAGIC_CHAR '_'
  30. // takes an integer and returns an ASCII representation
  31. static char intToHexDigit(int num)
  32. {
  33. if (num<0 || num >15) return '\0';
  34. if (num<10)
  35. {
  36. return '0' + num;
  37. }
  38. return 'A' + (num-10);
  39. }
  40. // convert an ASCII representation of a hex digit into the digit itself
  41. static int hexDigitToInt(char c)
  42. {
  43. if (c <= '9' && c >= '0') return (c - '0');
  44. if (c <= 'f' && c >= 'a') return (c - 'a' + 10);
  45. if (c <= 'F' && c >= 'A') return (c - 'A' + 10);
  46. return 0;
  47. }
  48. // Convert unicode strings into ascii quoted-printable strings
  49. AsciiString UnicodeStringToQuotedPrintable(UnicodeString original)
  50. {
  51. static char dest[1024];
  52. const char *src = (const char *)original.str();
  53. int i=0;
  54. while ( !(src[0]=='\0' && src[1]=='\0') && i<1021 )
  55. {
  56. if (!isalnum(*src))
  57. {
  58. dest[i++] = MAGIC_CHAR;
  59. dest[i++] = intToHexDigit((*src)>>4);
  60. dest[i++] = intToHexDigit((*src)&0xf);
  61. } else
  62. {
  63. dest[i++] = *src;
  64. }
  65. src ++;
  66. if (!isalnum(*src))
  67. {
  68. dest[i++] = MAGIC_CHAR;
  69. dest[i++] = intToHexDigit((*src)>>4);
  70. dest[i++] = intToHexDigit((*src)&0xf);
  71. }
  72. else
  73. {
  74. dest[i++] = *src;
  75. }
  76. src ++;
  77. }
  78. dest[i] = '\0';
  79. return dest;
  80. }
  81. // Convert ascii strings into ascii quoted-printable strings
  82. AsciiString AsciiStringToQuotedPrintable(AsciiString original)
  83. {
  84. static char dest[1024];
  85. const char *src = (const char *)original.str();
  86. int i=0;
  87. while ( src[0]!='\0' && i<1021 )
  88. {
  89. if (!isalnum(*src))
  90. {
  91. dest[i++] = MAGIC_CHAR;
  92. dest[i++] = intToHexDigit((*src)>>4);
  93. dest[i++] = intToHexDigit((*src)&0xf);
  94. } else
  95. {
  96. dest[i++] = *src;
  97. }
  98. src ++;
  99. }
  100. dest[i] = '\0';
  101. return dest;
  102. }
  103. // Convert ascii quoted-printable strings into unicode strings
  104. UnicodeString QuotedPrintableToUnicodeString(AsciiString original)
  105. {
  106. static unsigned short dest[1024];
  107. int i=0;
  108. unsigned char *c = (unsigned char *)dest;
  109. const unsigned char *src = (const unsigned char *)original.str();
  110. while (*src && i<1023)
  111. {
  112. if (*src == MAGIC_CHAR)
  113. {
  114. if (src[1] == '\0')
  115. {
  116. // string ends with MAGIC_CHAR
  117. break;
  118. }
  119. *c = hexDigitToInt(src[1]);
  120. src++;
  121. if (src[1] != '\0')
  122. {
  123. *c = *c<<4;
  124. *c = *c | hexDigitToInt(src[1]);
  125. src++;
  126. }
  127. }
  128. else
  129. {
  130. *c = *src;
  131. }
  132. src++;
  133. c++;
  134. }
  135. // Fixup odd-length strings
  136. if ((c-(unsigned char *)dest)%2)
  137. {
  138. // OK
  139. }
  140. else
  141. {
  142. *c = '\0';
  143. c++;
  144. }
  145. *c = 0;
  146. UnicodeString out(dest);
  147. return out;
  148. }
  149. // Convert ascii quoted-printable strings into ascii strings
  150. AsciiString QuotedPrintableToAsciiString(AsciiString original)
  151. {
  152. static unsigned char dest[1024];
  153. int i=0;
  154. unsigned char *c = (unsigned char *)dest;
  155. const unsigned char *src = (const unsigned char *)original.str();
  156. while (*src && i<1023)
  157. {
  158. if (*src == MAGIC_CHAR)
  159. {
  160. if (src[1] == '\0')
  161. {
  162. // string ends with MAGIC_CHAR
  163. break;
  164. }
  165. *c = hexDigitToInt(src[1]);
  166. src++;
  167. if (src[1] != '\0')
  168. {
  169. *c = *c<<4;
  170. *c = *c | hexDigitToInt(src[1]);
  171. src++;
  172. }
  173. }
  174. else
  175. {
  176. *c = *src;
  177. }
  178. src++;
  179. c++;
  180. }
  181. *c = 0;
  182. return AsciiString((const char *)dest);
  183. }