winlin

add comments to amf0

@@ -40,44 +40,76 @@ class SrsAmf0StrictArray; @@ -40,44 +40,76 @@ class SrsAmf0StrictArray;
40 class __SrsUnSortedHashtable; 40 class __SrsUnSortedHashtable;
41 class __SrsAmf0ObjectEOF; 41 class __SrsAmf0ObjectEOF;
42 42
  43 +/*
43 //////////////////////////////////////////////////////////////////////// 44 ////////////////////////////////////////////////////////////////////////
44 //////////////////////////////////////////////////////////////////////// 45 ////////////////////////////////////////////////////////////////////////
45 //////////////////////////////////////////////////////////////////////// 46 ////////////////////////////////////////////////////////////////////////
46 -// amf0 codec  
47 -// 1. SrsAmf0Any: read any from stream  
48 -// SrsAmf0Any* pany = NULL;  
49 -// if ((ret = srs_amf0_read_any(stream, &pany)) != ERROR_SUCCESS) {  
50 -// return ret;  
51 -// }  
52 -// srs_assert(pany); // if success, always valid object.  
53 -// 2. SrsAmf0Any: convert to specifid type, for instance, string  
54 -// SrsAmf0Any* pany = ...  
55 -// if (pany->is_string()) {  
56 -// string v = pany->to_str();  
57 -// }  
58 -// 3. SrsAmf0Any: parse specified type to any, for instance, string  
59 -// SrsAmf0Any* pany = SrsAmf0Any::str("winlin");  
60 -// 4. SrsAmf0Size: get amf0 instance size  
61 -// int size = SrsAmf0Size::str("winlin");  
62 -// 5. SrsAmf0Object: create the amf0 object.  
63 -// SrsAmf0Object* obj = SrsAmf0Any::object();  
64 -// 5. SrsAmf0EcmaArray: create the amf0 ecma array.  
65 -// SrsAmf0EcmaArray* arr = SrsAmf0Any::ecma_array();  
66 -// 6. SrsAmf0Any: set basic type value  
67 -// SrsAmf0Any* pany = ...  
68 -// if (pany->is_number()) {  
69 -// pany->set_number(100.1);  
70 -// }  
71 -//  
72 -// please carefully the size and count of amf0 any:  
73 -// 1. total_size(): the total memory size the object wrote to buffer.  
74 -// 2. count(): the total element count of object, for instance, the properties  
75 -// of amf0 object, used for key_at/value_at loop.  
76 -//  
77 -// for detail usage, see interfaces of each object. 47 +Usages:
  48 +
  49 +1. the bytes proxy: SrsStream
  50 + // when we got some bytes from file or network,
  51 + // use SrsStream proxy to read/write bytes
  52 +
  53 + // for example, read bytes from file or network.
  54 + char* bytes = ...;
  55 +
  56 + // initialize the stream, proxy for bytes.
  57 + SrsStream stream;
  58 + stream.initialize(bytes);
  59 +
  60 + // use stream instead.
  61 +
  62 +2. directly read AMF0 any instance from stream:
  63 + SrsAmf0Any* pany = NULL;
  64 + srs_amf0_read_any(&stream, &pany);
  65 +
  66 +3. use SrsAmf0Any to discovery instance from stream:
  67 + SrsAmf0Any* pany = NULL;
  68 + SrsAmf0Any::discovery(&stream, &pany);
  69 +
  70 +4. directly read specified AMF0 instance value from stream:
  71 + string value;
  72 + srs_amf0_read_string(&stream, value);
  73 +
  74 +5. directly read specified AMF0 instance from stream:
  75 + SrsAmf0Any* str = SrsAmf0Any::str();
  76 + str->read(&stream);
  77 +
  78 +6. get value from AMF0 instance:
  79 + // parse or set by other user
  80 + SrsAmf0Any* any = ...;
  81 +
  82 + if (any->is_string()) {
  83 + string str = any->to_string();
  84 + }
  85 +
  86 +7. get complex object from AMF0 insance:
  87 + // parse or set by other user
  88 + SrsAmf0Any* any = ...;
  89 +
  90 + if (any->is_object()) {
  91 + SrsAmf0Object* obj = any->to_object();
  92 + obj->set("width", SrsAmf0Any::number(1024));
  93 + obj->set("height", SrsAmf0Any::number(576));
  94 + }
  95 +
  96 +8. serialize AMF0 instance to bytes:
  97 + // parse or set by other user
  98 + SrsAmf0Any* any = ...;
  99 +
  100 + char* bytes = new char[any->total_size()];
  101 +
  102 + SrsStream stream;
  103 + stream.initialize(bytes);
  104 +
  105 + any->write(&stream);
  106 +
  107 +@remark: for detail usage, see interfaces of each object.
  108 +@remark: all examples ignore the error process.
78 //////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////////
79 //////////////////////////////////////////////////////////////////////// 110 ////////////////////////////////////////////////////////////////////////
80 //////////////////////////////////////////////////////////////////////// 111 ////////////////////////////////////////////////////////////////////////
  112 +*/
