winlin

refine amf0, move declarations from cpp to hpp, use namespace _srs_internal

@@ -32,6 +32,8 @@ using namespace std; @@ -32,6 +32,8 @@ using namespace std;
32 #include <srs_kernel_error.hpp> 32 #include <srs_kernel_error.hpp>
33 #include <srs_kernel_stream.hpp> 33 #include <srs_kernel_stream.hpp>
34 34
  35 +using namespace _srs_internal;
  36 +
35 // AMF0 marker 37 // AMF0 marker
36 #define RTMP_AMF0_Number 0x00 38 #define RTMP_AMF0_Number 0x00
37 #define RTMP_AMF0_Boolean 0x01 39 #define RTMP_AMF0_Boolean 0x01
@@ -58,164 +60,6 @@ using namespace std; @@ -58,164 +60,6 @@ using namespace std;
58 // User defined 60 // User defined
59 #define RTMP_AMF0_Invalid 0x3F 61 #define RTMP_AMF0_Invalid 0x3F
60 62
61 -/**  
62 -* read amf0 string from stream.  
63 -* 2.4 String Type  
64 -* string-type = string-marker UTF-8  
65 -* @return default value is empty string.  
66 -* @remark: use SrsAmf0Any::str() to create it.  
67 -*/  
68 -class __SrsAmf0String : public SrsAmf0Any  
69 -{  
70 -public:  
71 - std::string value;  
72 -  
73 - __SrsAmf0String(const char* _value);  
74 - virtual ~__SrsAmf0String();  
75 -  
76 - virtual int total_size();  
77 - virtual int read(SrsStream* stream);  
78 - virtual int write(SrsStream* stream);  
79 - virtual SrsAmf0Any* copy();  
80 -};  
81 -  
82 -/**  
83 -* read amf0 boolean from stream.  
84 -* 2.4 String Type  
85 -* boolean-type = boolean-marker U8  
86 -* 0 is false, <> 0 is true  
87 -* @return default value is false.  
88 -*/  
89 -class __SrsAmf0Boolean : public SrsAmf0Any  
90 -{  
91 -public:  
92 - bool value;  
93 -  
94 - __SrsAmf0Boolean(bool _value);  
95 - virtual ~__SrsAmf0Boolean();  
96 -  
97 - virtual int total_size();  
98 - virtual int read(SrsStream* stream);  
99 - virtual int write(SrsStream* stream);  
100 - virtual SrsAmf0Any* copy();  
101 -};  
102 -  
103 -/**  
104 -* read amf0 number from stream.  
105 -* 2.2 Number Type  
106 -* number-type = number-marker DOUBLE  
107 -* @return default value is 0.  
108 -*/  
109 -class __SrsAmf0Number : public SrsAmf0Any  
110 -{  
111 -public:  
112 - double value;  
113 -  
114 - __SrsAmf0Number(double _value);  
115 - virtual ~__SrsAmf0Number();  
116 -  
117 - virtual int total_size();  
118 - virtual int read(SrsStream* stream);  
119 - virtual int write(SrsStream* stream);  
120 - virtual SrsAmf0Any* copy();  
121 -};  
122 -  
123 -/**  
124 -* read amf0 null from stream.  
125 -* 2.7 null Type  
126 -* null-type = null-marker  
127 -*/  
128 -class __SrsAmf0Null : public SrsAmf0Any  
129 -{  
130 -public:  
131 - __SrsAmf0Null();  
132 - virtual ~__SrsAmf0Null();  
133 -  
134 - virtual int total_size();  
135 - virtual int read(SrsStream* stream);  
136 - virtual int write(SrsStream* stream);  
137 - virtual SrsAmf0Any* copy();  
138 -};  
139 -  
140 -/**  
141 -* read amf0 undefined from stream.  
142 -* 2.8 undefined Type  
143 -* undefined-type = undefined-marker  
144 -*/  
145 -class __SrsAmf0Undefined : public SrsAmf0Any  
146 -{  
147 -public:  
148 - __SrsAmf0Undefined();  
149 - virtual ~__SrsAmf0Undefined();  
150 -  
151 - virtual int total_size();  
152 - virtual int read(SrsStream* stream);  
153 - virtual int write(SrsStream* stream);  
154 - virtual SrsAmf0Any* copy();  
155 -};  
156 -  
157 -/**  
158 -* to ensure in inserted order.  
159 -* for the FMLE will crash when AMF0Object is not ordered by inserted,  
160 -* if ordered in map, the string compare order, the FMLE will creash when  
161 -* get the response of connect app.  
162 -*/  
163 -class __SrsUnSortedHashtable  
164 -{  
165 -private:  
166 - typedef std::pair<std::string, SrsAmf0Any*> SrsAmf0ObjectPropertyType;  
167 - std::vector<SrsAmf0ObjectPropertyType> properties;  
168 -public:  
169 - __SrsUnSortedHashtable();  
170 - virtual ~__SrsUnSortedHashtable();  
171 -  
172 - virtual int count();  
173 - virtual void clear();  
174 - virtual std::string key_at(int index);  
175 - virtual const char* key_raw_at(int index);  
176 - virtual SrsAmf0Any* value_at(int index);  
177 - virtual void set(std::string key, SrsAmf0Any* value);  
178 -  
179 - virtual SrsAmf0Any* get_property(std::string name);  
180 - virtual SrsAmf0Any* ensure_property_string(std::string name);  
181 - virtual SrsAmf0Any* ensure_property_number(std::string name);  
182 -  
183 - virtual void copy(__SrsUnSortedHashtable* src);  
184 -};  
185 -  
186 -/**  
187 -* 2.11 Object End Type  
188 -* object-end-type = UTF-8-empty object-end-marker  
189 -* 0x00 0x00 0x09  
190 -*/  
191 -class __SrsAmf0ObjectEOF : public SrsAmf0Any  
192 -{  
193 -public:  
194 - int16_t utf8_empty;  
195 -  
196 - __SrsAmf0ObjectEOF();  
197 - virtual ~__SrsAmf0ObjectEOF();  
198 -  
199 - virtual int total_size();  
200 - virtual int read(SrsStream* stream);  
201 - virtual int write(SrsStream* stream);  
202 - virtual SrsAmf0Any* copy();  
203 -};  
204 -  
205 -/**  
206 -* read amf0 utf8 string from stream.  
207 -* 1.3.1 Strings and UTF-8  
208 -* UTF-8 = U16 *(UTF8-char)  
209 -* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4  
210 -* UTF8-1 = %x00-7F  
211 -* @remark only support UTF8-1 char.  
212 -*/  
213 -extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);  
214 -extern int srs_amf0_write_utf8(SrsStream* stream, std::string value);  
215 -  
216 -bool srs_amf0_is_object_eof(SrsStream* stream);  
217 -int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value);  
218 -  
219 SrsAmf0Any::SrsAmf0Any() 63 SrsAmf0Any::SrsAmf0Any()
220 { 64 {
221 marker = RTMP_AMF0_Invalid; 65 marker = RTMP_AMF0_Invalid;
@@ -804,7 +648,7 @@ int SrsAmf0Object::read(SrsStream* stream) @@ -804,7 +648,7 @@ int SrsAmf0Object::read(SrsStream* stream)
804 648
805 // property-name: utf8 string 649 // property-name: utf8 string
806 std::string property_name; 650 std::string property_name;
807 - if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) { 651 + if ((ret = srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
808 srs_error("amf0 object read property name failed. ret=%d", ret); 652 srs_error("amf0 object read property name failed. ret=%d", ret);
809 return ret; 653 return ret;
810 } 654 }
@@ -1517,88 +1361,6 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any** ppvalue) @@ -1517,88 +1361,6 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any** ppvalue)
1517 return ret; 1361 return ret;
1518 } 1362 }
1519 1363
1520 -int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)  
1521 -{  
1522 - srs_assert(value != NULL);  
1523 - return value->write(stream);  
1524 -}  
1525 -  
1526 -int srs_amf0_read_utf8(SrsStream* stream, string& value)  
1527 -{  
1528 - int ret = ERROR_SUCCESS;  
1529 -  
1530 - // len  
1531 - if (!stream->require(2)) {  
1532 - ret = ERROR_RTMP_AMF0_DECODE;  
1533 - srs_error("amf0 read string length failed. ret=%d", ret);  
1534 - return ret;  
1535 - }  
1536 - int16_t len = stream->read_2bytes();  
1537 - srs_verbose("amf0 read string length success. len=%d", len);  
1538 -  
1539 - // empty string  
1540 - if (len <= 0) {  
1541 - srs_verbose("amf0 read empty string. ret=%d", ret);  
1542 - return ret;  
1543 - }  
1544 -  
1545 - // data  
1546 - if (!stream->require(len)) {  
1547 - ret = ERROR_RTMP_AMF0_DECODE;  
1548 - srs_error("amf0 read string data failed. ret=%d", ret);  
1549 - return ret;  
1550 - }  
1551 - std::string str = stream->read_string(len);  
1552 -  
1553 - // support utf8-1 only  
1554 - // 1.3.1 Strings and UTF-8  
1555 - // UTF8-1 = %x00-7F  
1556 - // TODO: support other utf-8 strings  
1557 - /*for (int i = 0; i < len; i++) {  
1558 - char ch = *(str.data() + i);  
1559 - if ((ch & 0x80) != 0) {  
1560 - ret = ERROR_RTMP_AMF0_DECODE;  
1561 - srs_error("ignored. only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret);  
1562 - ret = ERROR_SUCCESS;  
1563 - }  
1564 - }*/  
1565 -  
1566 - value = str;  
1567 - srs_verbose("amf0 read string data success. str=%s", str.c_str());  
1568 -  
1569 - return ret;  
1570 -}  
1571 -int srs_amf0_write_utf8(SrsStream* stream, string value)  
1572 -{  
1573 - int ret = ERROR_SUCCESS;  
1574 -  
1575 - // len  
1576 - if (!stream->require(2)) {  
1577 - ret = ERROR_RTMP_AMF0_ENCODE;  
1578 - srs_error("amf0 write string length failed. ret=%d", ret);  
1579 - return ret;  
1580 - }  
1581 - stream->write_2bytes(value.length());  
1582 - srs_verbose("amf0 write string length success. len=%d", (int)value.length());  
1583 -  
1584 - // empty string  
1585 - if (value.length() <= 0) {  
1586 - srs_verbose("amf0 write empty string. ret=%d", ret);  
1587 - return ret;  
1588 - }  
1589 -  
1590 - // data  
1591 - if (!stream->require(value.length())) {  
1592 - ret = ERROR_RTMP_AMF0_ENCODE;  
1593 - srs_error("amf0 write string data failed. ret=%d", ret);  
1594 - return ret;  
1595 - }  
1596 - stream->write_string(value);  
1597 - srs_verbose("amf0 write string data success. str=%s", value.c_str());  
1598 -  
1599 - return ret;  
1600 -}  
1601 -  
1602 int srs_amf0_read_string(SrsStream* stream, string& value) 1364 int srs_amf0_read_string(SrsStream* stream, string& value)
1603 { 1365 {
1604 int ret = ERROR_SUCCESS; 1366 int ret = ERROR_SUCCESS;
@@ -1849,44 +1611,130 @@ int srs_amf0_write_undefined(SrsStream* stream) @@ -1849,44 +1611,130 @@ int srs_amf0_write_undefined(SrsStream* stream)
1849 return ret; 1611 return ret;
1850 } 1612 }
1851 1613
1852 -bool srs_amf0_is_object_eof(SrsStream* stream)  
1853 -{  
1854 - // detect the object-eof specially  
1855 - if (stream->require(3)) {  
1856 - int32_t flag = stream->read_3bytes();  
1857 - stream->skip(-3);  
1858 -  
1859 - return 0x09 == flag;  
1860 - }  
1861 -  
1862 - return false;  
1863 -}  
1864 1614
1865 -int srs_amf0_write_object_eof(SrsStream* stream, __SrsAmf0ObjectEOF* value) 1615 +namespace _srs_internal
1866 { 1616 {
1867 - int ret = ERROR_SUCCESS;  
1868 -  
1869 - srs_assert(value != NULL);  
1870 -  
1871 - // value  
1872 - if (!stream->require(2)) {  
1873 - ret = ERROR_RTMP_AMF0_ENCODE;  
1874 - srs_error("amf0 write object eof value failed. ret=%d", ret); 1617 + int srs_amf0_read_utf8(SrsStream* stream, string& value)
  1618 + {
  1619 + int ret = ERROR_SUCCESS;
  1620 +
  1621 + // len
  1622 + if (!stream->require(2)) {
  1623 + ret = ERROR_RTMP_AMF0_DECODE;
  1624 + srs_error("amf0 read string length failed. ret=%d", ret);
  1625 + return ret;
  1626 + }
  1627 + int16_t len = stream->read_2bytes();
  1628 + srs_verbose("amf0 read string length success. len=%d", len);
  1629 +
  1630 + // empty string
  1631 + if (len <= 0) {
  1632 + srs_verbose("amf0 read empty string. ret=%d", ret);
  1633 + return ret;
  1634 + }
  1635 +
  1636 + // data
  1637 + if (!stream->require(len)) {
  1638 + ret = ERROR_RTMP_AMF0_DECODE;
  1639 + srs_error("amf0 read string data failed. ret=%d", ret);
  1640 + return ret;
  1641 + }
  1642 + std::string str = stream->read_string(len);
  1643 +
  1644 + // support utf8-1 only
  1645 + // 1.3.1 Strings and UTF-8
  1646 + // UTF8-1 = %x00-7F
  1647 + // TODO: support other utf-8 strings
  1648 + /*for (int i = 0; i < len; i++) {
  1649 + char ch = *(str.data() + i);
  1650 + if ((ch & 0x80) != 0) {
  1651 + ret = ERROR_RTMP_AMF0_DECODE;
  1652 + srs_error("ignored. only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret);
  1653 + ret = ERROR_SUCCESS;
  1654 + }
  1655 + }*/
  1656 +
  1657 + value = str;
  1658 + srs_verbose("amf0 read string data success. str=%s", str.c_str());
  1659 +
1875 return ret; 1660 return ret;
1876 } 1661 }
1877 - stream->write_2bytes(0x00);  
1878 - srs_verbose("amf0 write object eof value success");  
1879 -  
1880 - // marker  
1881 - if (!stream->require(1)) {  
1882 - ret = ERROR_RTMP_AMF0_ENCODE;  
1883 - srs_error("amf0 write object eof marker failed. ret=%d", ret); 1662 + int srs_amf0_write_utf8(SrsStream* stream, string value)
  1663 + {
  1664 + int ret = ERROR_SUCCESS;
  1665 +
  1666 + // len
  1667 + if (!stream->require(2)) {
  1668 + ret = ERROR_RTMP_AMF0_ENCODE;
  1669 + srs_error("amf0 write string length failed. ret=%d", ret);
  1670 + return ret;
  1671 + }
  1672 + stream->write_2bytes(value.length());
  1673 + srs_verbose("amf0 write string length success. len=%d", (int)value.length());
  1674 +
  1675 + // empty string
  1676 + if (value.length() <= 0) {
  1677 + srs_verbose("amf0 write empty string. ret=%d", ret);
  1678 + return ret;
  1679 + }
  1680 +
  1681 + // data
  1682 + if (!stream->require(value.length())) {
  1683 + ret = ERROR_RTMP_AMF0_ENCODE;
  1684 + srs_error("amf0 write string data failed. ret=%d", ret);
  1685 + return ret;
  1686 + }
  1687 + stream->write_string(value);
  1688 + srs_verbose("amf0 write string data success. str=%s", value.c_str());
  1689 +
1884 return ret; 1690 return ret;
1885 } 1691 }
1886 1692
1887 - stream->write_1bytes(RTMP_AMF0_ObjectEnd);  
1888 -  
1889 - srs_verbose("amf0 read object eof success"); 1693 + bool srs_amf0_is_object_eof(SrsStream* stream)
  1694 + {
  1695 + // detect the object-eof specially
  1696 + if (stream->require(3)) {
  1697 + int32_t flag = stream->read_3bytes();
  1698 + stream->skip(-3);
  1699 +
  1700 + return 0x09 == flag;
  1701 + }
  1702 +
  1703 + return false;
  1704 + }
1890 1705
1891 - return ret; 1706 + int srs_amf0_write_object_eof(SrsStream* stream, __SrsAmf0ObjectEOF* value)
  1707 + {
  1708 + int ret = ERROR_SUCCESS;
  1709 +
  1710 + srs_assert(value != NULL);
  1711 +
  1712 + // value
  1713 + if (!stream->require(2)) {
  1714 + ret = ERROR_RTMP_AMF0_ENCODE;
  1715 + srs_error("amf0 write object eof value failed. ret=%d", ret);
  1716 + return ret;
  1717 + }
  1718 + stream->write_2bytes(0x00);
  1719 + srs_verbose("amf0 write object eof value success");
  1720 +
  1721 + // marker
  1722 + if (!stream->require(1)) {
  1723 + ret = ERROR_RTMP_AMF0_ENCODE;
  1724 + srs_error("amf0 write object eof marker failed. ret=%d", ret);
  1725 + return ret;
  1726 + }
  1727 +
  1728 + stream->write_1bytes(RTMP_AMF0_ObjectEnd);
  1729 +
  1730 + srs_verbose("amf0 read object eof success");
  1731 +
  1732 + return ret;
  1733 + }
  1734 +
  1735 + int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
  1736 + {
  1737 + srs_assert(value != NULL);
  1738 + return value->write(stream);
  1739 + }
1892 } 1740 }
@@ -37,8 +37,13 @@ class SrsStream; @@ -37,8 +37,13 @@ class SrsStream;
37 class SrsAmf0Object; 37 class SrsAmf0Object;
38 class SrsAmf0EcmaArray; 38 class SrsAmf0EcmaArray;
39 class SrsAmf0StrictArray; 39 class SrsAmf0StrictArray;
40 -class __SrsUnSortedHashtable;  
41 -class __SrsAmf0ObjectEOF; 40 +
  41 +// internal objects, user should never use it.
  42 +namespace _srs_internal
  43 +{
  44 + class __SrsUnSortedHashtable;
  45 + class __SrsAmf0ObjectEOF;
  46 +}
