diff --git a/trunk/src/app/srs_app_json.cpp b/trunk/src/app/srs_app_json.cpp index 1506cb3a6..e6485540b 100644 --- a/trunk/src/app/srs_app_json.cpp +++ b/trunk/src/app/srs_app_json.cpp @@ -23,31 +23,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -#include +using namespace std; -// whether use nxjson -// @see: https://bitbucket.org/yarosla/nxjson -#undef SRS_JSON_USE_NXJSON -#define SRS_JSON_USE_NXJSON +#include +#include #ifdef SRS_JSON_USE_NXJSON -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// @@ -117,6 +99,374 @@ const nx_json* nx_json_item(const nx_json* json, int idx); // get array element #endif /* NXJSON_H */ +#endif + +// Json marker +#define SRS_JSON_Boolean 0x01 +#define SRS_JSON_String 0x02 +#define SRS_JSON_Object 0x03 +#define SRS_JSON_Integer 0x04 +#define SRS_JSON_Number 0x05 +#define SRS_JSON_Null 0x06 +#define SRS_JSON_Array 0x07 + +class __SrsJsonString : public SrsJsonAny +{ +public: + std::string value; + + __SrsJsonString(const char* _value) + { + marker = SRS_JSON_String; + if (_value) { + value = _value; + } + } + virtual ~__SrsJsonString() + { + } +}; + +class __SrsJsonBoolean : public SrsJsonAny +{ +public: + bool value; + + __SrsJsonBoolean(bool _value) + { + marker = SRS_JSON_Boolean; + value = _value; + } + virtual ~__SrsJsonBoolean() + { + } +}; + +class __SrsJsonInteger : public SrsJsonAny +{ +public: + int64_t value; + + __SrsJsonInteger(int64_t _value) + { + marker = SRS_JSON_Integer; + value = _value; + } + virtual ~__SrsJsonInteger() + { + } +}; + +class __SrsJsonNumber : public SrsJsonAny +{ +public: + double value; + + __SrsJsonNumber(double _value) + { + marker = SRS_JSON_Number; + value = _value; + } + virtual ~__SrsJsonNumber() + { + } +}; + +class __SrsJsonNull : public SrsJsonAny +{ +public: + __SrsJsonNull() { + marker = SRS_JSON_Null; + } + virtual ~__SrsJsonNull() { + } +}; + +SrsJsonAny::SrsJsonAny() +{ + marker = 0; +} + +SrsJsonAny::~SrsJsonAny() +{ +} + +bool SrsJsonAny::is_string() +{ + return marker == SRS_JSON_String; +} + +bool SrsJsonAny::is_boolean() +{ + return marker == SRS_JSON_Boolean; +} + +bool SrsJsonAny::is_number() +{ + return marker == SRS_JSON_Number; +} + +bool SrsJsonAny::is_integer() +{ + return marker == SRS_JSON_Integer; +} + +bool SrsJsonAny::is_object() +{ + return marker == SRS_JSON_Object; +} + +bool SrsJsonAny::is_array() +{ + return marker == SRS_JSON_Array; +} + +bool SrsJsonAny::is_null() +{ + return marker == SRS_JSON_Null; +} + +string SrsJsonAny::to_str() +{ + __SrsJsonString* p = dynamic_cast<__SrsJsonString*>(this); + srs_assert(p != NULL); + return p->value; +} + +bool SrsJsonAny::to_boolean() +{ + __SrsJsonBoolean* p = dynamic_cast<__SrsJsonBoolean*>(this); + srs_assert(p != NULL); + return p->value; +} + +int64_t SrsJsonAny::to_integer() +{ + __SrsJsonInteger* p = dynamic_cast<__SrsJsonInteger*>(this); + srs_assert(p != NULL); + return p->value; +} + +double SrsJsonAny::to_number() +{ + __SrsJsonNumber* p = dynamic_cast<__SrsJsonNumber*>(this); + srs_assert(p != NULL); + return p->value; +} + +SrsJsonObject* SrsJsonAny::to_object() +{ + SrsJsonObject* p = dynamic_cast(this); + srs_assert(p != NULL); + return p; +} + +SrsJsonArray* SrsJsonAny::to_array() +{ + SrsJsonArray* p = dynamic_cast(this); + srs_assert(p != NULL); + return p; +} + +SrsJsonAny* SrsJsonAny::str(const char* value) +{ + return new __SrsJsonString(value); +} + +SrsJsonAny* SrsJsonAny::boolean(bool value) +{ + return new __SrsJsonBoolean(value); +} + +SrsJsonAny* SrsJsonAny::ingeter(int64_t value) +{ + return new __SrsJsonInteger(value); +} + +SrsJsonAny* SrsJsonAny::number(double value) +{ + return new __SrsJsonNumber(value); +} + +SrsJsonAny* SrsJsonAny::null() +{ + return new __SrsJsonNull(); +} + +SrsJsonObject* SrsJsonAny::object() +{ + return new SrsJsonObject(); +} + +SrsJsonArray* SrsJsonAny::array() +{ + return new SrsJsonArray(); +} + +#ifdef SRS_JSON_USE_NXJSON +SrsJsonAny* srs_json_parse_tree_nx_json(const nx_json* node) +{ + switch (node->type) { + case NX_JSON_NULL: + return SrsJsonAny::null(); + case NX_JSON_STRING: + return SrsJsonAny::str(node->text_value); + case NX_JSON_INTEGER: + return SrsJsonAny::ingeter(node->int_value); + case NX_JSON_DOUBLE: + return SrsJsonAny::number(node->dbl_value); + case NX_JSON_BOOL: + return SrsJsonAny::boolean(node->int_value != 0); + case NX_JSON_OBJECT: { + SrsJsonObject* obj = SrsJsonAny::object(); + for (nx_json* p = node->child; p != NULL; p = p->next) { + SrsJsonAny* value = srs_json_parse_tree_nx_json(p); + if (value) { + obj->set(p->key, value); + } + } + return obj; + } + case NX_JSON_ARRAY: { + SrsJsonArray* arr = SrsJsonAny::array(); + for (nx_json* p = node->child; p != NULL; p = p->next) { + SrsJsonAny* value = srs_json_parse_tree_nx_json(p); + if (value) { + arr->add(value); + } + } + return arr; + } + } + return NULL; +} + +SrsJsonAny* SrsJsonAny::loads(char* str) +{ + srs_assert(str); + if (strlen(str) == 0) { + return NULL; + } + + const nx_json* o = nx_json_parse(str, 0); + SrsJsonAny* json = srs_json_parse_tree_nx_json(o); + nx_json_free(o); + return json; +} +#endif + +SrsJsonObject::SrsJsonObject() +{ + marker = SRS_JSON_Object; +} + +SrsJsonObject::~SrsJsonObject() +{ + std::vector::iterator it; + for (it = properties.begin(); it != properties.end(); ++it) { + SrsJsonObjectPropertyType item = *it; + SrsJsonAny* obj = item.second; + srs_freep(obj); + } + properties.clear(); +} + +int SrsJsonObject::count() +{ + return (int)properties.size(); +} + +string SrsJsonObject::key_at(int index) +{ + srs_assert(index < count()); + SrsJsonObjectPropertyType& elem = properties[index]; + return elem.first; +} + +SrsJsonAny* SrsJsonObject::value_at(int index) +{ + srs_assert(index < count()); + SrsJsonObjectPropertyType& elem = properties[index]; + return elem.second; +} + +void SrsJsonObject::set(string key, SrsJsonAny* value) +{ + if (!value) { + srs_warn("add a NULL propertity %s", key.c_str()); + return; + } + + std::vector::iterator it; + + for (it = properties.begin(); it != properties.end(); ++it) { + SrsJsonObjectPropertyType& elem = *it; + std::string name = elem.first; + SrsJsonAny* any = elem.second; + + if (key == name) { + srs_freep(any); + properties.erase(it); + break; + } + } + + properties.push_back(std::make_pair(key, value)); +} + +SrsJsonAny* SrsJsonObject::get_property(string name) +{ + std::vector::iterator it; + + for (it = properties.begin(); it != properties.end(); ++it) { + SrsJsonObjectPropertyType& elem = *it; + std::string key = elem.first; + SrsJsonAny* any = elem.second; + if (key == name) { + return any; + } + } + + return NULL; +} + +SrsJsonArray::SrsJsonArray() +{ + marker = SRS_JSON_Array; +} + +SrsJsonArray::~SrsJsonArray() +{ + std::vector::iterator it; + for (it = properties.begin(); it != properties.end(); ++it) { + SrsJsonAny* item = *it; + srs_freep(item); + } + properties.clear(); +} + +int SrsJsonArray::count() +{ + return (int)properties.size(); +} + +SrsJsonAny* SrsJsonArray::at(int index) +{ + srs_assert(index < count()); + SrsJsonAny* elem = properties[index]; + return elem; +} + +void SrsJsonArray::add(SrsJsonAny* value) +{ + properties.push_back(value); +} + +#ifdef SRS_JSON_USE_NXJSON + +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// /* * Copyright (c) 2013 Yaroslav Stavnichiy * @@ -170,6 +520,7 @@ static const nx_json dummy={ NX_JSON_NULL }; static nx_json* create_json(nx_json_type type, const char* key, nx_json* parent) { nx_json* js=(nx_json*)NX_JSON_CALLOC(); + memset(js, 0, sizeof(nx_json)); assert(js); js->type=type; js->key=key; @@ -475,6 +826,7 @@ const nx_json* nx_json_parse_utf8(char* text) { const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder) { nx_json js; + memset(&js, 0, sizeof(nx_json)); if (!parse_value(&js, 0, text, encoder)) { if (js.child) nx_json_free(js.child); return 0; @@ -506,25 +858,10 @@ const nx_json* nx_json_item(const nx_json* json, int idx) { #endif #endif /* NXJSON_C */ + //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// + #endif diff --git a/trunk/src/app/srs_app_json.hpp b/trunk/src/app/srs_app_json.hpp index 45eb150af..7aee140d7 100644 --- a/trunk/src/app/srs_app_json.hpp +++ b/trunk/src/app/srs_app_json.hpp @@ -29,6 +29,144 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include +#include + +// whether use nxjson +// @see: https://bitbucket.org/yarosla/nxjson +#undef SRS_JSON_USE_NXJSON +#define SRS_JSON_USE_NXJSON + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +// json decode +// 1. SrsJsonAny: read any from str:char* +// SrsJsonAny* pany = NULL; +// if ((ret = srs_json_read_any(str, &pany)) != ERROR_SUCCESS) { +// return ret; +// } +// srs_assert(pany); // if success, always valid object. +// 2. SrsJsonAny: convert to specifid type, for instance, string +// SrsJsonAny* pany = ... +// if (pany->is_string()) { +// string v = pany->to_str(); +// } +// +// for detail usage, see interfaces of each object. +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +// @see: https://bitbucket.org/yarosla/nxjson +// @see: https://github.com/udp/json-parser + +class SrsJsonArray; +class SrsJsonObject; + +class SrsJsonAny +{ +public: + char marker; +// donot directly create this object, +// instead, for examle, use SrsJsonAny::str() to create a concreated one. +protected: + SrsJsonAny(); +public: + virtual ~SrsJsonAny(); +public: + virtual bool is_string(); + virtual bool is_boolean(); + virtual bool is_integer(); + virtual bool is_number(); + virtual bool is_object(); + virtual bool is_array(); + virtual bool is_null(); +public: + /** + * get the string of any when is_string() indicates true. + * user must ensure the type is a string, or assert failed. + */ + virtual std::string to_str(); + /** + * get the boolean of any when is_boolean() indicates true. + * user must ensure the type is a boolean, or assert failed. + */ + virtual bool to_boolean(); + /** + * get the integer of any when is_integer() indicates true. + * user must ensure the type is a integer, or assert failed. + */ + virtual int64_t to_integer(); + /** + * get the number of any when is_number() indicates true. + * user must ensure the type is a number, or assert failed. + */ + virtual double to_number(); + /** + * get the object of any when is_object() indicates true. + * user must ensure the type is a object, or assert failed. + */ + virtual SrsJsonObject* to_object(); + /** + * get the ecma array of any when is_ecma_array() indicates true. + * user must ensure the type is a ecma array, or assert failed. + */ + virtual SrsJsonArray* to_array(); +public: + static SrsJsonAny* str(const char* value = NULL); + static SrsJsonAny* boolean(bool value = false); + static SrsJsonAny* ingeter(int64_t value = 0); + static SrsJsonAny* number(double value = 0.0); + static SrsJsonAny* null(); + static SrsJsonObject* object(); + static SrsJsonArray* array(); +public: + /** + * read json tree from str:char* + */ + static SrsJsonAny* loads(char* str); +}; + +class SrsJsonObject : public SrsJsonAny +{ +private: + typedef std::pair SrsJsonObjectPropertyType; + std::vector properties; +private: + // use SrsJsonAny::object() to create it. + friend class SrsJsonAny; + SrsJsonObject(); +public: + virtual ~SrsJsonObject(); +public: + virtual int count(); + // @remark: max index is count(). + virtual std::string key_at(int index); + // @remark: max index is count(). + virtual SrsJsonAny* value_at(int index); +public: + virtual void set(std::string key, SrsJsonAny* value); + virtual SrsJsonAny* get_property(std::string name); +}; + +class SrsJsonArray : public SrsJsonAny +{ +private: + std::vector properties; + +private: + // use SrsJsonAny::array() to create it. + friend class SrsJsonAny; + SrsJsonArray(); +public: + virtual ~SrsJsonArray(); +public: + virtual int count(); + // @remark: max index is count(). + virtual SrsJsonAny* at(int index); + virtual void add(SrsJsonAny* value); +}; + //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// @@ -81,27 +219,4 @@ that is: #define JARRAY_START "[" #define JARRAY_END "]" -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -// json decode -// 1. SrsJsonAny: read any from stream -// SrsJsonAny* pany = NULL; -// if ((ret = srs_json_read_any(stream, &pany)) != ERROR_SUCCESS) { -// return ret; -// } -// srs_assert(pany); // if success, always valid object. -// 2. SrsJsonAny: convert to specifid type, for instance, string -// SrsJsonAny* pany = ... -// if (pany->is_string()) { -// string v = pany->to_str(); -// } -// -// for detail usage, see interfaces of each object. -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -// @see: https://bitbucket.org/yarosla/nxjson -// @see: https://github.com/udp/json-parser - #endif \ No newline at end of file diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index b7b6d1e9f..e04213eff 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "101" +#define VERSION_REVISION "102" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "srs" diff --git a/trunk/src/rtmp/srs_protocol_amf0.cpp b/trunk/src/rtmp/srs_protocol_amf0.cpp index 5054d0402..95de4351a 100644 --- a/trunk/src/rtmp/srs_protocol_amf0.cpp +++ b/trunk/src/rtmp/srs_protocol_amf0.cpp @@ -157,8 +157,8 @@ public: class __SrsUnSortedHashtable { private: - typedef std::pair SrsObjectPropertyType; - std::vector properties; + typedef std::pair SrsAmf0ObjectPropertyType; + std::vector properties; public: __SrsUnSortedHashtable(); virtual ~__SrsUnSortedHashtable(); @@ -399,9 +399,9 @@ __SrsUnSortedHashtable::__SrsUnSortedHashtable() __SrsUnSortedHashtable::~__SrsUnSortedHashtable() { - std::vector::iterator it; + std::vector::iterator it; for (it = properties.begin(); it != properties.end(); ++it) { - SrsObjectPropertyType& elem = *it; + SrsAmf0ObjectPropertyType& elem = *it; SrsAmf0Any* any = elem.second; srs_freep(any); } @@ -421,14 +421,14 @@ void __SrsUnSortedHashtable::clear() string __SrsUnSortedHashtable::key_at(int index) { srs_assert(index < count()); - SrsObjectPropertyType& elem = properties[index]; + SrsAmf0ObjectPropertyType& elem = properties[index]; return elem.first; } SrsAmf0Any* __SrsUnSortedHashtable::value_at(int index) { srs_assert(index < count()); - SrsObjectPropertyType& elem = properties[index]; + SrsAmf0ObjectPropertyType& elem = properties[index]; return elem.second; } @@ -439,10 +439,10 @@ void __SrsUnSortedHashtable::set(string key, SrsAmf0Any* value) return; } - std::vector::iterator it; + std::vector::iterator it; for (it = properties.begin(); it != properties.end(); ++it) { - SrsObjectPropertyType& elem = *it; + SrsAmf0ObjectPropertyType& elem = *it; std::string name = elem.first; SrsAmf0Any* any = elem.second; @@ -458,10 +458,10 @@ void __SrsUnSortedHashtable::set(string key, SrsAmf0Any* value) SrsAmf0Any* __SrsUnSortedHashtable::get_property(string name) { - std::vector::iterator it; + std::vector::iterator it; for (it = properties.begin(); it != properties.end(); ++it) { - SrsObjectPropertyType& elem = *it; + SrsAmf0ObjectPropertyType& elem = *it; std::string key = elem.first; SrsAmf0Any* any = elem.second; if (key == name) {