AMFObject.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. #include "AMFObject.h"
  2. #include <strsafe.h>
  3. void AMFMixedArray::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  4. {
  5. AMFTypeList::iterator itr;
  6. StringCchCopyEx(str, len, L"Mixed Array [\n", &str, &len, 0);
  7. for (itr=array.begin();itr!=array.end();itr++)
  8. {
  9. for (int i=0;i<spaces;i++)
  10. StringCchCopyEx(str, len, L" ", &str, &len,0);
  11. if (itr->first.c_str() != 0 && itr->first.c_str()[0])
  12. StringCchPrintfEx(str, len, &str, &len, 0, L"%s: ", itr->first.c_str());
  13. if (itr->second)
  14. itr->second->DebugPrint(spaces+1, str, len);
  15. else
  16. StringCchCopyEx(str, len, L"(null)\n", &str, &len, 0);
  17. }
  18. StringCchCopyEx(str, len, L"]\n", &str, &len, 0);
  19. }
  20. size_t AMFMixedArray::Read(uint8_t *data, size_t size)
  21. {
  22. size_t read = 0;
  23. uint32_t maxIndex = FLV::Read32(data);
  24. // TODO? array.reserve(maxIndex);
  25. data += 4;
  26. size -= 4;
  27. read += 4;
  28. while (size)
  29. {
  30. AMFString amfString;
  31. size_t skip = amfString.Read(data, size);
  32. data += skip;
  33. size -= skip;
  34. read += skip;
  35. uint8_t type = *data;
  36. data++;
  37. size--;
  38. read++;
  39. AMFType *obj = MakeObject(type);
  40. if (obj)
  41. {
  42. obj->type = type;
  43. size_t skip = obj->Read(data, size);
  44. data += skip;
  45. size -= skip;
  46. read += skip;
  47. array[amfString.str] = obj;
  48. }
  49. else
  50. break;
  51. if (type == TYPE_TERMINATOR)
  52. break;
  53. }
  54. return read;
  55. }
  56. AMFMixedArray::~AMFMixedArray()
  57. {
  58. for (AMFTypeList::iterator itr=array.begin();itr!=array.end();itr++)
  59. {
  60. delete itr->second;
  61. }
  62. }
  63. void AMFObj::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  64. {
  65. StringCchCopyEx(str, len, L"Object (TODO)\n", &str, &len, 0);
  66. }
  67. size_t AMFObj::Read(uint8_t *data, size_t size)
  68. {
  69. size_t read = 0;
  70. while (size)
  71. {
  72. AMFString amfString;
  73. size_t skip = amfString.Read(data, size);
  74. data += skip;
  75. size -= skip;
  76. read += skip;
  77. uint8_t type = *data;
  78. data++;
  79. size--;
  80. read++;
  81. AMFType *obj = MakeObject(type);
  82. if (obj)
  83. {
  84. obj->type = type;
  85. size_t skip = obj->Read(data, size);
  86. data += skip;
  87. size -= skip;
  88. read += skip;
  89. }
  90. else
  91. return false;
  92. if (type == TYPE_TERMINATOR)
  93. break;
  94. }
  95. return read;
  96. }
  97. void AMFArray::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  98. {
  99. StringCchCopyEx(str, len, L"Array [\n", &str, &len, 0);
  100. for (size_t i=0;i!=array.size();i++)
  101. {
  102. for (int s=0;s<spaces;s++)
  103. StringCchCopyEx(str, len, L" ", &str, &len,0);
  104. StringCchPrintfEx(str, len, &str, &len, 0, L"%u: ", i);
  105. array[i]->DebugPrint(spaces+1, str, len);
  106. }
  107. StringCchCopyEx(str, len, L"]\n", &str, &len, 0);
  108. }
  109. size_t AMFArray::Read(uint8_t *data, size_t size)
  110. {
  111. size_t read = 0;
  112. uint32_t arrayLength = FLV::Read32(data);
  113. array.reserve(arrayLength);
  114. data += 4;
  115. read += 4;
  116. size -= 4;
  117. for (uint32_t i=0;i!=arrayLength;i++)
  118. {
  119. uint8_t type = *data;
  120. data++;
  121. read++;
  122. size--;
  123. AMFType *obj = MakeObject(type);
  124. size_t skip = obj->Read(data, size);
  125. //array[i]=obj;
  126. array.push_back(obj);
  127. data += skip;
  128. read += skip;
  129. size -= skip;
  130. }
  131. return read;
  132. }
  133. AMFArray::~AMFArray()
  134. {
  135. for (size_t i=0;i!=array.size();i++)
  136. {
  137. delete array[i];
  138. }
  139. }
  140. /* --- String --- */
  141. AMFString::AMFString() : str(0)
  142. {}
  143. AMFString::~AMFString()
  144. {
  145. free(str);
  146. }
  147. void AMFString::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  148. {
  149. StringCchPrintfEx(str, len, &str, &len, 0, L"%s\n", this->str);
  150. }
  151. size_t AMFString::Read(uint8_t *data, size_t size)
  152. {
  153. if (size < 2)
  154. return 0;
  155. unsigned __int16 strlength = FLV::Read16(data);
  156. data += 2;
  157. size -= 2;
  158. if (strlength > size)
  159. return 0;
  160. char *utf8string = (char *)calloc(strlength, sizeof(char));
  161. memcpy(utf8string, data, strlength);
  162. int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8string, strlength, 0, 0);
  163. str = (wchar_t *)calloc(wideLen + 2, sizeof(wchar_t));
  164. MultiByteToWideChar(CP_UTF8, 0, utf8string, strlength, str, wideLen);
  165. str[wideLen] = 0;
  166. free(utf8string);
  167. return strlength + 2;
  168. }
  169. /* --- Long String --- */
  170. AMFLongString::AMFLongString() : str(0)
  171. {}
  172. AMFLongString::~AMFLongString()
  173. {
  174. free(str);
  175. }
  176. void AMFLongString::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  177. {
  178. StringCchPrintfEx(str, len, &str, &len, 0, L"%s\n", this->str);
  179. }
  180. size_t AMFLongString::Read(uint8_t *data, size_t size)
  181. {
  182. if (size < 4)
  183. return 0;
  184. uint32_t strlength = FLV::Read32(data);
  185. data += 4;
  186. size -= 4;
  187. if (strlength > size)
  188. return 0;
  189. char *utf8string = (char *)calloc(strlength, sizeof(char));
  190. memcpy(utf8string, data, strlength);
  191. int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8string, strlength, 0, 0);
  192. str = (wchar_t *)calloc(wideLen + 2, sizeof(wchar_t));
  193. MultiByteToWideChar(CP_UTF8, 0, utf8string, strlength, str, wideLen);
  194. str[wideLen] = 0;
  195. free(utf8string);
  196. return strlength + 4;
  197. }
  198. /* --- Double --- */
  199. void AMFDouble::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  200. {
  201. StringCchPrintfEx(str, len, &str, &len, 0, L"%f\n", val);
  202. }
  203. /* --- Boolean --- */
  204. void AMFBoolean::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  205. {
  206. StringCchPrintfEx(str, len, &str, &len, 0, L"%s\n", boolean?L"true":L"false");
  207. }
  208. /* --- Time --- */
  209. static size_t MakeDateString(__time64_t convertTime, wchar_t *dest, size_t destlen)
  210. {
  211. SYSTEMTIME sysTime;
  212. tm *newtime = _localtime64(&convertTime);
  213. dest[0] = 0; // so we can bail out easily
  214. if (newtime)
  215. {
  216. sysTime.wYear = (WORD)(newtime->tm_year + 1900);
  217. sysTime.wMonth = (WORD)(newtime->tm_mon + 1);
  218. sysTime.wDayOfWeek = (WORD)newtime->tm_wday;
  219. sysTime.wDay = (WORD)newtime->tm_mday;
  220. sysTime.wHour = (WORD)newtime->tm_hour;
  221. sysTime.wMinute = (WORD)newtime->tm_min;
  222. sysTime.wSecond = (WORD)newtime->tm_sec;
  223. sysTime.wMilliseconds = 0;
  224. int charsWritten = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &sysTime, NULL, dest, (int)destlen);
  225. if (charsWritten)
  226. {
  227. size_t dateSize = charsWritten-1;
  228. dest += dateSize;
  229. destlen -= dateSize;
  230. if (destlen)
  231. {
  232. *dest++ = L' ';
  233. destlen--;
  234. dateSize++;
  235. }
  236. int charsWritten2 = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &sysTime, NULL, dest, (int)destlen);
  237. if (charsWritten2)
  238. {
  239. dateSize+=(charsWritten2-1);
  240. }
  241. return dateSize;
  242. }
  243. }
  244. return 1;
  245. }
  246. void AMFTime::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  247. {
  248. size_t written = MakeDateString((__time64_t)val, str, len);
  249. str+=written;
  250. len-=written;
  251. if (len>=2)
  252. {
  253. str[0]='\n';
  254. str[1]=0;
  255. len--;
  256. str++;
  257. }
  258. }
  259. /* --- Terminator --- */
  260. void AMFTerminator::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  261. {
  262. StringCchCopyEx(str, len, L"array terminator\n", &str, &len, 0);
  263. }
  264. /* --- Reference --- */
  265. void AMFReference::DebugPrint(int spaces, wchar_t *&str, size_t &len)
  266. {
  267. StringCchPrintfEx(str, len, &str, &len, 0, L"%u\n", val);
  268. }