winlin

amf0 utest: refine interface of amf0, only export required objects

@@ -57,18 +57,139 @@ using namespace std; @@ -57,18 +57,139 @@ using namespace std;
57 #define RTMP_AMF0_Invalid 0x3F 57 #define RTMP_AMF0_Invalid 0x3F
58 58
59 /** 59 /**
60 -* convert the any to specified object.  
61 -* @return T, the converted object. never NULL.  
62 -* @remark, user must ensure the current object type,  
63 -* or the covert will cause assert failed. 60 +* read amf0 string from stream.
  61 +* 2.4 String Type
  62 +* string-type = string-marker UTF-8
  63 +* @return default value is empty string.
  64 +* @remark: use SrsAmf0Any::str() to create it.
64 */ 65 */
65 -template<class T>  
66 -T srs_amf0_convert(SrsAmf0Any* any) 66 +class __SrsAmf0String : public SrsAmf0Any
67 { 67 {
68 - T p = dynamic_cast<T>(any);  
69 - srs_assert(p != NULL);  
70 - return p;  
71 -} 68 +public:
  69 + std::string value;
  70 +
  71 + __SrsAmf0String(const char* _value);
  72 + virtual ~__SrsAmf0String();
  73 +
  74 + virtual int size();
  75 + virtual int read(SrsStream* stream);
  76 + virtual int write(SrsStream* stream);
  77 +};
  78 +
  79 +/**
  80 +* read amf0 boolean from stream.
  81 +* 2.4 String Type
  82 +* boolean-type = boolean-marker U8
  83 +* 0 is false, <> 0 is true
  84 +* @return default value is false.
  85 +*/
  86 +class __SrsAmf0Boolean : public SrsAmf0Any
  87 +{
  88 +public:
  89 + bool value;
  90 +
  91 + __SrsAmf0Boolean(bool _value);
  92 + virtual ~__SrsAmf0Boolean();
  93 +
  94 + virtual int size();
  95 + virtual int read(SrsStream* stream);
  96 + virtual int write(SrsStream* stream);
  97 +};
  98 +
  99 +/**
  100 +* read amf0 number from stream.
  101 +* 2.2 Number Type
  102 +* number-type = number-marker DOUBLE
  103 +* @return default value is 0.
  104 +*/
  105 +class __SrsAmf0Number : public SrsAmf0Any
  106 +{
  107 +public:
  108 + double value;
  109 +
  110 + __SrsAmf0Number(double _value);
  111 + virtual ~__SrsAmf0Number();
  112 +
  113 + virtual int size();
  114 + virtual int read(SrsStream* stream);
  115 + virtual int write(SrsStream* stream);
  116 +};
  117 +
  118 +/**
  119 +* read amf0 null from stream.
  120 +* 2.7 null Type
  121 +* null-type = null-marker
  122 +*/
  123 +class __SrsAmf0Null : public SrsAmf0Any
  124 +{
  125 +public:
  126 + __SrsAmf0Null();
  127 + virtual ~__SrsAmf0Null();
  128 +
  129 + virtual int size();
  130 + virtual int read(SrsStream* stream);
  131 + virtual int write(SrsStream* stream);
  132 +};
  133 +
  134 +/**
  135 +* read amf0 undefined from stream.
  136 +* 2.8 undefined Type
  137 +* undefined-type = undefined-marker
  138 +*/
  139 +class __SrsAmf0Undefined : public SrsAmf0Any
  140 +{
  141 +public:
  142 + __SrsAmf0Undefined();
  143 + virtual ~__SrsAmf0Undefined();
  144 +
  145 + virtual int size();
  146 + virtual int read(SrsStream* stream);
  147 + virtual int write(SrsStream* stream);
  148 +};
  149 +
  150 +/**
  151 +* to ensure in inserted order.
  152 +* for the FMLE will crash when AMF0Object is not ordered by inserted,
  153 +* if ordered in map, the string compare order, the FMLE will creash when
  154 +* get the response of connect app.
  155 +*/
  156 +class __SrsUnSortedHashtable
  157 +{
  158 +private:
  159 + typedef std::pair<std::string, SrsAmf0Any*> SrsObjectPropertyType;
  160 + std::vector<SrsObjectPropertyType> properties;
  161 +public:
  162 + __SrsUnSortedHashtable();
  163 + virtual ~__SrsUnSortedHashtable();
  164 +
  165 + virtual int size();
  166 + virtual void clear();
  167 + virtual std::string key_at(int index);
  168 + virtual SrsAmf0Any* value_at(int index);
  169 + virtual void set(std::string key, SrsAmf0Any* value);
  170 +
  171 + virtual SrsAmf0Any* get_property(std::string name);
  172 + virtual SrsAmf0Any* ensure_property_string(std::string name);
  173 + virtual SrsAmf0Any* ensure_property_number(std::string name);
  174 +};
  175 +
  176 +/**
  177 +* 2.11 Object End Type
  178 +* object-end-type = UTF-8-empty object-end-marker
  179 +* 0x00 0x00 0x09
  180 +*/
  181 +class __SrsAmf0ObjectEOF : public SrsAmf0Any
  182 +{
  183 +public:
  184 + int16_t utf8_empty;
  185 +
  186 + __SrsAmf0ObjectEOF();
  187 + virtual ~__SrsAmf0ObjectEOF();
  188 +
  189 + virtual int size();
  190 + virtual int read(SrsStream* stream);
  191 + virtual int write(SrsStream* stream);
  192 +};
