id3_field_string_ascii.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
  2. // patent or other intellectual property protection in this work. This means that
  3. // it may be modified, redistributed and used in commercial and non-commercial
  4. // software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
  5. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  6. //
  7. // The ID3Lib authors encourage improvements and optimisations to be sent to the
  8. // ID3Lib coordinator, currently Dirk Mahoney ([email protected]). Approved
  9. // submissions may be altered, and will be included and released under these terms.
  10. //
  11. // Mon Nov 23 18:34:01 1998
  12. // improved/optimized/whatever 10/30/00 JF
  13. // improved/optimized/whatEVER jan-08-2006 benski
  14. #include <stdlib.h>
  15. #include "id3_field.h"
  16. #include "id3_misc_support.h"
  17. #include "../nu/AutoWide.h"
  18. #include "../Plugins/Input/in_mp3/config.h" // TODO: cut
  19. // the ::Set() function for ASCII
  20. void ID3_Field::SetLocal(const char *newString)
  21. {
  22. if (newString)
  23. {
  24. Clear();
  25. AutoWide temp(newString);
  26. SetUnicode(temp);
  27. if (!(flags & ID3FF_ADJUSTENC))
  28. type = ID3FTY_ASCIISTRING;
  29. }
  30. }
  31. void ID3_Field::SetLatin(const char *newString)
  32. {
  33. if (newString)
  34. {
  35. Clear();
  36. AutoWide temp(newString, 28591); // ISO-8859-1 code page
  37. SetUnicode(temp);
  38. type = ID3FTY_ASCIISTRING;
  39. }
  40. return;
  41. }
  42. void ID3_Field::SetUTF8(const char *newString)
  43. {
  44. if (newString)
  45. {
  46. Clear();
  47. AutoWide temp(newString, CP_UTF8);
  48. SetUnicode(temp);
  49. }
  50. return;
  51. }
  52. // the ::Get() function for ASCII
  53. luint ID3_Field::GetLocal(char *buffer, luint maxLength, luint itemNum)
  54. {
  55. luint bytesUsed = 0;
  56. wchar_t *temp;
  57. if (temp = (wchar_t*)calloc(maxLength, sizeof(wchar_t)))
  58. {
  59. if (GetUnicode(temp, maxLength, itemNum))
  60. {
  61. bytesUsed = ID3_UnicodeToLocal(buffer, temp, maxLength);
  62. }
  63. free(temp);
  64. }
  65. else
  66. ID3_THROW (ID3E_NoMemory);
  67. return bytesUsed;
  68. }
  69. void ID3_Field::AddLocal(const char *newString)
  70. {
  71. if (newString)
  72. {
  73. AutoWide temp(newString);
  74. AddUnicode(temp);
  75. }
  76. }
  77. void ID3_Field::AddLatin(const char *newString)
  78. {
  79. if (newString)
  80. {
  81. AutoWide temp(newString, 28591);
  82. AddUnicode(temp);
  83. type = ID3FTY_ASCIISTRING;
  84. }
  85. }
  86. luint ID3_Field::ParseASCIIString(uchar *buffer, luint posn, luint buffSize)
  87. {
  88. luint bytesUsed = 0;
  89. if (fixedLength != -1)
  90. bytesUsed = fixedLength;
  91. else
  92. {
  93. if (flags & ID3FF_NULL)
  94. while ((posn + bytesUsed) < buffSize && buffer[posn + bytesUsed] != 0)
  95. bytesUsed++;
  96. else
  97. bytesUsed = buffSize - posn;
  98. }
  99. if (bytesUsed > 0xffff) // keep it sane, yo (64kb string max should be good)
  100. {
  101. hasChanged=false;
  102. return 0;
  103. }
  104. if (bytesUsed)
  105. {
  106. char *temp = NULL;
  107. if (temp = (char*)calloc(bytesUsed + 1, sizeof(char)))
  108. {
  109. memcpy(temp, &buffer[posn], bytesUsed);
  110. temp[bytesUsed] = 0;
  111. if (config_read_mode == READ_LOCAL) // benski> I added a config option to deal with old tags
  112. SetLocal(temp);
  113. else
  114. SetLatin(temp);
  115. if (!(flags & ID3FF_ADJUSTENC))
  116. type = ID3FTY_ASCIISTRING;
  117. free(temp);
  118. }
  119. else
  120. ID3_THROW (ID3E_NoMemory);
  121. }
  122. if (flags & ID3FF_NULL)
  123. bytesUsed++;
  124. hasChanged = false;
  125. return bytesUsed;
  126. }
  127. luint ID3_Field::ParseUTF8String(uchar *buffer, luint posn, luint buffSize)
  128. {
  129. luint bytesUsed = 0;
  130. if (fixedLength != -1)
  131. bytesUsed = fixedLength;
  132. else
  133. {
  134. if (flags & ID3FF_NULL)
  135. while ((posn + bytesUsed) < buffSize && buffer[posn + bytesUsed] != 0)
  136. bytesUsed++;
  137. else
  138. bytesUsed = buffSize - posn;
  139. }
  140. if (bytesUsed > 0xffff) // keep it sane, yo (64kb string max should be good)
  141. {
  142. hasChanged=false;
  143. return 0;
  144. }
  145. if (bytesUsed)
  146. {
  147. char *temp = NULL;
  148. if (temp = (char*)calloc(bytesUsed + 1, sizeof(char)))
  149. {
  150. memcpy (temp, &buffer[posn], bytesUsed);
  151. temp[bytesUsed] = 0;
  152. SetUTF8(temp);
  153. free(temp);
  154. }
  155. else
  156. ID3_THROW (ID3E_NoMemory);
  157. }
  158. if (flags & ID3FF_NULL)
  159. bytesUsed++;
  160. hasChanged = false;
  161. return bytesUsed;
  162. }
  163. luint ID3_Field::RenderLatinString(uchar *buffer)
  164. {
  165. luint bytesUsed = 0;
  166. buffer[0] = 0;
  167. bytesUsed = BinSize();
  168. if (data && size)
  169. {
  170. luint i;
  171. // benski> I added a config option for whether to use "broken" local system encoding mode
  172. if (config_write_mode == WRITE_LATIN)
  173. ID3_UnicodeToLatin( (char*)buffer, (const wchar_t *) data, bytesUsed, (int)bytesUsed);
  174. else
  175. ID3_UnicodeToLocal( (char*)buffer, (const wchar_t *) data, bytesUsed, bytesUsed);
  176. for (i = 0;i < bytesUsed; i++)
  177. {
  178. if (buffer[i] == 1)
  179. {
  180. char sub = '/';
  181. if (flags & ID3FF_NULLDIVIDE)
  182. sub = '\0';
  183. buffer[i] = sub;
  184. }
  185. }
  186. }
  187. if (bytesUsed == 1 && flags & ID3FF_NULL)
  188. buffer[0] = 0;
  189. hasChanged = false;
  190. return bytesUsed;
  191. }