42 47
43 /* 48 /*
44 //////////////////////////////////////////////////////////////////////// 49 ////////////////////////////////////////////////////////////////////////
@@ -312,8 +317,8 @@ public: @@ -312,8 +317,8 @@ public:
312 class SrsAmf0Object : public SrsAmf0Any 317 class SrsAmf0Object : public SrsAmf0Any
313 { 318 {
314 private: 319 private:
315 - __SrsUnSortedHashtable* properties;  
316 - __SrsAmf0ObjectEOF* eof; 320 + _srs_internal::__SrsUnSortedHashtable* properties;
  321 + _srs_internal::__SrsAmf0ObjectEOF* eof;
317 private: 322 private:
318 friend class SrsAmf0Any; 323 friend class SrsAmf0Any;
319 /** 324 /**
@@ -394,8 +399,8 @@ public: @@ -394,8 +399,8 @@ public:
394 class SrsAmf0EcmaArray : public SrsAmf0Any 399 class SrsAmf0EcmaArray : public SrsAmf0Any
395 { 400 {
396 private: 401 private:
397 - __SrsUnSortedHashtable* properties;  
398 - __SrsAmf0ObjectEOF* eof; 402 + _srs_internal::__SrsUnSortedHashtable* properties;
  403 + _srs_internal::__SrsAmf0ObjectEOF* eof;
399 int32_t _count; 404 int32_t _count;
400 private: 405 private:
401 friend class SrsAmf0Any; 406 friend class SrsAmf0Any;
@@ -585,4 +590,168 @@ extern int srs_amf0_write_null(SrsStream* stream); @@ -585,4 +590,168 @@ extern int srs_amf0_write_null(SrsStream* stream);
585 extern int srs_amf0_read_undefined(SrsStream* stream); 590 extern int srs_amf0_read_undefined(SrsStream* stream);
586 extern int srs_amf0_write_undefined(SrsStream* stream); 591 extern int srs_amf0_write_undefined(SrsStream* stream);
587 592
  593 +// internal objects, user should never use it.
  594 +namespace _srs_internal
  595 +{
  596 + /**
  597 + * read amf0 string from stream.
  598 + * 2.4 String Type
  599 + * string-type = string-marker UTF-8
  600 + * @return default value is empty string.
  601 + * @remark: use SrsAmf0Any::str() to create it.
  602 + */
  603 + class __SrsAmf0String : public SrsAmf0Any
  604 + {
  605 + public:
  606 + std::string value;
  607 + public:
  608 + __SrsAmf0String(const char* _value);
  609 + virtual ~__SrsAmf0String();
  610 + public:
  611 + virtual int total_size();
  612 + virtual int read(SrsStream* stream);
  613 + virtual int write(SrsStream* stream);
  614 + virtual SrsAmf0Any* copy();
  615 + };
  616 +
  617 + /**
  618 + * read amf0 boolean from stream.
  619 + * 2.4 String Type
  620 + * boolean-type = boolean-marker U8
  621 + * 0 is false, <> 0 is true
  622 + * @return default value is false.
  623 + */
  624 + class __SrsAmf0Boolean : public SrsAmf0Any
  625 + {
  626 + public:
  627 + bool value;
  628 + public:
  629 + __SrsAmf0Boolean(bool _value);
  630 + virtual ~__SrsAmf0Boolean();
  631 + public:
  632 + virtual int total_size();
  633 + virtual int read(SrsStream* stream);
  634 + virtual int write(SrsStream* stream);
  635 + virtual SrsAmf0Any* copy();
  636 + };
  637 +
  638 + /**
  639 + * read amf0 number from stream.
  640 + * 2.2 Number Type
  641 + * number-type = number-marker DOUBLE
  642 + * @return default value is 0.
  643 + */
  644 + class __SrsAmf0Number : public SrsAmf0Any
  645 + {
  646 + public:
  647 + double value;
  648 + public:
  649 + __SrsAmf0Number(double _value);
  650 + virtual ~__SrsAmf0Number();
  651 + public:
  652 + virtual int total_size();
  653 + virtual int read(SrsStream* stream);
  654 + virtual int write(SrsStream* stream);
  655 + virtual SrsAmf0Any* copy();
  656 + };
  657 +
  658 + /**
  659 + * read amf0 null from stream.
  660 + * 2.7 null Type
  661 + * null-type = null-marker
  662 + */
  663 + class __SrsAmf0Null : public SrsAmf0Any
  664 + {
  665 + public:
  666 + __SrsAmf0Null();
  667 + virtual ~__SrsAmf0Null();
  668 + public:
  669 + virtual int total_size();
  670 + virtual int read(SrsStream* stream);
  671 + virtual int write(SrsStream* stream);
  672 + virtual SrsAmf0Any* copy();
  673 + };
  674 +
  675 + /**
  676 + * read amf0 undefined from stream.
  677 + * 2.8 undefined Type
  678 + * undefined-type = undefined-marker
  679 + */
  680 + class __SrsAmf0Undefined : public SrsAmf0Any
  681 + {
  682 + public:
  683 + __SrsAmf0Undefined();
  684 + virtual ~__SrsAmf0Undefined();
  685 + public:
  686 + virtual int total_size();
  687 + virtual int read(SrsStream* stream);
  688 + virtual int write(SrsStream* stream);
  689 + virtual SrsAmf0Any* copy();
  690 + };
  691 +
  692 + /**
  693 + * to ensure in inserted order.
  694 + * for the FMLE will crash when AMF0Object is not ordered by inserted,
  695 + * if ordered in map, the string compare order, the FMLE will creash when
  696 + * get the response of connect app.
  697 + */
  698 + class __SrsUnSortedHashtable
  699 + {
  700 + private:
  701 + typedef std::pair<std::string, SrsAmf0Any*> SrsAmf0ObjectPropertyType;
  702 + std::vector<SrsAmf0ObjectPropertyType> properties;
  703 + public:
  704 + __SrsUnSortedHashtable();
  705 + virtual ~__SrsUnSortedHashtable();
  706 + public:
  707 + virtual int count();
  708 + virtual void clear();
  709 + virtual std::string key_at(int index);
  710 + virtual const char* key_raw_at(int index);
  711 + virtual SrsAmf0Any* value_at(int index);
  712 + virtual void set(std::string key, SrsAmf0Any* value);
  713 + public:
  714 + virtual SrsAmf0Any* get_property(std::string name);
  715 + virtual SrsAmf0Any* ensure_property_string(std::string name);
  716 + virtual SrsAmf0Any* ensure_property_number(std::string name);
  717 + public:
  718 + virtual void copy(__SrsUnSortedHashtable* src);
  719 + };
  720 +
  721 + /**
  722 + * 2.11 Object End Type
  723 + * object-end-type = UTF-8-empty object-end-marker
  724 + * 0x00 0x00 0x09
  725 + */
  726 + class __SrsAmf0ObjectEOF : public SrsAmf0Any
  727 + {
  728 + public:
  729 + int16_t utf8_empty;
  730 +
  731 + __SrsAmf0ObjectEOF();
  732 + virtual ~__SrsAmf0ObjectEOF();
  733 +
  734 + virtual int total_size();
  735 + virtual int read(SrsStream* stream);
  736 + virtual int write(SrsStream* stream);
  737 + virtual SrsAmf0Any* copy();
  738 + };
  739 +
  740 + /**
  741 + * read amf0 utf8 string from stream.
  742 + * 1.3.1 Strings and UTF-8
  743 + * UTF-8 = U16 *(UTF8-char)
  744 + * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
  745 + * UTF8-1 = %x00-7F
  746 + * @remark only support UTF8-1 char.
  747 + */
  748 + extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);
  749 + extern int srs_amf0_write_utf8(SrsStream* stream, std::string value);
  750 +
  751 + extern bool srs_amf0_is_object_eof(SrsStream* stream);
  752 + extern int srs_amf0_write_object_eof(SrsStream* stream, __SrsAmf0ObjectEOF* value);
  753 +
  754 + extern int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value);
  755 +};
  756 +
588 #endif 757 #endif