72 193
73 /** 194 /**
74 * read amf0 utf8 string from stream. 195 * read amf0 utf8 string from stream.
@@ -130,20 +251,37 @@ bool SrsAmf0Any::is_ecma_array() @@ -130,20 +251,37 @@ bool SrsAmf0Any::is_ecma_array()
130 251
131 string SrsAmf0Any::to_str() 252 string SrsAmf0Any::to_str()
132 { 253 {
133 - __SrsAmf0String* o = srs_amf0_convert<__SrsAmf0String*>(this);  
134 - return o->value; 254 + __SrsAmf0String* p = dynamic_cast<__SrsAmf0String*>(this);
  255 + srs_assert(p != NULL);
  256 + return p->value;
135 } 257 }
136 258
137 bool SrsAmf0Any::to_boolean() 259 bool SrsAmf0Any::to_boolean()
138 { 260 {
139 - __SrsAmf0Boolean* o = srs_amf0_convert<__SrsAmf0Boolean*>(this);  
140 - return o->value; 261 + __SrsAmf0Boolean* p = dynamic_cast<__SrsAmf0Boolean*>(this);
  262 + srs_assert(p != NULL);
  263 + return p->value;
141 } 264 }
142 265
143 double SrsAmf0Any::to_number() 266 double SrsAmf0Any::to_number()
144 { 267 {
145 - __SrsAmf0Number* o = srs_amf0_convert<__SrsAmf0Number*>(this);  
146 - return o->value; 268 + __SrsAmf0Number* p = dynamic_cast<__SrsAmf0Number*>(this);
  269 + srs_assert(p != NULL);
  270 + return p->value;
  271 +}
  272 +
  273 +SrsAmf0Object* SrsAmf0Any::to_object()
  274 +{
  275 + SrsAmf0Object* p = dynamic_cast<SrsAmf0Object*>(this);
  276 + srs_assert(p != NULL);
  277 + return p;
  278 +}
  279 +
  280 +SrsAmf0EcmaArray* SrsAmf0Any::to_array()
  281 +{
  282 + SrsAmf0EcmaArray* p = dynamic_cast<SrsAmf0EcmaArray*>(this);
  283 + srs_assert(p != NULL);
  284 + return p;
147 } 285 }
148 286
149 bool SrsAmf0Any::is_object_eof() 287 bool SrsAmf0Any::is_object_eof()
@@ -216,31 +354,31 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue) @@ -216,31 +354,31 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
216 354
217 switch (marker) { 355 switch (marker) {
218 case RTMP_AMF0_String: { 356 case RTMP_AMF0_String: {
219 - *ppvalue = new __SrsAmf0String(); 357 + *ppvalue = SrsAmf0Any::str();
220 return ret; 358 return ret;
221 } 359 }
222 case RTMP_AMF0_Boolean: { 360 case RTMP_AMF0_Boolean: {
223 - *ppvalue = new __SrsAmf0Boolean(); 361 + *ppvalue = SrsAmf0Any::boolean();
224 return ret; 362 return ret;
225 } 363 }
226 case RTMP_AMF0_Number: { 364 case RTMP_AMF0_Number: {
227 - *ppvalue = new __SrsAmf0Number(); 365 + *ppvalue = SrsAmf0Any::number();
228 return ret; 366 return ret;
229 } 367 }
230 case RTMP_AMF0_Null: { 368 case RTMP_AMF0_Null: {
231 - *ppvalue = new __SrsAmf0Null(); 369 + *ppvalue = SrsAmf0Any::null();
232 return ret; 370 return ret;
233 } 371 }
234 case RTMP_AMF0_Undefined: { 372 case RTMP_AMF0_Undefined: {
235 - *ppvalue = new __SrsAmf0Undefined(); 373 + *ppvalue = SrsAmf0Any::undefined();
236 return ret; 374 return ret;
237 } 375 }
238 case RTMP_AMF0_Object: { 376 case RTMP_AMF0_Object: {
239 - *ppvalue = new SrsAmf0Object(); 377 + *ppvalue = SrsAmf0Any::object();
240 return ret; 378 return ret;
241 } 379 }
242 case RTMP_AMF0_EcmaArray: { 380 case RTMP_AMF0_EcmaArray: {
243 - *ppvalue = new SrsAmf0EcmaArray(); 381 + *ppvalue = SrsAmf0Any::array();
244 return ret; 382 return ret;
245 } 383 }
246 case RTMP_AMF0_Invalid: 384 case RTMP_AMF0_Invalid:
@@ -445,11 +583,15 @@ int __SrsAmf0ObjectEOF::write(SrsStream* stream) @@ -445,11 +583,15 @@ int __SrsAmf0ObjectEOF::write(SrsStream* stream)
445 583
446 SrsAmf0Object::SrsAmf0Object() 584 SrsAmf0Object::SrsAmf0Object()
447 { 585 {
  586 + properties = new __SrsUnSortedHashtable();
  587 + eof = new __SrsAmf0ObjectEOF();
448 marker = RTMP_AMF0_Object; 588 marker = RTMP_AMF0_Object;
449 } 589 }
450 590
451 SrsAmf0Object::~SrsAmf0Object() 591 SrsAmf0Object::~SrsAmf0Object()
452 { 592 {
  593 + srs_freep(properties);
  594 + srs_freep(eof);
453 } 595 }
454 596
455 int SrsAmf0Object::read(SrsStream* stream) 597 int SrsAmf0Object::read(SrsStream* stream)
@@ -476,8 +618,8 @@ int SrsAmf0Object::read(SrsStream* stream) @@ -476,8 +618,8 @@ int SrsAmf0Object::read(SrsStream* stream)
476 while (!stream->empty()) { 618 while (!stream->empty()) {
477 // detect whether is eof. 619 // detect whether is eof.
478 if (srs_amf0_is_object_eof(stream)) { 620 if (srs_amf0_is_object_eof(stream)) {
479 - __SrsAmf0ObjectEOF eof;  
480 - if ((ret = eof.read(stream)) != ERROR_SUCCESS) { 621 + __SrsAmf0ObjectEOF pbj_eof;
  622 + if ((ret = pbj_eof.read(stream)) != ERROR_SUCCESS) {
481 srs_error("amf0 object read eof failed. ret=%d", ret); 623 srs_error("amf0 object read eof failed. ret=%d", ret);
482 return ret; 624 return ret;
483 } 625 }
@@ -522,7 +664,7 @@ int SrsAmf0Object::write(SrsStream* stream) @@ -522,7 +664,7 @@ int SrsAmf0Object::write(SrsStream* stream)
522 srs_verbose("amf0 write object marker success"); 664 srs_verbose("amf0 write object marker success");
523 665
524 // value 666 // value
525 - for (int i = 0; i < properties.size(); i++) { 667 + for (int i = 0; i < properties->size(); i++) {
526 std::string name = this->key_at(i); 668 std::string name = this->key_at(i);
527 SrsAmf0Any* any = this->value_at(i); 669 SrsAmf0Any* any = this->value_at(i);
528 670
@@ -539,7 +681,7 @@ int SrsAmf0Object::write(SrsStream* stream) @@ -539,7 +681,7 @@ int SrsAmf0Object::write(SrsStream* stream)
539 srs_verbose("write amf0 property success. name=%s", name.c_str()); 681 srs_verbose("write amf0 property success. name=%s", name.c_str());
540 } 682 }
541 683
542 - if ((ret = eof.write(stream)) != ERROR_SUCCESS) { 684 + if ((ret = eof->write(stream)) != ERROR_SUCCESS) {
543 srs_error("write object eof failed. ret=%d", ret); 685 srs_error("write object eof failed. ret=%d", ret);
544 return ret; 686 return ret;
545 } 687 }
@@ -553,7 +695,7 @@ int SrsAmf0Object::size() @@ -553,7 +695,7 @@ int SrsAmf0Object::size()
553 { 695 {
554 int size = 1; 696 int size = 1;
555 697
556 - for (int i = 0; i < properties.size(); i++){ 698 + for (int i = 0; i < properties->size(); i++){
557 std::string name = key_at(i); 699 std::string name = key_at(i);
558 SrsAmf0Any* value = value_at(i); 700 SrsAmf0Any* value = value_at(i);
559 701
@@ -568,41 +710,45 @@ int SrsAmf0Object::size() @@ -568,41 +710,45 @@ int SrsAmf0Object::size()
568 710
569 std::string SrsAmf0Object::key_at(int index) 711 std::string SrsAmf0Object::key_at(int index)
570 { 712 {
571 - return properties.key_at(index); 713 + return properties->key_at(index);
572 } 714 }
573 715
574 SrsAmf0Any* SrsAmf0Object::value_at(int index) 716 SrsAmf0Any* SrsAmf0Object::value_at(int index)
575 { 717 {
576 - return properties.value_at(index); 718 + return properties->value_at(index);
577 } 719 }
578 720
579 void SrsAmf0Object::set(std::string key, SrsAmf0Any* value) 721 void SrsAmf0Object::set(std::string key, SrsAmf0Any* value)
580 { 722 {
581 - properties.set(key, value); 723 + properties->set(key, value);
582 } 724 }
583 725
584 SrsAmf0Any* SrsAmf0Object::get_property(std::string name) 726 SrsAmf0Any* SrsAmf0Object::get_property(std::string name)
585 { 727 {
586 - return properties.get_property(name); 728 + return properties->get_property(name);
587 } 729 }
588 730
589 SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) 731 SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)
590 { 732 {
591 - return properties.ensure_property_string(name); 733 + return properties->ensure_property_string(name);
592 } 734 }
593 735
594 SrsAmf0Any* SrsAmf0Object::ensure_property_number(std::string name) 736 SrsAmf0Any* SrsAmf0Object::ensure_property_number(std::string name)
595 { 737 {
596 - return properties.ensure_property_number(name); 738 + return properties->ensure_property_number(name);
597 } 739 }
598 740
599 SrsAmf0EcmaArray::SrsAmf0EcmaArray() 741 SrsAmf0EcmaArray::SrsAmf0EcmaArray()
600 { 742 {
  743 + properties = new __SrsUnSortedHashtable();
  744 + eof = new __SrsAmf0ObjectEOF();
601 marker = RTMP_AMF0_EcmaArray; 745 marker = RTMP_AMF0_EcmaArray;
602 } 746 }
603 747
604 SrsAmf0EcmaArray::~SrsAmf0EcmaArray() 748 SrsAmf0EcmaArray::~SrsAmf0EcmaArray()
605 { 749 {
  750 + srs_freep(properties);
  751 + srs_freep(eof);
606 } 752 }
607 753
608 int SrsAmf0EcmaArray::read(SrsStream* stream) 754 int SrsAmf0EcmaArray::read(SrsStream* stream)
@@ -641,8 +787,8 @@ int SrsAmf0EcmaArray::read(SrsStream* stream) @@ -641,8 +787,8 @@ int SrsAmf0EcmaArray::read(SrsStream* stream)
641 while (!stream->empty()) { 787 while (!stream->empty()) {
642 // detect whether is eof. 788 // detect whether is eof.
643 if (srs_amf0_is_object_eof(stream)) { 789 if (srs_amf0_is_object_eof(stream)) {
644 - __SrsAmf0ObjectEOF eof;  
645 - if ((ret = eof.read(stream)) != ERROR_SUCCESS) { 790 + __SrsAmf0ObjectEOF pbj_eof;
  791 + if ((ret = pbj_eof.read(stream)) != ERROR_SUCCESS) {
646 srs_error("amf0 ecma_array read eof failed. ret=%d", ret); 792 srs_error("amf0 ecma_array read eof failed. ret=%d", ret);
647 return ret; 793 return ret;
648 } 794 }
@@ -695,7 +841,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream) @@ -695,7 +841,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream)
695 srs_verbose("amf0 write ecma_array count success. count=%d", value->count); 841 srs_verbose("amf0 write ecma_array count success. count=%d", value->count);
696 842
697 // value 843 // value
698 - for (int i = 0; i < properties.size(); i++) { 844 + for (int i = 0; i < properties->size(); i++) {
699 std::string name = this->key_at(i); 845 std::string name = this->key_at(i);
700 SrsAmf0Any* any = this->value_at(i); 846 SrsAmf0Any* any = this->value_at(i);
701 847
@@ -712,7 +858,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream) @@ -712,7 +858,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream)
712 srs_verbose("write amf0 property success. name=%s", name.c_str()); 858 srs_verbose("write amf0 property success. name=%s", name.c_str());
713 } 859 }
714 860
715 - if ((ret = eof.write(stream)) != ERROR_SUCCESS) { 861 + if ((ret = eof->write(stream)) != ERROR_SUCCESS) {
716 srs_error("write ecma_array eof failed. ret=%d", ret); 862 srs_error("write ecma_array eof failed. ret=%d", ret);
717 return ret; 863 return ret;
718 } 864 }
@@ -726,7 +872,7 @@ int SrsAmf0EcmaArray::size() @@ -726,7 +872,7 @@ int SrsAmf0EcmaArray::size()
726 { 872 {
727 int size = 1 + 4; 873 int size = 1 + 4;
728 874
729 - for (int i = 0; i < properties.size(); i++){ 875 + for (int i = 0; i < properties->size(); i++){
730 std::string name = key_at(i); 876 std::string name = key_at(i);
731 SrsAmf0Any* value = value_at(i); 877 SrsAmf0Any* value = value_at(i);
732 878
@@ -741,32 +887,32 @@ int SrsAmf0EcmaArray::size() @@ -741,32 +887,32 @@ int SrsAmf0EcmaArray::size()
741 887
742 void SrsAmf0EcmaArray::clear() 888 void SrsAmf0EcmaArray::clear()
743 { 889 {
744 - properties.clear(); 890 + properties->clear();
745 } 891 }
746 892
747 std::string SrsAmf0EcmaArray::key_at(int index) 893 std::string SrsAmf0EcmaArray::key_at(int index)
748 { 894 {
749 - return properties.key_at(index); 895 + return properties->key_at(index);
750 } 896 }
751 897
752 SrsAmf0Any* SrsAmf0EcmaArray::value_at(int index) 898 SrsAmf0Any* SrsAmf0EcmaArray::value_at(int index)
753 { 899 {
754 - return properties.value_at(index); 900 + return properties->value_at(index);
755 } 901 }
756 902
757 void SrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value) 903 void SrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value)
758 { 904 {
759 - properties.set(key, value); 905 + properties->set(key, value);
760 } 906 }
761 907
762 SrsAmf0Any* SrsAmf0EcmaArray::get_property(std::string name) 908 SrsAmf0Any* SrsAmf0EcmaArray::get_property(std::string name)
763 { 909 {
764 - return properties.get_property(name); 910 + return properties->get_property(name);
765 } 911 }
766 912
767 SrsAmf0Any* SrsAmf0EcmaArray::ensure_property_string(std::string name) 913 SrsAmf0Any* SrsAmf0EcmaArray::ensure_property_string(std::string name)
768 { 914 {
769 - return properties.ensure_property_string(name); 915 + return properties->ensure_property_string(name);
770 } 916 }
771 917
772 int SrsAmf0Size::utf8(string value) 918 int SrsAmf0Size::utf8(string value)
@@ -1353,7 +1499,7 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) @@ -1353,7 +1499,7 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)
1353 { 1499 {
1354 int ret = ERROR_SUCCESS; 1500 int ret = ERROR_SUCCESS;
1355 1501
1356 - value = new SrsAmf0Object(); 1502 + value = SrsAmf0Any::object();
1357 1503
1358 if ((ret = value->read(stream)) != ERROR_SUCCESS) { 1504 if ((ret = value->read(stream)) != ERROR_SUCCESS) {
1359 srs_freep(value); 1505 srs_freep(value);
@@ -1371,7 +1517,7 @@ int srs_amf0_read_ecma_array(SrsStream* stream, SrsAmf0EcmaArray*& value) @@ -1371,7 +1517,7 @@ int srs_amf0_read_ecma_array(SrsStream* stream, SrsAmf0EcmaArray*& value)
1371 { 1517 {
1372 int ret = ERROR_SUCCESS; 1518 int ret = ERROR_SUCCESS;
1373 1519
1374 - value = new SrsAmf0EcmaArray(); 1520 + value = SrsAmf0Any::array();
1375 1521
1376 if ((ret = value->read(stream)) != ERROR_SUCCESS) { 1522 if ((ret = value->read(stream)) != ERROR_SUCCESS) {
1377 srs_freep(value); 1523 srs_freep(value);
@@ -36,6 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,6 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 class SrsStream; 36 class SrsStream;
37 class SrsAmf0Object; 37 class SrsAmf0Object;
38 class SrsAmf0EcmaArray; 38 class SrsAmf0EcmaArray;
  39 +class __SrsUnSortedHashtable;
  40 +class __SrsAmf0ObjectEOF;
39 41
40 //////////////////////////////////////////////////////////////////////// 42 ////////////////////////////////////////////////////////////////////////
41 //////////////////////////////////////////////////////////////////////// 43 ////////////////////////////////////////////////////////////////////////
@@ -46,21 +48,20 @@ class SrsAmf0EcmaArray; @@ -46,21 +48,20 @@ class SrsAmf0EcmaArray;
46 // if ((ret = srs_amf0_read_any(stream, &pany)) != ERROR_SUCCESS) { 48 // if ((ret = srs_amf0_read_any(stream, &pany)) != ERROR_SUCCESS) {
47 // return ret; 49 // return ret;
48 // } 50 // }
  51 +// srs_assert(pany); // if success, always valid object.
49 // 2. SrsAmf0Any: convert to specifid type, for instance, string 52 // 2. SrsAmf0Any: convert to specifid type, for instance, string
50 // SrsAmf0Any* pany = ... 53 // SrsAmf0Any* pany = ...
51 -// if (pany && pany->is_string()) { 54 +// if (pany->is_string()) {
52 // string v = pany->to_str(); 55 // string v = pany->to_str();
53 // } 56 // }
54 // 3. SrsAmf0Any: parse specified type to any, for instance, string 57 // 3. SrsAmf0Any: parse specified type to any, for instance, string
55 // SrsAmf0Any* pany = SrsAmf0Any::str("winlin"); 58 // SrsAmf0Any* pany = SrsAmf0Any::str("winlin");
56 // 4. SrsAmf0Size: get amf0 instance size 59 // 4. SrsAmf0Size: get amf0 instance size
57 // int size = SrsAmf0Size::str("winlin"); 60 // int size = SrsAmf0Size::str("winlin");
58 -// 5. SrsAmf0Object: the amf0 object, directly new is ok. 61 +// 5. SrsAmf0Object: the amf0 object.
59 // SrsAmf0Object* obj = SrsAmf0Any::object(); 62 // SrsAmf0Object* obj = SrsAmf0Any::object();
60 -// SrsAmf0Object* obj = new SrsAmf0Object();  
61 -// 5. SrsAmf0EcmaArray: the amf0 ecma array, directly new is ok. 63 +// 5. SrsAmf0EcmaArray: the amf0 ecma array.
62 // SrsAmf0EcmaArray* arr = SrsAmf0Any::array(); 64 // SrsAmf0EcmaArray* arr = SrsAmf0Any::array();
63 -// SrsAmf0EcmaArray* arr = new SrsAmf0EcmaArray();  
64 // for detail usage, see interfaces of each object. 65 // for detail usage, see interfaces of each object.
65 //////////////////////////////////////////////////////////////////////// 66 ////////////////////////////////////////////////////////////////////////
66 //////////////////////////////////////////////////////////////////////// 67 ////////////////////////////////////////////////////////////////////////
@@ -106,6 +107,16 @@ public: @@ -106,6 +107,16 @@ public:
106 * user must ensure the type is a number, or assert failed. 107 * user must ensure the type is a number, or assert failed.
107 */ 108 */
108 virtual double to_number(); 109 virtual double to_number();
  110 + /**
  111 + * get the object of any when is_object() indicates true.
  112 + * user must ensure the type is a object, or assert failed.
  113 + */
  114 + virtual SrsAmf0Object* to_object();
  115 + /**
  116 + * get the ecma array of any when is_ecma_array() indicates true.
  117 + * user must ensure the type is a ecma array, or assert failed.
  118 + */
  119 + virtual SrsAmf0EcmaArray* to_array();
