Skip to content

Commit

Permalink
change pre_write to size_of
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongxiaolei committed Feb 6, 2015
1 parent a79ec61 commit 4f38615
Show file tree
Hide file tree
Showing 22 changed files with 874 additions and 656 deletions.
File renamed without changes.
114 changes: 55 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,81 @@
ADATA v1.0
=======

ADATA is an C++ serialization library.
ADATA is an efficient cross platform serialization library for C/C++, with support for Lua, C#, JavaScript and Java.
Note: JavaScript and Java not support yet.

Features Overview
---------------

* Lightweight, fast and efficient serialization implementations
* Only one macro to register C++ struct, one line code that's all
* Header only, no need to build library, just three hpp files
* Support C++03 and C++11 (Need AMSG_STD_CXX11 macro)
* Default support C++ built-in types and all std containters (include C++11's)
* Lightweight, fast and efficient serialization implementations, specifically for game development and other performance-critical applications
* Flexible, using keyword "delete" to mark discarded fields, that means forwards compatibility
* Header only, no need to build library, just a fews hpp files
* Strongly typed, errors happen at compile time
* Cross platform C/C++(03,11)/C#/Lua/Java/JavaScript code with no dependencies

What is AMSG?
Usage in brief
---------------

```cpp
struct person
{
std::string name;
int age;

bool operator==(person const& rhs) const
{
return name == rhs.name && age == rhs.age;
}
};

AMSG(person, (name)(age));
* Write a schema file that allows you to define the data structures you may want to serialize. Fields can have a scalar type (ints/floats of all sizes), or they can be a: string; array of any type; reference to yet another object
* Use adatac (the ADATA compiler) to generate a C++ header (or Lua/JavaScript script or Java/C#/ classes) with helper classes to access and construct serialized data. This header (say mydata.adl.h) only depends on adata.h/hpp, which defines the core functionality
* Store or send your buffer somewhere

#define ENOUGH_SIZE 4096
unsigned char buf[ENOUGH_SIZE];

// serialize
person src;
src.name = "lordoffox"
src.age = 33

amsg::zero_copy_buffer writer(buf, ENOUGH_SIZE);
amsg::write(writer, src);
assert(!writer.bad());

// deserialize
person des;

amsg::zero_copy_buffer reader(buf, ENOUGH_SIZE);
amsg::read(reader, des);
assert(!reader.bad());

assert(src == des);
```
Dependencies
Build the compiler
------------

To build adatac, we need:
* CMake 2.8 and newer
* Boost 1.55.0 and newer (Header only)
Supported Compilers
* Boost 1.55.0 and newer (Headers and Boost.Program Options)
* GCC >= 4.9 or VC >= 12.0

Build Boost.Program Options:
* Please ref Boost's doc - http://www.boost.org/doc/libs/1_57_0/more/getting_started/
* Note: please build boost using stage mode.

Build adatac:
* Suppose that adata already unzip to dir adata/
* cd adata
* Make a dir named build
* cd build
* cmake -G "Visual Studio 12 2013"(or on unix-like platform: "Unix MakeFiles") -DBOOST_ROOT=[your_boost_root_dir]
* Build whatever generated
* If success, will get a exe named adatac

Use the compiler
-------------------

* GCC >= 4.6
* VC >= 9.0 (sp1)
adatac [-I PATH] [-O PATH] [-P PATH] [-G language] [--help]
* -I PATH: the adl file to generate, e.g. -I/home/username/work/project/xxx.adl
* -O PATH: the path that output generated files, e.g. -O/home/username/work/project/generated
* -P PATH: include path for other adl, could set more than once, e.g. -P/home/username/work/project/adl -P/home/username/work/project/include
* -G language: which language source to generate, could set more than once, e.g. -Gcpp -Glua(lua51,lua52,lua53,luajit) -Gcsharp -Gjs -Gjava
* --help: show help messages

Support C++11
Writing a schema (.adl file)
-------------------

Define AMSG_STD_CXX11 in your project or just before include amsg hpps
Let's look at an example first

```cpp
#define AMSG_STD_CXX11
#include <amsg/all.hpp>

// C++11's forward_list
#include <forward_list>
namespace = my.country;

person
{
string name(30); //this is a comment
int32 age = 18;
bool married = false;
}

test
{
fix_int16 i = 1;
float32 f = 3.0;
list<int32> lis;
map<int32,int64> ms;
sub_type sub;
}

std::forward_list<int> fwd_list = {1,2,3,4,5};
unsigned char buf[4096];
amsg::zero_copy_buffer writer(buf, 4096);
amsg::write(writer, fwd_list);
assert(!writer.bad());
```

amsg::size_of
Expand Down
31 changes: 13 additions & 18 deletions adl/CMakeLists.txt → adatac/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is part of the CMake build system for adl
# This file is part of the CMake build system for adatac
#
# CMake auto-generated configuration options.
# Do not check in modified versions of this file.
Expand All @@ -12,11 +12,11 @@
#

cmake_minimum_required (VERSION 2.8.6 FATAL_ERROR)
project (adl)
project (adatac)

# The version number.
set (ADL_VERSION_MAJOR 1)
set (ADL_VERSION_MINOR 0)
set (ADATAC_VERSION_MAJOR 1)
set (ADATAC_VERSION_MINOR 0)

if (WIN32)
set (WINVER "0x0501" CACHE STRING "Windows version maro. Default is 0x0501 - winxp, user can reset")
Expand All @@ -35,11 +35,6 @@ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/../cpp/)
# Boost libraries search.
set (Boost_USE_STATIC_LIBS ON)
set (Boost_USE_MULTITHREADED ON)
if (ADL_STATIC)
set (Boost_USE_STATIC_RUNTIME ON)
else ()
set (Boost_USE_STATIC_RUNTIME OFF)
endif ()
if (BOOST_ROOT)
set (Boost_NO_SYSTEM_PATHS ON)
endif ()
Expand All @@ -57,9 +52,9 @@ link_directories (${Boost_LIBRARY_DIRS})
set (CMAKE_VERBOSE_MAKEFILE true)