81 113
82 /** 114 /**
83 * any amf0 value. 115 * any amf0 value.
@@ -94,82 +126,181 @@ public: @@ -94,82 +126,181 @@ public:
94 public: 126 public:
95 SrsAmf0Any(); 127 SrsAmf0Any();
96 virtual ~SrsAmf0Any(); 128 virtual ~SrsAmf0Any();
  129 +// type identify, user should identify the type then convert from/to value.
97 public: 130 public:
  131 + /**
  132 + * whether current instance is an AMF0 string.
  133 + * @return true if instance is an AMF0 string; otherwise, false.
  134 + * @remark, if true, use to_string() to get its value.
  135 + */
98 virtual bool is_string(); 136 virtual bool is_string();
  137 + /**
  138 + * whether current instance is an AMF0 boolean.
  139 + * @return true if instance is an AMF0 boolean; otherwise, false.
  140 + * @remark, if true, use to_boolean() to get its value.
  141 + */
99 virtual bool is_boolean(); 142 virtual bool is_boolean();
  143 + /**
  144 + * whether current instance is an AMF0 number.
  145 + * @return true if instance is an AMF0 number; otherwise, false.
  146 + * @remark, if true, use to_number() to get its value.
  147 + */
100 virtual bool is_number(); 148 virtual bool is_number();
  149 + /**
  150 + * whether current instance is an AMF0 null.
  151 + * @return true if instance is an AMF0 null; otherwise, false.
  152 + */
101 virtual bool is_null(); 153 virtual bool is_null();
  154 + /**
  155 + * whether current instance is an AMF0 undefined.
  156 + * @return true if instance is an AMF0 undefined; otherwise, false.
  157 + */
102 virtual bool is_undefined(); 158 virtual bool is_undefined();
  159 + /**
  160 + * whether current instance is an AMF0 object.
  161 + * @return true if instance is an AMF0 object; otherwise, false.
  162 + * @remark, if true, use to_object() to get its value.
  163 + */
103 virtual bool is_object(); 164 virtual bool is_object();
  165 + /**
  166 + * whether current instance is an AMF0 object-EOF.
  167 + * @return true if instance is an AMF0 object-EOF; otherwise, false.
  168 + */
104 virtual bool is_object_eof(); 169 virtual bool is_object_eof();
  170 + /**
  171 + * whether current instance is an AMF0 ecma-array.
  172 + * @return true if instance is an AMF0 ecma-array; otherwise, false.
  173 + * @remark, if true, use to_ecma_array() to get its value.
  174 + */
105 virtual bool is_ecma_array(); 175 virtual bool is_ecma_array();
  176 + /**
  177 + * whether current instance is an AMF0 strict-array.
  178 + * @return true if instance is an AMF0 strict-array; otherwise, false.
  179 + * @remark, if true, use to_strict_array() to get its value.
  180 + */
106 virtual bool is_strict_array(); 181 virtual bool is_strict_array();
107 -public: 182 + /**
  183 + * whether current instance is an AMF0 object, object-EOF, ecma-array or strict-array.
  184 + */
108 virtual bool is_complex_object(); 185 virtual bool is_complex_object();
  186 +// get value of instance
109 public: 187 public:
110 /** 188 /**
111 - * get the string of any when is_string() indicates true.  
112 - * user must ensure the type is a string, or assert failed. 189 + * get a string copy of instance.
  190 + * @remark assert is_string(), user must ensure the type then convert.
113 */ 191 */
114 virtual std::string to_str(); 192 virtual std::string to_str();
  193 + /**
  194 + * get the raw str of instance,
  195 + * user can directly set the content of str.
  196 + * @remark assert is_string(), user must ensure the type then convert.
  197 + */
