整理代码

This commit is contained in:
xiongziliang 2019-09-20 10:37:41 +08:00
parent 5ad4103ce0
commit 9735d891da
2 changed files with 161 additions and 149 deletions

View File

@ -76,8 +76,8 @@ inline void AMFValue::init() {
} }
} }
AMFValue::AMFValue(AMFType type) : AMFValue::AMFValue() :
_type(type) { _type(AMF_NULL) {
init(); init();
} }
@ -161,6 +161,120 @@ AMFValue& AMFValue::operator =(AMFValue &&from) {
} }
void AMFValue::clear() {
switch (_type) {
case AMF_STRING:
_value.string->clear();
break;
case AMF_OBJECT:
case AMF_ECMA_ARRAY:
_value.object->clear();
break;
default:
break;
}
}
AMFType AMFValue::type() const {
return _type;
}
const std::string &AMFValue::as_string() const {
if(_type != AMF_STRING){
throw std::runtime_error("AMF not a string");
}
return *_value.string;
}
double AMFValue::as_number() const {
switch (_type) {
case AMF_NUMBER:
return _value.number;
case AMF_INTEGER:
return _value.integer;
case AMF_BOOLEAN:
return _value.boolean;
default:
throw std::runtime_error("AMF not a number");
}
}
int AMFValue::as_integer() const {
switch (_type) {
case AMF_NUMBER:
return _value.number;
case AMF_INTEGER:
return _value.integer;
case AMF_BOOLEAN:
return _value.boolean;
default:
throw std::runtime_error("AMF not a integer");
}
}
bool AMFValue::as_boolean() const {
switch (_type) {
case AMF_NUMBER:
return _value.number;
case AMF_INTEGER:
return _value.integer;
case AMF_BOOLEAN:
return _value.boolean;
default:
throw std::runtime_error("AMF not a boolean");
}
}
const AMFValue& AMFValue::operator[](const char *str) const {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
auto i = _value.object->find(str);
if (i == _value.object->end()) {
static AMFValue val(AMF_NULL);
return val;
}
return i->second;
}
void AMFValue::object_for_each(const function<void(const string &key, const AMFValue &val)> &fun) const {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
for (auto & pr : *(_value.object)) {
fun(pr.first, pr.second);
}
}
AMFValue::operator bool() const{
return _type != AMF_NULL;
}
void AMFValue::set(const std::string &s, const AMFValue &val) {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
_value.object->emplace(s, val);
}
void AMFValue::add(const AMFValue &val) {
if (_type != AMF_STRICT_ARRAY) {
throw std::runtime_error("AMF not a array");
}
assert(_type == AMF_STRICT_ARRAY);
_value.array->push_back(val);
}
const AMFValue::mapType &AMFValue::getMap() const {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
return *_value.object;
}
const AMFValue::arrayType &AMFValue::getArr() const {
if (_type != AMF_STRICT_ARRAY) {
throw std::runtime_error("AMF not a array");
}
return *_value.array;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
enum { enum {
@ -316,6 +430,14 @@ void AMFEncoder::write_key(const std::string& s) {
buf += s; buf += s;
} }
void AMFEncoder::clear() {
buf.clear();
}
const std::string& AMFEncoder::data() const {
return buf;
}
//////////////////Decoder////////////////// //////////////////Decoder//////////////////
uint8_t AMFDecoder::front() { uint8_t AMFDecoder::front() {
@ -551,3 +673,8 @@ AMFValue AMFDecoder::load_arr() {
}*/ }*/
return object; return object;
} }
AMFDecoder::AMFDecoder(const std::string &buf_in, size_t pos_in, int version_in) :
buf(buf_in), pos(pos_in), version(version_in) {
}

View File

@ -32,6 +32,9 @@
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <stdexcept> #include <stdexcept>
#include <functional>
using namespace std;
enum AMFType { enum AMFType {
AMF_NUMBER, AMF_NUMBER,
AMF_INTEGER, AMF_INTEGER,
@ -48,8 +51,11 @@ class AMFValue;
class AMFValue { class AMFValue {
public: public:
friend class AMFEncoder;
typedef std::map<std::string, AMFValue> mapType;
typedef std::vector<AMFValue> arrayType;
AMFValue(AMFType type = AMF_NULL); AMFValue();
AMFValue(const char *s); AMFValue(const char *s);
AMFValue(const std::string &s); AMFValue(const std::string &s);
AMFValue(double n); AMFValue(double n);
@ -61,115 +67,23 @@ public:
AMFValue &operator =(AMFValue &&from); AMFValue &operator =(AMFValue &&from);
~AMFValue(); ~AMFValue();
void clear() { void clear();
switch (_type) { AMFType type() const ;
case AMF_STRING: const std::string &as_string() const;
_value.string->clear(); double as_number() const;
break; int as_integer() const;
case AMF_OBJECT: bool as_boolean() const;
case AMF_ECMA_ARRAY: const AMFValue &operator[](const char *str) const;
_value.object->clear(); void object_for_each(const function<void(const string &key, const AMFValue &val)> &fun) const ;
break; operator bool() const;
default: void set(const std::string &s, const AMFValue &val);
break; void add(const AMFValue &val);
} private:
} const mapType &getMap() const;
const arrayType &getArr() const;
AMFType type() const { void destroy();
return _type; void init();
}
const std::string &as_string() const {
if(_type != AMF_STRING){
throw std::runtime_error("AMF not a string");
}
return *_value.string;
}
double as_number() const {
switch (_type) {
case AMF_NUMBER:
return _value.number;
case AMF_INTEGER:
return _value.integer;
case AMF_BOOLEAN:
return _value.boolean;
break;
default:
throw std::runtime_error("AMF not a number");
break;
}
}
int as_integer() const {
switch (_type) {
case AMF_NUMBER:
return _value.number;
case AMF_INTEGER:
return _value.integer;
case AMF_BOOLEAN:
return _value.boolean;
break;
default:
throw std::runtime_error("AMF not a integer");
break;
}
}
bool as_boolean() const {
switch (_type) {
case AMF_NUMBER:
return _value.number;
case AMF_INTEGER:
return _value.integer;
case AMF_BOOLEAN:
return _value.boolean;
break;
default:
throw std::runtime_error("AMF not a boolean");
break;
}
}
const AMFValue &operator[](const char *str) const {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
auto i = _value.object->find(str);
if (i == _value.object->end()) {
static AMFValue val(AMF_NULL);
return val;
}
return i->second;
}
template<typename FUN>
void object_for_each(const FUN &fun) const {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
for (auto & pr : *(_value.object)) {
fun(pr.first, pr.second);
}
}
operator bool() const{
return _type != AMF_NULL;
}
void set(const std::string &s, const AMFValue &val) {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
_value.object->emplace(s, val);
}
void add(const AMFValue &val) {
if (_type != AMF_STRICT_ARRAY) {
throw std::runtime_error("AMF not a array");
}
assert(_type == AMF_STRICT_ARRAY);
_value.array->push_back(val);
}
private: private:
typedef std::map<std::string, AMFValue> mapType;
typedef std::vector<AMFValue> arrayType;
AMFType _type; AMFType _type;
union { union {
std::string *string; std::string *string;
@ -179,50 +93,24 @@ private:
mapType *object; mapType *object;
arrayType *array; arrayType *array;
} _value; } _value;
friend class AMFEncoder;
const mapType &getMap() const {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
return *_value.object;
}
const arrayType &getArr() const {
if (_type != AMF_STRICT_ARRAY) {
throw std::runtime_error("AMF not a array");
}
return *_value.array;
}
inline void destroy();
inline void init();
}; };
class AMFDecoder { class AMFDecoder {
public: public:
AMFDecoder(const std::string &_buf, size_t _pos, int _version = 0) : AMFDecoder(const std::string &buf, size_t pos, int version = 0);
buf(_buf), pos(_pos), version(_version) {
}
int getVersion() const {
return version;
}
template<typename TP> template<typename TP>
TP load(); TP load();
private: private:
const std::string &buf;
size_t pos;
int version;
std::string load_key(); std::string load_key();
AMFValue load_object(); AMFValue load_object();
AMFValue load_ecma(); AMFValue load_ecma();
AMFValue load_arr(); AMFValue load_arr();
uint8_t front(); uint8_t front();
uint8_t pop_front(); uint8_t pop_front();
private:
const std::string &buf;
size_t pos;
int version;
}; };
class AMFEncoder { class AMFEncoder {
@ -234,15 +122,12 @@ public:
AMFEncoder & operator <<(const double n); AMFEncoder & operator <<(const double n);
AMFEncoder & operator <<(const bool b); AMFEncoder & operator <<(const bool b);
AMFEncoder & operator <<(const AMFValue &value); AMFEncoder & operator <<(const AMFValue &value);
const std::string data() const { const std::string& data() const ;
return buf; void clear() ;
}
void clear() {
buf.clear();
}
private: private:
void write_key(const std::string &s); void write_key(const std::string &s);
AMFEncoder &write_undefined(); AMFEncoder &write_undefined();
private:
std::string buf; std::string buf;
}; };