+++ /dev/null
-#include "reader.h"
-
-using STG::Reader;
-
-Reader::Reader()
-{
-}
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#ifndef __STG_SGCONFIG_READER_H__
-#define __STG_SGCONFIG_READER_H__
-
-#include <string>
-#include <vector>
-#include <utility>
-
-namespace STG
-{
-
-struct BaseReader
-{
- virtual ~BaseReader() {}
-
- virtual ssize_t read(TransportProto& proto) = 0;
- virtual bool done() const = 0;
-};
-
-template <typename T>
-class Reader : public BaseReader
-{
- public:
- Reader(size_t size = sizeof(T)) : m_size(size), m_done(0) {}
-
- virtual ssize_t read(TransportProto& proto)
- {
- char* pos = static_cast<void*>(&m_dest);
- pos += m_done;
- ssize_t res = proto.read(pos, m_size - m_done);
- if (res < 0)
- return res;
- if (res == 0) {
- m_done = m_size;
- return 0;
- }
- m_done += res;
- return res;
- }
-
- virtual bool done() const { return m_done == m_size; }
-
- T get() const { return ntoh(m_dest); }
-
- private:
- T m_dest;
- size_t m_size;
- size_t m_done;
-
-};
-
-template <>
-class Reader<std::vector<Reader*> > : public BaseReader
-{
- public:
- Reader(const std::vector<Reader*>& readers) : m_size(readers.size()), m_done(0) {}
-
- virtual ssize_t read(TransportProto& proto)
- {
- if (m_size == 0)
- return 0;
- size_t res = m_dest[m_done]->read(proto);
- if (res < 0)
- return res;
- if (res == 0) {
- m_done = m_size;
- return 0;
- }
- if (m_dest[m_done].done())
- ++m_dest;
- return res;
- }
-
- virtual bool done() const { return m_done == m_size; }
-
- const T& get() const { return m_dest; }
-
- private:
- T m_dest;
- size_t m_size;
- size_t m_done;
-
-};
-
-template <>
-class Reader<std::vector<char> > : public BaseReader
-{
- public:
- Reader(size_t size ) : m_dest(size), m_size(size), m_done(0) {}
-
- virtual ssize_t read(TransportProto& proto)
- {
- char* pos = static_cast<void*>(m_dest.data());
- pos += m_done;
- ssize_t res = proto.read(pos, m_size - m_done);
- if (res < 0)
- return res;
- if (res == 0) {
- m_done = m_size;
- return 0;
- }
- m_done += res;
- return res;
- }
-
- virtual bool done() const { return m_done == m_size; }
-
- const std::vector<char>& get() const { return m_dest; }
-
- private:
- std::vector<char> m_dest;
- size_t m_size;
- size_t m_done;
-
-};
-
-template <>
-class Reader<std::string>
-{
- public:
- Reader() : m_dest(Reader<std::string>::initDest()) {}
-
- virtual ssize_t read(TransportProto& proto)
- {
- if (m_size == 0)
- return 0;
- size_t res = m_dest[m_done]->read(proto);
- if (res < 0)
- return res;
- if (res == 0) {
- m_done = m_size;
- return 0;
- }
- if (m_dest[m_done].done())
- ++m_dest;
- return res;
- }
-
- virtual bool done() const { return m_done == m_size; }
-
- const T& get() const { return m_dest; }
-
- private:
- T m_dest;
- size_t m_size;
- size_t m_done;
-};
-
-} // namespace STG
-
-#endif
--- /dev/null
+###############################################################################
+# $Id: Makefile,v 1.9 2010/08/18 07:47:03 faust Exp $
+###############################################################################
+
+LIB_NAME = stgjson
+
+STGLIBS = -lstgcommon
+LIBS =
+
+SRCS = parser.cpp \
+ generator.cpp
+
+INCS = json_parser.h \
+ json_generator.h
+
+LIB_INCS = -I ../common.lib/include
+
+include ../Makefile.in
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include "stg/json_generator.h"
+
+#include <yajl/yajl_gen.h>
+
+using STG::JSON::NullGen;
+using STG::JSON::BoolGen;
+using STG::JSON::StringGen;
+using STG::JSON::NumberGen;
+using STG::JSON::MapGen;
+using STG::JSON::ArrayGen;
+using STG::JSON::Callback;
+
+namespace
+{
+
+void genString(yajl_gen_t* handle, const std::string& value)
+{
+ yajl_gen_string(handle, reinterpret_cast<const unsigned char*>(value.c_str()), value.length());
+}
+
+}
+
+void NullGen::run(yajl_gen_t* handle) const { yajl_gen_null(handle); }
+void BoolGen::run(yajl_gen_t* handle) const { yajl_gen_bool(handle, m_value); }
+void StringGen::run(yajl_gen_t* handle) const { genString(handle, m_value); }
+void NumberGen::run(yajl_gen_t* handle) const { yajl_gen_number(handle, m_value.c_str(), m_value.length()); }
+
+void MapGen::run(yajl_gen_t* handle) const
+{
+ yajl_gen_map_open(handle);
+ for (Value::const_iterator it = m_value.begin(); it != m_value.end(); ++it)
+ {
+ genString(handle, it->first);
+ it->second.first->run(handle);
+ }
+ yajl_gen_map_close(handle);
+}
+
+void ArrayGen::run(yajl_gen_t* handle) const
+{
+ yajl_gen_array_open(handle);
+ for (Value::const_iterator it = m_value.begin(); it != m_value.end(); ++it)
+ it->first->run(handle);
+ yajl_gen_array_close(handle);
+}
+
+bool STG::JSON::generate(Gen& gen, Callback callback, void* data)
+{
+ yajl_gen handle = yajl_gen_alloc(NULL);
+
+ gen.run(handle);
+
+ const unsigned char* buf = NULL;
+ size_t size = 0;
+ yajl_gen_get_buf(handle, &buf, &size);
+
+ bool res = callback(data, reinterpret_cast<const char*>(buf), size);
+
+ yajl_gen_free(handle);
+
+ return res;
+}
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_STGLIBS_JSON_GENERATOR_H__
+#define __STG_STGLIBS_JSON_GENERATOR_H__
+
+#include <string>
+#include <map>
+#include <vector>
+#include <utility>
+
+#include <boost/scoped_ptr.hpp>
+
+struct yajl_gen_t;
+
+namespace STG
+{
+namespace JSON
+{
+
+struct Gen
+{
+ virtual ~Gen() {}
+ virtual void run(yajl_gen_t* handle) const = 0;
+};
+
+struct NullGen : public Gen
+{
+ virtual void run(yajl_gen_t* handle) const;
+};
+
+class BoolGen : public Gen
+{
+ public:
+ BoolGen(bool value) : m_value(value) {}
+ virtual void run(yajl_gen_t* handle) const;
+ private:
+ bool m_value;
+};
+
+class StringGen : public Gen
+{
+ public:
+ StringGen(const std::string& value) : m_value(value) {}
+ virtual void run(yajl_gen_t* handle) const;
+ private:
+ std::string m_value;
+};
+
+class NumberGen : public Gen
+{
+ public:
+ NumberGen(const std::string& value) : m_value(value) {}
+ template <typename T>
+ NumberGen(const T& value) : m_value(x2str(value)) {}
+ virtual void run(yajl_gen_t* handle) const;
+ private:
+ std::string m_value;
+};
+
+class MapGen : public Gen
+{
+ public:
+ MapGen() {}
+ virtual ~MapGen()
+ {
+ for (Value::iterator it = m_value.begin(); it != m_value.end(); ++it)
+ if (it->second.second)
+ delete it->second.first;
+ }
+ MapGen& add(const std::string& key, Gen* value) { m_value[key] = std::make_pair(value, true); return *this; }
+ MapGen& add(const std::string& key, Gen& value) { m_value[key] = std::make_pair(&value, false); return *this; }
+ virtual void run(yajl_gen_t* handle) const;
+ private:
+ typedef std::pair<Gen*, bool> SmartGen;
+ typedef std::map<std::string, SmartGen> Value;
+ Value m_value;
+};
+
+class ArrayGen : public Gen
+{
+ public:
+ ArrayGen() {}
+ virtual ~ArrayGen()
+ {
+ for (Value::iterator it = m_value.begin(); it != m_value.end(); ++it)
+ if (it->second)
+ delete it->first;
+ }
+ void add(Gen* value) { m_value.push_back(std::make_pair(value, true)); }
+ void add(Gen& value) { m_value.push_back(std::make_pair(&value, false)); }
+ virtual void run(yajl_gen_t* handle) const;
+ private:
+ typedef std::pair<Gen*, bool> SmartGen;
+ typedef std::vector<SmartGen> Value;
+ Value m_value;
+};
+
+typedef bool (*Callback)(void* /*data*/, const char* /*buf*/, size_t /*size*/);
+bool generate(Gen& gen, Callback callback, void* data);
+
+}
+}
+
+#endif
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_STGLIBS_JSON_PARSER_H__
+#define __STG_STGLIBS_JSON_PARSER_H__
+
+#include "stg/common.h"
+
+#include <string>
+#include <map>
+
+#include <boost/scoped_ptr.hpp>
+
+namespace STG
+{
+namespace JSON
+{
+
+struct NodeParser
+{
+ virtual ~NodeParser() {}
+
+ virtual NodeParser* parseNull() { return this; }
+ virtual NodeParser* parseBoolean(const bool& /*value*/) { return this; }
+ virtual NodeParser* parseNumber(const std::string& /*value*/) { return this; }
+ virtual NodeParser* parseString(const std::string& /*value*/) { return this; }
+ virtual NodeParser* parseStartMap() { return this; }
+ virtual NodeParser* parseMapKey(const std::string& /*value*/) { return this; }
+ virtual NodeParser* parseEndMap() { return this; }
+ virtual NodeParser* parseStartArray() { return this; }
+ virtual NodeParser* parseEndArray() { return this; }
+};
+
+class Parser
+{
+ public:
+ Parser(NodeParser* topParser);
+ virtual ~Parser();
+
+ bool append(const char* data, size_t size);
+ bool done();
+
+ private:
+ class Impl;
+ boost::scoped_ptr<Impl> m_impl;
+};
+
+template <typename T>
+class EnumParser : public NodeParser
+{
+ public:
+ typedef std::map<std::string, T> Codes;
+ EnumParser(NodeParser* next, T& data, std::string& dataStr, const Codes& codes)
+ : m_next(next), m_data(data), m_dataStr(dataStr), m_codes(codes) {}
+ virtual NodeParser* parseString(const std::string& value)
+ {
+ m_dataStr = value;
+ const typename Codes::const_iterator it = m_codes.find(ToLower(value));
+ if (it != m_codes.end())
+ m_data = it->second;
+ return m_next;
+ }
+ private:
+ NodeParser* m_next;
+ T& m_data;
+ std::string& m_dataStr;
+ const Codes& m_codes;
+};
+
+class PairsParser : public NodeParser
+{
+ public:
+ typedef std::map<std::string, std::string> Pairs;
+
+ PairsParser(NodeParser* next, Pairs& pairs) : m_next(next), m_pairs(pairs) {}
+
+ virtual NodeParser* parseStartMap() { return this; }
+ virtual NodeParser* parseString(const std::string& value) { m_pairs[m_key] = value; return this; }
+ virtual NodeParser* parseMapKey(const std::string& value) { m_key = value; return this; }
+ virtual NodeParser* parseEndMap() { return m_next; }
+ private:
+ NodeParser* m_next;
+ Pairs& m_pairs;
+ std::string m_key;
+};
+
+}
+}
+
+#endif
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include "stg/json_parser.h"
+
+#include <yajl/yajl_parse.h>
+
+using STG::JSON::Parser;
+using STG::JSON::NodeParser;
+
+class Parser::Impl
+{
+ public:
+ Impl(NodeParser* topParser);
+ ~Impl()
+ {
+ yajl_free(m_handle);
+ }
+
+ bool append(const char* data, size_t size) { return yajl_parse(m_handle, reinterpret_cast<const unsigned char*>(data), size) != yajl_status_ok; }
+ bool done() { return yajl_complete_parse(m_handle) != yajl_status_ok; }
+
+ static int parseNull(void* ctx)
+ { return runParser(ctx, &NodeParser::parseNull); }
+ static int parseBoolean(void* ctx, int value)
+ { return runParser(ctx, &NodeParser::parseBoolean, value != 0); }
+ static int parseNumber(void* ctx, const char* value, size_t size)
+ { return runParser(ctx, &NodeParser::parseNumber, std::string(value, size)); }
+ static int parseString(void* ctx, const unsigned char* value, size_t size)
+ { return runParser(ctx, &NodeParser::parseString, std::string(reinterpret_cast<const char*>(value), size)); }
+ static int parseStartMap(void* ctx)
+ { return runParser(ctx, &NodeParser::parseStartMap); }
+ static int parseMapKey(void* ctx, const unsigned char* value, size_t size)
+ { return runParser(ctx, &NodeParser::parseMapKey, std::string(reinterpret_cast<const char*>(value), size)); }
+ static int parseEndMap(void* ctx)
+ { return runParser(ctx, &NodeParser::parseEndMap); }
+ static int parseStartArray(void* ctx)
+ { return runParser(ctx, &NodeParser::parseStartArray); }
+ static int parseEndArray(void* ctx)
+ { return runParser(ctx, &NodeParser::parseEndArray); }
+
+ private:
+ yajl_handle m_handle;
+ NodeParser* m_parser;
+
+ static yajl_callbacks callbacks;
+
+ static NodeParser& getParser(void* ctx) { return *static_cast<Impl*>(ctx)->m_parser; }
+ static bool runParser(void* ctx, NodeParser* (NodeParser::*func)())
+ {
+ Impl& p = *static_cast<Impl*>(ctx);
+ NodeParser* next = (p.m_parser->*func)();
+ if (next != NULL)
+ p.m_parser = next;
+ return next != NULL;
+ }
+ template <typename T>
+ static bool runParser(void* ctx, NodeParser* (NodeParser::*func)(const T&), const T& value)
+ {
+ Impl& p = *static_cast<Impl*>(ctx);
+ NodeParser* next = (p.m_parser->*func)(value);
+ if (next != NULL)
+ p.m_parser = next;
+ return next != NULL;
+ }
+};
+
+yajl_callbacks Parser::Impl::callbacks = {
+ Parser::Impl::parseNull,
+ Parser::Impl::parseBoolean,
+ NULL, // parsing of integer is done using parseNumber
+ NULL, // parsing of double is done using parseNumber
+ Parser::Impl::parseNumber,
+ Parser::Impl::parseString,
+ Parser::Impl::parseStartMap,
+ Parser::Impl::parseMapKey,
+ Parser::Impl::parseEndMap,
+ Parser::Impl::parseStartArray,
+ Parser::Impl::parseEndArray
+};
+
+Parser::Impl::Impl(NodeParser* topParser)
+ : m_handle(yajl_alloc(&callbacks, NULL, this)),
+ m_parser(topParser)
+{
+}
+
+Parser::Parser(NodeParser* topParser)
+ : m_impl(new Impl(topParser))
+{
+}
+
+Parser::~Parser()
+{
+}
+
+bool Parser::append(const char* data, size_t size)
+{
+ return m_impl->append(data, size);
+}
+
+bool Parser::done()
+{
+ return m_impl->done();
+}
+++ /dev/null
-include ../../Makefile.conf
-
-LIB_NAME = stgsgcp
-
-SRCS = proto.cpp \
- transport.cpp \
- unix.cpp \
- tcp.cpp \
- packet.cpp
-
-INCS = sgcp_proto.h \
- sgcp_types.h \
- sgcp_utils.h \
- sgcp_conn.h
-
-include ../Makefile.in
+++ /dev/null
-#ifndef __STG_SGCP_CONN_H__
-#define __STG_SGCP_CONN_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include "stg/os_int.h"
-
-#include <boost/asio/basic_stream_socket.hpp>
-#include <boost/function.hpp>
-
-#include <string>
-
-namespace STG
-{
-namespace SGCP
-{
-
-class Connection : public boost::enable_shared_from_this<Connection>
-{
- public:
- struct Chunk;
- typedef boost::function<Chunk (uint16_t /*type*/, uint32_t /*size*/)> Dispatcher;
- typedef boost::function<Chunk (const std::string& /*error*/)> Continuation;
- typedef boost::function<void (const std::string& /*error*/)> ErrorHandler;
- struct Chunk
- {
- void* buffer;
- size_t size;
- Continuation continuation;
- };
-
- Connection(Dispatcher dispatcher, ErrorHandler errorHandler) : m_dispatcher(dispatcher), m_errorHandler(errorHandler) {}
- virtual ~Connection() {}
-
- virtual boost::asio::basic_stream_socket& socket() = 0;
-
- virtual void send(const void* data, size_t size) = 0;
-
- virtual void start() = 0;
- virtual void stop() = 0;
-
- protected:
- Dispatcher m_dispatcher;
- ErrorHandler m_errorHandler;
-};
-
-typedef boost::shared_ptr<Connection> ConnectionPtr;
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#ifndef __STG_SGCP_PROTO_H__
-#define __STG_SGCP_PROTO_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include "sgcp_types.h" // TransportType
-#include "sgcp_conn.h"
-
-#include "stg/os_int.h"
-
-#include <boost/function.hpp>
-#include <boost/scoped_ptr.hpp>
-
-#include <string>
-#include <stdexcept>
-
-namespace STG
-{
-namespace SGCP
-{
-
-class Proto
-{
- public:
-
- struct Error : public std::runtime_error
- {
- Error(const std::string& mesage) : runtime_error(message) {}
- };
-
- typedef boost::function<void (ConnectionPtr /*conn*/, const std::string& /*enpoint*/, const std::string& /*error*/)> AcceptHandler;
-
- Proto(TransportType transport, const std::string& key);
- ~Proto();
-
- ConnectionPtr connect(const std::string& address, uint16_t port);
- void bind(const std::string& address, uint16_t port, AcceptHandler handler);
-
- void run();
- bool stop();
-
- private:
- class Impl;
- boost::scoped_ptr<Impl> m_impl;
-};
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#ifndef __STG_SGCP_TYPES_H__
-#define __STG_SGCP_TYPES_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-namespace STG
-{
-namespace SGCP
-{
-
-enum TransportType
-{
- UNIX,
- TCP,
- SSL
-};
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#ifndef __STG_SGCP_UTILS_H__
-#define __STG_SGCP_UTILS_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include "stg/os_int.h"
-
-#include <arpa/inet.h> // hton*
-
-namespace STG
-{
-namespace SGCP
-{
-
-template <typename T> inline T hton(T value) { return value; }
-template <typename T> inline T ntoh(T value) { return hton(value); }
-
-template <> inline uint16_t hton(uint16_t value) { return htons(value); }
-template <> inline int16_t hton(int16_t value) { return htons(value); }
-
-template <> inline uint32_t hton(uint32_t value) { return htonl(value); }
-template <> inline int32_t hton(int32_t value) { return htonl(value); }
-
-inline
-uint64_t htonll(uint64_t value)
-{
-#ifdef ARCH_LE
- const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
- const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));
-
- return (static_cast<uint64_t>(low_part) << 32) | high_part;
-#else
- return value;
-#endif
-}
-
-template <> inline uint64_t hton(uint64_t value) { return htonll(value); }
-template <> inline int64_t hton(int64_t value) { return htonll(value); }
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#include "packet.h"
-
-#include "stg/sgcp_utils.h"
-
-#include <ctime>
-
-using STG::SGCP::Packet;
-
-uint64_t Packet::MAGIC = 0x5f8edc0fdb6d3113; // Carefully picked random 64-bit number :)
-uint16_t Packet::VERSION = 1;
-
-Packet::Packet(uint16_t ver, uint16_t t, uint16_t sz)
- : magic(MAGIC),
- senderTime(time(NULL)),
- version(ver),
- type(t),
- size(s)
-{
-}
-
-Packet hton(Packet value)
-{
- value.magic = hton(value.magic);
- value.senderTime = hton(value.senderTime);
- value.version = hton(value.version);
- value.type = hton(value.type);
- value.size = hton(value.size);
-}
+++ /dev/null
-#ifndef __STG_SGCP_PACKET_H__
-#define __STG_SGCP_PACKET_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include <boost/stdint.hpp>
-
-namespace STG
-{
-namespace SGCP
-{
-
-struct __attribute__ ((__packed__)) Packet
-{
- Packet(uint16_t type, uint16_t size);
-
- bool valid() const { return magic == MAGIC; }
-
- static uint64_t MAGIC;
- static uint16_t VERSION;
-
- enum Types { PING, PONG, DATA };
-
- uint64_t magic;
- uint64_t senderTime;
- uint16_t version;
- uint16_t type;
- uint32_t size;
-};
-
-Packet hton(Packet value);
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#include "stg/sgcp_proto.h"
-
-#include "stg/sgcp_transport.h"
-
-#include <cstring>
-#include <cerrno>
-
-using STG::SGCP::Proto;
-
-Proto::Proto(TransportType transport, const std::string& key)
- : m_impl(new Impl(transport, key))
-{
-}
-
-Proto::~Proto()
-{
-}
-
-ConnectionPtr Proto::connect(const std::string& address, uint16_t port)
-{
- m_impl->connect(adress, port);
-}
-
-void Proto::bind(const std::string& address, uint16_t port, AcceptHandler handler)
-{
- m_impl->bind(address, port, handler);
-}
-
-void Proto::run()
-{
- m_impl->run();
-}
-
-bool Proto::stop()
-{
- return m_impl->stop();
-}
-
-class Proto::Impl
-{
- public:
- Impl(TransportType transport, const std::string& key);
- ~Impl();
-
- Connection& connect(const std::string& address, uint16_t port);
- void bind(const std::string& address, uint16_t port, AcceptHandler handler);
-
- void run();
- bool stop();
-
- private:
- ba::io_service m_ios;
- boost::scoped_ptr<Transport> m_transport;
- std::vector<ConnectionPtr> m_conns;
- bool m_running;
- bool m_stopped;
-};
-
-Proto::Impl::Impl(TransportType transport, const std::string& key)
- : m_transport(makeTransport(transport, key)),
- m_running(false),
- m_stopped(true)
-{
-}
-
-Proto::Impl::~Impl()
-{
- stop();
-}
-
-ConnectionPtr Proto::Impl::connect(const std::string& address, uint16_t port)
-{
- return m_transport->connect(address, port);
-}
-
-void Proto::Impl::bind(const std::string& address, uint16_t port, AcceptHandler handler)
-{
- m_transport->bind(address, port, handler);
-}
-
-void Proto::Impl::run()
-{
- m_stopped = false;
- m_running = true;
- while (m_running)
- m_ios.run_once();
- m_stopped = true;
-}
-
-bool Proto::Impl::stop()
-{
- for (size_t i = 0; i < m_conns.size(); ++i)
- m_conns[i]->stop();
- m_ios.stop();
- for (size_t i = 0; i < 10 && !m_ios.stopped(); ++i) {
- timspec ts;
- ts.tv_sec = 0;
- ts.tv_nsec = 10000000; // 10 msec
- }
- return m_ios.stopped();
-}
+++ /dev/null
-#ifndef __STG_SGCP_STREAM_CONN_H__
-#define __STG_SGCP_STREAM_CONN_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-namespace STG
-{
-namespace SGCP
-{
-namespace Impl
-{
-
-template <typename Stream>
-class StreamConn : public Connection
-{
- public:
- StreamConn(ba::io_service& ios, Dispatcher dispatcher, ErrorHandler errorHandler)
- : Connection(dispatcher, errorHandler),
- m_socket(ios)
- {
- }
-
- socket::endpoint_type& endpoint() { return m_endpoint; }
-
- virtual ba::basic_stream_socket& socket() { return m_socket; }
-
- virtual void start()
- {
- ba::read(m_socket, ba::buffer(&m_packet, sizeof(m_packet)),
- boost::bind(&StreamConn::m_handleReadHeader, this));
- }
- virtual void stop() { m_socket.shutdown(socket::shutdown_both); }
-
- virtual void send(const void* data, size_t size)
- {
- Packet* packet = new Packet(Packet::DATA, size));
- *packet = hton(*packet);
- boost::array<ba::const_buffer, 2> data = {
- ba::buffer(packet, sizeof(*packet)),
- ba::buffer(data, size)
- };
- ba::write(m_socket, data, boost::bind(&StreamConn::m_handleWrite, this, packet, boost::_1, boost::_2));
- }
-
- private:
- typedef Stream::socket socket;
- socket m_socket;
- Packet m_packet;
-
- void m_handleReadHeader(const boost::system::error_code& ec, size_t size)
- {
- if (ec) {
- // TODO: Handle errors.
- /*if (ec != ba::error::operation_aborted)
- m_errorHandler(ec);*/
- return;
- }
- Packet packet = ntoh(m_packet);
- Chunk chunk = m_dispatcher(packet.type, packet.size);
- if (chunk.size == 0) {
- // TODO: Discard current data.
- ba::read(m_socket, ba::buffer(&m_packet, sizeof(m_packet)),
- boost::bind(&StreamConn::m_handleReadHeader, this));
- return;
- }
- ba::read(m_socket, ba::buffer(chunk.buffer, chunk.size),
- boost::bind(&StreamConn::m_handleReadData, this, packet, chunk, boost::_1, boost::_2));
- }
-
- void m_handleReadData(Packet packet, Chunk chunk, const boost::system::error_code& ec, size_t size)
- {
- if (ec) {
- // TODO: Handle errors.
- /*if (ec != ba::error::operation_aborted)
- m_errorHandler(ec);*/
- return;
- }
- chunk = chunk.continuation(""); // TODO: Handle errors.
- if (chunk.size == 0) {
- // TODO: Discard current data.
- ba::read(m_socket, ba::buffer(&m_packet, sizeof(m_packet)),
- boost::bind(&StreamConn::m_handleReadHeader, this));
- return;
- }
- ba::read(m_socket, ba::buffer(chunk.buffer, chunk.size),
- boost::bind(&StreamConn::m_handleReadData, this, packet, chunk, boost::_1, boost::_2));
- }
-
- void m_handleWrite(Packet* packet, const boost::system::error_code& ec, size_t size)
- {
- delete packet;
- if (ec) {
- // TODO: Handle errors.
- /*if (ec != ba::error::operation_aborted)
- m_errorHandler(ec);*/
- return;
- }
- }
-};
-
-typedef StreamConn<ba::ip::tcp> TCPConn;
-typedef StreamConn<ba::local::stream_protocol> UNIXConn;
-
-} // namespace Impl
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#include "tcp.h"
-
-#include "stg/sgcp_utils.h"
-
-#include <cerrno>
-#include <cstring>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-using STG::SGCP::TCPProto;
-
-TCPProto::TCPProto(ba::io_service& ios)
- : m_ios(ios),
- m_acceptor(m_ios)
-{
-}
-
-TCPProto::~TCPProto()
-{
- close(m_sock);
-}
-
-ConnectionPtr TCPProto::connect(const std::string& address, uint16_t port)
-{
- bs::error_code ec;
- ConnectionPtr conn = boost::make_shared(m_ios);
- conn.socket().connect(ba::local::stream_protocol::enpoint(address, port), ec);
- if (ec)
- throw Error(ec.message());
- conn->start();
- return conn;
-}
-
-void TCPProto::bind(const std::string& address, uint16_t port, Proto::AcceptHandler handler)
-{
- bs::error_code ec;
- m_acceptor.bind(address, ec);
- if (ec)
- throw Error(ec.message());
-
- TCPConn* conn = new TCPConn(m_ios);
- m_acceptor.async_accept(conn->socket(), conn->endpoint(), boost::bind(&TCPProto::m_handleAccept, this, conn, handler, boost::_1);
-}
-
-void TCPProto::m_handleAccept(TCPConn* conn, Proto::AcceptHandler handler, const boost::system::error_code& ec)
-{
- if (ec) {
- delete conn;
- handler(NULL, "", ec.message());
- return;
- }
- handler(conn, conn->enpoint().address(), "");
-}
+++ /dev/null
-#ifndef __STG_SGCP_TCP_H__
-#define __STG_SGCP_TCP_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include "stg/sgcp_transport.h"
-
-#include "stg/os_int.h"
-
-#include <string>
-
-#include <unistd.h> // ssize_t
-
-namespace STG
-{
-namespace SGCP
-{
-
-class TCPProto : public TransportProto
-{
- public:
- TCPProto(boost::asio::io_service& ios);
- virtual ~TCPProto();
-
- virtual ConnectionPtr connect(const std::string& address, uint16_t port) = 0;
- virtual void bind(const std::string& address, uint16_t port, Proto::AcceptHandler handler) = 0;
-
- typedef boost::asio::ip::tcp protocol;
- private:
- ba::io_service& m_ios;
- protocol::acceptor m_acceptor;
-
- void m_handleAccept(TCPConn* conn, Proto::AcceptHandler handler, const boost::system::error_code& ec)
-};
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#include "stg/sgcp_transport.h"
-
-#include "crypto.h"
-#include "unix.h"
-#include "tcp.h"
-#include "ssl.h"
-
-using STG::SGCP::TransportProto;
-
-TransportProto* TransportProto::create(TransportType transport, const std::string& key)
-{
- switch (transport) {
- case UNIX: return new UnixProto;
- case TCP: return new TCPProto;
- case SSL: return new SSLProto(key);
- };
- return NULL;
-}
+++ /dev/null
-#ifndef __STG_SGCP_TRANSPORT_H__
-#define __STG_SGCP_TRANSPORT_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include "stg/sgcp_types.h"
-
-#include "stg/os_int.h"
-
-#include <string>
-#include <stdexcept>
-
-#include <unistd.h> // ssize_t
-
-namespace STG
-{
-namespace SGCP
-{
-
-class TransportProto
-{
- public:
- struct Error : public std::runtime_error {
- Error(const std::string& message) : runtime_error(message) {}
- };
-
- static TransportProto* create(TransportType transport, const std::string& key);
-
- virtual ~TransportProto() {}
-
- virtual ConnectionPtr connect(const std::string& address, uint16_t port) = 0;
- virtual void bind(const std::string& address, uint16_t port, Proto::AcceptHandler handler) = 0;
-};
-
-} // namespace SGCP
-} // namespace STG
-
-#endif
+++ /dev/null
-#include "unix.h"
-
-using STG::SGCP::UNIXProto;
-
-UNIXProto::UNIXProto(ba::io_service& ios)
- : m_ios(ios),
- m_acceptor(m_ios)
-{
-}
-
-UNIXProto::~UNIXProto()
-{
- close(m_sock);
-}
-
-ConnectionPtr UNIXProto::connect(const std::string& address, uint16_t /*port*/)
-{
- bs::error_code ec;
- ConnectionPtr conn = boost::make_shared(m_ios);
- conn.socket().connect(ba::local::stream_protocol::enpoint(address), ec);
- if (ec)
- throw Error(ec.message());
- conn->start();
- return conn;
-}
-
-void UNIXProto::bind(const std::string& address, uint16_t /*port*/, Proto::AcceptHandler handler)
-{
- bs::error_code ec;
- m_acceptor.bind(address, ec);
- if (ec)
- throw Error(ec.message());
-
- UNIXConn* conn = new UNIXConn(m_ios);
- m_acceptor.async_accept(conn->socket(), conn->endpoint(), boost::bind(&UNIXProto::m_handleAccept, this, conn, handler, boost::_1);
-}
-
-void UNIXProto::m_handleAccept(UNIXConn* conn, Proto::AcceptHandler handler, const boost::system::error_code& ec)
-{
- if (ec) {
- delete conn;
- handler(NULL, "", ec.message());
- return;
- }
- handler(conn, conn->enpoint().path(), "");
-}
+++ /dev/null
-#ifndef __STG_SGCP_UNIX_H__
-#define __STG_SGCP_UNIX_H__
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#include "stg/sgcp_transport.h"
-
-#include "stg/os_int.h"
-
-#include <string>
-
-#include <unistd.h> // ssize_t
-
-namespace STG
-{
-namespace SGCP
-{
-
-class UNIXProto : public TransportProto
-{
- public:
- UNIXProto(boost::asio::io_service& ios);
- virtual ~UNIXProto();
-
- virtual ConnectionPtr connect(const std::string& address, uint16_t port) = 0;
- virtual void bind(const std::string& address, uint16_t port, Proto::AcceptHandler handler) = 0;
-
- typedef boost::asio::local::stream_protocol protocol;
- private:
- ba::io_service& m_ios;
- protocol::acceptor m_acceptor;
-
- void m_handleAccept(UNIXConn* conn, Proto::AcceptHandler handler, const boost::system::error_code& ec)
-};
-
-} // namespace SGCP
-} // namespace STG
-
-#endif