115 virtual const char* to_str_raw(); 198 virtual const char* to_str_raw();
116 /** 199 /**
117 - * get the boolean of any when is_boolean() indicates true.  
118 - * user must ensure the type is a boolean, or assert failed. 200 + * convert instance to amf0 boolean,
  201 + * @remark assert is_boolean(), user must ensure the type then convert.
119 */ 202 */
120 virtual bool to_boolean(); 203 virtual bool to_boolean();
121 /** 204 /**
122 - * get the number of any when is_number() indicates true.  
123 - * user must ensure the type is a number, or assert failed. 205 + * convert instance to amf0 number,
  206 + * @remark assert is_number(), user must ensure the type then convert.
124 */ 207 */
125 virtual double to_number(); 208 virtual double to_number();
126 /** 209 /**
127 - * get the object of any when is_object() indicates true.  
128 - * user must ensure the type is a object, or assert failed. 210 + * convert instance to amf0 object,
  211 + * @remark assert is_object(), user must ensure the type then convert.
129 */ 212 */
130 virtual SrsAmf0Object* to_object(); 213 virtual SrsAmf0Object* to_object();
131 /** 214 /**
132 - * get the ecma array of any when is_ecma_array() indicates true.  
133 - * user must ensure the type is a ecma array, or assert failed. 215 + * convert instance to ecma array,
  216 + * @remark assert is_ecma_array(), user must ensure the type then convert.
134 */ 217 */
135 virtual SrsAmf0EcmaArray* to_ecma_array(); 218 virtual SrsAmf0EcmaArray* to_ecma_array();
  219 + /**
  220 + * convert instance to strict array,
  221 + * @remark assert is_strict_array(), user must ensure the type then convert.
  222 + */
136 virtual SrsAmf0StrictArray* to_strict_array(); 223 virtual SrsAmf0StrictArray* to_strict_array();
  224 +// set value of instance
137 public: 225 public:
138 /** 226 /**
139 * set the number of any when is_number() indicates true. 227 * set the number of any when is_number() indicates true.
140 * user must ensure the type is a number, or assert failed. 228 * user must ensure the type is a number, or assert failed.
141 */ 229 */
142 virtual void set_number(double value); 230 virtual void set_number(double value);
  231 +// serialize/deseriaize instance.
143 public: 232 public:
144 /** 233 /**
145 * get the size of amf0 any, including the marker size. 234 * get the size of amf0 any, including the marker size.
  235 + * the size is the bytes which instance serialized to.
146 */ 236 */
147 virtual int total_size() = 0; 237 virtual int total_size() = 0;
148 /** 238 /**
149 - * read elem from stream 239 + * read AMF0 instance from stream.
150 */ 240 */
151 virtual int read(SrsStream* stream) = 0; 241 virtual int read(SrsStream* stream) = 0;
  242 + /**
  243 + * write AMF0 instance to stream.
  244 + */
152 virtual int write(SrsStream* stream) = 0; 245 virtual int write(SrsStream* stream) = 0;
  246 + /**
  247 + * copy current AMF0 instance.
  248 + */
153 virtual SrsAmf0Any* copy() = 0; 249 virtual SrsAmf0Any* copy() = 0;
154 -public:  
155 /** 250 /**
156 * human readable print 251 * human readable print
157 * @param pdata, output the heap data, NULL to ignore. 252 * @param pdata, output the heap data, NULL to ignore.
158 - * user must use srs_amf0_free_bytes to free it.  
159 * @return return the *pdata for print. NULL to ignore. 253 * @return return the *pdata for print. NULL to ignore.
  254 + * @remark user must free the data returned or output by pdata.
160 */ 255 */
161 virtual char* human_print(char** pdata, int* psize); 256 virtual char* human_print(char** pdata, int* psize);
  257 +// create AMF0 instance.
162 public: 258 public:
  259 + /**
  260 + * create an AMF0 string instance, set string content by value.
  261 + */
163 static SrsAmf0Any* str(const char* value = NULL); 262 static SrsAmf0Any* str(const char* value = NULL);
  263 + /**
  264 + * create an AMF0 boolean instance, set boolean content by value.
  265 + */
164 static SrsAmf0Any* boolean(bool value = false); 266 static SrsAmf0Any* boolean(bool value = false);
  267 + /**
  268 + * create an AMF0 number instance, set number content by value.
  269 + */
165 static SrsAmf0Any* number(double value = 0.0); 270 static SrsAmf0Any* number(double value = 0.0);
  271 + /**
  272 + * create an AMF0 null instance
  273 + */
166 static SrsAmf0Any* null(); 274 static SrsAmf0Any* null();
  275 + /**
  276 + * create an AMF0 undefined instance
  277 + */
