1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

amf0 utest, refine amf0 size and object/array read/write

This commit is contained in:
winlin 2014-03-08 13:11:26 +08:00
parent 48343e4f3a
commit 3083759273
9 changed files with 613 additions and 431 deletions

8
trunk/configure vendored
View file

@ -335,20 +335,18 @@ LINK_OPTIONS="-ldl${SrsGprofLink}${SrsGperfLink}"
# srs: # srs:
# srs(simple rtmp server) over st(state-threads) # srs(simple rtmp server) over st(state-threads)
BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" . auto/apps.sh BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" . auto/apps.sh
# # bandwidth test tool, to test the bandwidth to server
if [ $SRS_BWTC = YES ]; then if [ $SRS_BWTC = YES ]; then
# bandwidth test tool, to test the bandwidth to server
BUILD_KEY="bandwidth" APP_MAIN="srs_main_bandcheck" APP_NAME="bandwidth" . auto/apps.sh BUILD_KEY="bandwidth" APP_MAIN="srs_main_bandcheck" APP_NAME="bandwidth" . auto/apps.sh
fi fi
# # srs librtmp
if [ $SRS_LIBRTMP = YES ]; then if [ $SRS_LIBRTMP = YES ]; then
# srs librtmp
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${LIBS_OBJS[@]}" MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${LIBS_OBJS[@]}"
BUILD_KEY="librtmp" LIB_NAME="lib/srs_librtmp" . auto/libs.sh BUILD_KEY="librtmp" LIB_NAME="lib/srs_librtmp" . auto/libs.sh
fi fi
# #
# utest, the unit-test cases of srs, base on gtest1.6 # utest, the unit-test cases of srs, base on gtest1.6
MODULE_FILES=("srs_utest") MODULE_FILES=("srs_utest" "srs_utest_amf0")
ModuleLibIncs=(${SRS_OBJS} ${LibSTRoot}) ModuleLibIncs=(${SRS_OBJS} ${LibSTRoot})
ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile}) ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile})
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP") MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP")

View file