if (NOT WIN32)
set (ADL_COMPILE_PROP "-std=c++11")
set (ADATAC_COMPILE_PROP "-std=c++11")
if (APPLE)
set (ADL_COMPILE_PROP "${ADL_COMPILE_PROP} -stdlib=libc++")
set (ADATAC_COMPILE_PROP "${ADATAC_COMPILE_PROP} -stdlib=libc++")
endif ()
endif ()

Expand All @@ -70,19 +65,19 @@ if (WIN32)
endif ()

file(GLOB_RECURSE SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
add_executable(adl ${SOURCE_FILES})
add_executable(adatac ${SOURCE_FILES})

if (ADL_COMPILE_PROP)
set_target_properties (adl PROPERTIES COMPILE_FLAGS "${ADL_COMPILE_PROP}")
if (ADATAC_COMPILE_PROP)
set_target_properties (adatac PROPERTIES COMPILE_FLAGS "${ADATAC_COMPILE_PROP}")
endif ()
target_link_libraries (adl ${Boost_LIBRARIES})
target_link_libraries (adatac ${Boost_LIBRARIES})

install (TARGETS adl RUNTIME DESTINATION bin)
install (TARGETS adatac RUNTIME DESTINATION bin)

# Build a CPack driven installer package.
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${ADL_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${ADL_VERSION_MINOR}")
set (CPACK_PACKAGE_VERSION_MAJOR "${ADATAC_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${ADATAC_VERSION_MINOR}")
set (CPACK_PACKAGE_CONTACT "QQ:99643412 lordoffox: [email protected]")
include (CPack)
File renamed without changes.
87 changes: 52 additions & 35 deletions adl/cpp_gen.cpp → adatac/cpp_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,15 +431,6 @@ namespace cpp_gen
os << tabs(1) << "}" << std::endl << std::endl;
}

inline void gen_size_check_write_member_code(const descrip_define&, const type_define&, const member_define& mdefine, std::ofstream& os, int tab_indent, bool trace_error = true)
{
os << tabs(tab_indent) << "if(len>" << mdefine.m_size
<< "){ context.set_error_code(number_of_element_not_macth);}";
if (trace_error)os << std::endl;
gen_trace_error_info(os, tab_indent, "context", mdefine.m_name, trace_error);
if (trace_error)os << std::endl;
}

void gen_adata_operator_write_tag_code(const descrip_define&, const type_define& tdefine, std::ofstream& os, int tab_indent)
{
uint64_t tag = 0;
Expand All @@ -464,63 +455,89 @@ namespace cpp_gen
}
}

