Goran Lazarevski 669cf5383b Lucky World source code
2025-03-18 19:25:25 +01:00

571 lines
13 KiB
C++

// Modifications Copyright 2018-current Getnamo. All Rights Reserved
//
// sio_message.h
//
// Created by Melo Yao on 3/25/15.
//
#ifndef __SIO_MESSAGE_H__
#define __SIO_MESSAGE_H__
#include <string>
#include <memory>
#include <vector>
#include <map>
#include <cassert>
#include <type_traits>
namespace sio
{
class message
{
public:
enum flag
{
flag_integer,
flag_double,
flag_string,
flag_binary,
flag_array,
flag_object,
flag_boolean,
flag_null
};
virtual ~message(){};
class list;
flag get_flag() const
{
return _flag;
}
typedef std::shared_ptr<message> ptr;
virtual bool get_bool() const
{
assert(false);
return false;
}
virtual int64_t get_int() const
{
assert(false);
return 0;
}
virtual double get_double() const
{
assert(false);
return 0;
}
virtual std::string const& get_string() const
{
assert(false);
static std::string s_empty_string;
s_empty_string.clear();
return s_empty_string;
}
virtual std::shared_ptr<const std::string> const& get_binary() const
{
assert(false);
static std::shared_ptr<const std::string> s_empty_binary;
s_empty_binary = nullptr;
return s_empty_binary;
}
virtual const std::vector<ptr>& get_vector() const
{
assert(false);
static std::vector<ptr> s_empty_vector;
s_empty_vector.clear();
return s_empty_vector;
}
virtual std::vector<ptr>& get_vector()
{
assert(false);
static std::vector<ptr> s_empty_vector;
s_empty_vector.clear();
return s_empty_vector;
}
virtual const std::map<std::string,message::ptr>& get_map() const
{
assert(false);
static std::map<std::string,message::ptr> s_empty_map;
s_empty_map.clear();
return s_empty_map;
}
virtual std::map<std::string,message::ptr>& get_map()
{
assert(false);
static std::map<std::string,message::ptr> s_empty_map;
s_empty_map.clear();
return s_empty_map;
}
private:
flag _flag;
protected:
message(flag f):_flag(f){}
};
class null_message : public message
{
protected:
null_message()
:message(flag_null)
{
}
public:
static message::ptr create()
{
return ptr(new null_message());
}
};
class bool_message : public message
{
bool _v;
protected:
bool_message(bool v)
:message(flag_boolean),_v(v)
{
}
public:
static message::ptr create(bool v)
{
return ptr(new bool_message(v));
}
bool get_bool() const
{
return _v;
}
};
class int_message : public message
{
int64_t _v;
protected:
int_message(int64_t v)
:message(flag_integer),_v(v)
{
}
public:
static message::ptr create(int64_t v)
{
return ptr(new int_message(v));
}
int64_t get_int() const
{
return _v;
}
double get_double() const//add double accessor for integer.
{
return static_cast<double>(_v);
}
};
class double_message : public message
{
double _v;
double_message(double v)
:message(flag_double),_v(v)
{
}
public:
static message::ptr create(double v)
{
return ptr(new double_message(v));
}
double get_double() const
{
return _v;
}
};
class string_message : public message
{
std::string _v;
string_message(std::string const& v)
:message(flag_string),_v(v)
{
}
string_message(std::string&& v)
:message(flag_string),_v(std::move(v))
{
}
public:
static message::ptr create(std::string const& v)
{
return ptr(new string_message(v));
}
static message::ptr create(std::string&& v)
{
return ptr(new string_message(std::move(v)));
}
std::string const& get_string() const
{
return _v;
}
};
class binary_message : public message
{
std::shared_ptr<const std::string> _v;
binary_message(std::shared_ptr<const std::string> const& v)
:message(flag_binary),_v(v)
{
}
public:
static message::ptr create(std::shared_ptr<const std::string> const& v)
{
return ptr(new binary_message(v));
}
std::shared_ptr<const std::string> const& get_binary() const
{
return _v;
}
};
class array_message : public message
{
std::vector<message::ptr> _v;
array_message():message(flag_array)
{
}
public:
static message::ptr create()
{
return ptr(new array_message());
}
void push(message::ptr const& message)
{
if(message)
_v.push_back(message);
}
void push(const std::string& text)
{
_v.push_back(string_message::create(text));
}
void push(std::string&& text)
{
_v.push_back(string_message::create(std::move(text)));
}
void push(std::shared_ptr<std::string> const& binary)
{
if(binary)
_v.push_back(binary_message::create(binary));
}
void push(std::shared_ptr<const std::string> const& binary)
{
if(binary)
_v.push_back(binary_message::create(binary));
}
void insert(size_t pos,message::ptr const& message)
{
_v.insert(_v.begin()+pos, message);
}
void insert(size_t pos,const std::string& text)
{
_v.insert(_v.begin()+pos, string_message::create(text));
}
void insert(size_t pos,std::string&& text)
{
_v.insert(_v.begin()+pos, string_message::create(std::move(text)));
}
void insert(size_t pos,std::shared_ptr<std::string> const& binary)
{
if(binary)
_v.insert(_v.begin()+pos, binary_message::create(binary));
}
void insert(size_t pos,std::shared_ptr<const std::string> const& binary)
{
if(binary)
_v.insert(_v.begin()+pos, binary_message::create(binary));
}
size_t size() const
{
return _v.size();
}
const message::ptr& at(size_t i) const
{
return _v[i];
}
const message::ptr& operator[] (size_t i) const
{
return _v[i];
}
std::vector<ptr>& get_vector()
{
return _v;
}
const std::vector<ptr>& get_vector() const
{
return _v;
}
};
class object_message : public message
{
std::map<std::string,message::ptr> _v;
object_message() : message(flag_object)
{
}
public:
static message::ptr create()
{
return ptr(new object_message());
}
void insert(const std::string & key,message::ptr const& message)
{
_v[key] = message;
}
void insert(const std::string & key,const std::string& text)
{
_v[key] = string_message::create(text);
}
void insert(const std::string & key,std::string&& text)
{
_v[key] = string_message::create(std::move(text));
}
void insert(const std::string & key,std::shared_ptr<std::string> const& binary)
{
if(binary)
_v[key] = binary_message::create(binary);
}
void insert(const std::string & key,std::shared_ptr<const std::string> const& binary)
{
if(binary)
_v[key] = binary_message::create(binary);
}
bool has(const std::string & key)
{
return _v.find(key) != _v.end();
}
const message::ptr& at(const std::string & key) const
{
static std::shared_ptr<message> not_found;
std::map<std::string,message::ptr>::const_iterator it = _v.find(key);
if (it != _v.cend()) return it->second;
return not_found;
}
const message::ptr& operator[] (const std::string & key) const
{
return at(key);
}
bool has(const std::string & key) const
{
return _v.find(key) != _v.end();
}
std::map<std::string,message::ptr>& get_map()
{
return _v;
}
const std::map<std::string,message::ptr>& get_map() const
{
return _v;
}
};
class message::list
{
public:
list()
{
}
list(std::nullptr_t)
{
}
list(message::list&& rhs):
m_vector(std::move(rhs.m_vector))
{
}
list & operator= (const message::list && rhs)
{
m_vector = std::move(rhs.m_vector);
return *this;
}
template <typename T>
list(T&& content,
typename std::enable_if<std::is_same<std::vector<message::ptr>,typename std::remove_reference<T>::type>::value>::type* = 0):
m_vector(std::forward<T>(content))
{
}
list(message::list const& rhs):
m_vector(rhs.m_vector)
{
}
list(message::ptr const& message)
{
if(message)
m_vector.push_back(message);
}
list(const std::string& text)
{
m_vector.push_back(string_message::create(text));
}
list(std::string&& text)
{
m_vector.push_back(string_message::create(std::move(text)));
}
list(std::shared_ptr<std::string> const& binary)
{
if(binary)
m_vector.push_back(binary_message::create(binary));
}
list(std::shared_ptr<const std::string> const& binary)
{
if(binary)
m_vector.push_back(binary_message::create(binary));
}
void push(message::ptr const& message)
{
if(message)
m_vector.push_back(message);
}
void push(const std::string& text)
{
m_vector.push_back(string_message::create(text));
}
void push(std::string&& text)
{
m_vector.push_back(string_message::create(std::move(text)));
}
void push(std::shared_ptr<std::string> const& binary)
{
if(binary)
m_vector.push_back(binary_message::create(binary));
}
void push(std::shared_ptr<const std::string> const& binary)
{
if(binary)
m_vector.push_back(binary_message::create(binary));
}
void insert(size_t pos,message::ptr const& message)
{
m_vector.insert(m_vector.begin()+pos, message);
}
void insert(size_t pos,const std::string& text)
{
m_vector.insert(m_vector.begin()+pos, string_message::create(text));
}
void insert(size_t pos,std::string&& text)
{
m_vector.insert(m_vector.begin()+pos, string_message::create(std::move(text)));
}
void insert(size_t pos,std::shared_ptr<std::string> const& binary)
{
if(binary)
m_vector.insert(m_vector.begin()+pos, binary_message::create(binary));
}
void insert(size_t pos,std::shared_ptr<const std::string> const& binary)
{
if(binary)
m_vector.insert(m_vector.begin()+pos, binary_message::create(binary));
}
size_t size() const
{
return m_vector.size();
}
const message::ptr& at(size_t i) const
{
return m_vector[i];
}
const message::ptr& operator[] (size_t i) const
{
return m_vector[i];
}
message::ptr to_array_message(std::string const& event_name) const
{
message::ptr arr = array_message::create();
arr->get_vector().push_back(string_message::create(event_name));
arr->get_vector().insert(arr->get_vector().end(),m_vector.begin(),m_vector.end());
return arr;
}
message::ptr to_array_message() const
{
message::ptr arr = array_message::create();
arr->get_vector().insert(arr->get_vector().end(),m_vector.begin(),m_vector.end());
return arr;
}
private:
std::vector<message::ptr> m_vector;
};
}
#endif