167 static SrsAmf0Any* undefined(); 278 static SrsAmf0Any* undefined();
  279 + /**
  280 + * create an AMF0 empty object instance
  281 + */
168 static SrsAmf0Object* object(); 282 static SrsAmf0Object* object();
  283 + /**
  284 + * create an AMF0 object-EOF instance
  285 + */
169 static SrsAmf0Any* object_eof(); 286 static SrsAmf0Any* object_eof();
  287 + /**
  288 + * create an AMF0 empty ecma-array instance
  289 + */
170 static SrsAmf0EcmaArray* ecma_array(); 290 static SrsAmf0EcmaArray* ecma_array();
  291 + /**
  292 + * create an AMF0 empty strict-array instance
  293 + */
171 static SrsAmf0StrictArray* strict_array(); 294 static SrsAmf0StrictArray* strict_array();
  295 +// discovery instance from stream
172 public: 296 public:
  297 + /**
  298 + * discovery AMF0 instance from stream
  299 + * @param ppvalue, output the discoveried AMF0 instance.
  300 + * NULL if error.
  301 + * @remark, instance is created without read from stream, user must
  302 + * use (*ppvalue)->read(stream) to get the instance.
  303 + */
173 static int discovery(SrsStream* stream, SrsAmf0Any** ppvalue); 304 static int discovery(SrsStream* stream, SrsAmf0Any** ppvalue);
174 }; 305 };
175 306
@@ -183,33 +314,74 @@ class SrsAmf0Object : public SrsAmf0Any @@ -183,33 +314,74 @@ class SrsAmf0Object : public SrsAmf0Any
183 private: 314 private:
184 __SrsUnSortedHashtable* properties; 315 __SrsUnSortedHashtable* properties;
185 __SrsAmf0ObjectEOF* eof; 316 __SrsAmf0ObjectEOF* eof;
186 -  
187 private: 317 private:
188 - // use SrsAmf0Any::object() to create it.  
189 friend class SrsAmf0Any; 318 friend class SrsAmf0Any;
  319 + /**
  320 + * make amf0 object to private,
  321 + * use should never declare it, use SrsAmf0Any::object() to create it.
  322 + */
190 SrsAmf0Object(); 323 SrsAmf0Object();
191 public: 324 public:
192 virtual ~SrsAmf0Object(); 325 virtual ~SrsAmf0Object();
193 - 326 +// serialize/deserialize to/from stream.
194 public: 327 public:
195 virtual int total_size(); 328 virtual int total_size();
196 virtual int read(SrsStream* stream); 329 virtual int read(SrsStream* stream);
197 virtual int write(SrsStream* stream); 330 virtual int write(SrsStream* stream);
198 virtual SrsAmf0Any* copy(); 331 virtual SrsAmf0Any* copy();
199 - 332 +// properties iteration
200 public: 333 public:
  334 + /**
  335 + * clear all propergies.
  336 + */
201 virtual void clear(); 337 virtual void clear();
  338 + /**
  339 + * get the count of properties(key:value).
  340 + */
202 virtual int count(); 341 virtual int count();
203 - // @remark: max index is count(). 342 + /**
  343 + * get the property(key:value) key at index.
  344 + * @remark: max index is count().
  345 + */
204 virtual std::string key_at(int index); 346 virtual std::string key_at(int index);
  347 + /**
  348 + * get the property(key:value) key raw bytes at index.
  349 + * user can directly set the key bytes.
  350 + * @remark: max index is count().
  351 + */
205 virtual const char* key_raw_at(int index); 352 virtual const char* key_raw_at(int index);
206 - // @remark: max index is count(). 353 + /**
  354 + * get the property(key:value) value at index.
  355 + * @remark: max index is count().
  356 + */
207 virtual SrsAmf0Any* value_at(int index); 357 virtual SrsAmf0Any* value_at(int index);
208 - 358 +// property set/get.
209 public: 359 public:
  360 + /**
  361 + * set the property(key:value) of object,
  362 + * @param key, string property name.
  363 + * @param value, an AMF0 instance property value.
  364 + * @remark user should never free the value, this instance will manage it.
  365 + */
210 virtual void set(std::string key, SrsAmf0Any* value); 366 virtual void set(std::string key, SrsAmf0Any* value);
  367 + /**
  368 + * get the property(key:value) of object,
  369 + * @param name, the property name/key
  370 + * @return the property AMF0 value, NULL if not found.
  371 + * @remark user should never free the returned value, copy it if needed.
  372 + */
