Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2014-03-08 21:56:14 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
3129c738cb153fcce2eac03bf092b0beeb9f8f23
3129c738
1 parent
b55efef2
amf0 utest: refine interface of amf0, only export required objects
隐藏空白字符变更
内嵌
并排对比
正在显示
5 个修改的文件
包含
357 行增加
和
288 行删除
trunk/src/rtmp/srs_protocol_amf0.cpp
trunk/src/rtmp/srs_protocol_amf0.hpp
trunk/src/rtmp/srs_protocol_rtmp.cpp
trunk/src/rtmp/srs_protocol_rtmp_stack.cpp
trunk/src/utest/srs_utest_amf0.cpp
trunk/src/rtmp/srs_protocol_amf0.cpp
查看文件 @
3129c73
...
...
@@ -57,18 +57,139 @@ using namespace std;
#define RTMP_AMF0_Invalid 0x3F
/**
* convert the any to specified object.
* @return T, the converted object. never NULL.
* @remark, user must ensure the current object type,
* or the covert will cause assert failed.
* read amf0 string from stream.
* 2.4 String Type
* string-type = string-marker UTF-8
* @return default value is empty string.
* @remark: use SrsAmf0Any::str() to create it.
*/
template
<
class
T
>
T
srs_amf0_convert
(
SrsAmf0Any
*
any
)
class
__SrsAmf0String
:
public
SrsAmf0Any
{
T
p
=
dynamic_cast
<
T
>
(
any
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
public
:
std
::
string
value
;
__SrsAmf0String
(
const
char
*
_value
);
virtual
~
__SrsAmf0String
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 boolean from stream.
* 2.4 String Type
* boolean-type = boolean-marker U8
* 0 is false, <> 0 is true
* @return default value is false.
*/
class
__SrsAmf0Boolean
:
public
SrsAmf0Any
{
public
:
bool
value
;
__SrsAmf0Boolean
(
bool
_value
);
virtual
~
__SrsAmf0Boolean
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 number from stream.
* 2.2 Number Type
* number-type = number-marker DOUBLE
* @return default value is 0.
*/
class
__SrsAmf0Number
:
public
SrsAmf0Any
{
public
:
double
value
;
__SrsAmf0Number
(
double
_value
);
virtual
~
__SrsAmf0Number
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 null from stream.
* 2.7 null Type
* null-type = null-marker
*/
class
__SrsAmf0Null
:
public
SrsAmf0Any
{
public
:
__SrsAmf0Null
();
virtual
~
__SrsAmf0Null
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 undefined from stream.
* 2.8 undefined Type
* undefined-type = undefined-marker
*/
class
__SrsAmf0Undefined
:
public
SrsAmf0Any
{
public
:
__SrsAmf0Undefined
();
virtual
~
__SrsAmf0Undefined
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* to ensure in inserted order.
* for the FMLE will crash when AMF0Object is not ordered by inserted,
* if ordered in map, the string compare order, the FMLE will creash when
* get the response of connect app.
*/
class
__SrsUnSortedHashtable
{
private
:
typedef
std
::
pair
<
std
::
string
,
SrsAmf0Any
*>
SrsObjectPropertyType
;
std
::
vector
<
SrsObjectPropertyType
>
properties
;
public
:
__SrsUnSortedHashtable
();
virtual
~
__SrsUnSortedHashtable
();
virtual
int
size
();
virtual
void
clear
();
virtual
std
::
string
key_at
(
int
index
);
virtual
SrsAmf0Any
*
value_at
(
int
index
);
virtual
void
set
(
std
::
string
key
,
SrsAmf0Any
*
value
);
virtual
SrsAmf0Any
*
get_property
(
std
::
string
name
);
virtual
SrsAmf0Any
*
ensure_property_string
(
std
::
string
name
);
virtual
SrsAmf0Any
*
ensure_property_number
(
std
::
string
name
);
};
/**
* 2.11 Object End Type
* object-end-type = UTF-8-empty object-end-marker
* 0x00 0x00 0x09
*/
class
__SrsAmf0ObjectEOF
:
public
SrsAmf0Any
{
public
:
int16_t
utf8_empty
;
__SrsAmf0ObjectEOF
();
virtual
~
__SrsAmf0ObjectEOF
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 utf8 string from stream.
...
...
@@ -130,20 +251,37 @@ bool SrsAmf0Any::is_ecma_array()
string
SrsAmf0Any
::
to_str
()
{
__SrsAmf0String
*
o
=
srs_amf0_convert
<
__SrsAmf0String
*>
(
this
);
return
o
->
value
;
__SrsAmf0String
*
p
=
dynamic_cast
<
__SrsAmf0String
*>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
->
value
;
}
bool
SrsAmf0Any
::
to_boolean
()
{
__SrsAmf0Boolean
*
o
=
srs_amf0_convert
<
__SrsAmf0Boolean
*>
(
this
);
return
o
->
value
;
__SrsAmf0Boolean
*
p
=
dynamic_cast
<
__SrsAmf0Boolean
*>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
->
value
;
}
double
SrsAmf0Any
::
to_number
()
{
__SrsAmf0Number
*
o
=
srs_amf0_convert
<
__SrsAmf0Number
*>
(
this
);
return
o
->
value
;
__SrsAmf0Number
*
p
=
dynamic_cast
<
__SrsAmf0Number
*>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
->
value
;
}
SrsAmf0Object
*
SrsAmf0Any
::
to_object
()
{
SrsAmf0Object
*
p
=
dynamic_cast
<
SrsAmf0Object
*>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
SrsAmf0EcmaArray
*
SrsAmf0Any
::
to_array
()
{
SrsAmf0EcmaArray
*
p
=
dynamic_cast
<
SrsAmf0EcmaArray
*>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
bool
SrsAmf0Any
::
is_object_eof
()
...
...
@@ -216,31 +354,31 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
switch
(
marker
)
{
case
RTMP_AMF0_String
:
{
*
ppvalue
=
new
__SrsAmf0String
();
*
ppvalue
=
SrsAmf0Any
::
str
();
return
ret
;
}
case
RTMP_AMF0_Boolean
:
{
*
ppvalue
=
new
__SrsAmf0B
oolean
();
*
ppvalue
=
SrsAmf0Any
::
b
oolean
();
return
ret
;
}
case
RTMP_AMF0_Number
:
{
*
ppvalue
=
new
__SrsAmf0N
umber
();
*
ppvalue
=
SrsAmf0Any
::
n
umber
();
return
ret
;
}
case
RTMP_AMF0_Null
:
{
*
ppvalue
=
new
__SrsAmf0N
ull
();
*
ppvalue
=
SrsAmf0Any
::
n
ull
();
return
ret
;
}
case
RTMP_AMF0_Undefined
:
{
*
ppvalue
=
new
__SrsAmf0U
ndefined
();
*
ppvalue
=
SrsAmf0Any
::
u
ndefined
();
return
ret
;
}
case
RTMP_AMF0_Object
:
{
*
ppvalue
=
new
SrsAmf0O
bject
();
*
ppvalue
=
SrsAmf0Any
::
o
bject
();
return
ret
;
}
case
RTMP_AMF0_EcmaArray
:
{
*
ppvalue
=
new
SrsAmf0EcmaA
rray
();
*
ppvalue
=
SrsAmf0Any
::
a
rray
();
return
ret
;
}
case
RTMP_AMF0_Invalid
:
...
...
@@ -445,11 +583,15 @@ int __SrsAmf0ObjectEOF::write(SrsStream* stream)
SrsAmf0Object
::
SrsAmf0Object
()
{
properties
=
new
__SrsUnSortedHashtable
();
eof
=
new
__SrsAmf0ObjectEOF
();
marker
=
RTMP_AMF0_Object
;
}
SrsAmf0Object
::~
SrsAmf0Object
()
{
srs_freep
(
properties
);
srs_freep
(
eof
);
}
int
SrsAmf0Object
::
read
(
SrsStream
*
stream
)
...
...
@@ -476,8 +618,8 @@ int SrsAmf0Object::read(SrsStream* stream)
while
(
!
stream
->
empty
())
{
// detect whether is eof.
if
(
srs_amf0_is_object_eof
(
stream
))
{
__SrsAmf0ObjectEOF
eof
;
if
((
ret
=
eof
.
read
(
stream
))
!=
ERROR_SUCCESS
)
{
__SrsAmf0ObjectEOF
pbj_eof
;
if
((
ret
=
pbj_eof
.
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 object read eof failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -522,7 +664,7 @@ int SrsAmf0Object::write(SrsStream* stream)
srs_verbose
(
"amf0 write object marker success"
);
// value
for
(
int
i
=
0
;
i
<
properties
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
properties
->
size
();
i
++
)
{
std
::
string
name
=
this
->
key_at
(
i
);
SrsAmf0Any
*
any
=
this
->
value_at
(
i
);
...
...
@@ -539,7 +681,7 @@ int SrsAmf0Object::write(SrsStream* stream)
srs_verbose
(
"write amf0 property success. name=%s"
,
name
.
c_str
());
}
if
((
ret
=
eof
.
write
(
stream
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
eof
->
write
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write object eof failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -553,7 +695,7 @@ int SrsAmf0Object::size()
{
int
size
=
1
;
for
(
int
i
=
0
;
i
<
properties
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
properties
->
size
();
i
++
){
std
::
string
name
=
key_at
(
i
);
SrsAmf0Any
*
value
=
value_at
(
i
);
...
...
@@ -568,41 +710,45 @@ int SrsAmf0Object::size()
std
::
string
SrsAmf0Object
::
key_at
(
int
index
)
{
return
properties
.
key_at
(
index
);
return
properties
->
key_at
(
index
);
}
SrsAmf0Any
*
SrsAmf0Object
::
value_at
(
int
index
)
{
return
properties
.
value_at
(
index
);
return
properties
->
value_at
(
index
);
}
void
SrsAmf0Object
::
set
(
std
::
string
key
,
SrsAmf0Any
*
value
)
{
properties
.
set
(
key
,
value
);
properties
->
set
(
key
,
value
);
}
SrsAmf0Any
*
SrsAmf0Object
::
get_property
(
std
::
string
name
)
{
return
properties
.
get_property
(
name
);
return
properties
->
get_property
(
name
);
}
SrsAmf0Any
*
SrsAmf0Object
::
ensure_property_string
(
std
::
string
name
)
{
return
properties
.
ensure_property_string
(
name
);
return
properties
->
ensure_property_string
(
name
);
}
SrsAmf0Any
*
SrsAmf0Object
::
ensure_property_number
(
std
::
string
name
)
{
return
properties
.
ensure_property_number
(
name
);
return
properties
->
ensure_property_number
(
name
);
}
SrsAmf0EcmaArray
::
SrsAmf0EcmaArray
()
{
properties
=
new
__SrsUnSortedHashtable
();
eof
=
new
__SrsAmf0ObjectEOF
();
marker
=
RTMP_AMF0_EcmaArray
;
}
SrsAmf0EcmaArray
::~
SrsAmf0EcmaArray
()
{
srs_freep
(
properties
);
srs_freep
(
eof
);
}
int
SrsAmf0EcmaArray
::
read
(
SrsStream
*
stream
)
...
...
@@ -641,8 +787,8 @@ int SrsAmf0EcmaArray::read(SrsStream* stream)
while
(
!
stream
->
empty
())
{
// detect whether is eof.
if
(
srs_amf0_is_object_eof
(
stream
))
{
__SrsAmf0ObjectEOF
eof
;
if
((
ret
=
eof
.
read
(
stream
))
!=
ERROR_SUCCESS
)
{
__SrsAmf0ObjectEOF
pbj_eof
;
if
((
ret
=
pbj_eof
.
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 ecma_array read eof failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -695,7 +841,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream)
srs_verbose
(
"amf0 write ecma_array count success. count=%d"
,
value
->
count
);
// value
for
(
int
i
=
0
;
i
<
properties
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
properties
->
size
();
i
++
)
{
std
::
string
name
=
this
->
key_at
(
i
);
SrsAmf0Any
*
any
=
this
->
value_at
(
i
);
...
...
@@ -712,7 +858,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream)
srs_verbose
(
"write amf0 property success. name=%s"
,
name
.
c_str
());
}
if
((
ret
=
eof
.
write
(
stream
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
eof
->
write
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write ecma_array eof failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -726,7 +872,7 @@ int SrsAmf0EcmaArray::size()
{
int
size
=
1
+
4
;
for
(
int
i
=
0
;
i
<
properties
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
properties
->
size
();
i
++
){
std
::
string
name
=
key_at
(
i
);
SrsAmf0Any
*
value
=
value_at
(
i
);
...
...
@@ -741,32 +887,32 @@ int SrsAmf0EcmaArray::size()
void
SrsAmf0EcmaArray
::
clear
()
{
properties
.
clear
();
properties
->
clear
();
}
std
::
string
SrsAmf0EcmaArray
::
key_at
(
int
index
)
{
return
properties
.
key_at
(
index
);
return
properties
->
key_at
(
index
);
}
SrsAmf0Any
*
SrsAmf0EcmaArray
::
value_at
(
int
index
)
{
return
properties
.
value_at
(
index
);
return
properties
->
value_at
(
index
);
}
void
SrsAmf0EcmaArray
::
set
(
std
::
string
key
,
SrsAmf0Any
*
value
)
{
properties
.
set
(
key
,
value
);
properties
->
set
(
key
,
value
);
}
SrsAmf0Any
*
SrsAmf0EcmaArray
::
get_property
(
std
::
string
name
)
{
return
properties
.
get_property
(
name
);
return
properties
->
get_property
(
name
);
}
SrsAmf0Any
*
SrsAmf0EcmaArray
::
ensure_property_string
(
std
::
string
name
)
{
return
properties
.
ensure_property_string
(
name
);
return
properties
->
ensure_property_string
(
name
);
}
int
SrsAmf0Size
::
utf8
(
string
value
)
...
...
@@ -1353,7 +1499,7 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)
{
int
ret
=
ERROR_SUCCESS
;
value
=
new
SrsAmf0O
bject
();
value
=
SrsAmf0Any
::
o
bject
();
if
((
ret
=
value
->
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_freep
(
value
);
...
...
@@ -1371,7 +1517,7 @@ int srs_amf0_read_ecma_array(SrsStream* stream, SrsAmf0EcmaArray*& value)
{
int
ret
=
ERROR_SUCCESS
;
value
=
new
SrsAmf0EcmaA
rray
();
value
=
SrsAmf0Any
::
a
rray
();
if
((
ret
=
value
->
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_freep
(
value
);
...
...
trunk/src/rtmp/srs_protocol_amf0.hpp
查看文件 @
3129c73
...
...
@@ -36,6 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class
SrsStream
;
class
SrsAmf0Object
;
class
SrsAmf0EcmaArray
;
class
__SrsUnSortedHashtable
;
class
__SrsAmf0ObjectEOF
;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
...
@@ -46,21 +48,20 @@ class SrsAmf0EcmaArray;
// if ((ret = srs_amf0_read_any(stream, &pany)) != ERROR_SUCCESS) {
// return ret;
// }
// srs_assert(pany); // if success, always valid object.
// 2. SrsAmf0Any: convert to specifid type, for instance, string
// SrsAmf0Any* pany = ...
// if (pany
&& pany
->is_string()) {
// if (pany->is_string()) {
// string v = pany->to_str();
// }
// 3. SrsAmf0Any: parse specified type to any, for instance, string
// SrsAmf0Any* pany = SrsAmf0Any::str("winlin");
// 4. SrsAmf0Size: get amf0 instance size
// int size = SrsAmf0Size::str("winlin");
// 5. SrsAmf0Object: the amf0 object
, directly new is ok
.
// 5. SrsAmf0Object: the amf0 object.
// SrsAmf0Object* obj = SrsAmf0Any::object();
// SrsAmf0Object* obj = new SrsAmf0Object();
// 5. SrsAmf0EcmaArray: the amf0 ecma array, directly new is ok.
// 5. SrsAmf0EcmaArray: the amf0 ecma array.
// SrsAmf0EcmaArray* arr = SrsAmf0Any::array();
// SrsAmf0EcmaArray* arr = new SrsAmf0EcmaArray();
// for detail usage, see interfaces of each object.
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
...
@@ -106,6 +107,16 @@ public:
* user must ensure the type is a number, or assert failed.
*/
virtual
double
to_number
();
/**
* get the object of any when is_object() indicates true.
* user must ensure the type is a object, or assert failed.
*/
virtual
SrsAmf0Object
*
to_object
();
/**
* get the ecma array of any when is_ecma_array() indicates true.
* user must ensure the type is a ecma array, or assert failed.
*/
virtual
SrsAmf0EcmaArray
*
to_array
();
public
:
/**
* get the size of amf0 any, including the marker size.
...
...
@@ -130,50 +141,6 @@ public:
};
/**
* to ensure in inserted order.
* for the FMLE will crash when AMF0Object is not ordered by inserted,
* if ordered in map, the string compare order, the FMLE will creash when
* get the response of connect app.
*/
class
__SrsUnSortedHashtable
{
private
:
typedef
std
::
pair
<
std
::
string
,
SrsAmf0Any
*>
SrsObjectPropertyType
;
std
::
vector
<
SrsObjectPropertyType
>
properties
;
public
:
__SrsUnSortedHashtable
();
virtual
~
__SrsUnSortedHashtable
();
virtual
int
size
();
virtual
void
clear
();
virtual
std
::
string
key_at
(
int
index
);
virtual
SrsAmf0Any
*
value_at
(
int
index
);
virtual
void
set
(
std
::
string
key
,
SrsAmf0Any
*
value
);
virtual
SrsAmf0Any
*
get_property
(
std
::
string
name
);
virtual
SrsAmf0Any
*
ensure_property_string
(
std
::
string
name
);
virtual
SrsAmf0Any
*
ensure_property_number
(
std
::
string
name
);
};
/**
* 2.11 Object End Type
* object-end-type = UTF-8-empty object-end-marker
* 0x00 0x00 0x09
*/
class
__SrsAmf0ObjectEOF
:
public
SrsAmf0Any
{
public
:
int16_t
utf8_empty
;
__SrsAmf0ObjectEOF
();
virtual
~
__SrsAmf0ObjectEOF
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* 2.5 Object Type
* anonymous-object-type = object-marker *(object-property)
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
...
...
@@ -181,11 +148,14 @@ public:
class
SrsAmf0Object
:
public
SrsAmf0Any
{
private
:
__SrsUnSortedHashtable
properties
;
public
:
__SrsAmf0ObjectEOF
eof
;
__SrsUnSortedHashtable
*
properties
;
__SrsAmf0ObjectEOF
*
eof
;
private
:
// use SrsAmf0Any::object() to create it.
friend
class
SrsAmf0Any
;
SrsAmf0Object
();
public
:
virtual
~
SrsAmf0Object
();
virtual
int
read
(
SrsStream
*
stream
);
...
...
@@ -210,12 +180,15 @@ public:
class
SrsAmf0EcmaArray
:
public
SrsAmf0Any
{
private
:
__SrsUnSortedHashtable
properties
;
public
:
__SrsUnSortedHashtable
*
properties
;
__SrsAmf0ObjectEOF
*
eof
;
int32_t
count
;
__SrsAmf0ObjectEOF
eof
;
private
:
// use SrsAmf0Any::array() to create it.
friend
class
SrsAmf0Any
;
SrsAmf0EcmaArray
();
public
:
virtual
~
SrsAmf0EcmaArray
();
virtual
int
read
(
SrsStream
*
stream
);
...
...
@@ -250,98 +223,9 @@ public:
};
/**
* read amf0 string from stream.
* 2.4 String Type
* string-type = string-marker UTF-8
* @return default value is empty string.
* @remark: use SrsAmf0Any::str() to create it.
*/
class
__SrsAmf0String
:
public
SrsAmf0Any
{
public
:
std
::
string
value
;
__SrsAmf0String
(
const
char
*
_value
=
NULL
);
virtual
~
__SrsAmf0String
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 boolean from stream.
* 2.4 String Type
* boolean-type = boolean-marker U8
* 0 is false, <> 0 is true
* @return default value is false.
*/
class
__SrsAmf0Boolean
:
public
SrsAmf0Any
{
public
:
bool
value
;
__SrsAmf0Boolean
(
bool
_value
=
false
);
virtual
~
__SrsAmf0Boolean
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 number from stream.
* 2.2 Number Type
* number-type = number-marker DOUBLE
* @return default value is 0.
*/
class
__SrsAmf0Number
:
public
SrsAmf0Any
{
public
:
double
value
;
__SrsAmf0Number
(
double
_value
=
0.0
);
virtual
~
__SrsAmf0Number
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 null from stream.
* 2.7 null Type
* null-type = null-marker
*/
class
__SrsAmf0Null
:
public
SrsAmf0Any
{
public
:
__SrsAmf0Null
();
virtual
~
__SrsAmf0Null
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 undefined from stream.
* 2.8 undefined Type
* undefined-type = undefined-marker
*/
class
__SrsAmf0Undefined
:
public
SrsAmf0Any
{
public
:
__SrsAmf0Undefined
();
virtual
~
__SrsAmf0Undefined
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read anything from stream.
* @param ppvalue, the output amf0 any elem.
* NULL if error; otherwise, never NULL and user must free it.
*/
extern
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
**
ppvalue
);
...
...
trunk/src/rtmp/srs_protocol_rtmp.cpp
查看文件 @
3129c73
...
...
@@ -279,7 +279,7 @@ int SrsRtmpClient::connect_app(string app, string tc_url)
SrsConnectAppPacket
*
pkt
=
new
SrsConnectAppPacket
();
msg
->
set_packet
(
pkt
,
0
);
pkt
->
command_object
=
new
SrsAmf0O
bject
();
pkt
->
command_object
=
SrsAmf0Any
::
o
bject
();
pkt
->
command_object
->
set
(
"app"
,
SrsAmf0Any
::
str
(
app
.
c_str
()));
pkt
->
command_object
->
set
(
"swfUrl"
,
SrsAmf0Any
::
str
());
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)
pkt
->
info
->
set
(
StatusCode
,
SrsAmf0Any
::
str
(
StatusCodeConnectSuccess
));
pkt
->
info
->
set
(
StatusDescription
,
SrsAmf0Any
::
str
(
"Connection succeeded"
));
pkt
->
info
->
set
(
"objectEncoding"
,
SrsAmf0Any
::
number
(
req
->
objectEncoding
));
SrsAmf0EcmaArray
*
data
=
new
SrsAmf0EcmaA
rray
();
SrsAmf0EcmaArray
*
data
=
SrsAmf0Any
::
a
rray
();
pkt
->
info
->
set
(
"data"
,
data
);
data
->
set
(
"version"
,
SrsAmf0Any
::
str
(
RTMP_SIG_FMS_VER
));
...
...
trunk/src/rtmp/srs_protocol_rtmp_stack.cpp
查看文件 @
3129c73
...
...
@@ -1828,8 +1828,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket()
transaction_id
=
1
;
// TODO: FIXME: memory leak for decode will set the props and info.
// TODO: FIXME: bug#22, refine the amf0.
props
=
new
SrsAmf0Object
();
info
=
new
SrsAmf0Object
();
props
=
SrsAmf0Any
::
object
();
info
=
SrsAmf0Any
::
object
();
}
SrsConnectAppResPacket
::~
SrsConnectAppResPacket
()
...
...
@@ -2718,7 +2718,7 @@ SrsPlayResPacket::SrsPlayResPacket()
command_name
=
RTMP_AMF0_COMMAND_RESULT
;
transaction_id
=
0
;
command_object
=
SrsAmf0Any
::
null
();
desc
=
new
SrsAmf0O
bject
();
desc
=
SrsAmf0Any
::
o
bject
();
}
SrsPlayResPacket
::~
SrsPlayResPacket
()
...
...
@@ -2837,7 +2837,7 @@ SrsOnStatusCallPacket::SrsOnStatusCallPacket()
command_name
=
RTMP_AMF0_COMMAND_ON_STATUS
;
transaction_id
=
0
;
args
=
SrsAmf0Any
::
null
();
data
=
new
SrsAmf0O
bject
();
data
=
SrsAmf0Any
::
o
bject
();
}
SrsOnStatusCallPacket
::~
SrsOnStatusCallPacket
()
...
...
@@ -2900,7 +2900,7 @@ SrsBandwidthPacket::SrsBandwidthPacket()
command_name
=
RTMP_AMF0_COMMAND_ON_STATUS
;
transaction_id
=
0
;
args
=
SrsAmf0Any
::
null
();
data
=
new
SrsAmf0O
bject
();
data
=
SrsAmf0Any
::
o
bject
();
}
SrsBandwidthPacket
::~
SrsBandwidthPacket
()
...
...
@@ -3055,7 +3055,7 @@ SrsBandwidthPacket* SrsBandwidthPacket::set_command(string command)
SrsOnStatusDataPacket
::
SrsOnStatusDataPacket
()
{
command_name
=
RTMP_AMF0_COMMAND_ON_STATUS
;
data
=
new
SrsAmf0O
bject
();
data
=
SrsAmf0Any
::
o
bject
();
}
SrsOnStatusDataPacket
::~
SrsOnStatusDataPacket
()
...
...
@@ -3156,7 +3156,7 @@ int SrsSampleAccessPacket::encode_packet(SrsStream* stream)
SrsOnMetaDataPacket
::
SrsOnMetaDataPacket
()
{
name
=
RTMP_AMF0_DATA_ON_METADATA
;
metadata
=
new
SrsAmf0O
bject
();
metadata
=
SrsAmf0Any
::
o
bject
();
}
SrsOnMetaDataPacket
::~
SrsOnMetaDataPacket
()
...
...
@@ -3190,27 +3190,27 @@ int SrsOnMetaDataPacket::decode(SrsStream* stream)
return
ret
;
}
if
(
any
&&
any
->
is_object
())
{
srs_assert
(
any
);
if
(
any
->
is_object
())
{
srs_freep
(
metadata
);
metadata
=
dynamic_cast
<
SrsAmf0Object
*>
(
any
);
metadata
=
any
->
to_object
(
);
srs_info
(
"decode metadata object success"
);
return
ret
;
}
SrsAmf0EcmaArray
*
arr
=
dynamic_cast
<
SrsAmf0EcmaArray
*>
(
any
);
if
(
!
arr
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"decode metadata array failed. ret=%d"
,
ret
);
return
ret
;
}
SrsAutoFree
(
SrsAmf0Any
,
any
,
false
);
// if ecma array, copy to object.
SrsAutoFree
(
SrsAmf0EcmaArray
,
arr
,
false
);
for
(
int
i
=
0
;
i
<
arr
->
size
();
i
++
)
{
metadata
->
set
(
arr
->
key_at
(
i
),
arr
->
value_at
(
i
));
if
(
any
->
is_ecma_array
())
{
SrsAmf0EcmaArray
*
arr
=
any
->
to_array
();
// if ecma array, copy to object.
for
(
int
i
=
0
;
i
<
arr
->
size
();
i
++
)
{
metadata
->
set
(
arr
->
key_at
(
i
),
arr
->
value_at
(
i
));
}
arr
->
clear
();
srs_info
(
"decode metadata array success"
);
}
arr
->
clear
();
srs_info
(
"decode metadata array success"
);
return
ret
;
}
...
...
trunk/src/utest/srs_utest_amf0.cpp
查看文件 @
3129c73
...
...
@@ -46,221 +46,239 @@ VOID TEST(AMF0Test, Size)
// object: empty
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
// object: elem
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"age"
)
+
SrsAmf0Size
::
number
();
o
.
set
(
"age"
,
SrsAmf0Any
::
number
(
9
));
o
->
set
(
"age"
,
SrsAmf0Any
::
number
(
9
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"email"
)
+
SrsAmf0Size
::
null
();
o
.
set
(
"email"
,
SrsAmf0Any
::
null
());
o
->
set
(
"email"
,
SrsAmf0Any
::
null
());
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"email"
)
+
SrsAmf0Size
::
undefined
();
o
.
set
(
"email"
,
SrsAmf0Any
::
undefined
());
o
->
set
(
"email"
,
SrsAmf0Any
::
undefined
());
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"sex"
)
+
SrsAmf0Size
::
boolean
();
o
.
set
(
"sex"
,
SrsAmf0Any
::
boolean
(
true
));
o
->
set
(
"sex"
,
SrsAmf0Any
::
boolean
(
true
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
// array: empty
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
// array: elem
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"age"
)
+
SrsAmf0Size
::
number
();
o
.
set
(
"age"
,
SrsAmf0Any
::
number
(
9
));
o
->
set
(
"age"
,
SrsAmf0Any
::
number
(
9
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"email"
)
+
SrsAmf0Size
::
null
();
o
.
set
(
"email"
,
SrsAmf0Any
::
null
());
o
->
set
(
"email"
,
SrsAmf0Any
::
null
());
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"email"
)
+
SrsAmf0Size
::
undefined
();
o
.
set
(
"email"
,
SrsAmf0Any
::
undefined
());
o
->
set
(
"email"
,
SrsAmf0Any
::
undefined
());
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"sex"
)
+
SrsAmf0Size
::
boolean
();
o
.
set
(
"sex"
,
SrsAmf0Any
::
boolean
(
true
));
o
->
set
(
"sex"
,
SrsAmf0Any
::
boolean
(
true
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
// object: array
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
SrsAmf0EcmaArray
*
args
=
new
SrsAmf0EcmaA
rray
();
SrsAmf0EcmaArray
*
args
=
SrsAmf0Any
::
a
rray
();
args
->
set
(
"p0"
,
SrsAmf0Any
::
str
(
"function"
));
size
+=
SrsAmf0Size
::
utf8
(
"args"
)
+
SrsAmf0Size
::
array
(
args
);
o
.
set
(
"args"
,
args
);
o
->
set
(
"args"
,
args
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
SrsAmf0EcmaArray
*
args
=
new
SrsAmf0EcmaA
rray
();
SrsAmf0EcmaArray
*
args
=
SrsAmf0Any
::
a
rray
();
args
->
set
(
"p0"
,
SrsAmf0Any
::
str
(
"function"
));
size
+=
SrsAmf0Size
::
utf8
(
"args"
)
+
SrsAmf0Size
::
array
(
args
);
o
.
set
(
"args"
,
args
);
o
->
set
(
"args"
,
args
);
SrsAmf0EcmaArray
*
params
=
new
SrsAmf0EcmaA
rray
();
SrsAmf0EcmaArray
*
params
=
SrsAmf0Any
::
a
rray
();
params
->
set
(
"p1"
,
SrsAmf0Any
::
number
(
10
));
size
+=
SrsAmf0Size
::
utf8
(
"params"
)
+
SrsAmf0Size
::
array
(
params
);
o
.
set
(
"params"
,
params
);
o
->
set
(
"params"
,
params
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
// array: object
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
SrsAmf0Object
*
args
=
new
SrsAmf0O
bject
();
SrsAmf0Object
*
args
=
SrsAmf0Any
::
o
bject
();
args
->
set
(
"p0"
,
SrsAmf0Any
::
str
(
"function"
));
size
+=
SrsAmf0Size
::
utf8
(
"args"
)
+
SrsAmf0Size
::
object
(
args
);
o
.
set
(
"args"
,
args
);
o
->
set
(
"args"
,
args
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
SrsAmf0Object
*
args
=
new
SrsAmf0O
bject
();
SrsAmf0Object
*
args
=
SrsAmf0Any
::
o
bject
();
args
->
set
(
"p0"
,
SrsAmf0Any
::
str
(
"function"
));
size
+=
SrsAmf0Size
::
utf8
(
"args"
)
+
SrsAmf0Size
::
object
(
args
);
o
.
set
(
"args"
,
args
);
o
->
set
(
"args"
,
args
);
SrsAmf0Object
*
params
=
new
SrsAmf0O
bject
();
SrsAmf0Object
*
params
=
SrsAmf0Any
::
o
bject
();
params
->
set
(
"p1"
,
SrsAmf0Any
::
number
(
10
));
size
+=
SrsAmf0Size
::
utf8
(
"params"
)
+
SrsAmf0Size
::
object
(
params
);
o
.
set
(
"params"
,
params
);
o
->
set
(
"params"
,
params
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
// object: object
if
(
true
)
{
int
size
=
1
+
3
;
SrsAmf0Object
o
;
SrsAmf0Object
*
o
=
SrsAmf0Any
::
object
();
SrsAutoFree
(
SrsAmf0Object
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
SrsAmf0Object
*
args
=
new
SrsAmf0O
bject
();
SrsAmf0Object
*
args
=
SrsAmf0Any
::
o
bject
();
args
->
set
(
"p0"
,
SrsAmf0Any
::
str
(
"function"
));
size
+=
SrsAmf0Size
::
utf8
(
"args"
)
+
SrsAmf0Size
::
object
(
args
);
o
.
set
(
"args"
,
args
);
o
->
set
(
"args"
,
args
);
SrsAmf0Object
*
params
=
new
SrsAmf0O
bject
();
SrsAmf0Object
*
params
=
SrsAmf0Any
::
o
bject
();
params
->
set
(
"p1"
,
SrsAmf0Any
::
number
(
10
));
size
+=
SrsAmf0Size
::
utf8
(
"params"
)
+
SrsAmf0Size
::
object
(
params
);
o
.
set
(
"params"
,
params
);
o
->
set
(
"params"
,
params
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
object
(
o
));
}
// array: array
if
(
true
)
{
int
size
=
1
+
4
+
3
;
SrsAmf0EcmaArray
o
;
SrsAmf0EcmaArray
*
o
=
SrsAmf0Any
::
array
();
SrsAutoFree
(
SrsAmf0EcmaArray
,
o
,
false
);
size
+=
SrsAmf0Size
::
utf8
(
"name"
)
+
SrsAmf0Size
::
str
(
"winlin"
);
o
.
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
o
->
set
(
"name"
,
SrsAmf0Any
::
str
(
"winlin"
));
SrsAmf0EcmaArray
*
args
=
new
SrsAmf0EcmaA
rray
();
SrsAmf0EcmaArray
*
args
=
SrsAmf0Any
::
a
rray
();
args
->
set
(
"p0"
,
SrsAmf0Any
::
str
(
"function"
));
size
+=
SrsAmf0Size
::
utf8
(
"args"
)
+
SrsAmf0Size
::
array
(
args
);
o
.
set
(
"args"
,
args
);
o
->
set
(
"args"
,
args
);
SrsAmf0EcmaArray
*
params
=
new
SrsAmf0EcmaA
rray
();
SrsAmf0EcmaArray
*
params
=
SrsAmf0Any
::
a
rray
();
params
->
set
(
"p1"
,
SrsAmf0Any
::
number
(
10
));
size
+=
SrsAmf0Size
::
utf8
(
"params"
)
+
SrsAmf0Size
::
array
(
params
);
o
.
set
(
"params"
,
params
);
o
->
set
(
"params"
,
params
);
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
&
o
));
EXPECT_EQ
(
size
,
SrsAmf0Size
::
array
(
o
));
}
}
...
...
@@ -656,3 +674,24 @@ VOID TEST(AMF0Test, AnyIO)
srs_freep
(
po
);
}
}
VOID
TEST
(
AMF0Test
,
AnyAssert
)
{
SrsStream
s
;
SrsAmf0Any
*
o
=
NULL
;
char
buf
[
1024
];
memset
(
buf
,
0
,
sizeof
(
buf
));
EXPECT_EQ
(
ERROR_SUCCESS
,
s
.
initialize
(
buf
,
sizeof
(
buf
)));
// read any
if
(
true
)
{
s
.
reset
();
s
.
current
()[
0
]
=
0x12
;
EXPECT_NE
(
ERROR_SUCCESS
,
srs_amf0_read_any
(
&
s
,
&
o
));
EXPECT_TRUE
(
NULL
==
o
);
srs_freep
(
o
);
}
//
}
...
...
请
注册
或
登录
后发表评论