@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_protocol_amf0.hpp> #include <srs_protocol_amf0.hpp>
#include <utility> #include <utility>
using namespace std;
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
@ -55,8 +56,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// User defined // User defined
#define RTMP_AMF0_Invalid 0x3F #define RTMP_AMF0_Invalid 0x3F
int srs_amf0_get_object_eof_size();
int srs_amf0_get_any_size(SrsAmf0Any* value);
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*); int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);
int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value); int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
@ -123,6 +122,11 @@ SrsAmf0String::~SrsAmf0String()
{ {
} }
int SrsAmf0String::size()
{
return SrsAmf0Size::str(value);
}
SrsAmf0Boolean::SrsAmf0Boolean(bool _value) SrsAmf0Boolean::SrsAmf0Boolean(bool _value)
{ {
marker = RTMP_AMF0_Boolean; marker = RTMP_AMF0_Boolean;
@ -133,6 +137,11 @@ SrsAmf0Boolean::~SrsAmf0Boolean()
{ {
} }
int SrsAmf0Boolean::size()
{
return SrsAmf0Size::boolean();
}
SrsAmf0Number::SrsAmf0Number(double _value) SrsAmf0Number::SrsAmf0Number(double _value)
{ {
marker = RTMP_AMF0_Number; marker = RTMP_AMF0_Number;
@ -143,6 +152,11 @@ SrsAmf0Number::~SrsAmf0Number()
{ {
} }
int SrsAmf0Number::size()
{
return SrsAmf0Size::number();
}
SrsAmf0Null::SrsAmf0Null() SrsAmf0Null::SrsAmf0Null()
{ {
marker = RTMP_AMF0_Null; marker = RTMP_AMF0_Null;
@ -152,6 +166,11 @@ SrsAmf0Null::~SrsAmf0Null()
{ {
} }
int SrsAmf0Null::size()
{
return SrsAmf0Size::null();
}
SrsAmf0Undefined::SrsAmf0Undefined() SrsAmf0Undefined::SrsAmf0Undefined()
{ {
marker = RTMP_AMF0_Undefined; marker = RTMP_AMF0_Undefined;
@ -161,6 +180,11 @@ SrsAmf0Undefined::~SrsAmf0Undefined()
{ {
} }
int SrsAmf0Undefined::size()
{
return SrsAmf0Size::undefined();
}
SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
{ {
marker = RTMP_AMF0_ObjectEnd; marker = RTMP_AMF0_ObjectEnd;
@ -171,6 +195,11 @@ SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF()
{ {
} }
int SrsAmf0ObjectEOF::size()
{
return SrsAmf0Size::object_eof();
}
SrsUnSortedHashtable::SrsUnSortedHashtable() SrsUnSortedHashtable::SrsUnSortedHashtable()
{ {
} }
@ -284,9 +313,115 @@ SrsAmf0Object::~SrsAmf0Object()
{ {
} }
int SrsAmf0Object::read(SrsStream* stream)
{
int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read object marker failed. ret=%d", ret);
return ret;
}
char marker = stream->read_1bytes();
if (marker != RTMP_AMF0_Object) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check object marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
return ret;
}
srs_verbose("amf0 read object marker success");
// value
while (!stream->empty()) {
// property-name: utf8 string
std::string property_name;
if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
srs_error("amf0 object read property name failed. ret=%d", ret);
return ret;
}
// property-value: any
SrsAmf0Any* property_value = NULL;
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);
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);
}
return ret;
}
int SrsAmf0Object::write(SrsStream* stream)
{
int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write object marker failed. ret=%d", ret);
return ret;
}
stream->write_1bytes(RTMP_AMF0_Object);
srs_verbose("amf0 write object marker success");
// value
for (int i = 0; i < properties.size(); i++) {
std::string name = this->key_at(i);
SrsAmf0Any* any = this->value_at(i);
if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
srs_error("write object property name failed. ret=%d", ret);
return ret;
}
if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
srs_error("write object property value failed. ret=%d", ret);
return ret;
}
srs_verbose("write amf0 property success. name=%s", name.c_str());
}
if ((ret = srs_amf0_write_object_eof(stream, &this->eof)) != ERROR_SUCCESS) {
srs_error("write object eof failed. ret=%d", ret);
return ret;
}
srs_verbose("write amf0 object success.");
return ret;
}
int SrsAmf0Object::size() int SrsAmf0Object::size()
{ {
return properties.size(); int size = 1;
for (int i = 0; i < properties.size(); i++){
std::string name = key_at(i);
SrsAmf0Any* value = value_at(i);
size += SrsAmf0Size::utf8(name);
size += SrsAmf0Size::any(value);
}
size += SrsAmf0Size::object_eof();
return size;
} }
std::string SrsAmf0Object::key_at(int index) std::string SrsAmf0Object::key_at(int index)
@ -319,46 +454,173 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_number(std::string name)
return properties.ensure_property_number(name); return properties.ensure_property_number(name);
} }
SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray() SrsAmf0EcmaArray::SrsAmf0EcmaArray()
{ {
marker = RTMP_AMF0_EcmaArray; marker = RTMP_AMF0_EcmaArray;
} }
SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray() SrsAmf0EcmaArray::~SrsAmf0EcmaArray()
{ {
} }
int SrsASrsAmf0EcmaArray::size() int SrsAmf0EcmaArray::read(SrsStream* stream)
{ {
return properties.size(); int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read ecma_array marker failed. ret=%d", ret);
return ret;
}
char marker = stream->read_1bytes();
if (marker != RTMP_AMF0_EcmaArray) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check ecma_array marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
return ret;
}
srs_verbose("amf0 read ecma_array marker success");
// count
if (!stream->require(4)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read ecma_array count failed. ret=%d", ret);
return ret;
}
int32_t count = stream->read_4bytes();
srs_verbose("amf0 read ecma_array count success. count=%d", count);
// value
this->count = count;
while (!stream->empty()) {
// property-name: utf8 string
std::string property_name;
if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
srs_error("amf0 ecma_array read property name failed. ret=%d", ret);
return ret;
}
// property-value: any
SrsAmf0Any* property_value = NULL;
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);
}
return ret;
}
int SrsAmf0EcmaArray::write(SrsStream* stream)
{
int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write ecma_array marker failed. ret=%d", ret);
return ret;
}
stream->write_1bytes(RTMP_AMF0_EcmaArray);
srs_verbose("amf0 write ecma_array marker success");
// count
if (!stream->require(4)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write ecma_array count failed. ret=%d", ret);
return ret;
}
stream->write_4bytes(this->count);
srs_verbose("amf0 write ecma_array count success. count=%d", value->count);
// value
for (int i = 0; i < properties.size(); i++) {
std::string name = this->key_at(i);
SrsAmf0Any* any = this->value_at(i);
if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
srs_error("write ecma_array property name failed. ret=%d", ret);
return ret;
}
if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
srs_error("write ecma_array property value failed. ret=%d", ret);
return ret;
}
srs_verbose("write amf0 property success. name=%s", name.c_str());
}
if ((ret = srs_amf0_write_object_eof(stream, &this->eof)) != ERROR_SUCCESS) {
srs_error("write ecma_array eof failed. ret=%d", ret);
return ret;
}
srs_verbose("write ecma_array object success.");
return ret;
} }
void SrsASrsAmf0EcmaArray::clear() int SrsAmf0EcmaArray::size()
{
int size = 1 + 4;
for (int i = 0; i < properties.size(); i++){
std::string name = key_at(i);
SrsAmf0Any* value = value_at(i);
size += SrsAmf0Size::utf8(name);
size += SrsAmf0Size::any(value);
}
size += SrsAmf0Size::object_eof();
return size;
}
void SrsAmf0EcmaArray::clear()
{ {
properties.clear(); properties.clear();
} }
std::string SrsASrsAmf0EcmaArray::key_at(int index) std::string SrsAmf0EcmaArray::key_at(int index)
{ {
return properties.key_at(index); return properties.key_at(index);
} }
SrsAmf0Any* SrsASrsAmf0EcmaArray::value_at(int index) SrsAmf0Any* SrsAmf0EcmaArray::value_at(int index)
{ {
return properties.value_at(index); return properties.value_at(index);
} }
void SrsASrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value) void SrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value)
{ {
properties.set(key, value); properties.set(key, value);
} }
SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name) SrsAmf0Any* SrsAmf0EcmaArray::get_property(std::string name)
{ {
return properties.get_property(name); return properties.get_property(name);
} }
SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name) SrsAmf0Any* SrsAmf0EcmaArray::ensure_property_string(std::string name)
{ {
return properties.ensure_property_string(name); return properties.ensure_property_string(name);
} }
@ -760,7 +1022,7 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
return ret; return ret;
} }
case RTMP_AMF0_EcmaArray: { case RTMP_AMF0_EcmaArray: {
SrsASrsAmf0EcmaArray* p = NULL; SrsAmf0EcmaArray* p = NULL;
if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) { if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -811,7 +1073,7 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
return srs_amf0_write_object(stream, p); return srs_amf0_write_object(stream, p);
} }
case RTMP_AMF0_EcmaArray: { case RTMP_AMF0_EcmaArray: {
SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value); SrsAmf0EcmaArray* p = srs_amf0_convert<SrsAmf0EcmaArray>(value);
return srs_amf0_write_ecma_array(stream, p); return srs_amf0_write_ecma_array(stream, p);
} }
case RTMP_AMF0_Invalid: case RTMP_AMF0_Invalid:
@ -824,59 +1086,6 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
return ret; return ret;
} }
int srs_amf0_get_any_size(SrsAmf0Any* value)
{
if (!value) {
return 0;
}
int size = 0;
switch (value->marker) {
case RTMP_AMF0_String: {
SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);
size += srs_amf0_get_string_size(p->value);
break;
}
case RTMP_AMF0_Boolean: {
size += srs_amf0_get_boolean_size();
break;
}
case RTMP_AMF0_Number: {
size += srs_amf0_get_number_size();
break;
}
case RTMP_AMF0_Null: {
size += srs_amf0_get_null_size();
break;
}
case RTMP_AMF0_Undefined: {
size += srs_amf0_get_undefined_size();
break;
}
case RTMP_AMF0_ObjectEnd: {
size += srs_amf0_get_object_eof_size();
break;
}
case RTMP_AMF0_Object: {
SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
size += srs_amf0_get_object_size(p);
break;
}
case RTMP_AMF0_EcmaArray: {
SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
size += srs_amf0_get_ecma_array_size(p);
break;
}
default: {
// TOOD: other AMF0 types.
srs_warn("ignore unkown AMF0 type size.");
break;
}
}
return size;
}
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
{ {
@ -954,290 +1163,96 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read object marker failed. ret=%d", ret);
return ret;
}
char marker = stream->read_1bytes();
if (marker != RTMP_AMF0_Object) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check object marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
return ret;
}
srs_verbose("amf0 read object marker success");
// value
value = new SrsAmf0Object(); value = new SrsAmf0Object();
while (!stream->empty()) { if ((ret = value->read(stream)) != ERROR_SUCCESS) {
// property-name: utf8 string srs_freep(value);
std::string property_name;
if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
srs_error("amf0 object read property name failed. ret=%d", ret);
return ret; return ret;
} }
// property-value: any
SrsAmf0Any* property_value = NULL;
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);
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
value->set(property_name, property_value);
}
return ret; return ret;
} }
int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)
{ {
int ret = ERROR_SUCCESS; return value->write(stream);
srs_assert(value != NULL);
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write object marker failed. ret=%d", ret);
return ret;
}
stream->write_1bytes(RTMP_AMF0_Object);
srs_verbose("amf0 write object marker success");
// value
for (int i = 0; i < value->size(); i++) {
std::string name = value->key_at(i);
SrsAmf0Any* any = value->value_at(i);
if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
srs_error("write object property name failed. ret=%d", ret);
return ret;
}
if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
srs_error("write object property value failed. ret=%d", ret);
return ret;
}
srs_verbose("write amf0 property success. name=%s", name.c_str());
}
if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
srs_error("write object eof failed. ret=%d", ret);
return ret;
}
srs_verbose("write amf0 object success.");
return ret;
} }
int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value) int srs_amf0_read_ecma_array(SrsStream* stream, SrsAmf0EcmaArray*& value)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// marker value = new SrsAmf0EcmaArray();
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_DECODE; if ((ret = value->read(stream)) != ERROR_SUCCESS) {
srs_error("amf0 read ecma_array marker failed. ret=%d", ret); srs_freep(value);
return ret; return ret;
} }
char marker = stream->read_1bytes();
if (marker != RTMP_AMF0_EcmaArray) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check ecma_array marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
return ret;
}
srs_verbose("amf0 read ecma_array marker success");
// count
if (!stream->require(4)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read ecma_array count failed. ret=%d", ret);
return ret;
}
int32_t count = stream->read_4bytes();
srs_verbose("amf0 read ecma_array count success. count=%d", count);
// value
value = new SrsASrsAmf0EcmaArray();
value->count = count;
while (!stream->empty()) {
// property-name: utf8 string
std::string property_name;
if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
srs_error("amf0 ecma_array read property name failed. ret=%d", ret);
return ret;
}
// property-value: any
SrsAmf0Any* property_value = NULL;
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
value->set(property_name, property_value);
}
return ret; return ret;
} }
int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value) int srs_amf0_write_ecma_array(SrsStream* stream, SrsAmf0EcmaArray* value)
{ {
int ret = ERROR_SUCCESS; return value->write(stream);
srs_assert(value != NULL);
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write ecma_array marker failed. ret=%d", ret);
return ret;
}
stream->write_1bytes(RTMP_AMF0_EcmaArray);
srs_verbose("amf0 write ecma_array marker success");
// count
if (!stream->require(4)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write ecma_array count failed. ret=%d", ret);
return ret;
}
stream->write_4bytes(value->count);
srs_verbose("amf0 write ecma_array count success. count=%d", value->count);
// value
for (int i = 0; i < value->size(); i++) {
std::string name = value->key_at(i);
SrsAmf0Any* any = value->value_at(i);
if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
srs_error("write ecma_array property name failed. ret=%d", ret);
return ret;
}
if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
srs_error("write ecma_array property value failed. ret=%d", ret);
return ret;
}
srs_verbose("write amf0 property success. name=%s", name.c_str());
}
if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
srs_error("write ecma_array eof failed. ret=%d", ret);
return ret;
}
srs_verbose("write ecma_array object success.");
return ret;
} }
int srs_amf0_get_utf8_size(std::string value) int SrsAmf0Size::utf8(string value)
{ {
return 2 + value.length(); return 2 + value.length();
} }
int srs_amf0_get_string_size(std::string value) int SrsAmf0Size::str(string value)
{ {
return 1 + srs_amf0_get_utf8_size(value); return 1 + SrsAmf0Size::utf8(value);
} }
int srs_amf0_get_number_size() int SrsAmf0Size::number()
{ {
return 1 + 8; return 1 + 8;
} }
int srs_amf0_get_null_size() int SrsAmf0Size::null()
{ {
return 1; return 1;
} }
int srs_amf0_get_undefined_size() int SrsAmf0Size::undefined()
{ {
return 1; return 1;
} }
int srs_amf0_get_boolean_size() int SrsAmf0Size::boolean()
{ {
return 1 + 1; return 1 + 1;
} }
int srs_amf0_get_object_size(SrsAmf0Object* obj) int SrsAmf0Size::object(SrsAmf0Object* obj)
{ {
if (!obj) { if (!obj) {
return 0; return 0;
} }
int size = 1; return obj->size();
for (int i = 0; i < obj->size(); i++){
std::string name = obj->key_at(i);
SrsAmf0Any* value = obj->value_at(i);
size += srs_amf0_get_utf8_size(name);
size += srs_amf0_get_any_size(value);
}
size += srs_amf0_get_object_eof_size();
return size;
} }
int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr) int SrsAmf0Size::object_eof()
{
return 2 + 1;
}
int SrsAmf0Size::array(SrsAmf0EcmaArray* arr)
{ {
if (!arr) { if (!arr) {
return 0; return 0;
} }
int size = 1 + 4; return arr->size();
}
for (int i = 0; i < arr->size(); i++){ int SrsAmf0Size::any(SrsAmf0Any* o)
std::string name = arr->key_at(i); {
SrsAmf0Any* value = arr->value_at(i); if (!o) {
return 0;
size += srs_amf0_get_utf8_size(name);
size += srs_amf0_get_any_size(value);
} }
size += srs_amf0_get_object_eof_size(); return o->size();
return size;
}
int srs_amf0_get_object_eof_size()
{
return 2 + 1;
} }