void gen_member_pre_write_type_code(const descrip_define& desc_define, const type_define& tdefine, const member_define& mdefine, std::ofstream& os, int tab_indent, const std::string& var_name, bool trace_error = true)
void gen_member_size_of_type_code(const descrip_define& desc_define, const type_define& tdefine, const member_define& mdefine, std::ofstream& os, int tab_indent, const std::string& var_name, bool trace_error = true)
{
if (mdefine.is_multi())
{
os << tabs(tab_indent) << "uint32_t len = (uint32_t)(" << var_name << ").size();" << std::endl;
if (mdefine.m_size.length())
os << tabs(tab_indent) << "int32_t len = (int32_t)(" << var_name << ").size();" << std::endl;

// Nous Xiong: remove size_of length check
/*if (mdefine.m_size.length())
{
gen_size_check_write_member_code(desc_define, tdefine, mdefine, os, tab_indent, trace_error);
}
os << tabs(tab_indent) << "pre_write(len,context);" << std::endl;
}*/
// Nous Xiong: change to size_of
os << tabs(tab_indent) << "size += size_of(len);" << std::endl;

if (mdefine.m_type == e_base_type::string)
{
os << tabs(tab_indent) << "context.m_write_bytes += len;";
// Nous Xiong: change for size_of
os << tabs(tab_indent) << "size += len;";
os << std::endl;
}
else if (mdefine.m_type == e_base_type::list)
{
os << tabs(tab_indent) << "int32_t count = 0;" << std::endl;
os << tabs(tab_indent) << "for (" << make_type_desc(desc_define, mdefine) << "::const_iterator i = " << var_name << ".begin() ; i != " << var_name << ".end() ; ++i, ++count)" << std::endl;
// Nous Xiong: remove count bcz no error check
//os << tabs(tab_indent) << "int32_t count = 0;" << std::endl;

os << tabs(tab_indent) << "for (" << make_type_desc(desc_define, mdefine) << "::const_iterator i = " << var_name << ".begin() ; i != " << var_name << ".end() ; ++i)" << std::endl;
os << tabs(tab_indent) << "{" << std::endl;
gen_member_pre_write_type_code(desc_define, tdefine, mdefine.m_template_parameters[0], os, tab_indent + 1, "*i", false);
gen_trace_error_info(os, tab_indent + 1, "context", mdefine.m_name, true, "count");
os << std::endl;
gen_member_size_of_type_code(desc_define, tdefine, mdefine.m_template_parameters[0], os, tab_indent + 1, "*i", false);

// Nous Xiong: rmv trace error bcz no need for that
//gen_trace_error_info(os, tab_indent + 1, "context", mdefine.m_name, true, "count");
//os << std::endl;

os << tabs(tab_indent) << "}";
os << std::endl;
}
else if (mdefine.m_type == e_base_type::map)
{
os << tabs(tab_indent) << "int32_t count = 0;" << std::endl;
os << tabs(tab_indent) << "for (" << make_type_desc(desc_define, mdefine) << "::const_iterator i = " << var_name << ".begin() ; i != " << var_name << ".end() ; ++i, ++count)" << std::endl;
// Nous Xiong: remove count bcz no error check
//os << tabs(tab_indent) << "int32_t count = 0;" << std::endl;

os << tabs(tab_indent) << "for (" << make_type_desc(desc_define, mdefine) << "::const_iterator i = " << var_name << ".begin() ; i != " << var_name << ".end() ; ++i)" << std::endl;
os << tabs(tab_indent) << "{" << std::endl;
gen_member_pre_write_type_code(desc_define, tdefine, mdefine.m_template_parameters[0], os, tab_indent + 1, "i->first", false);
gen_member_pre_write_type_code(desc_define, tdefine, mdefine.m_template_parameters[1], os, tab_indent + 1, "i->second", false);
gen_trace_error_info(os, tab_indent + 1, "context", mdefine.m_name, true, "count");
os << std::endl;
gen_member_size_of_type_code(desc_define, tdefine, mdefine.m_template_parameters[0], os, tab_indent + 1, "i->first", false);
gen_member_size_of_type_code(desc_define, tdefine, mdefine.m_template_parameters[1], os, tab_indent + 1, "i->second", false);

// Nous Xiong: rmv trace error bcz no need for that
//gen_trace_error_info(os, tab_indent + 1, "context", mdefine.m_name, true, "count");
//os << std::endl;

os << tabs(tab_indent) << "}";
os << std::endl;
}
}
else
{
os << tabs(tab_indent);

// Nous Xiong: add size +=
os << "size += ";

if (mdefine.m_fixed)
{
os << "fix_";
}
os << "pre_write(" << var_name << ",context);" << std::endl;
gen_trace_error_info(os, tab_indent, "context", mdefine.m_name, trace_error);
if (trace_error)os << std::endl;
// Nous Xiong: change pre_write to size_of
os << "size_of(" << var_name << ");" << std::endl;

// Nous Xiong: rmv trace error bcz no need for that
//gen_trace_error_info(os, tab_indent, "context", mdefine.m_name, trace_error);
//if (trace_error)os << std::endl;
}
}

