1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 03:41:55 +00:00

amf0 utest: elem read/write refined

This commit is contained in:
winlin 2014-03-08 16:56:35 +08:00
parent bfe771bbba
commit 4306db099d
6 changed files with 514 additions and 137 deletions

View file

@ -80,10 +80,6 @@ void SrsStream::skip(int size)
int SrsStream::pos()
{
if (empty()) {
return 0;
}
return p - bytes;
}

View file

@ -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,19 +420,11 @@ 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);
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;
return ret;
}
// add property
@ -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());
*ppvalue = 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);
*ppvalue = 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);
*ppvalue = SrsAmf0Any::number(data);
return ret;
}
case RTMP_AMF0_Null: {
stream->skip(1);
value = new __SrsAmf0Null();
*ppvalue = 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;
*ppvalue = 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;
*ppvalue = 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;

View file

@ -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,19 +301,10 @@ 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
@ -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

View file

@ -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;
}

View file

@ -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);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_TRUE(NULL != o);
EXPECT_TRUE(o->is_boolean());
EXPECT_FALSE(o->to_boolean());
}
if (true) {
o = SrsAmf0Any::boolean(false);
SrsAutoFree(SrsAmf0Any, o, false);
EXPECT_TRUE(NULL != o);
ASSERT_TRUE(NULL != o);
EXPECT_TRUE(o->is_boolean());
EXPECT_FALSE(o->to_boolean());
}
if (true) {
o = SrsAmf0Any::boolean(true);
SrsAutoFree(SrsAmf0Any, o, false);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_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);
EXPECT_TRUE(NULL != o);
ASSERT_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());
}
}

View file

@ -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