View file

@ -59,6 +59,8 @@ struct SrsAmf0Any
virtual bool is_object(); virtual bool is_object();
virtual bool is_object_eof(); virtual bool is_object_eof();
virtual bool is_ecma_array(); virtual bool is_ecma_array();
virtual int size() = 0;
}; };
/** /**
@ -73,6 +75,8 @@ struct SrsAmf0String : public SrsAmf0Any
SrsAmf0String(const char* _value = NULL); SrsAmf0String(const char* _value = NULL);
virtual ~SrsAmf0String(); virtual ~SrsAmf0String();
virtual int size();
}; };
/** /**
@ -88,6 +92,8 @@ struct SrsAmf0Boolean : public SrsAmf0Any
SrsAmf0Boolean(bool _value = false); SrsAmf0Boolean(bool _value = false);
virtual ~SrsAmf0Boolean(); virtual ~SrsAmf0Boolean();
virtual int size();
}; };
/** /**
@ -102,6 +108,8 @@ struct SrsAmf0Number : public SrsAmf0Any
SrsAmf0Number(double _value = 0.0); SrsAmf0Number(double _value = 0.0);
virtual ~SrsAmf0Number(); virtual ~SrsAmf0Number();
virtual int size();
}; };
/** /**
@ -113,6 +121,8 @@ struct SrsAmf0Null : public SrsAmf0Any
{ {
SrsAmf0Null(); SrsAmf0Null();
virtual ~SrsAmf0Null(); virtual ~SrsAmf0Null();
virtual int size();
}; };
/** /**
@ -124,6 +134,8 @@ struct SrsAmf0Undefined : public SrsAmf0Any
{ {
SrsAmf0Undefined(); SrsAmf0Undefined();
virtual ~SrsAmf0Undefined(); virtual ~SrsAmf0Undefined();
virtual int size();
}; };
/** /**
@ -137,6 +149,8 @@ struct SrsAmf0ObjectEOF : public SrsAmf0Any
SrsAmf0ObjectEOF(); SrsAmf0ObjectEOF();
virtual ~SrsAmf0ObjectEOF(); virtual ~SrsAmf0ObjectEOF();
virtual int size();
}; };
/** /**
@ -180,6 +194,9 @@ public:
SrsAmf0Object(); SrsAmf0Object();
virtual ~SrsAmf0Object(); virtual ~SrsAmf0Object();
virtual int read(SrsStream* stream);
virtual int write(SrsStream* stream);
virtual int size(); virtual int size();
virtual std::string key_at(int index); virtual std::string key_at(int index);
virtual SrsAmf0Any* value_at(int index); virtual SrsAmf0Any* value_at(int index);
@ -196,7 +213,7 @@ public:
* associative-count = U32 * associative-count = U32
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
*/ */
struct SrsASrsAmf0EcmaArray : public SrsAmf0Any struct SrsAmf0EcmaArray : public SrsAmf0Any
{ {
private: private:
SrsUnSortedHashtable properties; SrsUnSortedHashtable properties;
@ -204,8 +221,11 @@ public:
int32_t count; int32_t count;
SrsAmf0ObjectEOF eof; SrsAmf0ObjectEOF eof;
SrsASrsAmf0EcmaArray(); SrsAmf0EcmaArray();
virtual ~SrsASrsAmf0EcmaArray(); virtual ~SrsAmf0EcmaArray();
virtual int read(SrsStream* stream);
virtual int write(SrsStream* stream);
virtual int size(); virtual int size();
virtual void clear(); virtual void clear();
@ -287,20 +307,26 @@ extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
* associative-count = U32 * associative-count = U32
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
*/ */
extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value); extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsAmf0EcmaArray*& value);
extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value); extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsAmf0EcmaArray* value);
/** /**
* get amf0 objects size. * the class to get amf0 object size
*/ */
extern int srs_amf0_get_utf8_size(std::string value); class SrsAmf0Size
extern int srs_amf0_get_string_size(std::string value); {
extern int srs_amf0_get_number_size(); public:
extern int srs_amf0_get_null_size(); static int utf8(std::string value);
extern int srs_amf0_get_undefined_size(); static int str(std::string value);
extern int srs_amf0_get_boolean_size(); static int number();
extern int srs_amf0_get_object_size(SrsAmf0Object* obj); static int null();
extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr); static int undefined();
static int boolean();
static int object(SrsAmf0Object* obj);
static int object_eof();
static int array(SrsAmf0EcmaArray* arr);
static int any(SrsAmf0Any* o);
};
/** /**
* convert the any to specified object. * convert the any to specified object.

View file

@ -706,7 +706,7 @@ int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip)
pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess)); pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess));
pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded")); pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded"));
pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding)); pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding));
SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray(); SrsAmf0EcmaArray* data = new SrsAmf0EcmaArray();
pkt->info->set("data", data); pkt->info->set("data", data);
data->set("version", new SrsAmf0String(RTMP_SIG_FMS_VER)); data->set("version", new SrsAmf0String(RTMP_SIG_FMS_VER));

View file

@ -1791,8 +1791,8 @@ int SrsConnectAppPacket::get_message_type()
int SrsConnectAppPacket::get_size() int SrsConnectAppPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_object_size(command_object); + SrsAmf0Size::object(command_object);
} }
int SrsConnectAppPacket::encode_packet(SrsStream* stream) int SrsConnectAppPacket::encode_packet(SrsStream* stream)
@ -1901,14 +1901,14 @@ int SrsConnectAppResPacket::get_message_type()
int SrsConnectAppResPacket::get_size() int SrsConnectAppResPacket::get_size()
{ {
int size = srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size(); int size = SrsAmf0Size::str(command_name) + SrsAmf0Size::number();
if (props->size() > 0) { if (props->size() > 0) {
size += srs_amf0_get_object_size(props); size += SrsAmf0Size::object(props);
} }
if (info->size() > 0) { if (info->size() > 0) {
size += srs_amf0_get_object_size(info); size += SrsAmf0Size::object(info);
} }
return size; return size;
@ -2007,8 +2007,8 @@ int SrsCreateStreamPacket::get_message_type()
int SrsCreateStreamPacket::get_size() int SrsCreateStreamPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size(); + SrsAmf0Size::null();
} }
int SrsCreateStreamPacket::encode_packet(SrsStream* stream) int SrsCreateStreamPacket::encode_packet(SrsStream* stream)
@ -2098,8 +2098,8 @@ int SrsCreateStreamResPacket::get_message_type()
int SrsCreateStreamResPacket::get_size() int SrsCreateStreamResPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_number_size(); + SrsAmf0Size::null() + SrsAmf0Size::number();
} }
int SrsCreateStreamResPacket::encode_packet(SrsStream* stream) int SrsCreateStreamResPacket::encode_packet(SrsStream* stream)
@ -2234,8 +2234,8 @@ int SrsFMLEStartPacket::get_message_type()
int SrsFMLEStartPacket::get_size() int SrsFMLEStartPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_string_size(stream_name); + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name);
} }
int SrsFMLEStartPacket::encode_packet(SrsStream* stream) int SrsFMLEStartPacket::encode_packet(SrsStream* stream)
@ -2355,8 +2355,8 @@ int SrsFMLEStartResPacket::get_message_type()
int SrsFMLEStartResPacket::get_size() int SrsFMLEStartResPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_undefined_size(); + SrsAmf0Size::null() + SrsAmf0Size::undefined();
} }
int SrsFMLEStartResPacket::encode_packet(SrsStream* stream) int SrsFMLEStartResPacket::encode_packet(SrsStream* stream)
@ -2458,9 +2458,9 @@ int SrsPublishPacket::get_message_type()
int SrsPublishPacket::get_size() int SrsPublishPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_string_size(stream_name) + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name)
+ srs_amf0_get_string_size(type); + SrsAmf0Size::str(type);
} }
int SrsPublishPacket::encode_packet(SrsStream* stream) int SrsPublishPacket::encode_packet(SrsStream* stream)
@ -2654,10 +2654,10 @@ int SrsPlayPacket::get_message_type()
int SrsPlayPacket::get_size() int SrsPlayPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_string_size(stream_name) + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name)
+ srs_amf0_get_number_size() + srs_amf0_get_number_size() + SrsAmf0Size::number() + SrsAmf0Size::number()
+ srs_amf0_get_boolean_size(); + SrsAmf0Size::boolean();
} }
int SrsPlayPacket::encode_packet(SrsStream* stream) int SrsPlayPacket::encode_packet(SrsStream* stream)
@ -2737,8 +2737,8 @@ int SrsPlayResPacket::get_message_type()
int SrsPlayResPacket::get_size() int SrsPlayResPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_object_size(desc); + SrsAmf0Size::null() + SrsAmf0Size::object(desc);
} }
int SrsPlayResPacket::encode_packet(SrsStream* stream) int SrsPlayResPacket::encode_packet(SrsStream* stream)
@ -2799,8 +2799,8 @@ int SrsOnBWDonePacket::get_message_type()
int SrsOnBWDonePacket::get_size() int SrsOnBWDonePacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size(); + SrsAmf0Size::null();
} }
int SrsOnBWDonePacket::encode_packet(SrsStream* stream) int SrsOnBWDonePacket::encode_packet(SrsStream* stream)
@ -2856,8 +2856,8 @@ int SrsOnStatusCallPacket::get_message_type()
int SrsOnStatusCallPacket::get_size() int SrsOnStatusCallPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_object_size(data); + SrsAmf0Size::null() + SrsAmf0Size::object(data);
} }
int SrsOnStatusCallPacket::encode_packet(SrsStream* stream) int SrsOnStatusCallPacket::encode_packet(SrsStream* stream)
@ -2919,8 +2919,8 @@ int SrsBandwidthPacket::get_message_type()
int SrsBandwidthPacket::get_size() int SrsBandwidthPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() return SrsAmf0Size::str(command_name) + SrsAmf0Size::number()
+ srs_amf0_get_null_size() + srs_amf0_get_object_size(data); + SrsAmf0Size::null() + SrsAmf0Size::object(data);
} }
int SrsBandwidthPacket::encode_packet(SrsStream* stream) int SrsBandwidthPacket::encode_packet(SrsStream* stream)
@ -3073,7 +3073,7 @@ int SrsOnStatusDataPacket::get_message_type()
int SrsOnStatusDataPacket::get_size() int SrsOnStatusDataPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) + srs_amf0_get_object_size(data); return SrsAmf0Size::str(command_name) + SrsAmf0Size::object(data);
} }
int SrsOnStatusDataPacket::encode_packet(SrsStream* stream) int SrsOnStatusDataPacket::encode_packet(SrsStream* stream)
@ -3120,8 +3120,8 @@ int SrsSampleAccessPacket::get_message_type()
int SrsSampleAccessPacket::get_size() int SrsSampleAccessPacket::get_size()
{ {
return srs_amf0_get_string_size(command_name) return SrsAmf0Size::str(command_name)
+ srs_amf0_get_boolean_size() + srs_amf0_get_boolean_size(); + SrsAmf0Size::boolean() + SrsAmf0Size::boolean();
} }
int SrsSampleAccessPacket::encode_packet(SrsStream* stream) int SrsSampleAccessPacket::encode_packet(SrsStream* stream)
@ -3195,7 +3195,7 @@ int SrsOnMetaDataPacket::decode(SrsStream* stream)
return ret; return ret;
} }
SrsASrsAmf0EcmaArray* arr = dynamic_cast<SrsASrsAmf0EcmaArray*>(any); SrsAmf0EcmaArray* arr = dynamic_cast<SrsAmf0EcmaArray*>(any);
if (!arr) { if (!arr) {
ret = ERROR_RTMP_AMF0_DECODE; ret = ERROR_RTMP_AMF0_DECODE;
srs_error("decode metadata array failed. ret=%d", ret); srs_error("decode metadata array failed. ret=%d", ret);
@ -3224,7 +3224,7 @@ int SrsOnMetaDataPacket::get_message_type()
int SrsOnMetaDataPacket::get_size() int SrsOnMetaDataPacket::get_size()
{ {
return srs_amf0_get_string_size(name) + srs_amf0_get_object_size(metadata); return SrsAmf0Size::str(name) + SrsAmf0Size::object(metadata);
} }
int SrsOnMetaDataPacket::encode_packet(SrsStream* stream) int SrsOnMetaDataPacket::encode_packet(SrsStream* stream)

2
trunk/src/srs/srs.upp Normal file → Executable file
View file

@ -76,6 +76,8 @@ file
utest readonly separator, utest readonly separator,
..\utest\srs_utest.hpp, ..\utest\srs_utest.hpp,
..\utest\srs_utest.cpp, ..\utest\srs_utest.cpp,
..\utest\srs_utest_amf0.hpp,
..\utest\srs_utest_amf0.cpp,
research readonly separator, research readonly separator,
..\..\research\librtmp\srs_play.c, ..\..\research\librtmp\srs_play.c,
..\..\research\librtmp\srs_publish.c, ..\..\research\librtmp\srs_publish.c,

View file

@ -37,9 +37,32 @@ SrsConfig* _srs_config = NULL;
SrsServer* _srs_server = NULL; SrsServer* _srs_server = NULL;
// basic test and samples. // basic test and samples.
VOID TEST(SampleTest, FastSampleInt64Test){ VOID TEST(SampleTest, FastSampleInt64Test)
{
EXPECT_EQ(1, (int)sizeof(int8_t)); EXPECT_EQ(1, (int)sizeof(int8_t));
EXPECT_EQ(2, (int)sizeof(int16_t)); EXPECT_EQ(2, (int)sizeof(int16_t));
EXPECT_EQ(4, (int)sizeof(int32_t)); EXPECT_EQ(4, (int)sizeof(int32_t));
EXPECT_EQ(8, (int)sizeof(int64_t)); EXPECT_EQ(8, (int)sizeof(int64_t));
} }
VOID TEST(SampleTest, FastSampleMacrosTest)
{
EXPECT_TRUE(1);
EXPECT_FALSE(0);
EXPECT_EQ(1, 1); // ==
EXPECT_NE(1, 2); // !=
EXPECT_LE(1, 2); // <=
EXPECT_LT(1, 2); // <
EXPECT_GE(2, 1); // >=
EXPECT_GT(2, 1); // >
EXPECT_STREQ("winlin", "winlin");
EXPECT_STRNE("winlin", "srs");
EXPECT_STRCASEEQ("winlin", "Winlin");
EXPECT_STRCASENE("winlin", "srs");
EXPECT_FLOAT_EQ(1.0, 1.000000000000001);
EXPECT_DOUBLE_EQ(1.0, 1.0000000000000001);
EXPECT_NEAR(10, 15, 5);
}

View file

@ -0,0 +1,85 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2014 winlin
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_utest_amf0.hpp>
VOID TEST(AMF0Test, Size)
{
EXPECT_EQ(2+6, SrsAmf0Size::utf8("winlin"));
EXPECT_EQ(2+0, SrsAmf0Size::utf8(""));
EXPECT_EQ(1+2+6, SrsAmf0Size::str("winlin"));
EXPECT_EQ(1+2+0, SrsAmf0Size::str(""));
EXPECT_EQ(1+8, SrsAmf0Size::number());
EXPECT_EQ(1, SrsAmf0Size::null());
EXPECT_EQ(1, SrsAmf0Size::undefined());
EXPECT_EQ(1+1, SrsAmf0Size::boolean());
if (true) {
int size = 1+3;
SrsAmf0Object obj;
EXPECT_EQ(size, SrsAmf0Size::object(&obj));
}
if (true) {
int size = 1+3;
SrsAmf0Object obj;
size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
obj.set("name", new SrsAmf0String("winlin"));
EXPECT_EQ(size, SrsAmf0Size::object(&obj));
}
if (true) {
int size = 1+4+3;
SrsAmf0EcmaArray arr;
EXPECT_EQ(size, SrsAmf0Size::array(&arr));
}
if (true) {
int size = 1+4+3;
SrsAmf0EcmaArray arr;
size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
arr.set("name", new SrsAmf0String("winlin"));
EXPECT_EQ(size, SrsAmf0Size::array(&arr));
}
if (true) {
int size = 1+4+3;
SrsAmf0EcmaArray arr;
size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin");
arr.set("name", new SrsAmf0String("winlin"));
SrsAmf0Object* args = new SrsAmf0Object();
size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args);
arr.set("args", args);
EXPECT_EQ(size, SrsAmf0Size::array(&arr));
}
}

View file

@ -0,0 +1,33 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2014 winlin
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SRS_UTEST_AMF0_HPP
#define SRS_UTEST_AMF0_HPP
/*
#include <srs_utest_amf0.hpp>
*/
#include <srs_utest.hpp>
#include <srs_protocol_amf0.hpp>
#endif