Permalink
Browse files

Add a first step to Qark C++.

  • Loading branch information...
1 parent e3d19f1 commit 6c2566880cade0976cb7aeb82f090247e997e4a4 @warrenseine warrenseine committed Oct 1, 2011
Showing with 266 additions and 6 deletions.
  1. +40 −6 .gitignore
  2. +200 −0 c++/src/aerys/qark/Qark.hpp
  3. +26 −0 c++/test/QarkTest.cpp
View
@@ -1,6 +1,40 @@
-
-/as3/.actionScriptProperties
-/as3/.flexLibProperties
-/as3/.project
-/as3/.settings/org.eclipse.core.resources.prefs
-/as3/bin/aerys-qark.swc
+build
+bin-debug
+bin-release
+bin
+obj
+Debug
+Release
+profile
+Makefile
+.DS_Store
+.settings
+.project
+.actionScriptProperties
+.flexProperties
+.flexLibProperties
+.waf*
+.svn
+.lock-wscript
+.cproject
+*.make
+*.pyc
+*.as3proj
+*.sln
+*.vcproj.*.user
+*.vcxproj.*.user
+*.vcxproj.user
+*.vcxproj
+*.vcxproj.filters
+*.xcodeproj
+*.pch
+*.ncb
+*.aps
+*.suo
+*.opensdf
+*.sdf
+*.obj
+*.db
+*.pbxuser
+*.mode*
+*.1
@@ -0,0 +1,200 @@
+//
+// Created by Warren Seine on Oct 1, 2011.
+// Copyright (c) 2011 Aerys. All rights reserved.
+//
+
+#pragma once
+
+#include <iostream>
+#include <list>
+#include <map>
+#include <typeinfo>
+#include <vector>
+
+#include <boost/any.hpp>
+#include <boost/asio/streambuf.hpp>
+
+namespace aerys
+{
+ namespace qark
+ {
+ class Qark
+ {
+ public:
+ static const int MAGIC = 0x3121322b;
+
+ static const int FLAG_NONE = 0;
+ static const int FLAG_GZIP = 1;
+ static const int FLAG_DEFLATE = 2;
+
+ static const int TYPE_CUSTOM = 0;
+ static const int TYPE_OBJECT = 1;
+ static const int TYPE_ARRAY = 2;
+ static const int TYPE_INT = 3;
+ static const int TYPE_UINT = 4;
+ static const int TYPE_FLOAT = 5;
+ static const int TYPE_STRING = 6;
+ static const int TYPE_BYTES = 7;
+ static const int TYPE_BOOLEAN = 8;
+ static const int TYPE_BITMAP_DATA = 9;
+
+ typedef std::vector<char> ByteArray;
+ typedef boost::any Object;
+ typedef std::string String;
+ typedef std::list<Object> Array;
+ typedef std::map<String, Object> Map;
+
+ typedef void (*Encoder)(std::ostream&, const Object&);
+ typedef void (*Decoder)(std::istream&, Object&);
+
+ public:
+ static ByteArray encode(const Object& source)
+ {
+ boost::asio::streambuf buffer;
+ std::ostream stream(&buffer);
+
+ int magic = MAGIC;
+ write(stream, magic);
+ encodeRecursive(stream, source);
+
+ const char* data = boost::asio::buffer_cast<const char*>(buffer.data());
+ std::size_t size = buffer.size();
+
+ return ByteArray(data, data + size);
+ }
+
+ static Object decode(const ByteArray& source)
+ {
+ boost::asio::streambuf buffer;
+ std::iostream stream(&buffer);
+
+ stream.write(&*source.begin(), source.size());
+
+ int magic = 0;
+ read(stream, magic);
+
+ if (magic != MAGIC)
+ return Object();
+
+ Object result;
+ decodeRecursive(stream, result);
+ return result;
+ }
+
+ private:
+ static int getType(const Object& source)
+ {
+ if (source.type() == typeid(int))
+ return TYPE_INT;
+ if (source.type() == typeid(unsigned int))
+ return TYPE_UINT;
+ if (source.type() == typeid(float))
+ return TYPE_FLOAT;
+ if (source.type() == typeid(String))
+ return TYPE_STRING;
+ if (source.type() == typeid(Array))
+ return TYPE_ARRAY;
+ if (source.type() == typeid(ByteArray))
+ return TYPE_BYTES;
+ if (source.type() == typeid(bool))
+ return TYPE_BOOLEAN;
+ if (source.type() == typeid(Map))
+ return TYPE_OBJECT;
+
+ return TYPE_CUSTOM;
+ }
+
+ static Encoder getEncoder(char flag)
+ {
+ static std::map<char, Encoder> encoders;
+
+ if (encoders.empty())
+ {
+ encoders[TYPE_INT] = &Qark::encodeTrivial<int>;
+ }
+
+ return encoders[flag];
+ }
+
+ static Decoder getDecoder(char flag)
+ {
+ static std::map<char, Decoder> decoders;
+
+ if (decoders.empty())
+ {
+ decoders[TYPE_INT] = &Qark::decodeTrivial<int>;
+ }
+
+ return decoders[flag];
+ }
+
+ static void encodeRecursive(std::ostream& target, const Object& source)
+ {
+ char flag = getType(source);
+ write(target, flag);
+
+ Encoder f = getEncoder(flag);
+ f(target, source);
+ }
+
+ static void decodeRecursive(std::istream& source, Object& target)
+ {
+ char flag = 0;
+ read(source, flag);
+
+ Decoder f = getDecoder(flag);
+ f(source, target);
+ }
+
+ template <typename T>
+ static void
+ write(std::ostream& stream, const T& value)
+ {
+ stream.write(reinterpret_cast<const char*>(&value), sizeof (T));
+ }
+
+ template <typename T>
+ static void
+ read(std::istream& stream, T& value)
+ {
+ stream.read(reinterpret_cast<char*>(&value), sizeof (T));
+ }
+
+ template <typename T>
+ static void
+ encodeTrivial(std::ostream& stream, const Object& value)
+ {
+ write(stream, boost::any_cast<const T&>(value));
+ }
+
+ template <typename T>
+ static void
+ decodeTrivial(std::istream& stream, Object& value)
+ {
+ value = T();
+ read(stream, boost::any_cast<T&>(value));
+ }
+
+ static void
+ encodeString(std::ostream& stream, const String& value)
+ {
+ unsigned short size = value.size();
+
+ write(stream, size);
+ stream.write(value.c_str(), size);
+ }
+
+ static void
+ decodeString(std::istream& stream, String& value)
+ {
+ // FIXME: Doesn't work with non-ASCI strings.
+ unsigned short size = 0;
+ read(stream, size);
+
+ char data[size];
+ stream.read(data, size);
+ value.assign(data, size);
+ }
+ };
+ }
+}
View
@@ -0,0 +1,26 @@
+//
+// Created by Warren Seine on Oct 1, 2011.
+// Copyright (c) 2011 Aerys. All rights reserved.
+//
+
+#include <aerys/qark/Qark.hpp>
+#include <iostream>
+
+using namespace aerys::qark;
+
+template <typename T>
+bool compare(const Qark::Object& a, const Qark::Object& b)
+{
+ return boost::any_cast<T>(a) == boost::any_cast<T>(b);
+}
+
+int main()
+{
+ Qark::Object object = 42;
+
+ Qark::ByteArray data = Qark::encode(object);
+
+ Qark::Object result = Qark::decode(data);
+
+ std::cout << compare<int>(object, result) << std::endl;
+}

0 comments on commit 6c25668

Please sign in to comment.