123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- #if 0
- #include "amf.h"
- #include "global.h"
- #define DEBUG_LOG(x) { if (gOptions.RTMPClientDebug()) DLOG((x)); }
- #ifndef _WIN32
- #include <arpa/inet.h>
- #endif
- using namespace std;
- using namespace stringUtil;
- using namespace uniString;
- #ifdef _WIN32
- // Windows is little endian only
- #define __LITTLE_ENDIAN 1234
- #define __BIG_ENDIAN 4321
- #define __BYTE_ORDER __LITTLE_ENDIAN
- #define __FLOAT_WORD_ORDER __BYTE_ORDER
- typedef unsigned char uint8_t;
- #else /* !_WIN32 */
- #include <sys/param.h>
- #if defined(BYTE_ORDER) && !defined(__BYTE_ORDER)
- #define __BYTE_ORDER BYTE_ORDER
- #endif
- #if defined(BIG_ENDIAN) && !defined(__BIG_ENDIAN)
- #define __BIG_ENDIAN BIG_ENDIAN
- #endif
- #if defined(LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN)
- #define __LITTLE_ENDIAN LITTLE_ENDIAN
- #endif
- #endif /* !_WIN32 */
- // define default endianness
- #ifndef __LITTLE_ENDIAN
- #define __LITTLE_ENDIAN 1234
- #endif
- #ifndef __BIG_ENDIAN
- #define __BIG_ENDIAN 4321
- #endif
- #ifndef __BYTE_ORDER
- #warning "Byte order not defined on your system, assuming little endian!"
- #define __BYTE_ORDER __LITTLE_ENDIAN
- #endif
- // ok, we assume to have the same float word order and byte order if float word order is not defined
- #ifndef __FLOAT_WORD_ORDER
- //#warning "Float word order not defined, assuming the same as byte order!"
- #define __FLOAT_WORD_ORDER __BYTE_ORDER
- #endif
- #if !defined(__BYTE_ORDER) || !defined(__FLOAT_WORD_ORDER)
- #error "Undefined byte or float word order!"
- #endif
- #if __FLOAT_WORD_ORDER != __BIG_ENDIAN && __FLOAT_WORD_ORDER != __LITTLE_ENDIAN
- #error "Unknown/unsupported float word order!"
- #endif
- #if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN
- #error "Unknown/unsupported byte order!"
- #endif
- static double
- AMF0_DecodeNumber(const char *data)
- {
- double dVal;
- #if __FLOAT_WORD_ORDER == __BYTE_ORDER
- #if __BYTE_ORDER == __BIG_ENDIAN
- memcpy(&dVal, data, 8);
- #elif __BYTE_ORDER == __LITTLE_ENDIAN
- unsigned char *ci, *co;
- ci = (unsigned char *)data;
- co = (unsigned char *)&dVal;
- co[0] = ci[7];
- co[1] = ci[6];
- co[2] = ci[5];
- co[3] = ci[4];
- co[4] = ci[3];
- co[5] = ci[2];
- co[6] = ci[1];
- co[7] = ci[0];
- #endif
- #else
- #if __BYTE_ORDER == __LITTLE_ENDIAN // __FLOAT_WORD_ORER == __BIG_ENDIAN
- unsigned char *ci, *co;
- ci = (unsigned char *)data;
- co = (unsigned char *)&dVal;
- co[0] = ci[3];
- co[1] = ci[2];
- co[2] = ci[1];
- co[3] = ci[0];
- co[4] = ci[7];
- co[5] = ci[6];
- co[6] = ci[5];
- co[7] = ci[4];
- #else // __BYTE_ORDER == __BIG_ENDIAN && __FLOAT_WORD_ORER == __LITTLE_ENDIAN
- unsigned char *ci, *co;
- ci = (unsigned char *)data;
- co = (unsigned char *)&dVal;
- co[0] = ci[4];
- co[1] = ci[5];
- co[2] = ci[6];
- co[3] = ci[7];
- co[4] = ci[0];
- co[5] = ci[1];
- co[6] = ci[2];
- co[7] = ci[3];
- #endif
- #endif
- return dVal;
- }
- char *
- AMF0_EncodeNumber(char *output, char *outend, double dVal)
- {
- if (output+8 > outend)
- return NULL;
- // *output++ = AMF_NUMBER; // type: Number
- #if __FLOAT_WORD_ORDER == __BYTE_ORDER
- #if __BYTE_ORDER == __BIG_ENDIAN
- memcpy(output, &dVal, 8);
- #elif __BYTE_ORDER == __LITTLE_ENDIAN
- {
- unsigned char *ci, *co;
- ci = (unsigned char *)&dVal;
- co = (unsigned char *)output;
- co[0] = ci[7];
- co[1] = ci[6];
- co[2] = ci[5];
- co[3] = ci[4];
- co[4] = ci[3];
- co[5] = ci[2];
- co[6] = ci[1];
- co[7] = ci[0];
- }
- #endif
- #else
- #if __BYTE_ORDER == __LITTLE_ENDIAN /* __FLOAT_WORD_ORER == __BIG_ENDIAN */
- {
- unsigned char *ci, *co;
- ci = (unsigned char *)&dVal;
- co = (unsigned char *)output;
- co[0] = ci[3];
- co[1] = ci[2];
- co[2] = ci[1];
- co[3] = ci[0];
- co[4] = ci[7];
- co[5] = ci[6];
- co[6] = ci[5];
- co[7] = ci[4];
- }
- #else /* __BYTE_ORDER == __BIG_ENDIAN && __FLOAT_WORD_ORER == __LITTLE_ENDIAN */
- {
- unsigned char *ci, *co;
- ci = (unsigned char *)&dVal;
- co = (unsigned char *)output;
- co[0] = ci[4];
- co[1] = ci[5];
- co[2] = ci[6];
- co[3] = ci[7];
- co[4] = ci[0];
- co[5] = ci[1];
- co[6] = ci[2];
- co[7] = ci[3];
- }
- #endif
- #endif
- return output+8;
- }
- static void serialize(vector<__uint8> &s,const utf8 &v,int mode,const utf8 &logMsgPrefix) throw(exception)
- {
- assert(mode == 0); // AMF3 not yet implemented
- __uint16 slen = (__uint16)v.length();
- slen = htons(slen);
- s.insert(s.end(),(const char *)&slen,((const char *)&slen) + 2);
- s.insert(s.end(),v.begin(),v.end());
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- AMFObject::AMFObject() throw() {}
- AMFObject::~AMFObject() throw()
- {
- clearProperties();
- }
- AMFObject::AMFObject(const AMFObject &obj) throw()
- {
- for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
- {
- m_properties[(*i).first] = new AMFVal(*(*i).second);
- }
- }
- AMFObject& AMFObject::operator=(const AMFObject &obj) throw()
- {
- clearProperties();
- for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
- {
- m_properties[(*i).first] = new AMFVal(*(*i).second);
- }
- return *this;
- }
- void AMFObject::clearProperties() throw()
- {
- for(propertyMap_t::iterator i = m_properties.begin(); i != m_properties.end(); ++i)
- {
- delete (*i).second;
- }
- m_properties.clear();
- }
- // add property. Takes possession of value "v"
- // throws if value already exists
- void AMFObject::addProperty(const utf8 &key,AMFVal *v) throw(exception)
- {
- assert(v);
- assert(m_properties.find(key) == m_properties.end());
- if (m_properties.find(key) != m_properties.end())
- throwEx<runtime_error>(string(__FUNCTION__) + " property " + key + " already exists");
- if (!v)
- throwEx<runtime_error>(string(__FUNCTION__) + " value is null.");
- m_properties[key] = v;
- }
- const AMFVal* AMFObject::getProperty(const uniString::utf8 &key) const throw()
- {
- propertyMap_t::const_iterator i = m_properties.find(key);
- if (i == m_properties.end()) return 0;
- return (*i).second;
- }
- utf8 AMFObject::prettyPrint(int mode,const utf8 &tabs) const throw()
- {
- utf8 result;
- result += tabs + "{" + eol();
- for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
- {
- assert((*i).second);
- result += tabs + "\t" + (*i).first + ": ";
- result += (*i).second->prettyPrint(mode,tabs + "\t");
- result += eol();
- }
- result += tabs + "}";
- return result;
- }
- void AMFObject::serialize(vector<__uint8> &s,int mode,const utf8 &logMsgPrefix) const throw(exception)
- {
- assert(mode == 0); // AMF3 not yet implemented
- for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
- {
- assert((*i).second);
- ::serialize(s,(*i).first,mode,logMsgPrefix);
- (*i).second->serialize(s,mode,logMsgPrefix);
- }
- s.push_back(0);
- s.push_back(0);
- s.push_back(AMF0_object_end_marker);
- }
- void AMFObject::loadFromBitstream(const char *&bitstream,int &bitstreamLen,int mode,const utf8 &logMsgPrefix) throw(exception)
- {
- assert(mode == 0); // AMF3 not implemented yet
- propertyMap_t pmap;
- AMFVal *val = 0;
- try
- {
- while(true)
- {
- if (bitstreamLen < 3) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 object marker.");
- if (bitstream[0] == 0 && bitstream[1] == 0 && bitstream[2] == 9)
- {
- // end of object
- bitstream += 3;
- bitstreamLen -= 3;
- break;
- }
- if (bitstream[0] == 0 && bitstream[1] == 0) throwEx<runtime_error>(logMsgPrefix + " AMF0 object has null string keyed property");
- if (bitstreamLen < 4) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 object marker.");
- // alright, we've taken care of the abberant cases and end-of-object. Now let's get a property
- int slen = ntohs(*(__uint16*)bitstream);
- bitstream += 2;
- bitstreamLen -= 2;
- if (bitstreamLen < slen) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 object property key.");
- utf8 key(bitstream,bitstream + slen);
- bitstream += slen;
- bitstreamLen -= slen;
- assert(!val);
- val = new AMFVal;
- val->loadFromBitstream(bitstream,bitstreamLen,mode,logMsgPrefix);
- pmap[key] = val;
- val = 0;
- }
- clearProperties();
- m_properties = pmap;
- }
- catch(...)
- {
- delete val;
- throw;
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- AMFEMCAArray::AMFEMCAArray() throw() {}
- AMFEMCAArray::~AMFEMCAArray() throw()
- {
- clearProperties();
- }
- AMFEMCAArray::AMFEMCAArray(const AMFEMCAArray &obj) throw()
- {
- for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
- {
- m_properties[(*i).first] = new AMFVal(*(*i).second);
- }
- }
- AMFEMCAArray& AMFEMCAArray::operator=(const AMFEMCAArray &obj) throw()
- {
- clearProperties();
- for(propertyMap_t::const_iterator i = obj.m_properties.begin(); i != obj.m_properties.end(); ++i)
- {
- m_properties[(*i).first] = new AMFVal(*(*i).second);
- }
- return *this;
- }
- void AMFEMCAArray::clearProperties() throw()
- {
- for(propertyMap_t::iterator i = m_properties.begin(); i != m_properties.end(); ++i)
- {
- delete (*i).second;
- }
- m_properties.clear();
- }
- // add property. Takes possession of value "v"
- // throws if value already exists
- void AMFEMCAArray::addProperty(const utf8 &key,AMFVal *v) throw(exception)
- {
- assert(v);
- assert(m_properties.find(key) == m_properties.end());
- if (m_properties.find(key) != m_properties.end())
- throwEx<runtime_error>(string(__FUNCTION__) + " property " + key + " already exists");
- if (!v)
- throwEx<runtime_error>(string(__FUNCTION__) + " value is null.");
- m_properties[key] = v;
- }
- const AMFVal* AMFEMCAArray::getProperty(const uniString::utf8 &key) const throw()
- {
- propertyMap_t::const_iterator i = m_properties.find(key);
- if (i == m_properties.end()) return 0;
- return (*i).second;
- }
- utf8 AMFEMCAArray::prettyPrint(int mode,const utf8 &tabs) const throw()
- {
- utf8 result;
- result += tabs + "{" + eol();
- for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
- {
- assert((*i).second);
- result += tabs + "\t" + (*i).first + ": ";
- result += (*i).second->prettyPrint(mode,tabs + "\t");
- result += eol();
- }
- result += tabs + "}";
- return result;
- }
- void AMFEMCAArray::serialize(vector<__uint8> &s,int mode,const utf8 &logMsgPrefix) const throw(exception)
- {
- assert(mode == 0); // amf3 not implemented
- // wowza seems to always just use zero as array length
- s.push_back(0); s.push_back(0); s.push_back(0); s.push_back(0);
- for(propertyMap_t::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i)
- {
- assert((*i).second);
- ::serialize(s,(*i).first,mode,logMsgPrefix);
- (*i).second->serialize(s,mode,logMsgPrefix);
- }
- s.push_back(0);
- s.push_back(0);
- s.push_back(AMF0_object_end_marker);
- }
- void AMFEMCAArray::loadFromBitstream(const char *&bitstream,int &bitstreamLen,int mode,const utf8 &logMsgPrefix) throw(exception)
- {
- assert(mode == 0); // AMF3 not implemented yet
- propertyMap_t pmap;
- AMFVal *val = 0;
- try
- {
- if (bitstreamLen < 7) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 ECMA array type.");
- // skip length
- bitstream += 4;
- bitstreamLen -= 4;
- while(true)
- {
- if (bitstreamLen < 3) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for ECMA array type.");
- if (bitstream[0] == 0 && bitstream[1] == 0 && bitstream[2] == 9)
- {
- // end of object
- bitstream += 3;
- bitstreamLen -= 3;
- break;
- }
- if (bitstream[0] == 0 && bitstream[1] == 0) throwEx<runtime_error>(logMsgPrefix + " AMF0 ECMA array type has null string keyed property");
- if (bitstreamLen < 4) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 ECMA array type.");
- // alright, we've taken care of the abberant cases and end-of-object. Now let's get a property
- int slen = ntohs(*(__uint16*)bitstream);
- bitstream += 2;
- bitstreamLen -= 2;
- if (bitstreamLen < slen) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 ECMA array type property key.");
- utf8 key(bitstream,bitstream + slen);
- bitstream += slen;
- bitstreamLen -= slen;
- assert(!val);
- val = new AMFVal;
- val->loadFromBitstream(bitstream,bitstreamLen,mode,logMsgPrefix);
- pmap[key] = val;
- val = 0;
- }
- clearProperties();
- m_properties = pmap;
- }
- catch(...)
- {
- delete val;
- throw;
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- const uniString::utf8 & AMFVal::getString() const throw(std::exception)
- {
- if (m_type3 == AMF3_string_marker) return m_string_val;
- if (m_type0 != AMF0_string_marker) throwEx<runtime_error>("AMFVal type error. Wanted string but type is " + tos(m_type0));
- return m_string_val;
- }
- int AMFVal::getInteger() const throw(std::exception)
- {
- if (m_type3 != AMF3_integer_marker) throwEx<runtime_error>("AMFVal type error. Wanted integer but type is " + tos(m_type3));
- return m_integer_val;
- }
- double AMFVal::getNumber() const throw(std::exception)
- {
- if (m_type3 == AMF3_double_marker) return m_number_val;
- if (m_type0 != AMF0_number_marker) throwEx<runtime_error>("AMFVal type error. Wanted number but type is " + tos(m_type0));
- return m_number_val;
- }
- bool AMFVal::getBool() const throw(std::exception)
- {
- if (m_type3 == AMF3_true_marker) return true;
- if (m_type3 == AMF3_false_marker) return false;
- if (m_type0 != AMF0_boolean_marker) throwEx<runtime_error>("AMFVal type error. Wanted boolean but type is " + tos(m_type0));
- return m_boolean_val;
- }
- const AMFObject& AMFVal::getObject() const throw(std::exception)
- {
- if (m_type3 == AMF3_object_marker) return m_object_val;
- if (m_type0 != AMF0_object_marker) throwEx<runtime_error>("AMFVal type error. Wanted object but type is " + tos(m_type0));
- return m_object_val;
- }
- void AMFVal::serialize(vector<__uint8> &s,int mode,const utf8 &logMsgPrefix) const throw(exception)
- {
- s.push_back(mode == 3 ? (__uint8)m_type3 : (__uint8)m_type0);
- if (mode == 3)
- {
- switch(m_type3)
- {
- case AMF3_double_marker:
- {
- __uint8 buf[8] = {0};
- AMF0_EncodeNumber((char *)buf,(char *)buf+8,m_number_val);
- s.insert(s.end(),buf,buf+8);
- }
- break;
- default:
- throwEx<runtime_error>(logMsgPrefix + __FUNCTION__ + " unsupported type " + tos(m_type3));
- }
- }
- else
- {
- switch(m_type0)
- {
- case AMF0_number_marker:
- {
- __uint8 buf[8] = {0};
- AMF0_EncodeNumber((char *)buf,(char *)buf+8,m_number_val);
- s.insert(s.end(),buf,buf+8);
- }
- break;
- case AMF0_boolean_marker:
- s.push_back(m_boolean_val ? 1 : 0);
- break;
- case AMF0_string_marker:
- ::serialize(s,m_string_val,mode,logMsgPrefix);
- break;
- case AMF0_object_marker:
- m_object_val.serialize(s,mode,logMsgPrefix);
- break;
- case AMF0_ecma_array_marker:
- m_ecma_array_val.serialize(s,mode,logMsgPrefix);
- break;
- case AMF0_null_marker:
- break;
- default:
- throwEx<runtime_error>(logMsgPrefix + __FUNCTION__ + " unsupported type " + tos(m_type0));
- break;
- }
- }
- }
- utf8 AMFVal::prettyPrint(int mode,const utf8 &tabs) const throw()
- {
- if (mode == 3)
- {
- switch(m_type3)
- {
- case AMF3_double_marker:
- return tabs + tos(m_number_val);
- case AMF3_integer_marker:
- return tabs + tos(m_integer_val);
- default:
- break;
- }
- }
- else
- {
- switch(m_type0)
- {
- case AMF0_number_marker:
- return tabs + tos(m_number_val);
- case AMF0_boolean_marker:
- return tabs + (m_boolean_val ? "true" : "false");
- case AMF0_string_marker:
- return tabs + m_string_val;
- case AMF0_object_marker:
- return m_object_val.prettyPrint(mode,tabs);
- case AMF0_ecma_array_marker:
- return m_ecma_array_val.prettyPrint(mode,tabs);
- default:
- break;
- }
- }
- return "";
- }
- void AMFVal::loadFromBitstream(const char *&bitstream,int &bitstreamLen,int mode,const utf8 &logMsgPrefix) throw(exception)
- {
- if (!bitstreamLen) throwEx<runtime_error>(logMsgPrefix + " AMF bitstream is empty");
- if (mode == 3)
- {
- m_type3 = (AMF3Marker_t)*bitstream;
- bitstreamLen -= 1;
- bitstream += 1;
- switch(m_type3)
- {
- case AMF3_double_marker:
- if (bitstreamLen < 8) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF3 double marker.");
- m_number_val = AMF0_DecodeNumber(bitstream);
- bitstream += 8;
- bitstreamLen -= 8;
- break;
- case AMF3_null_marker:
- case AMF3_false_marker:
- case AMF3_true_marker:
- case AMF3_integer_marker:
- case AMF3_string_marker:
- case AMF3_xml_doc_marker:
- case AMF3_date_marker:
- case AMF3_array_marker:
- case AMF3_object_marker:
- case AMF3_xml_marker:
- case AMF3_byte_array_marker:
- case AMF3_undefined_marker:
- throwEx<runtime_error>(logMsgPrefix + " Unsupported AMF3 marker " + tos(m_type3));
- break;
- default:
- throwEx<runtime_error>(logMsgPrefix + " Unknown AMF3 marker " + tos(m_type3));
- break;
- }
- }
- else
- {
- m_type0 = (AMF0Marker_t)*bitstream;
- bitstreamLen -= 1;
- bitstream += 1;
- switch(m_type0)
- {
- case AMF0_number_marker:
- if (bitstreamLen < 8) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 number marker.");
- m_number_val = AMF0_DecodeNumber(bitstream);
- bitstream += 8;
- bitstreamLen -= 8;
- break;
- case AMF0_boolean_marker:
- if (bitstreamLen < 1) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 boolean marker.");
- m_boolean_val = ((*bitstream) ? true : false);
- bitstream += 1;
- bitstreamLen -= 1;
- break;
- case AMF0_string_marker:
- {
- if (bitstreamLen < 2) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 string marker.");
- __uint16 slen = ntohs(*(__uint16*)bitstream);
- bitstream += 2;
- bitstreamLen -= 2;
- if (bitstreamLen < slen) throwEx<runtime_error>(logMsgPrefix + " Insufficient data for AMF0 string marker.");
- m_string_val = utf8(bitstream,bitstream + slen);
- bitstream += slen;
- bitstreamLen -= slen;
- }
- break;
- case AMF0_object_marker:
- m_object_val.loadFromBitstream(bitstream,bitstreamLen,0,logMsgPrefix);
- break;
- case AMF0_ecma_array_marker:
- m_ecma_array_val.loadFromBitstream(bitstream,bitstreamLen,0,logMsgPrefix);
- break;
- case AMF0_undefined_marker:
- DEBUG_LOG(logMsgPrefix + "Warning - Undefined AMF0 marker " + tos(m_type0));
- case AMF0_null_marker:
- break;
- case AMF0_reference_marker:
- case AMF0_object_end_marker:
- case AMF0_strict_array_marker:
- case AMF0_date_marker:
- case AMF0_long_string_marker:
- case AMF0_unsupported_marker:
- case AMF0_recordset_marker:
- case AMF0_xml_Document_marker:
- case AMF0_typed_object_marker:
- case AMF0_amvplus_object_marker:
- case AMF0_movieclip_marker:
- throwEx<runtime_error>(logMsgPrefix + " Unsupported AMF0 marker " + tos(m_type0));
- break;
- default:
- throwEx<runtime_error>(logMsgPrefix + " Unknown AMF0 marker " + tos(m_type0));
- break;
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- void AMFEncoding::loadFromBitstream(const char *bitstream, int bitstreamLen,const uniString::utf8 &logMsgPrefix) throw(exception)
- {
- int blen = bitstreamLen;
- const char *bs = bitstream;
- vector<AMFVal> values;
- while(blen)
- {
- AMFVal v;
- v.loadFromBitstream(bs,blen,m_mode,logMsgPrefix);
- values.push_back(v);
- }
- m_values=values;
- }
- const AMFVal& AMFEncoding::getValue(size_t index) const throw(std::exception)
- {
- if (index >= m_values.size())
- throwEx<runtime_error>("AMFEncoding::getValue(" + tos(index) + ") out of range");
- return m_values[index];
- }
- void AMFEncoding::appendValue(const AMFVal &v) throw()
- {
- m_values.push_back(v);
- }
- void AMFEncoding::serialize(vector<__uint8> &s,const utf8 &logMsgPrefix) const throw(exception)
- {
- for(vector<AMFVal>::const_iterator i = m_values.begin(); i != m_values.end(); ++i)
- (*i).serialize(s,m_mode,logMsgPrefix);
- }
- utf8 AMFEncoding::prettyPrint() const throw()
- {
- utf8 result("INVOKE(");
- result += eol();
- for(vector<AMFVal>::const_iterator i = m_values.begin(); i != m_values.end(); ++i)
- result += (*i).prettyPrint(m_mode,"\t") + eol();
- result += ")";
- return result;
- }
- #endif
|