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 16:56:35 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
4306db099dd06689791d5cc8a7600ec5ef66c735
4306db09
1 parent
bfe771bb
amf0 utest: elem read/write refined
隐藏空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
514 行增加
和
137 行删除
trunk/src/kernel/srs_kernel_stream.cpp
trunk/src/rtmp/srs_protocol_amf0.cpp
trunk/src/rtmp/srs_protocol_amf0.hpp
trunk/src/rtmp/srs_protocol_rtmp_stack.cpp
trunk/src/utest/srs_utest_amf0.cpp
trunk/src/utest/srs_utest_amf0.hpp
trunk/src/kernel/srs_kernel_stream.cpp
查看文件 @
4306db0
...
...
@@ -80,10 +80,6 @@ void SrsStream::skip(int size)
int
SrsStream
::
pos
()
{
if
(
empty
())
{
return
0
;
}
return
p
-
bytes
;
}
...
...
trunk/src/rtmp/srs_protocol_amf0.cpp
查看文件 @
4306db0
...
...
@@ -56,9 +56,32 @@ using namespace std;
// User defined
#define RTMP_AMF0_Invalid 0x3F
int
srs_amf0_read_object_eof
(
SrsStream
*
stream
,
__SrsAmf0ObjectEOF
*&
);
int
srs_amf0_write_object_eof
(
SrsStream
*
stream
,
__SrsAmf0ObjectEOF
*
);
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
*&
value
);
/**
* 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.
*/
template
<
class
T
>
T
srs_amf0_convert
(
SrsAmf0Any
*
any
)
{
T
p
=
dynamic_cast
<
T
>
(
any
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
/**
* read amf0 utf8 string from stream.
* 1.3.1 Strings and UTF-8
* UTF-8 = U16 *(UTF8-char)
* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
* UTF8-1 = %x00-7F
* @remark only support UTF8-1 char.
*/
extern
int
srs_amf0_read_utf8
(
SrsStream
*
stream
,
std
::
string
&
value
);
extern
int
srs_amf0_write_utf8
(
SrsStream
*
stream
,
std
::
string
value
);
bool
srs_amf0_is_object_eof
(
SrsStream
*
stream
);
int
srs_amf0_write_any
(
SrsStream
*
stream
,
SrsAmf0Any
*
value
);
SrsAmf0Any
::
SrsAmf0Any
()
...
...
@@ -107,19 +130,19 @@ bool SrsAmf0Any::is_ecma_array()
string
SrsAmf0Any
::
to_str
()
{
__SrsAmf0String
*
o
=
srs_amf0_convert
<
__SrsAmf0String
>
(
this
);
__SrsAmf0String
*
o
=
srs_amf0_convert
<
__SrsAmf0String
*
>
(
this
);
return
o
->
value
;
}
bool
SrsAmf0Any
::
to_boolean
()
{
__SrsAmf0Boolean
*
o
=
srs_amf0_convert
<
__SrsAmf0Boolean
>
(
this
);
__SrsAmf0Boolean
*
o
=
srs_amf0_convert
<
__SrsAmf0Boolean
*
>
(
this
);
return
o
->
value
;
}
double
SrsAmf0Any
::
to_number
()
{
__SrsAmf0Number
*
o
=
srs_amf0_convert
<
__SrsAmf0Number
>
(
this
);
__SrsAmf0Number
*
o
=
srs_amf0_convert
<
__SrsAmf0Number
*
>
(
this
);
return
o
->
value
;
}
...
...
@@ -153,6 +176,11 @@ SrsAmf0Any* SrsAmf0Any::undefined()
return
new
__SrsAmf0Undefined
();
}
SrsAmf0Any
*
SrsAmf0Any
::
object_eof
()
{
return
new
__SrsAmf0ObjectEOF
();
}
__SrsUnSortedHashtable
::
__SrsUnSortedHashtable
()
{
}
...
...
@@ -194,6 +222,11 @@ SrsAmf0Any* __SrsUnSortedHashtable::value_at(int index)
void
__SrsUnSortedHashtable
::
set
(
std
::
string
key
,
SrsAmf0Any
*
value
)
{
if
(
!
value
)
{
srs_warn
(
"add a NULL propertity %s"
,
key
.
c_str
());
return
;
}
std
::
vector
<
SrsObjectPropertyType
>::
iterator
it
;
for
(
it
=
properties
.
begin
();
it
!=
properties
.
end
();
++
it
)
{
...
...
@@ -272,6 +305,71 @@ int __SrsAmf0ObjectEOF::size()
return
SrsAmf0Size
::
object_eof
();
}
int
__SrsAmf0ObjectEOF
::
read
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
// value
if
(
!
stream
->
require
(
2
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof value failed. ret=%d"
,
ret
);
return
ret
;
}
int16_t
temp
=
stream
->
read_2bytes
();
if
(
temp
!=
0x00
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof value check failed. "
"must be 0x00, actual is %#x, ret=%d"
,
temp
,
ret
);
return
ret
;
}
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_1bytes
();
if
(
marker
!=
RTMP_AMF0_ObjectEnd
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check object eof marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_ObjectEnd
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read object eof marker success"
);
srs_verbose
(
"amf0 read object eof success"
);
return
ret
;
}
int
__SrsAmf0ObjectEOF
::
write
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
// value
if
(
!
stream
->
require
(
2
))
{
ret
=
ERROR_RTMP_AMF0_ENCODE
;
srs_error
(
"amf0 write object eof value failed. ret=%d"
,
ret
);
return
ret
;
}
stream
->
write_2bytes
(
0x00
);
srs_verbose
(
"amf0 write object eof value success"
);
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_ENCODE
;
srs_error
(
"amf0 write object eof marker failed. ret=%d"
,
ret
);
return
ret
;
}
stream
->
write_1bytes
(
RTMP_AMF0_ObjectEnd
);
srs_verbose
(
"amf0 read object eof success"
);
return
ret
;
}
SrsAmf0Object
::
SrsAmf0Object
()
{
marker
=
RTMP_AMF0_Object
;
...
...
@@ -303,6 +401,17 @@ int SrsAmf0Object::read(SrsStream* stream)
// value
while
(
!
stream
->
empty
())
{
// detect whether is eof.
if
(
srs_amf0_is_object_eof
(
stream
))
{
__SrsAmf0ObjectEOF
eof
;
if
((
ret
=
eof
.
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 object read eof failed. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"amf0 read object EOF."
);
break
;
}
// property-name: utf8 string
std
::
string
property_name
;
if
((
ret
=
srs_amf0_read_utf8
(
stream
,
property_name
))
!=
ERROR_SUCCESS
)
{
...
...
@@ -311,21 +420,13 @@ int SrsAmf0Object::read(SrsStream* stream)
}
// property-value: any
SrsAmf0Any
*
property_value
=
NULL
;
if
((
ret
=
srs_amf0_read_any
(
stream
,
property_value
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
srs_amf0_read_any
(
stream
,
&
property_value
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 object read property_value failed. "
"name=%s, ret=%d"
,
property_name
.
c_str
(),
ret
);
srs_freep
(
property_value
);
return
ret
;
}
// AMF0 Object EOF.
if
(
property_name
.
empty
()
||
!
property_value
||
property_value
->
is_object_eof
())
{
if
(
property_value
)
{
srs_freep
(
property_value
);
}
srs_info
(
"amf0 read object EOF."
);
break
;
}
// add property
this
->
set
(
property_name
,
property_value
);
}
...
...
@@ -365,7 +466,7 @@ int SrsAmf0Object::write(SrsStream* stream)
srs_verbose
(
"write amf0 property success. name=%s"
,
name
.
c_str
());
}
if
((
ret
=
srs_amf0_write_object_eof
(
stream
,
&
this
->
eof
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
eof
.
write
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write object eof failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -465,6 +566,17 @@ int SrsAmf0EcmaArray::read(SrsStream* stream)
this
->
count
=
count
;
while
(
!
stream
->
empty
())
{
// detect whether is eof.
if
(
srs_amf0_is_object_eof
(
stream
))
{
__SrsAmf0ObjectEOF
eof
;
if
((
ret
=
eof
.
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 ecma_array read eof failed. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"amf0 read ecma_array EOF."
);
break
;
}
// property-name: utf8 string
std
::
string
property_name
;
if
((
ret
=
srs_amf0_read_utf8
(
stream
,
property_name
))
!=
ERROR_SUCCESS
)
{
...
...
@@ -473,21 +585,12 @@ int SrsAmf0EcmaArray::read(SrsStream* stream)
}
// property-value: any
SrsAmf0Any
*
property_value
=
NULL
;
if
((
ret
=
srs_amf0_read_any
(
stream
,
property_value
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
srs_amf0_read_any
(
stream
,
&
property_value
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 ecma_array read property_value failed. "
"name=%s, ret=%d"
,
property_name
.
c_str
(),
ret
);
return
ret
;
}
// AMF0 Object EOF.
if
(
property_name
.
empty
()
||
!
property_value
||
property_value
->
is_object_eof
())
{
if
(
property_value
)
{
srs_freep
(
property_value
);
}
srs_info
(
"amf0 read ecma_array EOF."
);
break
;
}
// add property
this
->
set
(
property_name
,
property_value
);
}
...
...
@@ -536,7 +639,7 @@ int SrsAmf0EcmaArray::write(SrsStream* stream)
srs_verbose
(
"write amf0 property success. name=%s"
,
name
.
c_str
());
}
if
((
ret
=
srs_amf0_write_object_eof
(
stream
,
&
this
->
eof
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
eof
.
write
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write ecma_array eof failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -672,6 +775,16 @@ int __SrsAmf0String::size()
return
SrsAmf0Size
::
str
(
value
);
}
int
__SrsAmf0String
::
read
(
SrsStream
*
stream
)
{
return
srs_amf0_read_string
(
stream
,
value
);
}
int
__SrsAmf0String
::
write
(
SrsStream
*
stream
)
{
return
srs_amf0_write_string
(
stream
,
value
);
}
__SrsAmf0Boolean
::
__SrsAmf0Boolean
(
bool
_value
)
{
marker
=
RTMP_AMF0_Boolean
;
...
...
@@ -687,6 +800,16 @@ int __SrsAmf0Boolean::size()
return
SrsAmf0Size
::
boolean
();
}
int
__SrsAmf0Boolean
::
read
(
SrsStream
*
stream
)
{
return
srs_amf0_read_boolean
(
stream
,
value
);
}
int
__SrsAmf0Boolean
::
write
(
SrsStream
*
stream
)
{
return
srs_amf0_write_boolean
(
stream
,
value
);
}
__SrsAmf0Number
::
__SrsAmf0Number
(
double
_value
)
{
marker
=
RTMP_AMF0_Number
;
...
...
@@ -702,6 +825,16 @@ int __SrsAmf0Number::size()
return
SrsAmf0Size
::
number
();
}
int
__SrsAmf0Number
::
read
(
SrsStream
*
stream
)
{
return
srs_amf0_read_number
(
stream
,
value
);
}
int
__SrsAmf0Number
::
write
(
SrsStream
*
stream
)
{
return
srs_amf0_write_number
(
stream
,
value
);
}
__SrsAmf0Null
::
__SrsAmf0Null
()
{
marker
=
RTMP_AMF0_Null
;
...
...
@@ -716,6 +849,16 @@ int __SrsAmf0Null::size()
return
SrsAmf0Size
::
null
();
}
int
__SrsAmf0Null
::
read
(
SrsStream
*
stream
)
{
return
srs_amf0_read_null
(
stream
);
}
int
__SrsAmf0Null
::
write
(
SrsStream
*
stream
)
{
return
srs_amf0_write_null
(
stream
);
}
__SrsAmf0Undefined
::
__SrsAmf0Undefined
()
{
marker
=
RTMP_AMF0_Undefined
;
...
...
@@ -730,6 +873,16 @@ int __SrsAmf0Undefined::size()
return
SrsAmf0Size
::
undefined
();
}
int
__SrsAmf0Undefined
::
read
(
SrsStream
*
stream
)
{
return
srs_amf0_read_undefined
(
stream
);
}
int
__SrsAmf0Undefined
::
write
(
SrsStream
*
stream
)
{
return
srs_amf0_write_undefined
(
stream
);
}
int
srs_amf0_read_utf8
(
SrsStream
*
stream
,
std
::
string
&
value
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -1055,10 +1208,33 @@ int srs_amf0_write_undefined(SrsStream* stream)
return
ret
;
}
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
*&
value
)
bool
srs_amf0_is_object_eof
(
SrsStream
*
stream
)
{
// detect the object-eof specially
if
(
stream
->
require
(
3
))
{
int32_t
flag
=
stream
->
read_3bytes
();
stream
->
skip
(
-
3
);
return
0x09
==
flag
;
}
return
false
;
}
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
**
ppvalue
)
{
int
ret
=
ERROR_SUCCESS
;
// detect the object-eof specially
if
(
srs_amf0_is_object_eof
(
stream
))
{
*
ppvalue
=
new
__SrsAmf0ObjectEOF
();
if
((
ret
=
(
*
ppvalue
)
->
read
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_freep
(
*
ppvalue
);
return
ret
;
}
return
ret
;
}
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
...
...
@@ -1078,7 +1254,7 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
if
((
ret
=
srs_amf0_read_string
(
stream
,
data
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
SrsAmf0Any
::
str
(
data
.
c_str
());
*
pp
value
=
SrsAmf0Any
::
str
(
data
.
c_str
());
return
ret
;
}
case
RTMP_AMF0_Boolean
:
{
...
...
@@ -1086,7 +1262,7 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
if
((
ret
=
srs_amf0_read_boolean
(
stream
,
data
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
SrsAmf0Any
::
boolean
(
data
);
*
pp
value
=
SrsAmf0Any
::
boolean
(
data
);
return
ret
;
}
case
RTMP_AMF0_Number
:
{
...
...
@@ -1094,25 +1270,17 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
if
((
ret
=
srs_amf0_read_number
(
stream
,
data
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
SrsAmf0Any
::
number
(
data
);
*
pp
value
=
SrsAmf0Any
::
number
(
data
);
return
ret
;
}
case
RTMP_AMF0_Null
:
{
stream
->
skip
(
1
);
value
=
new
__SrsAmf0Null
();
*
pp
value
=
new
__SrsAmf0Null
();
return
ret
;
}
case
RTMP_AMF0_Undefined
:
{
stream
->
skip
(
1
);
value
=
new
__SrsAmf0Undefined
();
return
ret
;
}
case
RTMP_AMF0_ObjectEnd
:
{
__SrsAmf0ObjectEOF
*
p
=
NULL
;
if
((
ret
=
srs_amf0_read_object_eof
(
stream
,
p
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
p
;
*
ppvalue
=
new
__SrsAmf0Undefined
();
return
ret
;
}
case
RTMP_AMF0_Object
:
{
...
...
@@ -1120,7 +1288,7 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
if
((
ret
=
srs_amf0_read_object
(
stream
,
p
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
p
;
*
pp
value
=
p
;
return
ret
;
}
case
RTMP_AMF0_EcmaArray
:
{
...
...
@@ -1128,7 +1296,7 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
if
((
ret
=
srs_amf0_read_ecma_array
(
stream
,
p
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
p
;
*
pp
value
=
p
;
return
ret
;
}
case
RTMP_AMF0_Invalid
:
...
...
@@ -1149,15 +1317,15 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
switch
(
value
->
marker
)
{
case
RTMP_AMF0_String
:
{
std
::
string
data
=
srs_amf0_convert
<
__SrsAmf0String
>
(
value
)
->
value
;
std
::
string
data
=
srs_amf0_convert
<
__SrsAmf0String
*
>
(
value
)
->
value
;
return
srs_amf0_write_string
(
stream
,
data
);
}
case
RTMP_AMF0_Boolean
:
{
bool
data
=
srs_amf0_convert
<
__SrsAmf0Boolean
>
(
value
)
->
value
;
bool
data
=
srs_amf0_convert
<
__SrsAmf0Boolean
*
>
(
value
)
->
value
;
return
srs_amf0_write_boolean
(
stream
,
data
);
}
case
RTMP_AMF0_Number
:
{
double
data
=
srs_amf0_convert
<
__SrsAmf0Number
>
(
value
)
->
value
;
double
data
=
srs_amf0_convert
<
__SrsAmf0Number
*
>
(
value
)
->
value
;
return
srs_amf0_write_number
(
stream
,
data
);
}
case
RTMP_AMF0_Null
:
{
...
...
@@ -1167,15 +1335,15 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
return
srs_amf0_write_undefined
(
stream
);
}
case
RTMP_AMF0_ObjectEnd
:
{
__SrsAmf0ObjectEOF
*
p
=
srs_amf0_convert
<
__SrsAmf0ObjectEOF
>
(
value
);
return
srs_amf0_write_object_eof
(
stream
,
p
);
__SrsAmf0ObjectEOF
*
p
=
srs_amf0_convert
<
__SrsAmf0ObjectEOF
*>
(
value
);
return
p
->
write
(
stream
);
}
case
RTMP_AMF0_Object
:
{
SrsAmf0Object
*
p
=
srs_amf0_convert
<
SrsAmf0Object
>
(
value
);
SrsAmf0Object
*
p
=
srs_amf0_convert
<
SrsAmf0Object
*
>
(
value
);
return
srs_amf0_write_object
(
stream
,
p
);
}
case
RTMP_AMF0_EcmaArray
:
{
SrsAmf0EcmaArray
*
p
=
srs_amf0_convert
<
SrsAmf0EcmaArray
>
(
value
);
SrsAmf0EcmaArray
*
p
=
srs_amf0_convert
<
SrsAmf0EcmaArray
*
>
(
value
);
return
srs_amf0_write_ecma_array
(
stream
,
p
);
}
case
RTMP_AMF0_Invalid
:
...
...
@@ -1189,49 +1357,6 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
return
ret
;
}
int
srs_amf0_read_object_eof
(
SrsStream
*
stream
,
__SrsAmf0ObjectEOF
*&
value
)
{
int
ret
=
ERROR_SUCCESS
;
// auto skip -2 to read the object eof.
srs_assert
(
stream
->
pos
()
>=
2
);
stream
->
skip
(
-
2
);
// value
if
(
!
stream
->
require
(
2
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof value failed. ret=%d"
,
ret
);
return
ret
;
}
int16_t
temp
=
stream
->
read_2bytes
();
if
(
temp
!=
0x00
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof value check failed. "
"must be 0x00, actual is %#x, ret=%d"
,
temp
,
ret
);
return
ret
;
}
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_1bytes
();
if
(
marker
!=
RTMP_AMF0_ObjectEnd
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check object eof marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_ObjectEnd
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read object eof marker success"
);
value
=
new
__SrsAmf0ObjectEOF
();
srs_verbose
(
"amf0 read object eof success"
);
return
ret
;
}
int
srs_amf0_write_object_eof
(
SrsStream
*
stream
,
__SrsAmf0ObjectEOF
*
value
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
trunk/src/rtmp/srs_protocol_amf0.hpp
查看文件 @
4306db0
...
...
@@ -76,13 +76,22 @@ public:
*/
virtual
double
to_number
();
public
:
/**
* get the size of amf0 any, including the marker size.
*/
virtual
int
size
()
=
0
;
/**
* read elem from stream
*/
virtual
int
read
(
SrsStream
*
stream
)
=
0
;
virtual
int
write
(
SrsStream
*
stream
)
=
0
;
public
:
static
SrsAmf0Any
*
str
(
const
char
*
value
=
NULL
);
static
SrsAmf0Any
*
boolean
(
bool
value
=
false
);
static
SrsAmf0Any
*
number
(
double
value
=
0.0
);
static
SrsAmf0Any
*
null
();
static
SrsAmf0Any
*
undefined
();
static
SrsAmf0Any
*
object_eof
();
};
/**
...
...
@@ -125,6 +134,8 @@ public:
virtual
~
__SrsAmf0ObjectEOF
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
...
...
@@ -219,6 +230,8 @@ public:
virtual
~
__SrsAmf0String
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
...
...
@@ -237,6 +250,8 @@ public:
virtual
~
__SrsAmf0Boolean
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
...
...
@@ -254,6 +269,8 @@ public:
virtual
~
__SrsAmf0Number
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
...
...
@@ -268,6 +285,8 @@ public:
virtual
~
__SrsAmf0Null
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
...
...
@@ -282,20 +301,11 @@ public:
virtual
~
__SrsAmf0Undefined
();
virtual
int
size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
};
/**
* read amf0 utf8 string from stream.
* 1.3.1 Strings and UTF-8
* UTF-8 = U16 *(UTF8-char)
* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
* UTF8-1 = %x00-7F
* @remark only support UTF8-1 char.
*/
extern
int
srs_amf0_read_utf8
(
SrsStream
*
stream
,
std
::
string
&
value
);
extern
int
srs_amf0_write_utf8
(
SrsStream
*
stream
,
std
::
string
value
);
/**
* read amf0 string from stream.
* 2.4 String Type
* string-type = string-marker UTF-8
...
...
@@ -336,7 +346,10 @@ extern int srs_amf0_write_null(SrsStream* stream);
extern
int
srs_amf0_read_undefined
(
SrsStream
*
stream
);
extern
int
srs_amf0_write_undefined
(
SrsStream
*
stream
);
extern
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
*&
value
);
/**
* read anything from stream.
*/
extern
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
**
ppvalue
);
/**
* read amf0 object from stream.
...
...
@@ -357,18 +370,4 @@ extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
extern
int
srs_amf0_read_ecma_array
(
SrsStream
*
stream
,
SrsAmf0EcmaArray
*&
value
);
extern
int
srs_amf0_write_ecma_array
(
SrsStream
*
stream
,
SrsAmf0EcmaArray
*
value
);
/**
* 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.
*/
template
<
class
T
>
T
*
srs_amf0_convert
(
SrsAmf0Any
*
any
)
{
T
*
p
=
dynamic_cast
<
T
*>
(
any
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
#endif
\ No newline at end of file
...
...
trunk/src/rtmp/srs_protocol_rtmp_stack.cpp
查看文件 @
4306db0
...
...
@@ -2617,7 +2617,7 @@ int SrsPlayPacket::decode(SrsStream* stream)
}
SrsAmf0Any
*
reset_value
=
NULL
;
if
((
ret
=
srs_amf0_read_any
(
stream
,
reset_value
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
srs_amf0_read_any
(
stream
,
&
reset_value
))
!=
ERROR_SUCCESS
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read play reset marker failed. ret=%d"
,
ret
);
return
ret
;
...
...
@@ -3183,14 +3183,14 @@ int SrsOnMetaDataPacket::decode(SrsStream* stream)
// the metadata maybe object or ecma array
SrsAmf0Any
*
any
=
NULL
;
if
((
ret
=
srs_amf0_read_any
(
stream
,
any
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
srs_amf0_read_any
(
stream
,
&
any
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"decode metadata metadata failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
any
->
is_object
())
{
srs_freep
(
metadata
);
metadata
=
srs_amf0_convert
<
SrsAmf0Object
>
(
any
);
metadata
=
dynamic_cast
<
SrsAmf0Object
*
>
(
any
);
srs_info
(
"decode metadata object success"
);
return
ret
;
}
...
...
trunk/src/utest/srs_utest_amf0.cpp
查看文件 @
4306db0
...
...
@@ -23,6 +23,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_utest_amf0.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_stream.hpp>
VOID
TEST
(
AMF0Test
,
Size
)
{
...
...
@@ -270,14 +272,14 @@ VOID TEST(AMF0Test, AnyElem)
if
(
true
)
{
o
=
SrsAmf0Any
::
str
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_string
());
EXPECT_STREQ
(
""
,
o
->
to_str
().
c_str
());
}
if
(
true
)
{
o
=
SrsAmf0Any
::
str
(
"winlin"
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_string
());
EXPECT_STREQ
(
"winlin"
,
o
->
to_str
().
c_str
());
}
...
...
@@ -286,21 +288,21 @@ VOID TEST(AMF0Test, AnyElem)
if
(
true
)
{
o
=
SrsAmf0Any
::
boolean
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_boolean
());
EXPECT_FALSE
(
o
->
to_boolean
());
}
if
(
true
)
{
o
=
SrsAmf0Any
::
boolean
(
false
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_boolean
());
EXPECT_FALSE
(
o
->
to_boolean
());
}
if
(
true
)
{
o
=
SrsAmf0Any
::
boolean
(
true
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_boolean
());
EXPECT_TRUE
(
o
->
to_boolean
());
}
...
...
@@ -309,21 +311,21 @@ VOID TEST(AMF0Test, AnyElem)
if
(
true
)
{
o
=
SrsAmf0Any
::
number
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_number
());
EXPECT_DOUBLE_EQ
(
0
,
o
->
to_number
());
}
if
(
true
)
{
o
=
SrsAmf0Any
::
number
(
100
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_number
());
EXPECT_DOUBLE_EQ
(
100
,
o
->
to_number
());
}
if
(
true
)
{
o
=
SrsAmf0Any
::
number
(
-
100
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_number
());
EXPECT_DOUBLE_EQ
(
-
100
,
o
->
to_number
());
}
...
...
@@ -332,7 +334,7 @@ VOID TEST(AMF0Test, AnyElem)
if
(
true
)
{
o
=
SrsAmf0Any
::
null
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_null
());
}
...
...
@@ -340,7 +342,261 @@ VOID TEST(AMF0Test, AnyElem)
if
(
true
)
{
o
=
SrsAmf0Any
::
undefined
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPEC
T_TRUE
(
NULL
!=
o
);
ASSER
T_TRUE
(
NULL
!=
o
);
EXPECT_TRUE
(
o
->
is_undefined
());
}
}
VOID
TEST
(
AMF0Test
,
AnyIO
)
{
SrsStream
s
;
SrsAmf0Any
*
o
=
NULL
;
char
buf
[
1024
];
memset
(
buf
,
0
,
sizeof
(
buf
));
EXPECT_EQ
(
ERROR_SUCCESS
,
s
.
initialize
(
buf
,
sizeof
(
buf
)));
// object eof
if
(
true
)
{
s
.
reset
();
s
.
current
()[
2
]
=
0x09
;
o
=
SrsAmf0Any
::
object_eof
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_EQ
(
3
,
s
.
pos
());
s
.
reset
();
s
.
current
()[
0
]
=
0x01
;
EXPECT_NE
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
}
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
object_eof
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_EQ
(
3
,
s
.
pos
());
s
.
skip
(
-
3
);
EXPECT_EQ
(
0x09
,
s
.
read_3bytes
());
}
// string
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
str
(
"winlin"
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
EXPECT_EQ
(
2
,
s
.
read_1bytes
());
EXPECT_EQ
(
6
,
s
.
read_2bytes
());
EXPECT_EQ
(
'w'
,
s
.
current
()[
0
]);
EXPECT_EQ
(
'n'
,
s
.
current
()[
5
]);
s
.
reset
();
s
.
current
()[
3
]
=
'x'
;
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_STREQ
(
"xinlin"
,
o
->
to_str
().
c_str
());
}
// number
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
number
(
10
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
EXPECT_EQ
(
0
,
s
.
read_1bytes
());
s
.
reset
();
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_DOUBLE_EQ
(
10
,
o
->
to_number
());
}
// boolean
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
boolean
(
true
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
EXPECT_EQ
(
1
,
s
.
read_1bytes
());
s
.
reset
();
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_TRUE
(
o
->
to_boolean
());
}
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
boolean
(
false
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
EXPECT_EQ
(
1
,
s
.
read_1bytes
());
s
.
reset
();
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_FALSE
(
o
->
to_boolean
());
}
// null
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
null
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
EXPECT_EQ
(
5
,
s
.
read_1bytes
());
s
.
reset
();
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_TRUE
(
o
->
is_null
());
}
// undefined
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
undefined
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
EXPECT_EQ
(
6
,
s
.
read_1bytes
());
s
.
reset
();
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
read
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
EXPECT_TRUE
(
o
->
is_undefined
());
}
// any: string
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
str
(
"winlin"
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
SrsAmf0Any
*
po
=
NULL
;
EXPECT_EQ
(
ERROR_SUCCESS
,
srs_amf0_read_any
(
&
s
,
&
po
));
ASSERT_TRUE
(
NULL
!=
po
);
SrsAutoFree
(
SrsAmf0Any
,
po
,
false
);
ASSERT_TRUE
(
po
->
is_string
());
EXPECT_STREQ
(
"winlin"
,
po
->
to_str
().
c_str
());
}
// any: number
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
number
(
10
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
SrsAmf0Any
*
po
=
NULL
;
EXPECT_EQ
(
ERROR_SUCCESS
,
srs_amf0_read_any
(
&
s
,
&
po
));
ASSERT_TRUE
(
NULL
!=
po
);
SrsAutoFree
(
SrsAmf0Any
,
po
,
false
);
ASSERT_TRUE
(
po
->
is_number
());
EXPECT_DOUBLE_EQ
(
10
,
po
->
to_number
());
}
// any: boolean
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
boolean
(
true
);
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
SrsAmf0Any
*
po
=
NULL
;
EXPECT_EQ
(
ERROR_SUCCESS
,
srs_amf0_read_any
(
&
s
,
&
po
));
ASSERT_TRUE
(
NULL
!=
po
);
SrsAutoFree
(
SrsAmf0Any
,
po
,
false
);
ASSERT_TRUE
(
po
->
is_boolean
());
EXPECT_TRUE
(
po
->
to_boolean
());
}
// any: null
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
null
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
SrsAmf0Any
*
po
=
NULL
;
EXPECT_EQ
(
ERROR_SUCCESS
,
srs_amf0_read_any
(
&
s
,
&
po
));
ASSERT_TRUE
(
NULL
!=
po
);
SrsAutoFree
(
SrsAmf0Any
,
po
,
false
);
ASSERT_TRUE
(
po
->
is_null
());
}
// any: undefined
if
(
true
)
{
s
.
reset
();
o
=
SrsAmf0Any
::
undefined
();
SrsAutoFree
(
SrsAmf0Any
,
o
,
false
);
EXPECT_EQ
(
ERROR_SUCCESS
,
o
->
write
(
&
s
));
EXPECT_EQ
(
o
->
size
(),
s
.
pos
());
s
.
reset
();
SrsAmf0Any
*
po
=
NULL
;
EXPECT_EQ
(
ERROR_SUCCESS
,
srs_amf0_read_any
(
&
s
,
&
po
));
ASSERT_TRUE
(
NULL
!=
po
);
SrsAutoFree
(
SrsAmf0Any
,
po
,
false
);
ASSERT_TRUE
(
po
->
is_undefined
());
}
}
...
...
trunk/src/utest/srs_utest_amf0.hpp
查看文件 @
4306db0
...
...
@@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_utest_amf0.hpp>
*/
#include <srs_utest.hpp>
#include <srs_protocol_amf0.hpp>
#endif
...
...
请
注册
或
登录
后发表评论