109 public: 120 public:
110 /** 121 /**
111 * get the size of amf0 any, including the marker size. 122 * get the size of amf0 any, including the marker size.
@@ -130,50 +141,6 @@ public: @@ -130,50 +141,6 @@ public:
130 }; 141 };
131 142
132 /** 143 /**
133 -* to ensure in inserted order.  
134 -* for the FMLE will crash when AMF0Object is not ordered by inserted,  
135 -* if ordered in map, the string compare order, the FMLE will creash when  
136 -* get the response of connect app.  
137 -*/  
138 -class __SrsUnSortedHashtable  
139 -{  
140 -private:  
141 - typedef std::pair<std::string, SrsAmf0Any*> SrsObjectPropertyType;  
142 - std::vector<SrsObjectPropertyType> properties;  
143 -public:  
144 - __SrsUnSortedHashtable();  
145 - virtual ~__SrsUnSortedHashtable();  
146 -  
147 - virtual int size();  
148 - virtual void clear();  
149 - virtual std::string key_at(int index);  
150 - virtual SrsAmf0Any* value_at(int index);  
151 - virtual void set(std::string key, SrsAmf0Any* value);  
152 -  
153 - virtual SrsAmf0Any* get_property(std::string name);  
154 - virtual SrsAmf0Any* ensure_property_string(std::string name);  
155 - virtual SrsAmf0Any* ensure_property_number(std::string name);  
156 -};  
157 -  
158 -/**  
159 -* 2.11 Object End Type  
160 -* object-end-type = UTF-8-empty object-end-marker  
161 -* 0x00 0x00 0x09  
162 -*/  
163 -class __SrsAmf0ObjectEOF : public SrsAmf0Any  
164 -{  
165 -public:  
166 - int16_t utf8_empty;  
167 -  
168 - __SrsAmf0ObjectEOF();  
169 - virtual ~__SrsAmf0ObjectEOF();  
170 -  
171 - virtual int size();  
172 - virtual int read(SrsStream* stream);  
173 - virtual int write(SrsStream* stream);  
174 -};  
175 -  
176 -/**  
177 * 2.5 Object Type 144 * 2.5 Object Type
178 * anonymous-object-type = object-marker *(object-property) 145 * anonymous-object-type = object-marker *(object-property)
179 * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) 146 * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
@@ -181,11 +148,14 @@ public: @@ -181,11 +148,14 @@ public:
181 class SrsAmf0Object : public SrsAmf0Any 148 class SrsAmf0Object : public SrsAmf0Any
182 { 149 {
183 private: 150 private:
184 - __SrsUnSortedHashtable properties;  
185 -public:  
186 - __SrsAmf0ObjectEOF eof; 151 + __SrsUnSortedHashtable* properties;
  152 + __SrsAmf0ObjectEOF* eof;
187 153
  154 +private:
  155 + // use SrsAmf0Any::object() to create it.
  156 + friend class SrsAmf0Any;
188 SrsAmf0Object(); 157 SrsAmf0Object();
  158 +public:
189 virtual ~SrsAmf0Object(); 159 virtual ~SrsAmf0Object();
190 160
191 virtual int read(SrsStream* stream); 161 virtual int read(SrsStream* stream);
@@ -210,12 +180,15 @@ public: @@ -210,12 +180,15 @@ public:
210 class SrsAmf0EcmaArray : public SrsAmf0Any 180 class SrsAmf0EcmaArray : public SrsAmf0Any
211 { 181 {
212 private: 182 private:
213 - __SrsUnSortedHashtable properties;  
214 -public: 183 + __SrsUnSortedHashtable* properties;
  184 + __SrsAmf0ObjectEOF* eof;
215 int32_t count; 185 int32_t count;
216 - __SrsAmf0ObjectEOF eof;  
217 186
  187 +private:
  188 + // use SrsAmf0Any::array() to create it.
  189 + friend class SrsAmf0Any;
218 SrsAmf0EcmaArray(); 190 SrsAmf0EcmaArray();
  191 +public:
219 virtual ~SrsAmf0EcmaArray(); 192 virtual ~SrsAmf0EcmaArray();
220 193
221 virtual int read(SrsStream* stream); 194 virtual int read(SrsStream* stream);
@@ -250,98 +223,9 @@ public: @@ -250,98 +223,9 @@ public:
250 }; 223 };
251 224
252 /** 225 /**
253 -* read amf0 string from stream.  
254 -* 2.4 String Type  
255 -* string-type = string-marker UTF-8  
256 -* @return default value is empty string.  
257 -* @remark: use SrsAmf0Any::str() to create it.  
258 -*/  
259 -class __SrsAmf0String : public SrsAmf0Any  
260 -{  
261 -public:  
262 - std::string value;  
263 -  
264 - __SrsAmf0String(const char* _value = NULL);  
265 - virtual ~__SrsAmf0String();  
266 -  
267 - virtual int size();  
268 - virtual int read(SrsStream* stream);  
269 - virtual int write(SrsStream* stream);  
270 -};  
271 -  
272 -/**  
273 -* read amf0 boolean from stream.  
274 -* 2.4 String Type  
275 -* boolean-type = boolean-marker U8  
276 -* 0 is false, <> 0 is true  
277 -* @return default value is false.  
278 -*/  
279 -class __SrsAmf0Boolean : public SrsAmf0Any  
280 -{  
281 -public:  
282 - bool value;  
283 -  
284 - __SrsAmf0Boolean(bool _value = false);  
285 - virtual ~__SrsAmf0Boolean();  
286 -  
287 - virtual int size();  
288 - virtual int read(SrsStream* stream);  
289 - virtual int write(SrsStream* stream);  
290 -};  
291 -  
292 -/**  
293 -* read amf0 number from stream.  
294 -* 2.2 Number Type  
295 -* number-type = number-marker DOUBLE  
296 -* @return default value is 0.  
297 -*/  
298 -class __SrsAmf0Number : public SrsAmf0Any  
299 -{  
300 -public:  
301 - double value;  
302 -  
303 - __SrsAmf0Number(double _value = 0.0);  
304 - virtual ~__SrsAmf0Number();  
305 -  
306 - virtual int size();  
307 - virtual int read(SrsStream* stream);  
308 - virtual int write(SrsStream* stream);  
309 -};  
310 -  
311 -/**  
312 -* read amf0 null from stream.  
313 -* 2.7 null Type  
314 -* null-type = null-marker  
315 -*/  
316 -class __SrsAmf0Null : public SrsAmf0Any  
317 -{  
318 -public:  
319 - __SrsAmf0Null();  
320 - virtual ~__SrsAmf0Null();  
321 -  
322 - virtual int size();  
323 - virtual int read(SrsStream* stream);  
324 - virtual int write(SrsStream* stream);  
325 -};  
326 -  
327 -/**  
328 -* read amf0 undefined from stream.  
329 -* 2.8 undefined Type  
330 -* undefined-type = undefined-marker  
331 -*/  
332 -class __SrsAmf0Undefined : public SrsAmf0Any  
333 -{  
334 -public:  
335 - __SrsAmf0Undefined();  
336 - virtual ~__SrsAmf0Undefined();  
337 -  
338 - virtual int size();  
339 - virtual int read(SrsStream* stream);  
340 - virtual int write(SrsStream* stream);  
341 -};  
342 -  
343 -/**  
344 * read anything from stream. 226 * read anything from stream.
  227 +* @param ppvalue, the output amf0 any elem.
  228 +* NULL if error; otherwise, never NULL and user must free it.
345 */ 229 */
346 extern int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any** ppvalue); 230 extern int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any** ppvalue);
347 231
@@ -279,7 +279,7 @@ int SrsRtmpClient::connect_app(string app, string tc_url) @@ -279,7 +279,7 @@ int SrsRtmpClient::connect_app(string app, string tc_url)
279 SrsConnectAppPacket* pkt = new SrsConnectAppPacket(); 279 SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
280 msg->set_packet(pkt, 0); 280 msg->set_packet(pkt, 0);
281 281
282 - pkt->command_object = new SrsAmf0Object(); 282 + pkt->command_object = SrsAmf0Any::object();
283 pkt->command_object->set("app", SrsAmf0Any::str(app.c_str())); 283 pkt->command_object->set("app", SrsAmf0Any::str(app.c_str()));
284 pkt->command_object->set("swfUrl", SrsAmf0Any::str()); 284 pkt->command_object->set("swfUrl", SrsAmf0Any::str());
285 pkt->command_object->set("tcUrl", SrsAmf0Any::str(tc_url.c_str())); 285 pkt->command_object->set("tcUrl", SrsAmf0Any::str(tc_url.c_str()));
@@ -706,7 +706,7 @@ int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip) @@ -706,7 +706,7 @@ int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip)
706 pkt->info->set(StatusCode, SrsAmf0Any::str(StatusCodeConnectSuccess)); 706 pkt->info->set(StatusCode, SrsAmf0Any::str(StatusCodeConnectSuccess));
707 pkt->info->set(StatusDescription, SrsAmf0Any::str("Connection succeeded")); 707 pkt->info->set(StatusDescription, SrsAmf0Any::str("Connection succeeded"));
708 pkt->info->set("objectEncoding", SrsAmf0Any::number(req->objectEncoding)); 708 pkt->info->set("objectEncoding", SrsAmf0Any::number(req->objectEncoding));
709 - SrsAmf0EcmaArray* data = new SrsAmf0EcmaArray(); 709 + SrsAmf0EcmaArray* data = SrsAmf0Any::array();
710 pkt->info->set("data", data); 710 pkt->info->set("data", data);
711 711
712 data->set("version", SrsAmf0Any::str(RTMP_SIG_FMS_VER)); 712 data->set("version", SrsAmf0Any::str(RTMP_SIG_FMS_VER));
@@ -1828,8 +1828,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket() @@ -1828,8 +1828,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket()
1828 transaction_id = 1; 1828 transaction_id = 1;
1829 // TODO: FIXME: memory leak for decode will set the props and info. 1829 // TODO: FIXME: memory leak for decode will set the props and info.
1830 // TODO: FIXME: bug#22, refine the amf0. 1830 // TODO: FIXME: bug#22, refine the amf0.
1831 - props = new SrsAmf0Object();  
1832 - info = new SrsAmf0Object(); 1831 + props = SrsAmf0Any::object();
  1832 + info = SrsAmf0Any::object();