void gen_adata_operator_pre_write_type_code(const descrip_define& desc_define, const type_define& tdefine, std::ofstream& os)
void gen_adata_operator_size_of_type_code(const descrip_define& desc_define, const type_define& tdefine, std::ofstream& os)
{
std::string full_type_name = desc_define.m_namespace.m_cpp_fullname + tdefine.m_name;
os << tabs(1) << gen_inline_code(tdefine) << "void pre_write(const " << full_type_name << "& value , stream_context& context)" << std::endl;
os << tabs(1) << gen_inline_code(tdefine) << "int32_t size_of(const " << full_type_name << "& value)" << std::endl;
os << tabs(1) << "{" << std::endl;

// Nous Xiong: add size_of result var
os << tabs(2) << "int32_t size = 0;" << std::endl;

gen_adata_operator_write_tag_code(desc_define, tdefine, os, 2);
uint64_t tag_mask = 1;
for (const auto& member : tdefine.m_members)
Expand All @@ -534,7 +551,7 @@ namespace cpp_gen
os << tabs(2) << "if(tag&" << tag_mask << "ULL)" << std::endl;
}
os << tabs(2) << "{" << std::endl;
gen_member_pre_write_type_code(desc_define, tdefine, member, os, 3, var_name);
gen_member_size_of_type_code(desc_define, tdefine, member, os, 3, var_name);
os << tabs(2) << "}" << std::endl;
}
else
Expand All @@ -543,8 +560,8 @@ namespace cpp_gen
}
tag_mask <<= 1;
}
os << tabs(2) << "pre_write(tag,context);" << std::endl;
os << tabs(2) << "return;" << std::endl;
os << tabs(2) << "size += size_of(tag);" << std::endl;
os << tabs(2) << "return size;" << std::endl;
os << tabs(1) << "}" << std::endl << std::endl;
}

Expand Down Expand Up @@ -642,7 +659,7 @@ namespace cpp_gen
{
gen_adata_operator_read_type_code(desc_define, tdefine, os);
gen_adata_operator_skip_read_type_code(desc_define, tdefine, os);
gen_adata_operator_pre_write_type_code(desc_define, tdefine, os);
gen_adata_operator_size_of_type_code(desc_define, tdefine, os);
gen_adata_operator_write_type_code(desc_define, tdefine, os);
}

Expand Down
Loading

0 comments on commit 4f38615

Please sign in to comment.