211 virtual SrsAmf0Any* get_property(std::string name); 373 virtual SrsAmf0Any* get_property(std::string name);
  374 + /**
  375 + * get the string property, ensure the property is_string().
  376 + * @return the property AMF0 value, NULL if not found, or not a string.
  377 + * @remark user should never free the returned value, copy it if needed.
  378 + */
212 virtual SrsAmf0Any* ensure_property_string(std::string name); 379 virtual SrsAmf0Any* ensure_property_string(std::string name);
  380 + /**
  381 + * get the number property, ensure the property is_number().
  382 + * @return the property AMF0 value, NULL if not found, or not a number.
  383 + * @remark user should never free the returned value, copy it if needed.
  384 + */
213 virtual SrsAmf0Any* ensure_property_number(std::string name); 385 virtual SrsAmf0Any* ensure_property_number(std::string name);
214 }; 386 };
215 387
@@ -225,33 +397,74 @@ private: @@ -225,33 +397,74 @@ private:
225 __SrsUnSortedHashtable* properties; 397 __SrsUnSortedHashtable* properties;
226 __SrsAmf0ObjectEOF* eof; 398 __SrsAmf0ObjectEOF* eof;
227 int32_t _count; 399 int32_t _count;
228 -  
229 private: 400 private:
230 - // use SrsAmf0Any::ecma_array() to create it.  
231 friend class SrsAmf0Any; 401 friend class SrsAmf0Any;
  402 + /**
  403 + * make amf0 object to private,
  404 + * use should never declare it, use SrsAmf0Any::ecma_array() to create it.
  405 + */
232 SrsAmf0EcmaArray(); 406 SrsAmf0EcmaArray();
233 public: 407 public:
234 virtual ~SrsAmf0EcmaArray(); 408 virtual ~SrsAmf0EcmaArray();
235 - 409 +// serialize/deserialize to/from stream.
236 public: 410 public:
237 virtual int total_size(); 411 virtual int total_size();
238 virtual int read(SrsStream* stream); 412 virtual int read(SrsStream* stream);
239 virtual int write(SrsStream* stream); 413 virtual int write(SrsStream* stream);
240 virtual SrsAmf0Any* copy(); 414 virtual SrsAmf0Any* copy();
241 - 415 +// properties iteration
242 public: 416 public:
  417 + /**
  418 + * clear all propergies.
  419 + */
243 virtual void clear(); 420 virtual void clear();
  421 + /**
  422 + * get the count of properties(key:value).
  423 + */
244 virtual int count(); 424 virtual int count();
245 - // @remark: max index is count(). 425 + /**
  426 + * get the property(key:value) key at index.
  427 + * @remark: max index is count().
  428 + */
246 virtual std::string key_at(int index); 429 virtual std::string key_at(int index);
  430 + /**
  431 + * get the property(key:value) key raw bytes at index.
  432 + * user can directly set the key bytes.
  433 + * @remark: max index is count().
  434 + */
247 virtual const char* key_raw_at(int index); 435 virtual const char* key_raw_at(int index);
248 - // @remark: max index is count(). 436 + /**
  437 + * get the property(key:value) value at index.
  438 + * @remark: max index is count().
  439 + */
249 virtual SrsAmf0Any* value_at(int index); 440 virtual SrsAmf0Any* value_at(int index);
250 - 441 +// property set/get.
251 public: 442 public:
  443 + /**
  444 + * set the property(key:value) of array,
  445 + * @param key, string property name.
  446 + * @param value, an AMF0 instance property value.
  447 + * @remark user should never free the value, this instance will manage it.
  448 + */
252 virtual void set(std::string key, SrsAmf0Any* value); 449 virtual void set(std::string key, SrsAmf0Any* value);
  450 + /**
  451 + * get the property(key:value) of array,
  452 + * @param name, the property name/key
  453 + * @return the property AMF0 value, NULL if not found.
  454 + * @remark user should never free the returned value, copy it if needed.
  455 + */
253 virtual SrsAmf0Any* get_property(std::string name); 456 virtual SrsAmf0Any* get_property(std::string name);
  457 + /**
  458 + * get the string property, ensure the property is_string().
  459 + * @return the property AMF0 value, NULL if not found, or not a string.
  460 + * @remark user should never free the returned value, copy it if needed.
  461 + */
254 virtual SrsAmf0Any* ensure_property_string(std::string name); 462 virtual SrsAmf0Any* ensure_property_string(std::string name);
  463 + /**
  464 + * get the number property, ensure the property is_number().
  465 + * @return the property AMF0 value, NULL if not found, or not a number.
  466 + * @remark user should never free the returned value, copy it if needed.
  467 + */