1833 } 1833 }
1834 1834
1835 SrsConnectAppResPacket::~SrsConnectAppResPacket() 1835 SrsConnectAppResPacket::~SrsConnectAppResPacket()
@@ -2718,7 +2718,7 @@ SrsPlayResPacket::SrsPlayResPacket() @@ -2718,7 +2718,7 @@ SrsPlayResPacket::SrsPlayResPacket()
2718 command_name = RTMP_AMF0_COMMAND_RESULT; 2718 command_name = RTMP_AMF0_COMMAND_RESULT;
2719 transaction_id = 0; 2719 transaction_id = 0;
2720 command_object = SrsAmf0Any::null(); 2720 command_object = SrsAmf0Any::null();
2721 - desc = new SrsAmf0Object(); 2721 + desc = SrsAmf0Any::object();
2722 } 2722 }
2723 2723
2724 SrsPlayResPacket::~SrsPlayResPacket() 2724 SrsPlayResPacket::~SrsPlayResPacket()
@@ -2837,7 +2837,7 @@ SrsOnStatusCallPacket::SrsOnStatusCallPacket() @@ -2837,7 +2837,7 @@ SrsOnStatusCallPacket::SrsOnStatusCallPacket()
2837 command_name = RTMP_AMF0_COMMAND_ON_STATUS; 2837 command_name = RTMP_AMF0_COMMAND_ON_STATUS;
2838 transaction_id = 0; 2838 transaction_id = 0;
2839 args = SrsAmf0Any::null(); 2839 args = SrsAmf0Any::null();
2840 - data = new SrsAmf0Object(); 2840 + data = SrsAmf0Any::object();
2841 } 2841 }
2842 2842
2843 SrsOnStatusCallPacket::~SrsOnStatusCallPacket() 2843 SrsOnStatusCallPacket::~SrsOnStatusCallPacket()
@@ -2900,7 +2900,7 @@ SrsBandwidthPacket::SrsBandwidthPacket() @@ -2900,7 +2900,7 @@ SrsBandwidthPacket::SrsBandwidthPacket()
2900 command_name = RTMP_AMF0_COMMAND_ON_STATUS; 2900 command_name = RTMP_AMF0_COMMAND_ON_STATUS;
2901 transaction_id = 0; 2901 transaction_id = 0;
2902 args = SrsAmf0Any::null(); 2902 args = SrsAmf0Any::null();
2903 - data = new SrsAmf0Object(); 2903 + data = SrsAmf0Any::object();
2904 } 2904 }
2905 2905
2906 SrsBandwidthPacket::~SrsBandwidthPacket() 2906 SrsBandwidthPacket::~SrsBandwidthPacket()
@@ -3055,7 +3055,7 @@ SrsBandwidthPacket* SrsBandwidthPacket::set_command(string command) @@ -3055,7 +3055,7 @@ SrsBandwidthPacket* SrsBandwidthPacket::set_command(string command)
3055 SrsOnStatusDataPacket::SrsOnStatusDataPacket() 3055 SrsOnStatusDataPacket::SrsOnStatusDataPacket()
3056 { 3056 {
3057 command_name = RTMP_AMF0_COMMAND_ON_STATUS; 3057 command_name = RTMP_AMF0_COMMAND_ON_STATUS;
3058 - data = new SrsAmf0Object(); 3058 + data = SrsAmf0Any::object();
3059 } 3059 }
3060 3060
3061 SrsOnStatusDataPacket::~SrsOnStatusDataPacket() 3061 SrsOnStatusDataPacket::~SrsOnStatusDataPacket()
@@ -3156,7 +3156,7 @@ int SrsSampleAccessPacket::encode_packet(SrsStream* stream) @@ -3156,7 +3156,7 @@ int SrsSampleAccessPacket::encode_packet(SrsStream* stream)
3156 SrsOnMetaDataPacket::SrsOnMetaDataPacket() 3156 SrsOnMetaDataPacket::SrsOnMetaDataPacket()
3157 { 3157 {
3158 name = RTMP_AMF0_DATA_ON_METADATA; 3158 name = RTMP_AMF0_DATA_ON_METADATA;
3159 - metadata = new SrsAmf0Object(); 3159 + metadata = SrsAmf0Any::object();
3160 } 3160 }
3161 3161
3162 SrsOnMetaDataPacket::~SrsOnMetaDataPacket() 3162 SrsOnMetaDataPacket::~SrsOnMetaDataPacket()
@@ -3190,27 +3190,27 @@ int SrsOnMetaDataPacket::decode(SrsStream* stream) @@ -3190,27 +3190,27 @@ int SrsOnMetaDataPacket::decode(SrsStream* stream)
3190 return ret; 3190 return ret;
3191 } 3191 }
3192 3192
3193 - if (any && any->is_object()) { 3193 + srs_assert(any);
  3194 + if (any->is_object()) {
3194 srs_freep(metadata); 3195 srs_freep(metadata);
3195 - metadata = dynamic_cast<SrsAmf0Object*>(any); 3196 + metadata = any->to_object();
3196 srs_info("decode metadata object success"); 3197 srs_info("decode metadata object success");
3197 return ret; 3198 return ret;
3198 } 3199 }
3199 3200
3200 - SrsAmf0EcmaArray* arr = dynamic_cast<SrsAmf0EcmaArray*>(any);  
3201 - if (!arr) {  
3202 - ret = ERROR_RTMP_AMF0_DECODE;  
3203 - srs_error("decode metadata array failed. ret=%d", ret);  
3204 - return ret;  
3205 - } 3201 + SrsAutoFree(SrsAmf0Any, any, false);
3206 3202
3207 - // if ecma array, copy to object.  
3208 - SrsAutoFree(SrsAmf0EcmaArray, arr, false);  
3209 - for (int i = 0; i < arr->size(); i++) {  
3210 - metadata->set(arr->key_at(i), arr->value_at(i)); 3203 + if (any->is_ecma_array()) {
  3204 + SrsAmf0EcmaArray* arr = any->to_array();
  3205 +
  3206 + // if ecma array, copy to object.
  3207 + for (int i = 0; i < arr->size(); i++) {
  3208 + metadata->set(arr->key_at(i), arr->value_at(i));
  3209 + }
  3210 +
  3211 + arr->clear();
  3212 + srs_info("decode metadata array success");
3211 } 3213 }
3212 - arr->clear();  
3213 - srs_info("decode metadata array success");  
3214 3214
3215 return ret; 3215 return ret;
3216 } 3216 }
@@ -46,221 +46,239 @@ VOID TEST(AMF0Test, Size) @@ -46,221 +46,239 @@ VOID TEST(AMF0Test, Size)
46 // object: empty 46 // object: empty
47 if (true) { 47 if (true) {
48 int size = 1+3; 48 int size = 1+3;
49 - SrsAmf0Object o; 49 + SrsAmf0Object* o = SrsAmf0Any::object();
  50 + SrsAutoFree(SrsAmf0Object, o, false);
50 51
51 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 52 + EXPECT_EQ(size, SrsAmf0Size::object(o));
52 } 53 }
53 // object: elem 54 // object: elem
54 if (true) { 55 if (true) {
55 int size = 1+3; 56 int size = 1+3;
56 - SrsAmf0Object o; 57 + SrsAmf0Object* o = SrsAmf0Any::object();
  58 + SrsAutoFree(SrsAmf0Object, o, false);
57 59
58 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 60 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
59 - o.set("name", SrsAmf0Any::str("winlin")); 61 + o->set("name", SrsAmf0Any::str("winlin"));
60 62
61 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 63 + EXPECT_EQ(size, SrsAmf0Size::object(o));
62 } 64 }
63 if (true) { 65 if (true) {
64 int size = 1+3; 66 int size = 1+3;
65 - SrsAmf0Object o; 67 + SrsAmf0Object* o = SrsAmf0Any::object();
  68 + SrsAutoFree(SrsAmf0Object, o, false);
66 69
67 size += SrsAmf0Size::utf8("age")+SrsAmf0Size::number(); 70 size += SrsAmf0Size::utf8("age")+SrsAmf0Size::number();
68 - o.set("age", SrsAmf0Any::number(9)); 71 + o->set("age", SrsAmf0Any::number(9));
69 72
70 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 73 + EXPECT_EQ(size, SrsAmf0Size::object(o));
71 } 74 }
72 if (true) { 75 if (true) {
73 int size = 1+3; 76 int size = 1+3;
74 - SrsAmf0Object o; 77 + SrsAmf0Object* o = SrsAmf0Any::object();
  78 + SrsAutoFree(SrsAmf0Object, o, false);
75 79
76 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::null(); 80 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::null();
77 - o.set("email", SrsAmf0Any::null()); 81 + o->set("email", SrsAmf0Any::null());
78 82
79 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 83 + EXPECT_EQ(size, SrsAmf0Size::object(o));
80 } 84 }
81 if (true) { 85 if (true) {
82 int size = 1+3; 86 int size = 1+3;
83 - SrsAmf0Object o; 87 + SrsAmf0Object* o = SrsAmf0Any::object();
  88 + SrsAutoFree(SrsAmf0Object, o, false);
84 89
85 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::undefined(); 90 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::undefined();
86 - o.set("email", SrsAmf0Any::undefined()); 91 + o->set("email", SrsAmf0Any::undefined());
87 92
88 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 93 + EXPECT_EQ(size, SrsAmf0Size::object(o));
89 } 94 }
90 if (true) { 95 if (true) {
91 int size = 1+3; 96 int size = 1+3;
92 - SrsAmf0Object o; 97 + SrsAmf0Object* o = SrsAmf0Any::object();
  98 + SrsAutoFree(SrsAmf0Object, o, false);
93 99
94 size += SrsAmf0Size::utf8("sex")+SrsAmf0Size::boolean(); 100 size += SrsAmf0Size::utf8("sex")+SrsAmf0Size::boolean();
95 - o.set("sex", SrsAmf0Any::boolean(true)); 101 + o->set("sex", SrsAmf0Any::boolean(true));
96 102
97 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 103 + EXPECT_EQ(size, SrsAmf0Size::object(o));
98 } 104 }
99 105
100 // array: empty 106 // array: empty
101 if (true) { 107 if (true) {
102 int size = 1+4+3; 108 int size = 1+4+3;
103 - SrsAmf0EcmaArray o; 109 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  110 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
104 111
105 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 112 + EXPECT_EQ(size, SrsAmf0Size::array(o));
106 } 113 }
107 // array: elem 114 // array: elem
108 if (true) { 115 if (true) {
109 int size = 1+4+3; 116 int size = 1+4+3;
110 - SrsAmf0EcmaArray o; 117 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  118 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
111 119
112 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 120 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
113 - o.set("name", SrsAmf0Any::str("winlin")); 121 + o->set("name", SrsAmf0Any::str("winlin"));
114 122
115 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 123 + EXPECT_EQ(size, SrsAmf0Size::array(o));
116 } 124 }
117 if (true) { 125 if (true) {
118 int size = 1+4+3; 126 int size = 1+4+3;
119 - SrsAmf0EcmaArray o; 127 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  128 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
120 129
121 size += SrsAmf0Size::utf8("age")+SrsAmf0Size::number(); 130 size += SrsAmf0Size::utf8("age")+SrsAmf0Size::number();
122 - o.set("age", SrsAmf0Any::number(9)); 131 + o->set("age", SrsAmf0Any::number(9));
123 132
124 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 133 + EXPECT_EQ(size, SrsAmf0Size::array(o));
125 } 134 }
126 if (true) { 135 if (true) {
127 int size = 1+4+3; 136 int size = 1+4+3;
128 - SrsAmf0EcmaArray o; 137 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  138 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
129 139
130 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::null(); 140 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::null();
131 - o.set("email", SrsAmf0Any::null()); 141 + o->set("email", SrsAmf0Any::null());
132 142
133 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 143 + EXPECT_EQ(size, SrsAmf0Size::array(o));
134 } 144 }
135 if (true) { 145 if (true) {
136 int size = 1+4+3; 146 int size = 1+4+3;
137 - SrsAmf0EcmaArray o; 147 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  148 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
138 149
139 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::undefined(); 150 size += SrsAmf0Size::utf8("email")+SrsAmf0Size::undefined();
140 - o.set("email", SrsAmf0Any::undefined()); 151 + o->set("email", SrsAmf0Any::undefined());
141 152
142 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 153 + EXPECT_EQ(size, SrsAmf0Size::array(o));
143 } 154 }
144 if (true) { 155 if (true) {
145 int size = 1+4+3; 156 int size = 1+4+3;
146 - SrsAmf0EcmaArray o; 157 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  158 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
147 159
148 size += SrsAmf0Size::utf8("sex")+SrsAmf0Size::boolean(); 160 size += SrsAmf0Size::utf8("sex")+SrsAmf0Size::boolean();
149 - o.set("sex", SrsAmf0Any::boolean(true)); 161 + o->set("sex", SrsAmf0Any::boolean(true));
150 162
151 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 163 + EXPECT_EQ(size, SrsAmf0Size::array(o));
152 } 164 }
153 165
154 // object: array 166 // object: array
155 if (true) { 167 if (true) {
156 int size = 1+3; 168 int size = 1+3;
157 - SrsAmf0Object o; 169 + SrsAmf0Object* o = SrsAmf0Any::object();
  170 + SrsAutoFree(SrsAmf0Object, o, false);
158 171
159 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 172 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
160 - o.set("name", SrsAmf0Any::str("winlin")); 173 + o->set("name", SrsAmf0Any::str("winlin"));
161 174
162 - SrsAmf0EcmaArray* args = new SrsAmf0EcmaArray(); 175 + SrsAmf0EcmaArray* args = SrsAmf0Any::array();
163 args->set("p0", SrsAmf0Any::str("function")); 176 args->set("p0", SrsAmf0Any::str("function"));
164 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::array(args); 177 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::array(args);
165 - o.set("args", args); 178 + o->set("args", args);
166 179
167 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 180 + EXPECT_EQ(size, SrsAmf0Size::object(o));
168 } 181 }
169 if (true) { 182 if (true) {
170 int size = 1+3; 183 int size = 1+3;
171 - SrsAmf0Object o; 184 + SrsAmf0Object* o = SrsAmf0Any::object();
  185 + SrsAutoFree(SrsAmf0Object, o, false);
172 186
173 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 187 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
174 - o.set("name", SrsAmf0Any::str("winlin")); 188 + o->set("name", SrsAmf0Any::str("winlin"));
175 189
176 - SrsAmf0EcmaArray* args = new SrsAmf0EcmaArray(); 190 + SrsAmf0EcmaArray* args = SrsAmf0Any::array();
177 args->set("p0", SrsAmf0Any::str("function")); 191 args->set("p0", SrsAmf0Any::str("function"));
178 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::array(args); 192 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::array(args);
179 - o.set("args", args); 193 + o->set("args", args);
180 194
181 - SrsAmf0EcmaArray* params = new SrsAmf0EcmaArray(); 195 + SrsAmf0EcmaArray* params = SrsAmf0Any::array();
182 params->set("p1", SrsAmf0Any::number(10)); 196 params->set("p1", SrsAmf0Any::number(10));
183 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::array(params); 197 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::array(params);
184 - o.set("params", params); 198 + o->set("params", params);
185 199
186 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 200 + EXPECT_EQ(size, SrsAmf0Size::object(o));
187 } 201 }
188 202
189 // array: object 203 // array: object
190 if (true) { 204 if (true) {
191 int size = 1+4+3; 205 int size = 1+4+3;
192 - SrsAmf0EcmaArray o; 206 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  207 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
193 208
194 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 209 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
195 - o.set("name", SrsAmf0Any::str("winlin")); 210 + o->set("name", SrsAmf0Any::str("winlin"));
196 211
197 - SrsAmf0Object* args = new SrsAmf0Object(); 212 + SrsAmf0Object* args = SrsAmf0Any::object();
198 args->set("p0", SrsAmf0Any::str("function")); 213 args->set("p0", SrsAmf0Any::str("function"));
199 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args); 214 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args);
200 - o.set("args", args); 215 + o->set("args", args);
201 216
202 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 217 + EXPECT_EQ(size, SrsAmf0Size::array(o));
203 } 218 }
204 if (true) { 219 if (true) {
205 int size = 1+4+3; 220 int size = 1+4+3;
206 - SrsAmf0EcmaArray o; 221 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  222 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
207 223
208 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 224 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
209 - o.set("name", SrsAmf0Any::str("winlin")); 225 + o->set("name", SrsAmf0Any::str("winlin"));
210 226
211 - SrsAmf0Object* args = new SrsAmf0Object(); 227 + SrsAmf0Object* args = SrsAmf0Any::object();
212 args->set("p0", SrsAmf0Any::str("function")); 228 args->set("p0", SrsAmf0Any::str("function"));
213 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args); 229 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args);
214 - o.set("args", args); 230 + o->set("args", args);
215 231
216 - SrsAmf0Object* params = new SrsAmf0Object(); 232 + SrsAmf0Object* params = SrsAmf0Any::object();
217 params->set("p1", SrsAmf0Any::number(10)); 233 params->set("p1", SrsAmf0Any::number(10));
218 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::object(params); 234 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::object(params);
219 - o.set("params", params); 235 + o->set("params", params);
220 236
221 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 237 + EXPECT_EQ(size, SrsAmf0Size::array(o));
222 } 238 }
223 239
224 // object: object 240 // object: object
225 if (true) { 241 if (true) {
226 int size = 1+3; 242 int size = 1+3;
227 - SrsAmf0Object o; 243 + SrsAmf0Object* o = SrsAmf0Any::object();
  244 + SrsAutoFree(SrsAmf0Object, o, false);
228 245
229 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 246 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
230 - o.set("name", SrsAmf0Any::str("winlin")); 247 + o->set("name", SrsAmf0Any::str("winlin"));
231 248
232 - SrsAmf0Object* args = new SrsAmf0Object(); 249 + SrsAmf0Object* args = SrsAmf0Any::object();
233 args->set("p0", SrsAmf0Any::str("function")); 250 args->set("p0", SrsAmf0Any::str("function"));
234 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args); 251 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args);
235 - o.set("args", args); 252 + o->set("args", args);
236 253
237 - SrsAmf0Object* params = new SrsAmf0Object(); 254 + SrsAmf0Object* params = SrsAmf0Any::object();
238 params->set("p1", SrsAmf0Any::number(10)); 255 params->set("p1", SrsAmf0Any::number(10));
239 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::object(params); 256 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::object(params);
240 - o.set("params", params); 257 + o->set("params", params);
241 258
242 - EXPECT_EQ(size, SrsAmf0Size::object(&o)); 259 + EXPECT_EQ(size, SrsAmf0Size::object(o));
243 } 260 }
244 261
245 // array: array 262 // array: array
246 if (true) { 263 if (true) {
247 int size = 1+4+3; 264 int size = 1+4+3;
248 - SrsAmf0EcmaArray o; 265 + SrsAmf0EcmaArray* o = SrsAmf0Any::array();
  266 + SrsAutoFree(SrsAmf0EcmaArray, o, false);
249 267
250 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); 268 size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
251 - o.set("name", SrsAmf0Any::str("winlin")); 269 + o->set("name", SrsAmf0Any::str("winlin"));
252 270
253 - SrsAmf0EcmaArray* args = new SrsAmf0EcmaArray(); 271 + SrsAmf0EcmaArray* args = SrsAmf0Any::array();
254 args->set("p0", SrsAmf0Any::str("function")); 272 args->set("p0", SrsAmf0Any::str("function"));
255 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::array(args); 273 size += SrsAmf0Size::utf8("args")+SrsAmf0Size::array(args);
256 - o.set("args", args); 274 + o->set("args", args);
257 275
258 - SrsAmf0EcmaArray* params = new SrsAmf0EcmaArray(); 276 + SrsAmf0EcmaArray* params = SrsAmf0Any::array();
259 params->set("p1", SrsAmf0Any::number(10)); 277 params->set("p1", SrsAmf0Any::number(10));
260 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::array(params); 278 size += SrsAmf0Size::utf8("params")+SrsAmf0Size::array(params);
261 - o.set("params", params); 279 + o->set("params", params);
262 280
263 - EXPECT_EQ(size, SrsAmf0Size::array(&o)); 281 + EXPECT_EQ(size, SrsAmf0Size::array(o));
264 } 282 }
265 } 283 }
266 284
@@ -656,3 +674,24 @@ VOID TEST(AMF0Test, AnyIO) @@ -656,3 +674,24 @@ VOID TEST(AMF0Test, AnyIO)
656 srs_freep(po); 674 srs_freep(po);
657 } 675 }
658 } 676 }
  677 +
  678 +VOID TEST(AMF0Test, AnyAssert)
  679 +{
  680 + SrsStream s;
  681 + SrsAmf0Any* o = NULL;
  682 +
  683 + char buf[1024];
  684 + memset(buf, 0, sizeof(buf));
  685 + EXPECT_EQ(ERROR_SUCCESS, s.initialize(buf, sizeof(buf)));
  686 +
  687 + // read any
  688 + if (true) {
  689 + s.reset();
  690 + s.current()[0] = 0x12;
  691 + EXPECT_NE(ERROR_SUCCESS, srs_amf0_read_any(&s, &o));
  692 + EXPECT_TRUE(NULL == o);
  693 + srs_freep(o);
  694 + }
  695 +
  696 + //
  697 +}