amf.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. #if 0
  2. #include "amf.h"
  3. #include "global.h"
  4. #define DEBUG_LOG(x) { if (gOptions.RTMPClientDebug()) DLOG((x)); }
  5. #ifndef _WIN32
  6. #include <arpa/inet.h>
  7. #endif
  8. using namespace std;
  9. using namespace stringUtil;
  10. using namespace uniString;
  11. #ifdef _WIN32
  12. // Windows is little endian only
  13. #define __LITTLE_ENDIAN 1234
  14. #define __BIG_ENDIAN 4321
  15. #define __BYTE_ORDER __LITTLE_ENDIAN
  16. #define __FLOAT_WORD_ORDER __BYTE_ORDER
  17. typedef unsigned char uint8_t;
  18. #else /* !_WIN32 */
  19. #include <sys/param.h>
  20. #if defined(BYTE_ORDER) && !defined(__BYTE_ORDER)
  21. #define __BYTE_ORDER BYTE_ORDER
  22. #endif
  23. #if defined(BIG_ENDIAN) && !defined(__BIG_ENDIAN)
  24. #define __BIG_ENDIAN BIG_ENDIAN
  25. #endif
  26. #if defined(LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN)
  27. #define __LITTLE_ENDIAN LITTLE_ENDIAN
  28. #endif
  29. #endif /* !_WIN32 */
  30. // define default endianness
  31. #ifndef __LITTLE_ENDIAN
  32. #define __LITTLE_ENDIAN 1234
  33. #endif
  34. #ifndef __BIG_ENDIAN
  35. #define __BIG_ENDIAN 4321
  36. #endif
  37. #ifndef __BYTE_ORDER
  38. #warning "Byte order not defined on your system, assuming little endian!"
  39. #define __BYTE_ORDER __LITTLE_ENDIAN
  40. #endif
  41. // ok, we assume to have the same float word order and byte order if float word order is not defined
  42. #ifndef __FLOAT_WORD_ORDER
  43. //#warning "Float word order not defined, assuming the same as byte order!"
  44. #define __FLOAT_WORD_ORDER __BYTE_ORDER
  45. #endif
  46. #if !defined(__BYTE_ORDER) || !defined(__FLOAT_WORD_ORDER)
  47. #error "Undefined byte or float word order!"
  48. #endif
  49. #if __FLOAT_WORD_ORDER != __BIG_ENDIAN && __FLOAT_WORD_ORDER != __LITTLE_ENDIAN
  50. #error "Unknown/unsupported float word order!"
  51. #endif
  52. #if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN
  53. #error "Unknown/unsupported byte order!"
  54. #endif
  55. static double
  56. AMF0_DecodeNumber(const char *data)
  57. {
  58. double dVal;
  59. #if __FLOAT_WORD_ORDER == __BYTE_ORDER
  60. #if __BYTE_ORDER == __BIG_ENDIAN
  61. memcpy(&dVal, data, 8);
  62. #elif __BYTE_ORDER == __LITTLE_ENDIAN
  63. unsigned char *ci, *co;
  64. ci = (unsigned char *)data;
  65. co = (unsigned char *)&dVal;
  66. co[0] = ci[7];
  67. co[1] = ci[6];
  68. co[2] = ci[5];
  69. co[3] = ci[4];
  70. co[4] = ci[3];
  71. co[5] = ci[2];
  72. co[6] = ci[1];
  73. co[7] = ci[0];
  74. #endif
  75. #else
  76. #if __BYTE_ORDER == __LITTLE_ENDIAN // __FLOAT_WORD_ORER == __BIG_ENDIAN
  77. unsigned char *ci, *co;
  78. ci = (unsigned char *)data;
  79. co = (unsigned char *)&dVal;
  80. co[0] = ci[3];
  81. co[1] = ci[2];
  82. co[2] = ci[1];
  83. co[3] = ci[0];
  84. co[4] = ci[7];
  85. co[5] = ci[6];
  86. co[6] = ci[5];
  87. co[7] = ci[4];
  88. #else // __BYTE_ORDER == __BIG_ENDIAN && __FLOAT_WORD_ORER == __LITTLE_ENDIAN
  89. unsigned char *ci, *co;
  90. ci = (unsigned char *)data;
  91. co = (unsigned char *)&dVal;
  92. co[0] = ci[4];
  93. co[1] = ci[5];
  94. co[2] = ci[6];
  95. co[3] = ci[7];
  96. co[4] = ci[0];
  97. co[5] = ci[1];
  98. co[6] = ci[2];
  99. co[7] = ci[3];
  100. #endif
  101. #endif
  102. return dVal;
  103. }
  104. char *
  105. AMF0_EncodeNumber(char *output, char *outend, double dVal)
  106. {
  107. if (output+8 > outend)
  108. return NULL;
  109. // *output++ = AMF_NUMBER; // type: Number
  110. #if __FLOAT_WORD_ORDER == __BYTE_ORDER
  111. #if __BYTE_ORDER == __BIG_ENDIAN
  112. memcpy(output, &dVal, 8);
  113. #elif __BYTE_ORDER == __LITTLE_ENDIAN
  114. {
  115. unsigned char *ci, *co;
  116. ci = (unsigned char *)&dVal;
  117. co = (unsigned char *)output;
  118. co[0] = ci[7];
  119. co[1] = ci[6];
  120. co[2] = ci[5];
  121. co[3] = ci[4];
  122. co[4] = ci[3];
  123. co[5] = ci[2];
  124. co[6] = ci[1];
  125. co[7] = ci[0];
  126. }
  127. #endif
  128. #else
  129. #if __BYTE_ORDER == __LITTLE_ENDIAN /* __FLOAT_WORD_ORER == __BIG_ENDIAN */
  130. {
  131. unsigned char *ci, *co;
  132. ci = (unsigned char *)&dVal;
  133. co = (unsigned char *)output;
  134. co[0] = ci[3];
  135. co[1] = ci[2];
  136. co[2] = ci[1];
  137. co[3] = ci[0];
  138. co[4] = ci[7];
  139. co[5] = ci[6];
  140. co[6] = ci[5];
  141. co[7] = ci[4];
  142. }
  143. #else /* __BYTE_ORDER == __BIG_ENDIAN && __FLOAT_WORD_ORER == __LITTLE_ENDIAN */
  144. {
  145. unsigned char *ci, *co;
  146. ci = (unsigned char *)&dVal;
  147. co = (unsigned char *)output;
  148. co[0] = ci[4];
  149. co[1] = ci[5];
  150. co[2] = ci[6];
  151. co[3] = ci[7];
  152. co[4] = ci[0];
  153. co[5] = ci[1];
  154. co[6] = ci[2];
  155. co[7] = ci[3];
  156. }
  157. #endif
  158. #endif
  159. return output+8;
  160. }
  161. static void serialize(vector<__uint8> &s,const utf8 &v,int mode,const utf8 &logMsgPrefix) throw(exception)
  162. {
  163. assert(mode == 0); // AMF3 not yet implemented
  164. __uint16 slen = (__uint16)v.length();
  165. slen = htons(slen);
  166. s.insert(s.end(),(const char *)&slen,((const char *)&slen) + 2);
  167. s.insert(s.end(),v.begin(),v.end());
  168. }
  169. /////////////////////////////////////////////////////////////////////////////////////////////////
  170. AMFObject::AMFObject() throw() {}
  171. AMFObject::~AMFObject() throw()
  172. {
  173. clearProperties();
  174. }
  175. AMFObject::AMFObject(const AMFObject &obj) throw()
  176. {
  177. for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
  178. {
  179. m_properties[(*i).first] = new AMFVal(*(*i).second);
  180. }
  181. }
  182. AMFObject& AMFObject::operator=(const AMFObject &obj) throw()
  183. {
  184. clearProperties();
  185. for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
  186. {
  187. m_properties[(*i).first] = new AMFVal(*(*i).second);
  188. }
  189. return *this;
  190. }
  191. void AMFObject::clearProperties() throw()
  192. {
  193. for(propertyMap_t::iterator i = m_properties.begin(); i != m_properties.end(); ++i)
  194. {
  195. delete (*i).second;
  196. }
  197. m_properties.clear();
  198. }
  199. // add property. Takes possession of value "v"
  200. // throws if value already exists
  201. void AMFObject::addProperty(const utf8 &key,AMFVal *v) throw(exception)
  202. {
  203. assert(v);
  204. assert(m_properties.find(key) == m_properties.end());
  205. if (m_properties.find(key) != m_properties.end())
  206. throwEx<runtime_error>(string(__FUNCTION__) + " property " + key + " already exists");
  207. if (!v)
  208. throwEx<runtime_error>(string(__FUNCTION__) + " value is null.");
  209. m_properties[key] = v;
  210. }
  211. const AMFVal* AMFObject::getProperty(const uniString::utf8 &key) const throw()
  212. {
  213. propertyMap_t::const_iterator i = m_properties.find(key);
  214. if (i == m_properties.end()) return 0;
  215. return (*i).second;
  216. }
  217. utf8 AMFObject::prettyPrint(int mode,const utf8 &tabs) const throw()
  218. {
  219. utf8 result;
  220. result += tabs + "{" + eol();
  221. for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
  222. {
  223. assert((*i).second);
  224. result += tabs + "\t" + (*i).first + ": ";
  225. result += (*i).second->prettyPrint(mode,tabs + "\t");
  226. result += eol();
  227. }
  228. result += tabs + "}";
  229. return result;
  230. }
  231. void AMFObject::serialize(vector<__uint8> &s,int mode,const utf8 &logMsgPrefix) const throw(exception)
  232. {
  233. assert(mode == 0); // AMF3 not yet implemented
  234. for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
  235. {
  236. assert((*i).second);
  237. ::serialize(s,(*i).first,mode,logMsgPrefix);
  238. (*i).second->serialize(s,mode,logMsgPrefix);
  239. }
  240. s.push_back(0);
  241. s.push_back(0);
  242. s.push_back(AMF0_object_end_marker);
  243. }
  244. void AMFObject::loadFromBitstream(const char *&bitstream,int &bitstreamLen,int mode,const utf8 &logMsgPrefix) throw(exception)
  245. {
  246. assert(mode == 0); // AMF3 not implemented yet
  247. propertyMap_t pmap;
  248. AMFVal *val = 0;
  249. try
  250. {
  251. while(true)
  252. {
  253. if (bitstreamLen < 3) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 object marker.");
  254. if (bitstream[0] == 0 && bitstream[1] == 0 && bitstream[2] == 9)
  255. {
  256. // end of object
  257. bitstream += 3;
  258. bitstreamLen -= 3;
  259. break;
  260. }
  261. if (bitstream[0] == 0 && bitstream[1] == 0) throwEx<runtime_error>(logMsgPrefix + " AMF0 object has null string keyed property");
  262. if (bitstreamLen < 4) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 object marker.");
  263. // alright, we've taken care of the abberant cases and end-of-object. Now let's get a property
  264. int slen = ntohs(*(__uint16*)bitstream);
  265. bitstream += 2;
  266. bitstreamLen -= 2;
  267. if (bitstreamLen < slen) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 object property key.");
  268. utf8 key(bitstream,bitstream + slen);
  269. bitstream += slen;
  270. bitstreamLen -= slen;
  271. assert(!val);
  272. val = new AMFVal;
  273. val->loadFromBitstream(bitstream,bitstreamLen,mode,logMsgPrefix);
  274. pmap[key] = val;
  275. val = 0;
  276. }
  277. clearProperties();
  278. m_properties = pmap;
  279. }
  280. catch(...)
  281. {
  282. delete val;
  283. throw;
  284. }
  285. }
  286. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  287. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  288. /////////////////////////////////////////////////////////////////////////////////////////////////
  289. AMFEMCAArray::AMFEMCAArray() throw() {}
  290. AMFEMCAArray::~AMFEMCAArray() throw()
  291. {
  292. clearProperties();
  293. }
  294. AMFEMCAArray::AMFEMCAArray(const AMFEMCAArray &obj) throw()
  295. {
  296. for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
  297. {
  298. m_properties[(*i).first] = new AMFVal(*(*i).second);
  299. }
  300. }
  301. AMFEMCAArray& AMFEMCAArray::operator=(const AMFEMCAArray &obj) throw()
  302. {
  303. clearProperties();
  304. for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
  305. {
  306. m_properties[(*i).first] = new AMFVal(*(*i).second);
  307. }
  308. return *this;
  309. }
  310. void AMFEMCAArray::clearProperties() throw()
  311. {
  312. for(propertyMap_t::iterator i = m_properties.begin(); i != m_properties.end(); ++i)
  313. {
  314. delete (*i).second;
  315. }
  316. m_properties.clear();
  317. }
  318. // add property. Takes possession of value "v"
  319. // throws if value already exists
  320. void AMFEMCAArray::addProperty(const utf8 &key,AMFVal *v) throw(exception)
  321. {
  322. assert(v);
  323. assert(m_properties.find(key) == m_properties.end());
  324. if (m_properties.find(key) != m_properties.end())
  325. throwEx<runtime_error>(string(__FUNCTION__) + " property " + key + " already exists");
  326. if (!v)
  327. throwEx<runtime_error>(string(__FUNCTION__) + " value is null.");
  328. m_properties[key] = v;
  329. }
  330. const AMFVal* AMFEMCAArray::getProperty(const uniString::utf8 &key) const throw()
  331. {
  332. propertyMap_t::const_iterator i = m_properties.find(key);
  333. if (i == m_properties.end()) return 0;
  334. return (*i).second;
  335. }
  336. utf8 AMFEMCAArray::prettyPrint(int mode,const utf8 &tabs) const throw()
  337. {
  338. utf8 result;
  339. result += tabs + "{" + eol();
  340. for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
  341. {
  342. assert((*i).second);
  343. result += tabs + "\t" + (*i).first + ": ";
  344. result += (*i).second->prettyPrint(mode,tabs + "\t");
  345. result += eol();
  346. }
  347. result += tabs + "}";
  348. return result;
  349. }
  350. void AMFEMCAArray::serialize(vector<__uint8> &s,int mode,const utf8 &logMsgPrefix) const throw(exception)
  351. {
  352. assert(mode == 0); // amf3 not implemented
  353. // wowza seems to always just use zero as array length
  354. s.push_back(0); s.push_back(0); s.push_back(0); s.push_back(0);
  355. for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
  356. {
  357. assert((*i).second);
  358. ::serialize(s,(*i).first,mode,logMsgPrefix);
  359. (*i).second->serialize(s,mode,logMsgPrefix);
  360. }
  361. s.push_back(0);
  362. s.push_back(0);
  363. s.push_back(AMF0_object_end_marker);
  364. }
  365. void AMFEMCAArray::loadFromBitstream(const char *&bitstream,int &bitstreamLen,int mode,const utf8 &logMsgPrefix) throw(exception)
  366. {
  367. assert(mode == 0); // AMF3 not implemented yet
  368. propertyMap_t pmap;
  369. AMFVal *val = 0;
  370. try
  371. {
  372. if (bitstreamLen < 7) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 ECMA array type.");
  373. // skip length
  374. bitstream += 4;
  375. bitstreamLen -= 4;
  376. while(true)
  377. {
  378. if (bitstreamLen < 3) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for ECMA array type.");
  379. if (bitstream[0] == 0 && bitstream[1] == 0 && bitstream[2] == 9)
  380. {
  381. // end of object
  382. bitstream += 3;
  383. bitstreamLen -= 3;
  384. break;
  385. }
  386. if (bitstream[0] == 0 && bitstream[1] == 0) throwEx<runtime_error>(logMsgPrefix + " AMF0 ECMA array type has null string keyed property");
  387. if (bitstreamLen < 4) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 ECMA array type.");
  388. // alright, we've taken care of the abberant cases and end-of-object. Now let's get a property
  389. int slen = ntohs(*(__uint16*)bitstream);
  390. bitstream += 2;
  391. bitstreamLen -= 2;
  392. if (bitstreamLen < slen) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 ECMA array type property key.");
  393. utf8 key(bitstream,bitstream + slen);
  394. bitstream += slen;
  395. bitstreamLen -= slen;
  396. assert(!val);
  397. val = new AMFVal;
  398. val->loadFromBitstream(bitstream,bitstreamLen,mode,logMsgPrefix);
  399. pmap[key] = val;
  400. val = 0;
  401. }
  402. clearProperties();
  403. m_properties = pmap;
  404. }
  405. catch(...)
  406. {
  407. delete val;
  408. throw;
  409. }
  410. }
  411. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  412. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  413. const uniString::utf8 & AMFVal::getString() const throw(std::exception)
  414. {
  415. if (m_type3 == AMF3_string_marker) return m_string_val;
  416. if (m_type0 != AMF0_string_marker) throwEx<runtime_error>("AMFVal type error. Wanted string but type is " + tos(m_type0));
  417. return m_string_val;
  418. }
  419. int AMFVal::getInteger() const throw(std::exception)
  420. {
  421. if (m_type3 != AMF3_integer_marker) throwEx<runtime_error>("AMFVal type error. Wanted integer but type is " + tos(m_type3));
  422. return m_integer_val;
  423. }
  424. double AMFVal::getNumber() const throw(std::exception)
  425. {
  426. if (m_type3 == AMF3_double_marker) return m_number_val;
  427. if (m_type0 != AMF0_number_marker) throwEx<runtime_error>("AMFVal type error. Wanted number but type is " + tos(m_type0));
  428. return m_number_val;
  429. }
  430. bool AMFVal::getBool() const throw(std::exception)
  431. {
  432. if (m_type3 == AMF3_true_marker) return true;
  433. if (m_type3 == AMF3_false_marker) return false;
  434. if (m_type0 != AMF0_boolean_marker) throwEx<runtime_error>("AMFVal type error. Wanted boolean but type is " + tos(m_type0));
  435. return m_boolean_val;
  436. }
  437. const AMFObject& AMFVal::getObject() const throw(std::exception)
  438. {
  439. if (m_type3 == AMF3_object_marker) return m_object_val;
  440. if (m_type0 != AMF0_object_marker) throwEx<runtime_error>("AMFVal type error. Wanted object but type is " + tos(m_type0));
  441. return m_object_val;
  442. }
  443. void AMFVal::serialize(vector<__uint8> &s,int mode,const utf8 &logMsgPrefix) const throw(exception)
  444. {
  445. s.push_back(mode == 3 ? (__uint8)m_type3 : (__uint8)m_type0);
  446. if (mode == 3)
  447. {
  448. switch(m_type3)
  449. {
  450. case AMF3_double_marker:
  451. {
  452. __uint8 buf[8] = {0};
  453. AMF0_EncodeNumber((char *)buf,(char *)buf+8,m_number_val);
  454. s.insert(s.end(),buf,buf+8);
  455. }
  456. break;
  457. default:
  458. throwEx<runtime_error>(logMsgPrefix + __FUNCTION__ + " unsupported type " + tos(m_type3));
  459. }
  460. }
  461. else
  462. {
  463. switch(m_type0)
  464. {
  465. case AMF0_number_marker:
  466. {
  467. __uint8 buf[8] = {0};
  468. AMF0_EncodeNumber((char *)buf,(char *)buf+8,m_number_val);
  469. s.insert(s.end(),buf,buf+8);
  470. }
  471. break;
  472. case AMF0_boolean_marker:
  473. s.push_back(m_boolean_val ? 1 : 0);
  474. break;
  475. case AMF0_string_marker:
  476. ::serialize(s,m_string_val,mode,logMsgPrefix);
  477. break;
  478. case AMF0_object_marker:
  479. m_object_val.serialize(s,mode,logMsgPrefix);
  480. break;
  481. case AMF0_ecma_array_marker:
  482. m_ecma_array_val.serialize(s,mode,logMsgPrefix);
  483. break;
  484. case AMF0_null_marker:
  485. break;
  486. default:
  487. throwEx<runtime_error>(logMsgPrefix + __FUNCTION__ + " unsupported type " + tos(m_type0));
  488. break;
  489. }
  490. }
  491. }
  492. utf8 AMFVal::prettyPrint(int mode,const utf8 &tabs) const throw()
  493. {
  494. if (mode == 3)
  495. {
  496. switch(m_type3)
  497. {
  498. case AMF3_double_marker:
  499. return tabs + tos(m_number_val);
  500. case AMF3_integer_marker:
  501. return tabs + tos(m_integer_val);
  502. default:
  503. break;
  504. }
  505. }
  506. else
  507. {
  508. switch(m_type0)
  509. {
  510. case AMF0_number_marker:
  511. return tabs + tos(m_number_val);
  512. case AMF0_boolean_marker:
  513. return tabs + (m_boolean_val ? "true" : "false");
  514. case AMF0_string_marker:
  515. return tabs + m_string_val;
  516. case AMF0_object_marker:
  517. return m_object_val.prettyPrint(mode,tabs);
  518. case AMF0_ecma_array_marker:
  519. return m_ecma_array_val.prettyPrint(mode,tabs);
  520. default:
  521. break;
  522. }
  523. }
  524. return "";
  525. }
  526. void AMFVal::loadFromBitstream(const char *&bitstream,int &bitstreamLen,int mode,const utf8 &logMsgPrefix) throw(exception)
  527. {
  528. if (!bitstreamLen) throwEx<runtime_error>(logMsgPrefix + " AMF bitstream is empty");
  529. if (mode == 3)
  530. {
  531. m_type3 = (AMF3Marker_t)*bitstream;
  532. bitstreamLen -= 1;
  533. bitstream += 1;
  534. switch(m_type3)
  535. {
  536. case AMF3_double_marker:
  537. if (bitstreamLen < 8) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF3 double marker.");
  538. m_number_val = AMF0_DecodeNumber(bitstream);
  539. bitstream += 8;
  540. bitstreamLen -= 8;
  541. break;
  542. case AMF3_null_marker:
  543. case AMF3_false_marker:
  544. case AMF3_true_marker:
  545. case AMF3_integer_marker:
  546. case AMF3_string_marker:
  547. case AMF3_xml_doc_marker:
  548. case AMF3_date_marker:
  549. case AMF3_array_marker:
  550. case AMF3_object_marker:
  551. case AMF3_xml_marker:
  552. case AMF3_byte_array_marker:
  553. case AMF3_undefined_marker:
  554. throwEx<runtime_error>(logMsgPrefix + " Unsupported AMF3 marker " + tos(m_type3));
  555. break;
  556. default:
  557. throwEx<runtime_error>(logMsgPrefix + " Unknown AMF3 marker " + tos(m_type3));
  558. break;
  559. }
  560. }
  561. else
  562. {
  563. m_type0 = (AMF0Marker_t)*bitstream;
  564. bitstreamLen -= 1;
  565. bitstream += 1;
  566. switch(m_type0)
  567. {
  568. case AMF0_number_marker:
  569. if (bitstreamLen < 8) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 number marker.");
  570. m_number_val = AMF0_DecodeNumber(bitstream);
  571. bitstream += 8;
  572. bitstreamLen -= 8;
  573. break;
  574. case AMF0_boolean_marker:
  575. if (bitstreamLen < 1) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 boolean marker.");
  576. m_boolean_val = ((*bitstream) ? true : false);
  577. bitstream += 1;
  578. bitstreamLen -= 1;
  579. break;
  580. case AMF0_string_marker:
  581. {
  582. if (bitstreamLen < 2) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 string marker.");
  583. __uint16 slen = ntohs(*(__uint16*)bitstream);
  584. bitstream += 2;
  585. bitstreamLen -= 2;
  586. if (bitstreamLen < slen) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 string marker.");
  587. m_string_val = utf8(bitstream,bitstream + slen);
  588. bitstream += slen;
  589. bitstreamLen -= slen;
  590. }
  591. break;
  592. case AMF0_object_marker:
  593. m_object_val.loadFromBitstream(bitstream,bitstreamLen,0,logMsgPrefix);
  594. break;
  595. case AMF0_ecma_array_marker:
  596. m_ecma_array_val.loadFromBitstream(bitstream,bitstreamLen,0,logMsgPrefix);
  597. break;
  598. case AMF0_undefined_marker:
  599. DEBUG_LOG(logMsgPrefix + "Warning - Undefined AMF0 marker " + tos(m_type0));
  600. case AMF0_null_marker:
  601. break;
  602. case AMF0_reference_marker:
  603. case AMF0_object_end_marker:
  604. case AMF0_strict_array_marker:
  605. case AMF0_date_marker:
  606. case AMF0_long_string_marker:
  607. case AMF0_unsupported_marker:
  608. case AMF0_recordset_marker:
  609. case AMF0_xml_Document_marker:
  610. case AMF0_typed_object_marker:
  611. case AMF0_amvplus_object_marker:
  612. case AMF0_movieclip_marker:
  613. throwEx<runtime_error>(logMsgPrefix + " Unsupported AMF0 marker " + tos(m_type0));
  614. break;
  615. default:
  616. throwEx<runtime_error>(logMsgPrefix + " Unknown AMF0 marker " + tos(m_type0));
  617. break;
  618. }
  619. }
  620. }
  621. ///////////////////////////////////////////////////////////////////////////////////////////
  622. void AMFEncoding::loadFromBitstream(const char *bitstream, int bitstreamLen,const uniString::utf8 &logMsgPrefix) throw(exception)
  623. {
  624. int blen = bitstreamLen;
  625. const char *bs = bitstream;
  626. vector<AMFVal> values;
  627. while(blen)
  628. {
  629. AMFVal v;
  630. v.loadFromBitstream(bs,blen,m_mode,logMsgPrefix);
  631. values.push_back(v);
  632. }
  633. m_values=values;
  634. }
  635. const AMFVal& AMFEncoding::getValue(size_t index) const throw(std::exception)
  636. {
  637. if (index >= m_values.size())
  638. throwEx<runtime_error>("AMFEncoding::getValue(" + tos(index) + ") out of range");
  639. return m_values[index];
  640. }
  641. void AMFEncoding::appendValue(const AMFVal &v) throw()
  642. {
  643. m_values.push_back(v);
  644. }
  645. void AMFEncoding::serialize(vector<__uint8> &s,const utf8 &logMsgPrefix) const throw(exception)
  646. {
  647. for(vector<AMFVal>::const_iterator i = m_values.begin(); i != m_values.end(); ++i)
  648. (*i).serialize(s,m_mode,logMsgPrefix);
  649. }
  650. utf8 AMFEncoding::prettyPrint() const throw()
  651. {
  652. utf8 result("INVOKE(");
  653. result += eol();
  654. for(vector<AMFVal>::const_iterator i = m_values.begin(); i != m_values.end(); ++i)
  655. result += (*i).prettyPrint(m_mode,"\t") + eol();
  656. result += ")";
  657. return result;
  658. }
  659. #endif