255 virtual SrsAmf0Any* ensure_property_number(std::string name); 468 virtual SrsAmf0Any* ensure_property_number(std::string name);
256 }; 469 };
257 470
@@ -265,25 +478,43 @@ class SrsAmf0StrictArray : public SrsAmf0Any @@ -265,25 +478,43 @@ class SrsAmf0StrictArray : public SrsAmf0Any
265 private: 478 private:
266 std::vector<SrsAmf0Any*> properties; 479 std::vector<SrsAmf0Any*> properties;
267 int32_t _count; 480 int32_t _count;
268 -  
269 private: 481 private:
270 - // use SrsAmf0Any::strict_array() to create it.  
271 friend class SrsAmf0Any; 482 friend class SrsAmf0Any;
  483 + /**
  484 + * make amf0 object to private,
  485 + * use should never declare it, use SrsAmf0Any::strict_array() to create it.
  486 + */
272 SrsAmf0StrictArray(); 487 SrsAmf0StrictArray();
273 public: 488 public:
274 virtual ~SrsAmf0StrictArray(); 489 virtual ~SrsAmf0StrictArray();
275 - 490 +// serialize/deserialize to/from stream.
276 public: 491 public:
277 virtual int total_size(); 492 virtual int total_size();
278 virtual int read(SrsStream* stream); 493 virtual int read(SrsStream* stream);
279 virtual int write(SrsStream* stream); 494 virtual int write(SrsStream* stream);
280 virtual SrsAmf0Any* copy(); 495 virtual SrsAmf0Any* copy();
281 - 496 +// properties iteration
282 public: 497 public:
  498 + /**
  499 + * clear all elements.
  500 + */
283 virtual void clear(); 501 virtual void clear();
  502 + /**
  503 + * get the count of elements
  504 + */
284 virtual int count(); 505 virtual int count();
285 - // @remark: max index is count(). 506 + /**
  507 + * get the elements key at index.
  508 + * @remark: max index is count().
  509 + */
286 virtual SrsAmf0Any* at(int index); 510 virtual SrsAmf0Any* at(int index);
  511 +// property set/get.
  512 +public:
  513 + /**
  514 + * append new element to array
  515 + * @param any, an AMF0 instance property value.
  516 + * @remark user should never free the any, this instance will manage it.
  517 + */
287 virtual void append(SrsAmf0Any* any); 518 virtual void append(SrsAmf0Any* any);
288 }; 519 };
289 520
@@ -1131,3 +1131,28 @@ VOID TEST(ProtocolAMF0Test, ApiStrictArray) @@ -1131,3 +1131,28 @@ VOID TEST(ProtocolAMF0Test, ApiStrictArray)
1131 EXPECT_EQ(5 + SrsAmf0Size::number(), s.pos()); 1131 EXPECT_EQ(5 + SrsAmf0Size::number(), s.pos());
1132 } 1132 }
1133 } 1133 }
  1134 +
  1135 +VOID TEST(ProtocolAMF0Test, ObjectObjectObject)
  1136 +{
  1137 + SrsAmf0Any* obj = SrsAmf0Any::object();
  1138 + SrsAutoFree(SrsAmf0Any, obj);
  1139 + EXPECT_EQ(0, obj->to_object()->count());
  1140 +
  1141 + SrsAmf0Any* child1 = SrsAmf0Any::object();
  1142 + obj->to_object()->set("child1", child1);
  1143 + EXPECT_EQ(1, obj->to_object()->count());
  1144 + EXPECT_EQ(0, child1->to_object()->count());
  1145 +
  1146 + SrsAmf0Any* child2 = SrsAmf0Any::object();
  1147 + child1->to_object()->set("child2", child2);
  1148 + EXPECT_EQ(1, obj->to_object()->count());
  1149 + EXPECT_EQ(1, child1->to_object()->count());
  1150 + EXPECT_EQ(0, child2->to_object()->count());
  1151 +
  1152 + SrsAmf0Any* child3 = SrsAmf0Any::object();
  1153 + child2->to_object()->set("child3", child3);
  1154 + EXPECT_EQ(1, obj->to_object()->count());
  1155 + EXPECT_EQ(1, child1->to_object()->count());
  1156 + EXPECT_EQ(1, child2->to_object()->count());
  1157 + EXPECT_EQ(0, child3->to_object()->count());
  1158 +}