From a89e5a4784086bbe6ef888bf3d791ff24327d7d0 Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 16 Nov 2007 04:45:00 +0000 Subject: [PATCH] Addition of new makefile scripts. Addition of the new serialiser (the start anyway). Addition of regression test system. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@249 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/scripts/checks.mk | 29 + libretroshare/src/scripts/config-cygwin.mk | 95 +++ libretroshare/src/scripts/config-linux.mk | 72 ++ libretroshare/src/scripts/config-mingw.mk | 249 +++++++ libretroshare/src/scripts/config.mk | 22 + libretroshare/src/scripts/regress.mk | 25 + libretroshare/src/scripts/rules.mk | 23 + libretroshare/src/serialiser/Makefile | 41 ++ libretroshare/src/serialiser/rsbaseitems.cc | 123 ++++ libretroshare/src/serialiser/rsbaseitems.h | 216 ++++++ libretroshare/src/serialiser/rsbaseserial.cc | 76 +++ libretroshare/src/serialiser/rsbaseserial.h | 53 ++ libretroshare/src/serialiser/rsconfigitems.h | 119 ++++ libretroshare/src/serialiser/rsserial.cc | 318 +++++++++ libretroshare/src/serialiser/rsserial.h | 133 ++++ libretroshare/src/serialiser/rsserviceitems.h | 113 ++++ libretroshare/src/serialiser/rstlvbase.cc | 446 +++++++++++++ libretroshare/src/serialiser/rstlvbase.h | 166 +++++ libretroshare/src/serialiser/rstlvfileitem.cc | 584 +++++++++++++++++ libretroshare/src/serialiser/rstlvtypes.cc | 615 ++++++++++++++++++ libretroshare/src/serialiser/rstlvtypes.h | 203 ++++++ libretroshare/src/serialiser/rstlvutil.cc | 182 ++++++ libretroshare/src/serialiser/rstlvutil.h | 47 ++ libretroshare/src/serialiser/tlvbase_test.cc | 184 ++++++ libretroshare/src/serialiser/tlvbase_test2.cc | 121 ++++ .../src/serialiser/tlvfileitem_test.cc | 190 ++++++ libretroshare/src/serialiser/tlvitems_test.cc | 88 +++ libretroshare/src/serialiser/tlvstack_test.cc | 104 +++ libretroshare/src/util/exampletst.c | 40 ++ libretroshare/src/util/utest.h | 23 + 30 files changed, 4700 insertions(+) create mode 100644 libretroshare/src/scripts/checks.mk create mode 100644 libretroshare/src/scripts/config-cygwin.mk create mode 100644 libretroshare/src/scripts/config-linux.mk create mode 100644 libretroshare/src/scripts/config-mingw.mk create mode 100644 libretroshare/src/scripts/config.mk create mode 100644 libretroshare/src/scripts/regress.mk create mode 100644 libretroshare/src/scripts/rules.mk create mode 100644 libretroshare/src/serialiser/Makefile create mode 100644 libretroshare/src/serialiser/rsbaseitems.cc create mode 100644 libretroshare/src/serialiser/rsbaseitems.h create mode 100644 libretroshare/src/serialiser/rsbaseserial.cc create mode 100644 libretroshare/src/serialiser/rsbaseserial.h create mode 100644 libretroshare/src/serialiser/rsconfigitems.h create mode 100644 libretroshare/src/serialiser/rsserial.cc create mode 100644 libretroshare/src/serialiser/rsserial.h create mode 100644 libretroshare/src/serialiser/rsserviceitems.h create mode 100644 libretroshare/src/serialiser/rstlvbase.cc create mode 100644 libretroshare/src/serialiser/rstlvbase.h create mode 100644 libretroshare/src/serialiser/rstlvfileitem.cc create mode 100644 libretroshare/src/serialiser/rstlvtypes.cc create mode 100644 libretroshare/src/serialiser/rstlvtypes.h create mode 100644 libretroshare/src/serialiser/rstlvutil.cc create mode 100644 libretroshare/src/serialiser/rstlvutil.h create mode 100644 libretroshare/src/serialiser/tlvbase_test.cc create mode 100644 libretroshare/src/serialiser/tlvbase_test2.cc create mode 100644 libretroshare/src/serialiser/tlvfileitem_test.cc create mode 100644 libretroshare/src/serialiser/tlvitems_test.cc create mode 100644 libretroshare/src/serialiser/tlvstack_test.cc create mode 100644 libretroshare/src/util/exampletst.c create mode 100644 libretroshare/src/util/utest.h diff --git a/libretroshare/src/scripts/checks.mk b/libretroshare/src/scripts/checks.mk new file mode 100644 index 000000000..6d1722335 --- /dev/null +++ b/libretroshare/src/scripts/checks.mk @@ -0,0 +1,29 @@ +#Basic checks + +ifndef RS_TOP_DIR +dummy: + echo "RS_TOP_DIR is not defined in your makefile" +endif + +ifndef SSL_DIR +dummy: + echo "you must define SSL_DIR before you can compile" + +endif + +ifndef KADC_DIR +dummy: + echo "you must define KADC_DIR before you can compile" + +endif + +ifneq ($(OS),Linux) + ifndef PTHREADS_DIR +dummy: + echo "you must define PTHREADS_DIR before you can compile" + + endif +endif + + + diff --git a/libretroshare/src/scripts/config-cygwin.mk b/libretroshare/src/scripts/config-cygwin.mk new file mode 100644 index 000000000..635808566 --- /dev/null +++ b/libretroshare/src/scripts/config-cygwin.mk @@ -0,0 +1,95 @@ +ifneq ($(OS),Cygwin) +dummy: + echo "ERROR Cygwin configuration file included, but (OS != Cygwin) + +endif + +############ LINUX CONFIGURATION ######################## + +# flags for components.... +PQI_USE_XPGP = 1 +PQI_USE_PROXY = 1 +PQI_USE_CHANNELS = 1 +USE_FILELOOK = 1 + +########################################################################### + +CYGWIN_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW +SSL_DIR=$(CYGWIN_SRC_ROOT)/openssl-0.9.7g +FLTK_DIR=$(CYGWIN_SRC_ROOT)/FLTK-1.1.6 +PTHREADS_DIR=$(CYGWIN_SRC_ROOT)/pthreads/pthreads.2 +KADC_DIR=$(CYGWIN_SRC_ROOT)/debug/KadC-2006-Oct-19 +ZLIB_DIR=$(CYGWIN_SRC_ROOT)/zlib-1.2.3 +UPNPC_DIR=$(CYGWIN_SRC_ROOT)/libs/src/miniupnpc-20070515 + +include $(RS_TOP_DIR)/scripts/checks.mk + +############ ENFORCE DIRECTORY NAMING ######################## + +CC = g++ +RM = /bin/rm +RANLIB = ranlib +LIBDIR = $(RS_TOP_DIR)/lib +LIBRS = $(LIBDIR)/libretroshare.a + +# Unix: Linux/Cygwin +INCLUDE = -I $(RS_TOP_DIR) -I$(KADC_DIR) +CFLAGS = -Wall -g $(INCLUDE) + +ifdef PQI_USE_XPGP + INCLUDE += -I $(SSL_DIR)/include +endif + +ifdef PQI_USE_XPGP + CFLAGS += -DPQI_USE_XPGP +endif + +ifdef PQI_USE_PROXY + CFLAGS += -DPQI_USE_PROXY +endif + +ifdef PQI_USE_CHANNELS + CFLAGS += -DPQI_USE_CHANNELS +endif + +ifdef USE_FILELOOK + CFLAGS += -DUSE_FILELOOK +endif + + +RSCFLAGS = -Wall -g $(INCLUDE) + +######################################################################### +# OS specific Linking. +######################################################################### + +# for static pthread libs.... +WININC += -DPTW32_STATIC_LIB +WININC += -mno-cygwin -mwindows -fno-exceptions +WININC += -DWINDOWS_SYS + +WINLIB = -lws2_32 -luuid -lole32 -liphlpapi +WINLIB += -lcrypt32 + +CFLAGS += -I$(PTHREADS_DIR) $(WININC) +CFLAGS += -I$(ZLIB_DIR) + +LIBS = -L$(LIBDIR) -lretroshare +ifdef PQI_USE_XPGP + LIBS += -L$(SSL_DIR) +endif + +LIBS += -lssl -lcrypto +LIBS += -L$(KADC_DIR) -lKadC +LIBS += -L$(UPNPC_DIR) -lminiupnpc +LIBS += -L$(ZLIB_DIR) -lz + +RSLIBS += $(LIBS) +RSLIBS += -L$(PTHREADS_DIR) -lpthreadGC2d + +RSLIBS += $(WINLIB) +LIBS += $(WINLIB) + +RSCFLAGS += $(WININC) + + diff --git a/libretroshare/src/scripts/config-linux.mk b/libretroshare/src/scripts/config-linux.mk new file mode 100644 index 000000000..f77ee6a7c --- /dev/null +++ b/libretroshare/src/scripts/config-linux.mk @@ -0,0 +1,72 @@ + +ifneq ($(OS),Linux) +dummy: + echo "ERROR Linux configuration file included, but (OS != Linux) + +endif + +############ LINUX CONFIGURATION ######################## + +# flags for components.... +PQI_USE_XPGP = 1 +PQI_USE_PROXY = 1 +PQI_USE_CHANNELS = 1 +USE_FILELOOK = 1 + +SSL_DIR=../../../../../src/openssl-0.9.7g-xpgp-0.1c +KADC_DIR=../../../../../src/KadC +UPNPC_DIR=../../../../../src/miniupnpc-20070515 + +include $(RS_TOP_DIR)/scripts/checks.mk + +############ ENFORCE DIRECTORY NAMING ######################## + +CC = g++ +RM = /bin/rm +RANLIB = ranlib +LIBDIR = $(RS_TOP_DIR)/lib +LIBRS = $(LIBDIR)/libretroshare.a + +# Unix: Linux/Cygwin +INCLUDE = -I $(RS_TOP_DIR) -I$(KADC_DIR) +CFLAGS = -Wall -g $(INCLUDE) + +ifdef PQI_USE_XPGP + INCLUDE += -I $(SSL_DIR)/include +endif + +ifdef PQI_USE_XPGP + CFLAGS += -DPQI_USE_XPGP +endif + +ifdef PQI_USE_PROXY + CFLAGS += -DPQI_USE_PROXY +endif + +ifdef PQI_USE_CHANNELS + CFLAGS += -DPQI_USE_CHANNELS +endif + +ifdef USE_FILELOOK + CFLAGS += -DUSE_FILELOOK +endif + + +RSCFLAGS = -Wall -g $(INCLUDE) + +######################################################################### +# OS specific Linking. +######################################################################### + +LIBS = -L$(LIBDIR) -lretroshare +ifdef PQI_USE_XPGP + LIBS += -L$(SSL_DIR) + endif +LIBS += -lssl -lcrypto -lpthread +LIBS += -L$(KADC_DIR) -lKadC +LIBS += -L$(UPNPC_DIR) -lminiupnpc +LIBS += $(XLIB) -ldl -lz + +RSLIBS = $(LIBS) + + diff --git a/libretroshare/src/scripts/config-mingw.mk b/libretroshare/src/scripts/config-mingw.mk new file mode 100644 index 000000000..1a0812a51 --- /dev/null +++ b/libretroshare/src/scripts/config-mingw.mk @@ -0,0 +1,249 @@ +#### +#Define OS. +# +OS = Linux +#OS = Cygwin +#OS = Win # MinGw. +# +# +# +# +# +########################################################################### +########################################################################### +# Please Define these Variables before Compiling. (Examples below:) +# Linux (SSL_DIR & KADC_DIR) +# Cygwin (SSL_DIR & KADC_DIR & FLTK_DIR & PTHREADS_DIR) +# MinGW (SSL_DIR & KADC_DIR & FLTK_DIR & PTHREADS_DIR) + +#### Linux/Cygwin Parameters. +#SSL_DIR=/home/xxx/prog/src/openssl-0.9.7g-xpgp-0.1c +#KADC_DIR=/home/xxx/prog/src/KadC +# +#### Cygwin Only.... +#FLTK_DIR=/MinGWlibs/FLTK-1.1.6 +#PTHREADS_DIR=/cygdrive/c/home/dev/prog/MinGw/pthreads/Pre-built.2 +#KADC_DIR=/cygdrive/c/home/dev/prog/MinGW/KadC +#ZLIB_DIR=/cygdrive/c/home/dev/prog/MinGW/zlib-1.2.3 +# +########################################################################### +# My Versions +ifeq ($(OS),Linux) + #Linux. + SSL_DIR=../../../../../src/openssl-0.9.7g-xpgp-0.1c + KADC_DIR=../../../../../src/KadC + UPNPC_DIR=../../../../../src/miniupnpc-20070515 +else +########################################################################### + ifeq ($(OS),Cygwin) + + #Cygwin.... + CYGWIN_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW + SSL_DIR=/home/rmfern/prog/src/openssl-0.9.7g + #SSL_DIR=$(CYGWIN_SRC_ROOT)/openssl-0.9.7g + FLTK_DIR=$(CYGWIN_SRC_ROOT)/FLTK-1.1.6 + PTHREADS_DIR=$(CYGWIN_SRC_ROOT)/pthreads/pthreads.2 + KADC_DIR=$(CYGWIN_SRC_ROOT)/debug/KadC-2006-Oct-19 + ZLIB_DIR=$(CYGWIN_SRC_ROOT)/zlib-1.2.3 + UPNPC_DIR=$(CYGWIN_SRC_ROOT)/libs/src/miniupnpc-20070515 + + else + + #MinGw.... + MINGW_SRC_ROOT=c:\home\rmfern\prog\MinGW + SSL_DIR=$(MINGW_SRC_ROOT)\openssl-0.9.7g + FLTK_DIR=$(MINGW_SRC_ROOT)\FLTK-1.1.6 + PTHREADS_DIR=$(MINGW_SRC_ROOT)\pthreads\pthreads.2 + KADC_DIR=$(MINGW_SRC_ROOT)\debug\KadC-2006-Oct-19 + ZLIB_DIR=$(MINGW_SRC_ROOT)\zlib-1.2.3 + UPNPC_DIR=$(MINGW_SRC_ROOT)\miniupnpc-20070515 + + endif + +########################################################################### +endif +########################################################################### + +ifndef RS_TOP_DIR +dummy: + echo "RS_TOP_DIR is not defined in your makefile" +endif + +RS_DIR=$(RS_TOP_DIR) + +ifndef SSL_DIR +dummy: + echo "you must define SSL_DIR before you can compile" + +endif + +ifndef KADC_DIR +dummy: + echo "you must define KADC_DIR before you can compile" + +endif + +ifneq ($(OS),Linux) +# no longer dependancy +# ifndef FLTK_DIR +#dummy: +# echo "you must define FLTK_DIR before you can compile" + +# endif +# + ifndef PTHREADS_DIR +dummy: + echo "you must define PTHREADS_DIR before you can compile" + + endif +endif + +############ ENFORCE DIRECTORY NAMING ######################## + +CC = g++ + + +# flags for components.... +PQI_USE_XPGP = 1 +PQI_USE_PROXY = 1 +#PQI_USE_CHANNELS = 1 +USE_FILELOOK = 1 + +ifeq ($(OS),Win) + # MinGw + INCLUDE = -I $(RS_DIR) -I$(KADC_DIR) + ifdef PQI_USE_XPGP + INCLUDE += -I $(SSL_DIR)\include + endif +else + # Unix: Linux/Cygwin + INCLUDE = -I $(RS_DIR) -I$(KADC_DIR) + ifdef PQI_USE_XPGP + INCLUDE += -I $(SSL_DIR)/include + endif +endif + +CFLAGS = -Wall -g $(INCLUDE) + +RANLIB = ranlib +LIBRS = ../lib/libretroshare.a +RSCFLAGS = -Wall -g $(INCLUDE) + +ifdef PQI_USE_XPGP + CFLAGS += -DPQI_USE_XPGP +endif + +ifdef PQI_USE_PROXY + CFLAGS += -DPQI_USE_PROXY +endif + +ifdef PQI_USE_CHANNELS + CFLAGS += -DPQI_USE_CHANNELS +endif + +ifdef USE_FILELOOK + CFLAGS += -DUSE_FILELOOK +endif + + +######################################################################### +# OS specific Includes/Libs. +# LINUX... +ifeq ($(OS),Linux) + + + # XLIBS arent needed for basic libretroshare. + # only needed for FLTK interface. + + #XLIB = -lXft -lpthread -lXext -lX11 \ + # -lXrender -lexpat -L/usr/X11R6/lib -lXau \ + # -lXinerama -lXdmcp -lXext \ + # -lfontconfig -lfreetype -lz + + RM = /bin/rm + + LIBDIR = $(RS_DIR)/lib + LIBS = -L$(LIBDIR) -lretroshare + ifdef PQI_USE_XPGP + LIBS += -L$(SSL_DIR) + endif + LIBS += -lssl -lcrypto -lpthread + LIBS += -L$(KADC_DIR) -lKadC + LIBS += -L$(UPNPC_DIR) -lminiupnpc + LIBS += $(XLIB) -ldl -lz + + RSLIBS = $(LIBS) + +else # windows (Cygwin or MinGW) + +# for static pthread libs.... +WININC += -DPTW32_STATIC_LIB +WINLIB = -lws2_32 -luuid -lole32 -liphlpapi + + ifeq ($(OS),Cygwin) + # Cygwin + WININC += -mno-cygwin -mwindows -fno-exceptions -fomit-frame-pointer -DWINDOWS_SYS + WINLIB += -lcrypt32 + + # Cygwin + #CFLAGS += -I$(FLTK_DIR)/include + CFLAGS += -I$(PTHREADS_DIR) $(WININC) + CFLAGS += -I$(ZLIB_DIR) + + LIBDIR = $(RS_DIR)/lib + LIBS = -L$(LIBDIR) -lretroshare + ifdef PQI_USE_XPGP + LIBS += -L$(SSL_DIR) + endif + LIBS += -lssl -lcrypto + LIBS += -L$(KADC_DIR) -lKadC + LIBS += -L$(UPNPC_DIR) -lminiupnpc + LIBS += -L$(ZLIB_DIR) -lz + + RSLIBS += $(LIBS) + RSLIBS += -L$(PTHREADS_DIR) -lpthreadGC2d + + RSLIBS += $(WINLIB) + LIBS += $(WINLIB) + + + RSCFLAGS += $(WININC) + + RM = /bin/rm + + else # MinGw. + + #WININC += -mwindows -fno-exceptions -fomit-frame-pointer -DWINDOWS_SYS + WININC += -frtti -fexceptions -DWINDOWS_SYS + WINLIB += -lcrypt32-cygwin + + # Cygwin + CFLAGS += -I$(PTHREADS_DIR) $(WININC) + CFLAGS += -I$(ZLIB_DIR) + #CFLAGS += -I$(FLTK_DIR)\include + + LIBDIR = $(RS_DIR)\lib + LIBS = -L$(LIBDIR) -lretroshare + ifdef PQI_USE_XPGP + LIBS += -L$(SSL_DIR) + endif + LIBS += -lssl -lcrypto + LIBS += -L$(KADC_DIR) -lKadC + LIBS += -L$(UPNPC_DIR) -lminiupnpc + LIBS += -L$(ZLIB_DIR) -lz + + RSLIBS = $(LIBS) + RSLIBS += -L$(PTHREADS_DIR) -lpthreadGC2d + + LIBS += $(WINLIB) + RSLIBS += $(WINLIB) + + + RSCFLAGS += $(WININC) + + RM = del + endif +endif + + + diff --git a/libretroshare/src/scripts/config.mk b/libretroshare/src/scripts/config.mk new file mode 100644 index 000000000..45fdf8921 --- /dev/null +++ b/libretroshare/src/scripts/config.mk @@ -0,0 +1,22 @@ + +# determine which operating system +# +########################################################################### +#Define OS. +# +OS = Linux +#OS = Cygwin +#OS = Win # MinGw. +########################################################################### + +ifeq ($(OS),Linux) + include $(RS_TOP_DIR)/scripts/config-linux.mk +else + ifeq ($(OS),Cygwin) + include $(RS_TOP_DIR)/scripts/config-cygwin.mk + else + include $(RS_TOP_DIR)/scripts/config-mingw.mk + endif +endif + +########################################################################### diff --git a/libretroshare/src/scripts/regress.mk b/libretroshare/src/scripts/regress.mk new file mode 100644 index 000000000..f80b48451 --- /dev/null +++ b/libretroshare/src/scripts/regress.mk @@ -0,0 +1,25 @@ + +testoutputfiles = $(foreach tt,$(1),$(tt).tstout) + +%.tstout : %.sh + -sh ./$< > $@ 2>&1 + +%.tstout : % + -./$< > $@ 2>&1 + +TESTOUT = $(call testoutputfiles,$(TESTS)) + +.phony : tests regress retest clobber + +tests: $(TESTS) + +regress: $(TESTOUT) + @-echo "--------------- SUCCESS (count):" + @-grep -c SUCCESS $(TESTOUT) + @-echo "--------------- FAILURE REPORTS:" + @-grep FAILURE $(TESTOUT) || echo no failures + @-echo "--------------- end" + +retest: + -/bin/rm $(TESTOUT) + diff --git a/libretroshare/src/scripts/rules.mk b/libretroshare/src/scripts/rules.mk new file mode 100644 index 000000000..f8d75c21f --- /dev/null +++ b/libretroshare/src/scripts/rules.mk @@ -0,0 +1,23 @@ + +# defines required / used. +# +# CFLAGS +# +# + +librs: $(RSOBJ) + $(AR) r $(LIBRS) $(RSOBJ) + $(RANLIB) $(LIBRS) + +.cc.o: + $(CC) $(CFLAGS) -c $< + +clean: + -/bin/rm $(RSOBJ) $(EXECOBJ) $(TESTOBJ) + +clobber: clean retest + -/bin/rm $(EXEC) $(TESTS) + + +include $(RS_TOP_DIR)/scripts/regress.mk + diff --git a/libretroshare/src/serialiser/Makefile b/libretroshare/src/serialiser/Makefile new file mode 100644 index 000000000..47c154144 --- /dev/null +++ b/libretroshare/src/serialiser/Makefile @@ -0,0 +1,41 @@ + +RS_TOP_DIR = .. +##### Define any flags that are needed for this section ####### +############################################################### + +############################################################### +include $(RS_TOP_DIR)/scripts/config.mk +############################################################### + +RSOBJ = rsserial.o rsbaseserial.o rstlvbase.o rstlvtypes.o rsbaseitems.o +RSOBJ += rstlvfileitem.o rstlvutil.o + +TESTOBJ = tlvbase_test.o tlvbase_test2.o tlvfileitem_test.o +TESTOBJ += tlvitems_test.o tlvstack_test.o + +TESTS = tlvbase_test tlvbase_test2 tlvfileitem_test +TESTS += tlvitems_test tlvstack_test + +all: librs tests + +tlvbase_test : tlvbase_test.o + $(CC) $(CFLAGS) -o tlvbase_test tlvbase_test.o $(OBJ) $(LIBS) + +tlvbase_test2 : tlvbase_test2.o + $(CC) $(CFLAGS) -o tlvbase_test2 tlvbase_test2.o $(OBJ) $(LIBS) + +tlvfileitem_test : tlvfileitem_test.o + $(CC) $(CFLAGS) -o tlvfileitem_test tlvfileitem_test.o $(OBJ) $(LIBS) + +tlvitems_test : tlvitems_test.o + $(CC) $(CFLAGS) -o tlvitems_test tlvitems_test.o $(OBJ) $(LIBS) + +tlvstack_test : tlvstack_test.o + $(CC) $(CFLAGS) -o tlvstack_test tlvstack_test.o $(OBJ) $(LIBS) + + + +############################################################### +include $(RS_TOP_DIR)/scripts/rules.mk +############################################################### + diff --git a/libretroshare/src/serialiser/rsbaseitems.cc b/libretroshare/src/serialiser/rsbaseitems.cc new file mode 100644 index 000000000..e6002e9c5 --- /dev/null +++ b/libretroshare/src/serialiser/rsbaseitems.cc @@ -0,0 +1,123 @@ + +/* + * libretroshare/src/serialiser: rsbaseitems.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "serialiser/rsbaseserial.h" +#include "serialiser/rsbaseitems.h" + +RsFileItem::~RsFileItem() +{ + return; +} + +void RsFileItem::clear() +{ + file.TlvClear(); + reqType = 0; +} + +uint32_t RsFileItemSerialiser::size(RsItem *i) +{ + RsFileItem *item = (RsFileItem *) i; + uint32_t s = 12; /* header + 4 for reqType */ + s += item->file.TlvSize(); + + return s; +} + +/* serialise the data to the buffer */ +bool RsFileItemSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) +{ + RsFileItem *item = (RsFileItem *) i; + + uint32_t tlvsize = size(item); + uint32_t offset = 8; + + if (*pktsize < tlvsize) + return false; /* not enough space */ + + *pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= setRawUInt32(data, tlvsize, &offset, item->reqType); + ok &= item->file.SetTlv(data, tlvsize, &offset); + + return ok; +} + +RsItem *RsFileItemSerialiser::deserialise(void *data, uint32_t *pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || + (RS_PKT_CLASS_BASE != getRsItemClass(rstype)) || + (RS_PKT_TYPE_FILE_ITEM != getRsItemType(rstype)) || + (0 != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*pktsize < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *pktsize = rssize; + + bool ok = true; + + /* ready to load */ + RsFileItem *item = new RsFileItem(); + item->clear(); + + /* skip the header */ + offset += 8; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, rssize, &offset, &(item->reqType)); + ok &= item->file.GetTlv(data, rssize, &offset); + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + + + diff --git a/libretroshare/src/serialiser/rsbaseitems.h b/libretroshare/src/serialiser/rsbaseitems.h new file mode 100644 index 000000000..327f3b08c --- /dev/null +++ b/libretroshare/src/serialiser/rsbaseitems.h @@ -0,0 +1,216 @@ +#ifndef RS_BASE_ITEMS_H +#define RS_BASE_ITEMS_H + +/* + * libretroshare/src/serialiser: rsbaseitems.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +const uint8_t RS_PKT_TYPE_FILE_ITEM = 0x01; +const uint8_t RS_PKT_TYPE_FILE_DATA = 0x02; +const uint8_t RS_PKT_TYPE_CHAT = 0x03; +const uint8_t RS_PKT_TYPE_MESSAGE = 0x04; +const uint8_t RS_PKT_TYPE_STATUS = 0x05; + +/**************************************************************************/ +class RsFileItem: public RsItem +{ + public: + RsFileItem() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_FILE_ITEM, 0) + { return; } +virtual ~RsFileItem(); +virtual void clear(); + + uint32_t reqType; /* a request / result etc */ + RsTlvFileItem file; /* file information */ +}; + +class RsFileItemSerialiser: public RsSerialType +{ + public: + RsFileItemSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_FILE_ITEM) + { return; } +virtual ~RsFileItemSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +class RsFileData: public RsItem +{ + public: + RsFileData() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_FILE_DATA, 0) + { return; } +virtual ~RsFileData(); +virtual void clear(); + + RsTlvFileItem file; + RsTlvFileData data; +}; + +class RsFileDataSerialiser: public RsSerialType +{ + public: + RsFileDataSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_FILE_DATA) + { return; } +virtual ~RsFileDataSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +class RsChatItem: public RsItem +{ + public: + RsChatItem() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_CHAT, 0) + { return; } +virtual ~RsChatItem(); +virtual void clear(); + + uint32_t chatFlags; + uint32_t sendTime; + + std::string message; + +}; + +class RsChatItemSerialiser: public RsSerialType +{ + public: + RsChatItemSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_CHAT) + { return; } +virtual ~RsChatItemSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +class RsMessageItem: public RsItem +{ + public: + RsMessageItem() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_MESSAGE, 0) + { return; } +virtual ~RsMessageItem(); +virtual void clear(); + + uint32_t msgFlags; + uint32_t sendTime; + uint32_t recvTime; + + std::string subject; + std::string message; + + RsTlvPeerIdSet msgto; + RsTlvPeerIdSet msgcc; + RsTlvPeerIdSet msgbcc; + + RsTlvFileSet attachment; +}; + +class RsMessageItemSerialiser: public RsSerialType +{ + public: + RsMessageItemSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_MESSAGE) + { return; } +virtual ~RsMessageItemSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +class RsStatus: public RsItem +{ + public: + RsStatus() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_STATUS, 0) + { return; } +virtual ~RsStatus(); +virtual void clear(); + + /* status */ + uint32_t status; + RsTlvServiceIdSet services; +}; + +class RsStatusSerialiser: public RsSerialType +{ + public: + RsStatusSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE, + RS_PKT_TYPE_STATUS) + { return; } +virtual ~RsStatusSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + + +/**************************************************************************/ + /* BELOW HERE to be fully defined */ +/**************************************************************************/ + +#endif + diff --git a/libretroshare/src/serialiser/rsbaseserial.cc b/libretroshare/src/serialiser/rsbaseserial.cc new file mode 100644 index 000000000..f337f962e --- /dev/null +++ b/libretroshare/src/serialiser/rsbaseserial.cc @@ -0,0 +1,76 @@ + +/* + * libretroshare/src/serialiser: rsbaseserial.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "serialiser/rsbaseserial.h" + +/* UInt32 get/set */ + +bool getRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t *out) +{ + /* first check there is space */ + if (size < *offset + 4) + { + return false; + } + void *buf = (void *) &(((uint8_t *) data)[*offset]); + + /* extract the data */ + uint32_t netorder_num; + memcpy(&netorder_num, buf, sizeof(uint32_t)); + + (*out) = ntohl(netorder_num); + (*offset) += 4; + return true; +} + +bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in) +{ + /* first check there is space */ + if (size < *offset + 4) + { + return false; + } + + void *buf = (void *) &(((uint8_t *) data)[*offset]); + + /* convert the data to the right format */ + uint32_t netorder_num = htonl(in); + + /* pack it in */ + memcpy(buf, &netorder_num, sizeof(uint32_t)); + + (*offset) += 4; + return true; +} + + + + + + + diff --git a/libretroshare/src/serialiser/rsbaseserial.h b/libretroshare/src/serialiser/rsbaseserial.h new file mode 100644 index 000000000..fd2a300b2 --- /dev/null +++ b/libretroshare/src/serialiser/rsbaseserial.h @@ -0,0 +1,53 @@ +#ifndef RS_BASE_PACKING_H +#define RS_BASE_PACKING_H + +/* + * libretroshare/src/serialiser: rsbaseserial.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +/******************************************************************* + * This is at the lowlevel packing routines. They are usually + * created in pairs - one to pack the data, the other to unpack. + * + * getRawXXX(void *data, uint32_t size, uint32_t *offset, XXX *out); + * setRawXXX(void *data, uint32_t size, uint32_t *offset, XXX *in); + * + * + * data - the base pointer to the serialised data. + * size - size of the memory pointed to by data. + * *offset - where we want to (un)pack the data. + * This is incremented by the datasize. + * + * *in / *out - the data to (un)pack. + * + ******************************************************************/ + + +bool getRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t *out); +bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in); + +#endif + diff --git a/libretroshare/src/serialiser/rsconfigitems.h b/libretroshare/src/serialiser/rsconfigitems.h new file mode 100644 index 000000000..74f74867e --- /dev/null +++ b/libretroshare/src/serialiser/rsconfigitems.h @@ -0,0 +1,119 @@ +#ifndef RS_CONFIG_ITEMS_SERIALISER_H +#define RS_CONFIG_ITEMS_SERIALISER_H + +/* + * libretroshare/src/serialiser: rsconfigitems.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +const uint8_t RS_PKT_TYPE_PEER_CONFIG = 0x01; +const uint8_t RS_PKT_TYPE_CACHE_CONFIG = 0x02; + +/**************************************************************************/ + +class RsPeerConfig: public RsItem +{ + public: + RsPeerConfig() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, + RS_PKT_TYPE_PEER_CONFIG, 0) + { return; } +virtual ~RsPeerConfig(); +virtual void clear(); + + RsTlvPeerId peerid; /* Mandatory */ + RsTlvPeerFingerprint fpr; /* Mandatory */ + + struct sockaddr_in lastaddr; /* Mandatory */ + struct sockaddr_in localaddr; /* Mandatory */ + struct sockaddr_in serveraddr; /* Mandatory */ + + uint32_t status; /* Mandatory */ + + uint32_t lastconn_ts; /* Mandatory */ + uint32_t lastrecv_ts; /* Mandatory */ + uint32_t nextconn_ts; /* Mandatory */ + uint32_t nextconn_period; /* Mandatory */ +}; + + +class RsPeerConfigSerialiser: public RsSerialType +{ + public: + RsPeerConfigSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, + RS_PKT_TYPE_PEER_CONFIG) + { return; } + +virtual ~RsPeerConfigSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +class RsCacheConfig: public RsItem +{ + public: + RsCacheConfig() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, + RS_PKT_TYPE_CACHE_CONFIG, 0) + { return; } +virtual ~RsCacheConfig(); +virtual void clear(); + + RsTlvPeerId peerid; /* Mandatory */ + uint32_t cacheid; /* Mandatory */ + + std::string path; /* Mandatory */ + std::string name; /* Mandatory */ + std::string hash; /* Mandatory */ + + uint32_t recvd; /* Mandatory */ +}; + + +class RsCacheConfigSerialiser: public RsSerialType +{ + public: + RsCacheConfigSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, + RS_PKT_TYPE_CACHE_CONFIG) + { return; } + +virtual ~RsCacheConfigSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +#endif /* RS_CONFIG_ITEMS_SERIALISER_H */ diff --git a/libretroshare/src/serialiser/rsserial.cc b/libretroshare/src/serialiser/rsserial.cc new file mode 100644 index 000000000..83b2d8517 --- /dev/null +++ b/libretroshare/src/serialiser/rsserial.cc @@ -0,0 +1,318 @@ + +/* + * libretroshare/src/serialiser: rsserial.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "serialiser/rsbaseserial.h" +#include "serialiser/rsserial.h" + +#include + + +RsItem::RsItem(uint32_t t) +:type(t) +{ + return; +} + +RsItem::RsItem(uint8_t ver, uint8_t cls, uint8_t t, uint8_t subtype) +{ + type = (ver << 24) + (cls << 16) + (t << 8) + subtype; + return; +} + +RsItem::~RsItem() +{ + return; +} + + +uint32_t RsItem::PacketId() +{ + return type; +} + +uint8_t RsItem::PacketVersion() +{ + return (type >> 24); +} + + +uint8_t RsItem::PacketClass() +{ + return (type >> 16) & 0xFF; +} + + +uint8_t RsItem::PacketType() +{ + return (type >> 8) & 0xFF; +} + + +uint8_t RsItem::PacketSubType() +{ + return (type & 0xFF); +} + + + +RsSerialType::RsSerialType(uint32_t t) + :type(t & 0xFFFFFF00) +{ + return; +} + +RsSerialType::RsSerialType(uint8_t ver, uint8_t cls, uint8_t t) +{ + type = (ver << 24) + (cls << 16) + (t << 8); + return; +} + + +RsSerialType::~RsSerialType() +{ + return; +} + +uint32_t RsSerialType::size(RsItem *) +{ +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialType::size()" << std::endl; +#endif + + /* base size: type + length */ + return 8; +} + +bool RsSerialType::serialise(RsItem *item, void *data, uint32_t *size) +{ +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialType::serialise()" << std::endl; +#endif + return false; +} + +RsItem * RsSerialType::deserialise(void *data, uint32_t *size) +{ +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialType::deserialise()" << std::endl; +#endif + return NULL; +} + +uint32_t RsSerialType::PacketId() +{ + return type; +} + + + + +RsSerialiser::RsSerialiser() +{ + return; +} + + +RsSerialiser::~RsSerialiser() +{ + /* clean up the map */ + std::map::iterator it; + for(it = serialisers.begin(); it != serialisers.end(); it++) + { + delete (it->second); + } + serialisers.clear(); + return; +} + + + +bool RsSerialiser::addSerialType(RsSerialType *serialiser) +{ + uint32_t type = serialiser->PacketId(); + std::map::iterator it; + if (serialisers.end() != (it = serialisers.find(type))) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::addSerialType() Error Serialiser already exists!"; + std::cerr << std::endl; +#endif + return false; + } + + serialisers[type] = serialiser; + return true; +} + + + +uint32_t RsSerialiser::size(RsItem *item) +{ + /* find the type */ + uint32_t type = item->PacketId(); + std::map::iterator it; + + if (serialisers.end() == (it = serialisers.find(type))) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::size() serialiser missing!"; + std::cerr << std::endl; +#endif + return 0; + } + + return (it->second)->size(item); +} + +bool RsSerialiser::serialise (RsItem *item, void *data, uint32_t *size) +{ + /* find the type */ + uint32_t type = (item->PacketId() & 0xFFFFFF00); + std::map::iterator it; + + if (serialisers.end() == (it = serialisers.find(type))) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::serialise() serialiser missing!"; + std::cerr << std::endl; +#endif + return false; + } + + return (it->second)->serialise(item, data, size); +} + + + +RsItem * RsSerialiser::deserialise(void *data, uint32_t *size) +{ + /* find the type */ + if (*size < 8) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::deserialise() Not Enough Data(1)"; + std::cerr << std::endl; +#endif + return NULL; + } + + uint32_t type = (getRsItemId(data) & 0xFFFFFF00); + uint32_t pkt_size = getRsItemSize(data); + + if (pkt_size < *size) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::deserialise() Not Enough Data(2)"; + std::cerr << std::endl; +#endif + return NULL; + } + + /* store the packet size to return the amount we should use up */ + *size = pkt_size; + + std::map::iterator it; + if (serialisers.end() == (it = serialisers.find(type))) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::deserialise() deserialiser missing!"; + std::cerr << std::endl; +#endif + return NULL; + } + + RsItem *item = (it->second)->deserialise(data, &pkt_size); + if (!item) + { + return NULL; + } + + if (pkt_size != *size) + { +#ifdef RSSERIAL_DEBUG + std::cerr << "RsSerialiser::deserialise() Warning: size mismatch!"; + std::cerr << std::endl; +#endif + } + return item; +} + + +bool setRsItemHeader(void *data, uint32_t size, uint32_t type, uint32_t pktsize) +{ + if (size < 8) + return false; + + uint32_t offset = 0; + bool ok = true; + ok &= setRawUInt32(data, 8, &offset, type); + ok &= setRawUInt32(data, 8, &offset, pktsize); + + return ok; +} + + + +uint32_t getRsItemId(void *data) +{ + uint32_t type; + uint32_t offset = 0; + getRawUInt32(data, 4, &offset, &type); + return type; +} + + +uint32_t getRsItemSize(void *data) +{ + uint32_t size; + uint32_t offset = 4; + getRawUInt32(data, 8, &offset, &size); + return size; +} + +uint8_t getRsItemVersion(uint32_t type) +{ + return (type >> 24); +} + +uint8_t getRsItemClass(uint32_t type) +{ + return (type >> 16) & 0xFF; +} + +uint8_t getRsItemType(uint32_t type) +{ + return (type >> 8) & 0xFF; +} + +uint8_t getRsItemSubType(uint32_t type) +{ + return (type & 0xFF); +} + + + + diff --git a/libretroshare/src/serialiser/rsserial.h b/libretroshare/src/serialiser/rsserial.h new file mode 100644 index 000000000..662d693e1 --- /dev/null +++ b/libretroshare/src/serialiser/rsserial.h @@ -0,0 +1,133 @@ +#ifndef RS_BASE_SERIALISER_H +#define RS_BASE_SERIALISER_H + +/* + * libretroshare/src/serialiser: rsserial.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + + +/******************************************************************* + * This is the Top-Level serialiser/deserialise, + * + * Data is Serialised into the following format + * + * ----------------------------------------- + * | TYPE (4 bytes) | Size (4 bytes) | + * ----------------------------------------- + * | | + * | Data .... | + * | | + * ----------------------------------------- + * + * Size is the total size of the packet (including the 8 byte header) + * Type is composed of: + * + * 8 bits: Version (0x01) + * 8 bits: Class + * 8 bits: Type + * 8 bits: SubType + ******************************************************************/ + +const uint8_t RS_PKT_VERSION1 = 0x01; + +const uint8_t RS_PKT_CLASS_BASE = 0x01; +const uint8_t RS_PKT_CLASS_SERVICE = 0x02; +const uint8_t RS_PKT_CLASS_SERV_INIT = 0x03; +const uint8_t RS_PKT_CLASS_CONFIG = 0x11; + + +class RsItem +{ + public: + RsItem(uint32_t t); + RsItem(uint8_t ver, uint8_t cls, uint8_t t, uint8_t subtype); + +virtual ~RsItem(); +virtual void clear() = 0; + + /* complete id */ +uint32_t PacketId(); + + /* id parts */ +uint8_t PacketVersion(); +uint8_t PacketClass(); +uint8_t PacketType(); +uint8_t PacketSubType(); + + private: +uint32_t type; +}; + + +class RsSerialType +{ + public: + RsSerialType(uint32_t t); /* only uses top 24bits */ + RsSerialType(uint8_t ver, uint8_t cls, uint8_t t); + +virtual ~RsSerialType(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +uint32_t PacketId(); + private: +uint32_t type; +}; + + +class RsSerialiser +{ + public: + RsSerialiser(); + ~RsSerialiser(); + bool addSerialType(RsSerialType *type); + + uint32_t size(RsItem *); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + + private: + std::map serialisers; +}; + +bool setRsItemHeader(void *data, uint32_t size, uint32_t type, uint32_t pktsize); + +/* Extract Header Information from Packet */ +uint32_t getRsItemId(void *data); +uint32_t getRsItemSize(void *data); + +uint8_t getRsItemVersion(uint32_t type); +uint8_t getRsItemClass(uint32_t type); +uint8_t getRsItemType(uint32_t type); +uint8_t getRsItemSubType(uint32_t type); + + + + +#endif /* RS_BASE_SERIALISER_H */ diff --git a/libretroshare/src/serialiser/rsserviceitems.h b/libretroshare/src/serialiser/rsserviceitems.h new file mode 100644 index 000000000..5d13335b5 --- /dev/null +++ b/libretroshare/src/serialiser/rsserviceitems.h @@ -0,0 +1,113 @@ +#ifndef RS_SERVICE_ITEMS_H +#define RS_SERVICE_ITEMS_H + +/* + * libretroshare/src/serialiser: rsserviceitems.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +const uint8_t RS_PKT_TYPE_DISC_MSG = 0x01; +const uint8_t RS_PKT_TYPE_CHANNEL_MSG = 0x02; +const uint8_t RS_PKT_TYPE_PROXY_MSG = 0x03; + +/**************************************************************************/ + +class RsDiscMsg: public RsItem +{ + public: + RsDiscMsg() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE, + RS_PKT_TYPE_DISC_MSG, 0) + { return; } +virtual ~RsDiscMsg(); +virtual void clear(); + + uint32_t discType; + uint32_t discFlags; + + uint32_t connect_tr; + uint32_t receive_tr; + + struct sockaddr_in laddr; + struct sockaddr_in saddr; + + RsTlvBinaryData cert; +}; + +class RsDiscMsgSerialiser: public RsSerialType +{ + public: + RsDiscMsgSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE, + RS_PKT_TYPE_DISC_MSG) + { return; } + +virtual ~RsDiscMsgSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + + +/**************************************************************************/ + +class RsChannelMsg: public RsItem +{ + public: + RsChannelMsg() + :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE, + RS_PKT_TYPE_CHANNEL_MSG, 0) + { return; } +virtual ~RsChannelMsg(); +virtual void clear(); + + RsTlvBinaryData cert; /* Mandatory */ + RsTlvFileSet files; /* Mandatory */ + RsTlvBinaryData sign; /* Mandatory */ +}; + +class RsChannelMsgSerialiser: public RsSerialType +{ + public: + RsChannelMsgSerialiser() + :RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE, + RS_PKT_TYPE_CHANNEL_MSG) + { return; } + +virtual ~RsChannelMsgSerialiser(); + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + +}; + + +/**************************************************************************/ + + +#endif /* RS_SERVICE_ITEMS_H */ diff --git a/libretroshare/src/serialiser/rstlvbase.cc b/libretroshare/src/serialiser/rstlvbase.cc new file mode 100644 index 000000000..90f3727d7 --- /dev/null +++ b/libretroshare/src/serialiser/rstlvbase.cc @@ -0,0 +1,446 @@ + +/* + * libretroshare/src/serialiser: rstlvbase.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie, Horatio, Chris Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include + +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +/******************************************************************* + * These are the general TLV (un)packing routines. + * + * Data is Serialised into the following format + * + * ----------------------------------------- + * | TLV TYPE (2 bytes)| TLV LEN (2 bytes) | + * ----------------------------------------- + * | | + * | Data .... | + * | | + * ----------------------------------------- + * + * Size is the total size of the TLV Field (including the 4 byte header) + * + * Like the lowlevel packing routines. They are usually + * created in pairs - one to pack the data, the other to unpack. + * + * GetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *out); + * SetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *in); + * + * + * data - the base pointer to the serialised data. + * size - size of the memory pointed to by data. + * *offset - where we want to (un)pack the data. + * This is incremented by the datasize. + * + * *in / *out - the data to (un)pack. + * + ******************************************************************/ + +//********************* + +// A facility func +inline void* right_shift_void_pointer(void* p, uint32_t len) { + + return (void*)( (uint8_t*)p + len); +} +//********************* + +#define TLV_BASE_DEBUG 1 + + +const uint32_t TYPE_FIELD_BYTES = 2; + +/**** Basic TLV Functions ****/ +uint16_t GetTlvSize(void *data) { + if (!data) + return 0; + + uint16_t len; + + void * from =right_shift_void_pointer(data, sizeof(uint16_t)); + + memcpy((void *)&len, from , sizeof(uint16_t)); + + len = ntohs(len); + + return len; +} + +uint16_t GetTlvType(void *data) { + if (!data) + return 0; + + uint16_t type; + + memcpy((void*)&type, data, TYPE_FIELD_BYTES); + + type = ntohs(type); + + return type; + +} + +//tested +bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type, + uint16_t len) { + if (!data) + return false; + if (!offset) + return false; + if (size < *offset +4) + return false; + + uint16_t type_n = htons(type); + + //copy type_n to (data+*offset) + void* to = right_shift_void_pointer(data, *offset); + memcpy(to , (void*)&type_n, sizeof(uint16_t)); + + uint16_t len_n =htons(len); + //copy len_n to (data + *offset +2) + to = right_shift_void_pointer(to, sizeof(uint16_t)); + memcpy((void *)to, (void*)&len_n, sizeof(uint16_t)); + + *offset += sizeof(uint16_t)*2; + + return true; +} + +//tested +bool SetTlvSize(void *data, uint32_t size, uint16_t len) { + if (!data) + return false; + + if(size < sizeof(uint16_t)*2 ) + return false; + + uint16_t len_n = htons(len); + + void * to = (void*)((uint8_t *) data + sizeof(uint16_t)); + + memcpy(to, (void*) &len_n, sizeof(uint16_t)); + + return true; + +} + +/**** Generic TLV Functions **** + * This have the same data (int or string for example), + * but they can have different types eg. a string could represent a name or a path, + * so we include a type parameter in the arguments + */ +//tested +bool SetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, + uint32_t out) +{ + if (!data) + return false; + uint16_t tlvsize = GetTlvUInt32Size(); /* this will always be 8 bytes */ + uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ + if (size < tlvend) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "SetTlvUInt32() FAILED - not enough space. (or earlier)" << std::endl; + std::cerr << "SetTlvUInt32() size: " << size << std::endl; + std::cerr << "SetTlvUInt32() tlvsize: " << tlvsize << std::endl; + std::cerr << "SetTlvUInt32() tlvend: " << tlvend << std::endl; +#endif + return false; + } + + bool ok = true; + + /* Now use the function we got to set the TlvHeader */ + /* function shifts offset to the new start for the next data */ + ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); + +#ifdef TLV_BASE_DEBUG + if (!ok) + { + std::cerr << "SetTlvUInt32() SetTlvBase FAILED (or earlier)" << std::endl; + } +#endif + + /* now set the UInt32 ( in rsbaseserial.h???) */ + ok &= setRawUInt32(data, tlvend, offset, out); + +#ifdef TLV_BASE_DEBUG + if (!ok) + { + std::cerr << "SetTlvUInt32() setRawUInt32 FAILED (or earlier)" << std::endl; + } +#endif + + + return ok; + +} + +//tested +bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset, + uint16_t type, uint32_t *in) +{ + if (!data) + return false; + + if (size < *offset + 4) + return false; + + /* extract the type and size */ + void *tlvstart = right_shift_void_pointer(data, *offset); + uint16_t tlvtype = GetTlvType(tlvstart); + uint16_t tlvsize = GetTlvSize(tlvstart); + + /* check that there is size */ + uint32_t tlvend = *offset + tlvsize; + if (size < tlvend) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "GetTlvUInt32() FAILED - not enough space." << std::endl; + std::cerr << "GetTlvUInt32() size: " << size << std::endl; + std::cerr << "GetTlvUInt32() tlvsize: " << tlvsize << std::endl; + std::cerr << "GetTlvUInt32() tlvend: " << tlvend << std::endl; +#endif + return false; + } + + if (type != tlvtype) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "GetTlvUInt32() FAILED - Type mismatch" << std::endl; + std::cerr << "GetTlvUInt32() type: " << type << std::endl; + std::cerr << "GetTlvUInt32() tlvtype: " << tlvtype << std::endl; +#endif + return false; + } + + uint32_t *intdata = (uint32_t *) right_shift_void_pointer(tlvstart, 4); + *in = ntohl(*intdata); + + *offset += tlvsize; /* step along */ + return true; +} + +uint32_t GetTlvUInt32Size() { + return 8; +} + +uint32_t GetTlvUInt16Size() { + return sizeof(uint16_t); + +} + +uint32_t GetTlvUInt8Size() { + return sizeof(uint8_t); + +} + +bool SetTlvString(void *data, uint32_t size, uint32_t *offset, + uint16_t type, std::string out) +{ + if (!data) + return false; + uint16_t tlvsize = GetTlvStringSize(out); + uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ + + if (size < tlvend) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "SetTlvString() FAILED - not enough space" << std::endl; + std::cerr << "SetTlvString() size: " << size << std::endl; + std::cerr << "SetTlvString() tlvsize: " << tlvsize << std::endl; + std::cerr << "SetTlvString() tlvend: " << tlvend << std::endl; +#endif + return false; + } + + bool ok = true; + ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); + + void * to = right_shift_void_pointer(data, *offset); + + uint16_t strlen = tlvsize - 4; + memcpy(to, out.c_str(), strlen); + + *offset += strlen; + + return ok; +} + +//tested +bool GetTlvString(void *data, uint32_t size, uint32_t *offset, + uint16_t type, std::string &in) +{ + if (!data) + return false; + + if (size < *offset + 4) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "GetTlvString() FAILED - not enough space" << std::endl; + std::cerr << "GetTlvString() size: " << size << std::endl; + std::cerr << "GetTlvString() *offset: " << *offset << std::endl; +#endif + return false; + } + + /* extract the type and size */ + void *tlvstart = right_shift_void_pointer(data, *offset); + uint16_t tlvtype = GetTlvType(tlvstart); + uint16_t tlvsize = GetTlvSize(tlvstart); + + /* check that there is size */ + uint32_t tlvend = *offset + tlvsize; + if (size < tlvend) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "GetTlvString() FAILED - not enough space" << std::endl; + std::cerr << "GetTlvString() size: " << size << std::endl; + std::cerr << "GetTlvString() tlvsize: " << tlvsize << std::endl; + std::cerr << "GetTlvString() tlvend: " << tlvend << std::endl; +#endif + return false; + } + + if (type != tlvtype) + { +#ifdef TLV_BASE_DEBUG + std::cerr << "GetTlvString() FAILED - invalid type" << std::endl; + std::cerr << "GetTlvString() type: " << type << std::endl; + std::cerr << "GetTlvString() tlvtype: " << tlvtype << std::endl; +#endif + return false; + } + + char *strdata = (char *) right_shift_void_pointer(tlvstart, 4); + uint16_t strsize = tlvsize - 4; /* remove the header */ + in = std::string(strdata, strsize); + + *offset += tlvsize; /* step along */ + return true; +} + +uint32_t GetTlvStringSize(std::string &in) { + return 4 + in.size(); +} + +//How to handle structure sockaddr_in? Convert it to void*? +bool SetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, + uint16_t type, struct sockaddr_in *out) { + if (!data) + return false; + + if (size < *offset + sizeof(uint16_t)*2+ sizeof(sockaddr_in)) + return false; + + // struct sockaddr_in out_n = *out; + // out_n. sin_port = htons(out_n.sin_port); + // out_n.sin_addr = htonl(out_n.sin_addr); + + void * to = right_shift_void_pointer(data, *offset); + memcpy(to, (void *)&type, sizeof(uint16_t)); + + to = right_shift_void_pointer(to, sizeof(uint16_t)); + uint16_t len = sizeof(sockaddr_in); + memcpy(to, (void*)&len, sizeof(uint16_t)); + + to = right_shift_void_pointer(to, sizeof(uint16_t)); + memcpy(to, (void *)out, sizeof(sockaddr_in)); + + *offset += sizeof(uint16_t)*2+ sizeof(sockaddr_in); + + return true; + +} + +bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, + uint16_t type, struct sockaddr_in *in) { + if (!data) + return false; + + if (size < *offset + sizeof(uint16_t)*2+ sizeof(sockaddr_in)) + return false; + + void * from = right_shift_void_pointer(data, *offset +2); + + uint16_t len; + memcpy((void *)&len, from, sizeof(uint16_t)); + len = ntohs(len); + + if (len != sizeof(sockaddr_in)) + return false; + + from = right_shift_void_pointer(from, sizeof(uint16_t)); + + memcpy((void*)in, from, sizeof(sockaddr_in)); + + *offset += sizeof(uint16_t)*2+ len; + return true; + +} + +//intention? +bool GetTlvIpAddrPortV4Size() { + return sizeof(uint16_t)*2+ sizeof(sockaddr_in); +} + +bool SetRawUInt32(void* data, uint32_t size, uint32_t* offset, uint32_t out) { + if (!data) + return false; + if (size < *offset + sizeof(uint32_t)) + return false; + + uint32_t out_n = htonl(out); + + memcpy(right_shift_void_pointer(data, *offset), (void*)&out_n, + sizeof(uint32_t)); + + *offset += sizeof(uint32_t); + return true; +} + +// additional serializer of data +/* +bool SetTlvBinData(void* data, uint32_t size, uint32_t* offset, uint16_t type, void* data_bin, uint32_t len_tlv) + { + if (!data) + return false; + if (size < *offset + len) + return false; + + setTlvBase(data, size, offset, TLV_TYPE_DATA, len_tlv); + + memcpy(right_shift_void_pointer(data, *offset), data_bin, + len); + + *offset += len; + return true; +} + +*/ + diff --git a/libretroshare/src/serialiser/rstlvbase.h b/libretroshare/src/serialiser/rstlvbase.h new file mode 100644 index 000000000..6a4ad105c --- /dev/null +++ b/libretroshare/src/serialiser/rstlvbase.h @@ -0,0 +1,166 @@ +#ifndef RS_TLV_BASE_H +#define RS_TLV_BASE_H + +/* + * libretroshare/src/serialiser: rstlvbase.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie, Horatio, Chris Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +/******************************************************************* + * These are the general TLV (un)packing routines. + * + * Data is Serialised into the following format + * + * ----------------------------------------- + * | TLV TYPE (2 bytes)| TLV LEN (2 bytes) | + * ----------------------------------------- + * | | + * | Data .... | + * | | + * ----------------------------------------- + * + * Size is the total size of the TLV Field (including the 4 byte header) + * + * Like the lowlevel packing routines. They are usually + * created in pairs - one to pack the data, the other to unpack. + * + * GetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *out); + * SetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *in); + * + * + * data - the base pointer to the serialised data. + * size - size of the memory pointed to by data. + * *offset - where we want to (un)pack the data. + * This is incremented by the datasize. + * + * *in / *out - the data to (un)pack. + * + ******************************************************************/ + +#include + + +/* 0b 0000 0000 0001 XXXX UInt32 */ +/* 0b 0000 0000 0010 XXXX String */ +/* 0b 0000 0000 0011 XXXX IP:Port V4 */ +/* 0b 0000 0000 0011 XXXX IP:Port V4 */ + +/******* BINARY TYPES ****************/ +/* 0b 0000 0000 1000 XXXX CERT */ +/* 0b 0000 0000 1001 XXXX Priv Key */ +/* 0b 0000 0000 1010 XXXX Pub Key */ +/* 0b 0000 0000 1011 XXXX Signature */ + +/* 0b 0001 XXXX XXXX XXXX Compound */ + +const uint16_t TLV_TYPE_UINT32_SIZE = 0x0010; +const uint16_t TLV_TYPE_UINT32_POP = 0x0011; +const uint16_t TLV_TYPE_UINT32_AGE = 0x0012; +const uint16_t TLV_TYPE_UINT32_OFFSET = 0x0013; + +const uint16_t TLV_TYPE_STR_HASH = 0x0020; +const uint16_t TLV_TYPE_STR_NAME = 0x0021; +const uint16_t TLV_TYPE_STR_PATH = 0x0022; +const uint16_t TLV_TYPE_STR_PEERID = 0x0023; +const uint16_t TLV_TYPE_STR_KEY = 0x0024; +const uint16_t TLV_TYPE_STR_VALUE = 0x0025; +const uint16_t TLV_TYPE_STR_COMMENT = 0x0026; +const uint16_t TLV_TYPE_STR_TITLE = 0x0027; + +const uint16_t TLV_TYPE_UINT8_SERID = 0x0028; + +const uint16_t TLV_TYPE_IPV4_LOCAL = 0x0030; +const uint16_t TLV_TYPE_IPV4_SERVER = 0x0031; +const uint16_t TLV_TYPE_IPV4_LAST = 0x0032; + + /**** Binary Types ****/ +const uint16_t TLV_TYPE_CERT_XPGP = 0x0080; +const uint16_t TLV_TYPE_CERT_X509 = 0x0081; +const uint16_t TLV_TYPE_CERT_OPENPGP = 0x0082; + +const uint16_t TLV_TYPE_PRIV_KEY_RSA = 0x0090; + +const uint16_t TLV_TYPE_PUB_KEY_RSA = 0x00A0; + +const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x00B0; + +const uint16_t TLV_TYPE_BIN_FILEDATA = 0x00C0; + + /**** Compound Types ****/ +const uint16_t TLV_TYPE_FILEITEM = 0x1001; +const uint16_t TLV_TYPE_FILESET = 0x1002; +const uint16_t TLV_TYPE_FILEDATA = 0x1003; + +const uint16_t TLV_TYPE_KEYVALUE = 0x1005; +const uint16_t TLV_TYPE_KEYVALUESET = 0x1006; + +const uint16_t TLV_TYPE_PEERSET = 0x1007; +const uint16_t TLV_TYPE_SERVICESET = 0x1008; + + +/**** Basic TLV Functions ****/ +uint16_t GetTlvSize(void *data); +uint16_t GetTlvType(void *data); +bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint16_t len); +bool SetTlvSize(void *data, uint32_t size, uint16_t len); + + +/**** Generic TLV Functions **** + * This have the same data (int or string for example), + * but they can have different types eg. a string could represent a name or a path, + * so we include a type parameter in the arguments + */ + +bool SetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t out); +bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t *in); +uint32_t GetTlvUInt32Size(); +uint32_t GetTlvUInt16Size(); +uint32_t GetTlvUInt8Size(); +/* additiona numerical set and Get Routine to be added + +bool SetTlvUInt16(...) +bool SetTlvUInt8(...) +bool GetTlvUInt16(...) +bool GetTlvUInt8(...) +............................could above just be templated? */ + + +bool SetTlvString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string out); +bool GetTlvString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string &in); +uint32_t GetTlvStringSize(std::string &in); + +bool SetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in *out); +bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in *in); +bool GetTlvIpAddrPortV4Size(); + +/* additional function to be added + +bool SetTlvBinData(void* data, uint32_t size, uint32_t* offset, uint16_t type, void* data_bin, uint32_t len_tlv) + +above(SetTlvbinData) is partially implemented + +bool GetTlvBinData(void* data, uint32_t size, uint32_t* offset, uint16_t type, void* data_bin, uint32_t len_tlv) + +*************************************/ +#endif diff --git a/libretroshare/src/serialiser/rstlvfileitem.cc b/libretroshare/src/serialiser/rstlvfileitem.cc new file mode 100644 index 000000000..80f46b366 --- /dev/null +++ b/libretroshare/src/serialiser/rstlvfileitem.cc @@ -0,0 +1,584 @@ + +/* + * libretroshare/src/serialiser: rstlvfileitem.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "serialiser/rstlvbase.h" +#include "serialiser/rstlvtypes.h" +#include "serialiser/rsbaseserial.h" + +/*** + * #define TLV_FI_DEBUG 1 + **/ + +void RsTlvFileItem::TlvClear() +{ + filesize = 0; + hash = ""; + name = ""; + path = ""; + pop = 0; + age = 0; +} + +uint16_t RsTlvFileItem::TlvSize() +{ + uint32_t s = 8; /* header + 4 for size */ + s += GetTlvStringSize(hash); +#ifdef TLV_FI_DEBUG + std::cerr << "RsTlvFileItem::TlvSize() 8 + Hash: " << s << std::endl; +#endif + + + /* now optional ones */ + if (name.length() > 0) + { + s += GetTlvStringSize(name); +#ifdef TLV_FI_DEBUG + std::cerr << "RsTlvFileItem::TlvSize() + Name: " << s << std::endl; +#endif + } + + if (path.length() > 0) + { + s += GetTlvStringSize(path); +#ifdef TLV_FI_DEBUG + std::cerr << "RsTlvFileItem::TlvSize() + Path: " << s << std::endl; +#endif + } + + if (pop != 0) + { + s += GetTlvUInt32Size(); +#ifdef TLV_FI_DEBUG + std::cerr << "RsTlvFileItem::TlvSize() + Pop: " << s << std::endl; +#endif + } + + if (age != 0) + { + s += GetTlvUInt32Size(); +#ifdef TLV_FI_DEBUG + std::cerr << "RsTlvFileItem::TlvSize() 4 + Age: " << s << std::endl; +#endif + } + +#ifdef TLV_FI_DEBUG + std::cerr << "RsTlvFileItem::TlvSize() Total: " << s << std::endl; +#endif + + return s; +} + +/* serialise the data to the buffer */ +bool RsTlvFileItem::SetTlv(void *data, uint32_t size, uint32_t *offset) +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_FILEITEM, tlvsize); + +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() SetTlvBase Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() PostBase:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << std::endl; +#endif + + + /* add mandatory parts first */ + ok &= setRawUInt32(data, tlvend, offset, filesize); + +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() SetRawUInt32(FILESIZE) Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() PostSize:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << std::endl; +#endif + + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH, hash); + + +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() SetTlvString(HASH) Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() PostHash:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << std::endl; +#endif + + /* now optional ones */ + if (name.length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_NAME, name); +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Name Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() PostName:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << std::endl; +#endif + + if (path.length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_PATH, path); +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Path Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() Pre Pop:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << " type: " << TLV_TYPE_UINT32_POP << " value: " << pop; + std::cerr << std::endl; +#endif + + if (pop != 0) + ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_POP, pop); +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Pop Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() Post Pop/Pre Age:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << " type: " << TLV_TYPE_UINT32_AGE << " value: " << age; + std::cerr << std::endl; +#endif + + if (age != 0) + ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_AGE, age); +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Age Failed (or earlier)" << std::endl; + } + std::cerr << "RsTlvFileItem::SetTlv() Post Age:" << std::endl; + std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; + std::cerr << std::endl; +#endif + + + +#ifdef TLV_FI_DEBUG + if (!ok) + { + std::cerr << "RsTlvFileItem::SetTlv() Setting Options Failed (or earlier)" << std::endl; + } +#endif + + return ok; +} + +bool RsTlvFileItem::GetTlv(void *data, uint32_t size, uint32_t *offset) +{ + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_FILEITEM) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, tlvend, offset, &filesize); + ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH, hash); + + /* while there is more TLV (optional part) */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + switch(tlvsubtype) + { + case TLV_TYPE_STR_NAME: + ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_NAME, name); + break; + case TLV_TYPE_STR_PATH: + ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_PATH, path); + break; + case TLV_TYPE_UINT32_POP: + ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_POP, &pop); + break; + case TLV_TYPE_UINT32_AGE: + ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_AGE, &age); + break; + default: + ok = false; + } + if (!ok) + { + return false; + } + } + return ok; +} + + +/* print it out */ +std::ostream &RsTlvFileItem::print(std::ostream &out, uint16_t indent) +{ + printBase(out, "RsTlvFileItem", indent); + uint16_t int_Indent = indent + 2; + + + printIndent(out, int_Indent); + out << "Mandatory: FileSize: " << filesize << " Hash: " << hash; + out << std::endl; + + printIndent(out, int_Indent); + out << "Optional:" << std::endl; + + /* now optional ones */ + if (name.length() > 0) + { + printIndent(out, int_Indent); + out << "Name: " << name << std::endl; + } + if (path.length() > 0) + { + printIndent(out, int_Indent); + out << "Path: " << path << std::endl; + } + if (pop != 0) + { + printIndent(out, int_Indent); + out << "Pop: " << pop << std::endl; + } + if (age != 0) + { + printIndent(out, int_Indent); + out << "Age: " << age << std::endl; + } + + printEnd(out, "RsTlvFileItem", indent); + + return out; +} + + +/************************************* RsTlvFileSet ************************************/ + +void RsTlvFileSet::TlvClear() +{ + title = ""; + comment = ""; + items.clear(); +} + +uint16_t RsTlvFileSet::TlvSize() +{ + uint32_t s = 4; /* header */ + + /* first determine the total size of RstlvFileItems in list */ + + std::list::iterator it; + + for(it = items.begin(); it != items.end() ; ++it) + { + s += (*it).TlvSize(); + } + + /* now add comment and title length of this tlv object */ + + if (title.length() > 0) + s += GetTlvStringSize(title); + if (comment.length() > 0) + s += GetTlvStringSize(comment); + + return s; +} + + +/* serialize data to the buffer */ + +bool RsTlvFileSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_FILESET, tlvsize); + + /* add mandatory parts first */ + std::list::iterator it; + + for(it = items.begin(); it != items.end() ; ++it) + { + ok &= (*it).SetTlv(data, size, offset); + /* drop out if fails */ + if (!ok) + return false; + } + + /* now optional ones */ + if (title.length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_TITLE, title); // no base tlv type for title? + if (comment.length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_COMMENT, comment); // no base tlv type for comment? + + return ok; + +} + + +bool RsTlvFileSet::GetTlv(void *data, uint32_t size, uint32_t *offset) +{ + if (size < *offset + 4) + return false; + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_FILESET) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + /* while there is more TLV */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + if (tlvsubtype == TLV_TYPE_FILEITEM) + { + RsTlvFileItem newitem; + ok &= newitem.GetTlv(data, size, offset); + if (ok) + { + items.push_back(newitem); + } + } + else if (tlvsubtype == TLV_TYPE_STR_TITLE) + { + ok &= GetTlvString(data, tlvend, offset, + TLV_TYPE_STR_TITLE, title); + } + else if (tlvsubtype == TLV_TYPE_STR_COMMENT) + { + ok &= GetTlvString(data, tlvend, offset, + TLV_TYPE_STR_COMMENT, comment); + } + else + { + /* unknown subtype -> error */ + ok = false; + } + + if (!ok) + { + return false; + } + } + + return ok; +} + +/* print it out */ + +std::ostream &RsTlvFileSet::print(std::ostream &out, uint16_t indent) +{ + printBase(out, "RsTlvFileSet", indent); + uint16_t int_Indent = indent + 2; + + + printIndent(out, int_Indent); + out << "Mandatory:" << std::endl; + std::list::iterator it; + + for(it = items.begin(); it != items.end() ; ++it) + { + it->print(out, int_Indent); + } + printIndent(out, int_Indent); + out << "Optional:" << std::endl; + + /* now optional ones */ + if (title.length() > 0) + { + printIndent(out, int_Indent); + out << "Title: " << title << std::endl; + } + if (comment.length() > 0) + { + printIndent(out, int_Indent); + out << "Comment: " << comment << std::endl; + } + + printEnd(out, "RsTlvFileSet", indent); + + return out; +} + + +/************************************* RsTlvFileData ************************************/ + +RsTlvFileData::RsTlvFileData() + :RsTlvItem(), file_offset(0), binData(TLV_TYPE_BIN_FILEDATA) +{ + return; +} + +void RsTlvFileData::TlvClear() +{ + file.TlvClear(); + binData.TlvClear(); + file_offset = 0; +} + + +uint16_t RsTlvFileData::TlvSize() +{ + uint32_t s = 4; /* header */ + + /* collect sizes for both uInts and data length */ + s+= file.TlvSize(); + s+= GetTlvUInt32Size(); + s+= binData.TlvSize(); + + return s; +} + + +bool RsTlvFileData::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_FILEDATA , tlvsize); + + /* add mandatory part */ + ok &= file.SetTlv(data, size, offset); + ok &= SetTlvUInt32(data,size,offset, + TLV_TYPE_UINT32_OFFSET,file_offset); + ok &= binData.SetTlv(data, size, offset); + + return ok; + + +} + +bool RsTlvFileData::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + if (size < *offset + 4) + { + return false; + } + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_FILEDATA) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + ok &= file.GetTlv(data, size, offset); + ok &= GetTlvUInt32(data,size,offset, + TLV_TYPE_UINT32_OFFSET,&file_offset); + ok &= binData.GetTlv(data, size, offset); + + return ok; + +} + +/* print it out */ +std::ostream &RsTlvFileData::print(std::ostream &out, uint16_t indent) +{ + printBase(out, "RsTlvFileData", indent); + uint16_t int_Indent = indent + 2; + + file.print(out, int_Indent); + + printIndent(out, int_Indent); + out << "FileOffset: " << file_offset; + out << std::endl; + + binData.print(out, int_Indent); + + printEnd(out, "RsTlvFileData", indent); + return out; + +} + diff --git a/libretroshare/src/serialiser/rstlvtypes.cc b/libretroshare/src/serialiser/rstlvtypes.cc new file mode 100644 index 000000000..3f354601c --- /dev/null +++ b/libretroshare/src/serialiser/rstlvtypes.cc @@ -0,0 +1,615 @@ + +/* + * libretroshare/src/serialiser: rstlvtypes.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie, Chris Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include + +#include "serialiser/rstlvbase.h" +#include "serialiser/rstlvtypes.h" +#include "serialiser/rsbaseserial.h" + +std::ostream &RsTlvItem::printBase(std::ostream &out, std::string clsName, uint16_t indent) +{ + printIndent(out, indent); + out << "RsTlvItem: " << clsName << " Size: " << TlvSize() << " ***********************"; + out << std::endl; + return out; +} + +std::ostream &RsTlvItem::printEnd(std::ostream &out, std::string clsName, uint16_t indent) +{ + printIndent(out, indent); + out << "********************** " << clsName << " *********************"; + out << std::endl; + return out; +} + +std::ostream &printIndent(std::ostream &out, uint16_t indent) +{ + for(int i = 0; i < indent; i++) + { + out << " "; + } + return out; +} + + + +/*********************************** RsTlvFileBinaryData **********************************/ + + +RsTlvBinaryData::RsTlvBinaryData(uint16_t t) + :tlvtype(t), bin_len(0), bin_data(NULL) +{ + return; +} + +bool RsTlvBinaryData::setBinData(void *data, uint16_t size) +{ + /* ready to load */ + TlvClear(); + + /* get mandatory */ + /* the rest of the TLV size binary data */ + bin_len = size; + if (bin_len == 0) + { + bin_data = NULL; + return true; + } + + bin_data = malloc(bin_len); + memcpy(bin_data, data, bin_len); + return true; +} + +void RsTlvBinaryData::TlvClear() +{ + if (bin_data) + { + free(bin_data); + } + bin_data = NULL; + bin_len = 0; +} + +uint16_t RsTlvBinaryData::TlvSize() +{ + uint32_t s = 4; /* header */ + + if (bin_data != NULL) + s += bin_len; // len is the size of data + + return s; +} + + +bool RsTlvBinaryData::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, tlvtype, tlvsize); + + /* add mandatory data */ + if ((bin_data != NULL) && (bin_len)) + { + memcpy(&(((uint8_t *) data)[*offset]), bin_data, bin_len); + *offset += bin_len; + } + return ok; +} + + + +bool RsTlvBinaryData::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + if (size < *offset + 4) + { + return false; /* not enough space to get the header */ + } + + uint16_t tlvtype_in = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvsize < 4) + { + return false; /* bad tlv size */ + } + + if (tlvtype != tlvtype_in) /* check type */ + return false; + + /* skip the header */ + (*offset) += 4; + + bool ok = setBinData(&(((uint8_t *) data)[*offset]), tlvsize - 4); + (*offset) += bin_len; + + return ok; +} + +std::ostream &RsTlvBinaryData::print(std::ostream &out, uint16_t indent) +{ + uint16_t int_Indent = indent + 2; + + uint32_t i; + std::ostringstream sout; + printIndent(sout, indent); + sout << "RsTlvBinaryData: Type: " << tlvtype << " Size: " << bin_len; + sout << std::hex; + for(i = 0; i < bin_len; i++) + { + if (i % 16 == 0) + { + sout << std::endl; + printIndent(sout, int_Indent); + } + sout << std::setw(2) << std::setfill('0') + << (int) (((unsigned char *) bin_data)[i]) << ":"; + } + sout << std::endl; + out << sout.str(); + + printEnd(out, "RsTlvBinaryData", indent); + return out; + +} + +/************************************* Peer Id Set ************************************/ + +void RsTlvPeerIdSet::TlvClear() +{ + ids.clear(); + +} + +uint16_t RsTlvPeerIdSet::TlvSize() +{ + + uint32_t s = 8; /* header + 4 for size */ + + /* determine the total size of ids strings in list */ + + std::list::iterator it; + + for(it = ids.begin(); it != ids.end() ; ++it) + { + if ((*it).length() > 0) + s += GetTlvStringSize(*it); + } + + return s; +} + +bool RsTlvPeerIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_PEERSET , tlvsize); + + /* determine the total size of ids strings in list */ + + std::list::iterator it; + + for(it = ids.begin(); it != ids.end() ; ++it) + { + if ((*it).length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_PEERID, *it); + } + + return ok; + +} + +bool RsTlvPeerIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_FILEDATA) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + int i = 0; /* temp variable to iterate through 'listed' data */ + +/* while there is TLV */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + + if (tlvsubtype = TLV_TYPE_STR_PEERID) + { + i++; + + ids.resize(i); + + ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_PEERID, *ids.rbegin()); + + + } + + if (!ok) + { + return false; + } + } + +} + + +/************************************* Service Id Set ************************************/ + +void RsTlvServiceIdSet::TlvClear() +{ + ids.clear(); + +} + +uint16_t RsTlvServiceIdSet::TlvSize() +{ + uint32_t s = 8; /* header + 4 for size */ + + /* determine the total size of ids strings in list */ + + std::list::iterator it; + + for(it = ids.begin(); it != ids.end() ; ++it) + { + if (*it > 0) + s += GetTlvUInt8Size(); + } + + return s; +} + +bool RsTlvServiceIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SERVICESET , tlvsize); + + /* determine the total size of ids strings in list */ + + std::list::iterator it; + + for(it = ids.begin(); it != ids.end() ; ++it) + { + /* if (*it > 0) + ok &= SetTlvUInt8(data, tlvend, offset, TLV_TYPE_UINT8_SERID, *it); (function needs to be implemented in rstlvbase.cc)*/ + } + + return ok; + +} + +bool RsTlvServiceIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_SERVICESET) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + int i = 0; /* temp variable to iterate through 'listed' data */ + +/* while there is TLV */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + + if (tlvsubtype = TLV_TYPE_UINT8_SERID) + { + i++; + + ids.resize(i); + + // ok &= GetTlvUint8(data, size, offset); (function needs to be implemented in rstlvbase.cc) + + + } + + if (!ok) + { + return false; + } + } + +} + +/************************************* RsTlvKeyValue ************************************/ + +void RsTlvKeyValue::TlvClear() +{ + key = ""; + value = ""; +} + +uint16_t RsTlvKeyValue::TlvSize() +{ + uint32_t s = 8; /* header + 4 for size */ + + /* first determine the total size of RstlvFileItems in list */ + + std::list::iterator it; + + /* now add comment and title length of this tlv object */ + + if (key.length() > 0) + s += GetTlvStringSize(key); + if (value.length() > 0) + s += GetTlvStringSize(value); + + return s; + +} + +bool RsTlvKeyValue::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYVALUE, tlvsize); + + + + /* now optional ones */ + if (key.length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEY, key); // no base tlv type for title? + if (value.length() > 0) + ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_VALUE, value); // no base tlv type for comment? + +return ok; + +} + +bool RsTlvKeyValue::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_KEYVALUE) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + /* while there is TLV */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + + switch(tlvsubtype) + { + case TLV_TYPE_STR_KEY: + ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEY, key); + break; + case TLV_TYPE_STR_VALUE: + ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_VALUE, value); + break; + default: + break; + + } + + if (!ok) + { + return false; + } + } + + return ok; + +} + + + +/************************************* RsTlvKeyValueSet ************************************/ + +void RsTlvKeyValueSet::TlvClear() +{ + pairs.clear(); //empty list +} + +uint16_t RsTlvKeyValueSet::TlvSize() +{ + + uint32_t s = 8; /* header + 4 for size */ + + std::list::iterator it; + + if(!pairs.empty()) + { + + for(it = pairs.begin(); it != pairs.end() ; ++it) + s += (*it).TlvSize(); + + } + + return s; +} + +bool RsTlvKeyValueSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint16_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYVALUESET , tlvsize); + + + if(!pairs.empty()) + { + std::list::iterator it; + + for(it = pairs.begin(); it != pairs.end() ; ++it) + ok &= (*it).SetTlv(data, size, offset); + + } + + +return ok; + +} + +bool RsTlvKeyValueSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_KEYVALUESET) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += 4; + + int i = 0; /* temporary variable to go through listed data*/ + + /* while there is TLV */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + + if (tlvsubtype = TLV_TYPE_KEYVALUE) + { + i++; + + pairs.resize(i); + + ok &= (*pairs.rbegin()).GetTlv(data, size, offset); + + + } + + if (!ok) + { + return false; + } + } + +} + + + +std::ostream &RsTlvPeerIdSet::print(std::ostream &out, uint16_t indent) +{ return out; } +std::ostream &RsTlvServiceIdSet::print(std::ostream &out, uint16_t indent) +{ return out; } +std::ostream &RsTlvKeyValue::print(std::ostream &out, uint16_t indent) +{ return out; } +std::ostream &RsTlvKeyValueSet::print(std::ostream &out, uint16_t indent) +{ return out; } + diff --git a/libretroshare/src/serialiser/rstlvtypes.h b/libretroshare/src/serialiser/rstlvtypes.h new file mode 100644 index 000000000..baa0be0fc --- /dev/null +++ b/libretroshare/src/serialiser/rstlvtypes.h @@ -0,0 +1,203 @@ +#ifndef RS_TLV_COMPOUND_TYPES_H +#define RS_TLV_COMPOUND_TYPES_H + +/* + * libretroshare/src/serialiser: rstlvtypes.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie, Chris Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +/******************************************************************* + * These are the Compound TLV structures that must be (un)packed. + * + ******************************************************************/ + +#include +#include + +#define RS_TLV_TYPE_FILE_ITEM 0x0000 + +class RsTlvItem +{ + public: + RsTlvItem() { return; } +virtual ~RsTlvItem() { return; } +virtual uint16_t TlvSize() = 0; +virtual void TlvClear() = 0; +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) = 0; /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset) = 0; /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent) = 0; +std::ostream &printBase(std::ostream &out, std::string clsName, uint16_t indent); +std::ostream &printEnd(std::ostream &out, std::string clsName, uint16_t indent); +}; + +std::ostream &printIndent(std::ostream &out, uint16_t indent); + +/**** GENERIC Binary Data TLV ****/ +class RsTlvBinaryData: public RsTlvItem +{ + public: + RsTlvBinaryData(uint16_t t); + virtual ~RsTlvBinaryData() { return;} +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + +bool setBinData(void *data, uint16_t size); + + uint16_t tlvtype; /* set/checked against TLV input */ + uint16_t bin_len; /* size of malloc'ed data (not serialised) */ + void *bin_data; /* manditory: */ +}; + +class RsTlvFileItem: public RsTlvItem +{ + public: + RsTlvFileItem() { return; } +virtual ~RsTlvFileItem() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + uint32_t filesize; /* Mandatory */ + std::string hash; /* Mandatory */ + std::string name; /* Optional */ + std::string path; /* Optional */ + uint32_t pop; /* Optional */ + uint32_t age; /* Optional */ +}; + +class RsTlvFileSet: public RsTlvItem +{ + public: + RsTlvFileSet() { return; } +virtual ~RsTlvFileSet() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::list items; /* Mandatory */ + std::string title; /* Optional */ + std::string comment; /* Optional */ +}; + + +class RsTlvFileData: public RsTlvItem +{ + public: + RsTlvFileData(); + virtual ~RsTlvFileData() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + RsTlvFileItem file; /* Mandatory */ + uint32_t file_offset; /* Mandatory */ + RsTlvBinaryData binData; /* Mandatory */ +}; + + +/**** MORE TLV ***** + * + * + */ + + +class RsTlvPeerIdSet: public RsTlvItem +{ + public: + RsTlvPeerIdSet() { return; } +virtual ~RsTlvPeerIdSet() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::list ids; /* Mandatory */ +}; + + +class RsTlvServiceIdSet: public RsTlvItem +{ + public: + RsTlvServiceIdSet() { return; } +virtual ~RsTlvServiceIdSet() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::list ids; /* Mandatory */ +}; + + + + +/**** MORE TLV ***** + * Key/Value + Set used for Generic Configuration Parameters. + * + */ + + +class RsTlvKeyValue: public RsTlvItem +{ + public: + RsTlvKeyValue() { return; } +virtual ~RsTlvKeyValue() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::string key; /* Mandatory */ + std::string value; /* Mandatory */ +}; + +class RsTlvKeyValueSet: public RsTlvItem +{ + public: + RsTlvKeyValueSet() { return; } +virtual ~RsTlvKeyValueSet() { return; } +virtual uint16_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::list pairs; /* Mandatory */ +}; + + + +#endif + diff --git a/libretroshare/src/serialiser/rstlvutil.cc b/libretroshare/src/serialiser/rstlvutil.cc new file mode 100644 index 000000000..c808b237e --- /dev/null +++ b/libretroshare/src/serialiser/rstlvutil.cc @@ -0,0 +1,182 @@ + +/* + * libretroshare/src/serialiser: rstlvutil.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +/* some utility functions mainly for debugging + * + * + * + */ + +/* print out a packet */ +#include +#include +#include +#include +#include + +#include "serialiser/rstlvbase.h" +#include "serialiser/rstlvtypes.h" +#include "util/utest.h" + +void displayRawPacket(std::ostream &out, void *data, uint32_t size) +{ + uint32_t i; + std::ostringstream sout; + sout << "DisplayRawPacket: Size: " << size; + sout << std::hex; + for(i = 0; i < size; i++) + { + if (i % 16 == 0) + { + sout << std::endl; + } + sout << std::setw(2) << std::setfill('0') + << (int) (((unsigned char *) data)[i]) << ":"; + } + sout << std::endl; + + out << sout.str(); +} + + +#define WHOLE_64K_SIZE 65536 + +int test_SerialiseTlvItem(std::ostream &str, RsTlvItem *in, RsTlvItem *out) +{ + uint16_t initsize = in->TlvSize(); + uint32_t serialOffset = 0; + uint32_t deserialOffset = 0; + + str << "test_SerialiseTlvItem() Testing ... Print/Serialise/Deserialise"; + str << std::endl; + + + /* some space to serialise into */ + unsigned char serbuffer[WHOLE_64K_SIZE]; + + CHECK(in->SetTlv(serbuffer, WHOLE_64K_SIZE, &serialOffset)); + + CHECK(serialOffset == initsize); /* check that the offset matches the size */ + CHECK(in->TlvSize() == initsize); /* check size hasn't changed */ + + REPORT("Serialise RsTlvItem"); + + /* now we try to read it back in! */ + CHECK(out->GetTlv(serbuffer, serialOffset, &deserialOffset)); + + /* again check sizes */ + CHECK(serialOffset == deserialOffset); + CHECK(deserialOffset == initsize); + CHECK(out->TlvSize() == initsize); + + str << "Class In/Serialised/Out!" << std::endl; + in->print(str, 0); + displayRawPacket(str, serbuffer, serialOffset); + out->print(str, 0); + + /* Can't check the actual data -> should add function */ + REPORT("DeSerialise RsTlvFileItem"); + + /* print it out */ + + + return 1; +} + +/* This function checks the TLV header, and steps on to the next one + */ + +bool test_StepThroughTlvStack(std::ostream &str, void *data, int size) +{ + uint32_t offset = 0; + uint32_t index = 0; + while (offset + 4 <= size) + { + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[offset]) ); + uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[offset]) ); + str << "Tlv Entry[" << index << "] => Offset: " << offset; + str << " Type: " << tlvtype; + str << " Size: " << tlvsize; + str << std::endl; + + offset += tlvsize; + } + CHECK(offset == size); /* we match up exactly */ + + REPORT("Step Through RsTlvStack"); + return 1; +} + + +int test_CreateTlvStack(std::ostream &str, + std::vector items, void *data, uint32_t *totalsize) +{ + /* (1) select a random item + * (2) check size -> if okay serialise onto the end + * (3) loop!. + */ + uint32_t offset = 0; + uint32_t count = 0; + + while(1) + { + int idx = (int) (items.size() * (rand() / (RAND_MAX + 1.0))); + uint32_t tlvsize = items[idx] -> TlvSize(); + + if (offset + tlvsize > *totalsize) + { + *totalsize = offset; + return count; + } + + str << "Stack[" << count << "]"; + str << " Offset: " << offset; + str << " TlvSize: " << tlvsize; + str << std::endl; + + /* serialise it */ + items[idx] -> SetTlv(data, *totalsize, &offset); + items[idx] -> print(str, 10); + count++; + } + *totalsize = offset; + return 0; +} + +int test_TlvSet(std::vector items, int maxsize) +{ + int totalsize = maxsize; + void *data = malloc(totalsize); + uint32_t size = totalsize; + + int bytes = test_CreateTlvStack(std::cerr, items, data, &size); + test_StepThroughTlvStack(std::cerr, data, size); + + return 1; +} + + diff --git a/libretroshare/src/serialiser/rstlvutil.h b/libretroshare/src/serialiser/rstlvutil.h new file mode 100644 index 000000000..87a8280ba --- /dev/null +++ b/libretroshare/src/serialiser/rstlvutil.h @@ -0,0 +1,47 @@ +#ifndef RS_TLV_UTIL_H +#define RS_TLV_UTIL_H + +/* + * libretroshare/src/serialiser: rstlvutil.h + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +/* some utility functions mainly for debugging + */ + +#include + +class RsTlvItem; + +/* print out a packet */ +void displayRawPacket(std::ostream &out, void *data, uint32_t size); +int test_SerialiseTlvItem(std::ostream &str, RsTlvItem *in, RsTlvItem *out); + +#include + +bool test_StepThroughTlvStack(std::ostream &str, void *data, int size); +int test_CreateTlvStack(std::ostream &str, + std::vector items, void *data, int totalsize); +int test_TlvSet(std::vector items, int maxsize); + +#endif diff --git a/libretroshare/src/serialiser/tlvbase_test.cc b/libretroshare/src/serialiser/tlvbase_test.cc new file mode 100644 index 000000000..5d61364fd --- /dev/null +++ b/libretroshare/src/serialiser/tlvbase_test.cc @@ -0,0 +1,184 @@ + +/* + * libretroshare/src/serialiser: tlvbase_test.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Horatio. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + + + +#include +#include +#include + +#include "serialiser/rstlvbase.h" +#include "util/utest.h" + +INITTEST(); + +static int test_RsTlvBase(); +int main() +{ + std::cerr << " RsTlvBase Tests" < +#include "serialiser/rstlvtypes.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rstlvutil.h" +#include "util/utest.h" + +INITTEST(); + +static int test_RsTlvString(); +static int test_RsTlvUInt32(); + +int main() +{ + std::cerr << "RsTlvBase Tests" << std::endl; + + test_RsTlvString(); + test_RsTlvUInt32(); + + FINALREPORT("RsTlvBase Tests"); + + return TESTRESULT(); +} + +int test_RsTlvUInt32() +{ + return 1; +} + +int test_OneString(std::string input, uint16_t type); + +int test_RsTlvString() +{ + std::string nullString; + std::string oneString = "1"; + std::string shortString = "ab cd"; + std::string longString = "abcd efgh ijkl mnop qrst uvw"; + + std::cerr << "test_RsTlvString() Testing" << std::endl; + test_OneString(nullString, 1234); + test_OneString(oneString, 12); + test_OneString(shortString, 79); + test_OneString(longString, 7654); + + REPORT("Serialise RsTlvFileItem"); + + return 1; +} + + +int test_OneString(std::string input, uint16_t type) +{ + /* an array to work from */ + char tlvdata[2048]; + std::string OutString; + + std::cerr << "test_OneString() Testing ... Print/Serialise/Deserialise"; + /* start with SetTlvString() */ + + uint16_t initsize = GetTlvStringSize(input); + uint32_t outOffset = 0; + uint32_t inOffset = 0; + + std::cerr << "Serialising: " << input << std::endl; + CHECK(SetTlvString((void*)tlvdata, 2048, &outOffset, type, input)); + std::cerr << "Init Size: " << initsize << std::endl; + std::cerr << "Serialised Size: " << outOffset << std::endl; + displayRawPacket(std::cerr, tlvdata, outOffset); + + CHECK(outOffset == initsize); /* check that the offset matches the size */ + + std::cerr << "DeSerialising" << std::endl; + + /* fails if type is wrong! */ + CHECK(0 == GetTlvString((void*)tlvdata, outOffset, &inOffset, type-1, OutString)); + CHECK(GetTlvString((void*)tlvdata, outOffset, &inOffset, type, OutString)); + + CHECK(initsize == inOffset); /* check that the offset matches the size */ + CHECK(input == OutString); /* check that strings match */ + std::cerr << "Deserialised: Size: " << inOffset << std::endl; + std::cerr << "Deserialised: String: " << OutString << std::endl; + + REPORT("Serialise OneString"); + + return 1; +} + + + diff --git a/libretroshare/src/serialiser/tlvfileitem_test.cc b/libretroshare/src/serialiser/tlvfileitem_test.cc new file mode 100644 index 000000000..50ed423a9 --- /dev/null +++ b/libretroshare/src/serialiser/tlvfileitem_test.cc @@ -0,0 +1,190 @@ + +/* + * libretroshare/src/serialiser: tlvfileitem_test.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +/****************************************************************** + * tlvfileitem test. + * + * + */ + +#include +#include +#include "serialiser/rstlvtypes.h" +#include "serialiser/rstlvutil.h" +#include "util/utest.h" + +INITTEST(); + +static int test_RsTlvFileItem(); +static int test_RsTlvFileSet(); +static int test_RsTlvFileData(); +static int test_RsTlvFileStack(); + +int main() +{ + std::cerr << "RsTlvFile[Item/Data/...] Tests" << std::endl; + + test_RsTlvFileItem(); + test_RsTlvFileData(); + test_RsTlvFileSet(); + + FINALREPORT("RsTlvFile[Item/Data/...] Tests"); + + return TESTRESULT(); +} + +int test_RsTlvFileItem() +{ + RsTlvFileItem i1; + RsTlvFileItem i2; + + /* initialise */ + i1.filesize = 101010; + i1.hash = "ABCDEFEGHE"; + i1.name = "TestFile.txt"; + i1.pop = 12; + i1.age = 456; + + CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); + + /* check the data is the same */ + CHECK(i1.filesize == i2.filesize); + CHECK(i1.hash == i2.hash); + CHECK(i1.name == i2.name); + CHECK(i1.path == i2.path); + CHECK(i1.pop == i2.pop); + CHECK(i1.age == i2.age); + + /* do it again without optional data */ + i1.filesize = 123; + i1.name = ""; + i1.pop = 0; + i1.age = 0; + + CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); + + /* check the data is the same */ + CHECK(i1.filesize == i2.filesize); + CHECK(i1.hash == i2.hash); + CHECK(i1.name == i2.name); + CHECK(i1.path == i2.path); + CHECK(i1.pop == i2.pop); + CHECK(i1.age == i2.age); + + /* one more time - long file name, some optional data */ + i1.filesize = 123; + i1.name = "A Very Long File name that should fit in easily ??? with som $&%&^%* strange char (**$^%#&^$#*^%(&^ in there too!!!! ~~~!!$#(^$)$)(&%^)&\" oiyu thend"; + i1.pop = 666; + i1.age = 0; + + CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); + + /* check the data is the same */ + CHECK(i1.filesize == i2.filesize); + CHECK(i1.hash == i2.hash); + CHECK(i1.name == i2.name); + CHECK(i1.path == i2.path); + CHECK(i1.pop == i2.pop); + CHECK(i1.age == i2.age); + + REPORT("Serialise/Deserialise RsTlvFileItem"); + + return 1; +} + +int test_RsTlvFileSet() +{ + RsTlvFileSet s1; + RsTlvFileSet s2; + + int i = 0; + for(i = 0; i < 15; i++) + { + RsTlvFileItem fi; + fi.filesize = 16 + i * i; + fi.hash = "ABCDEF"; + std::ostringstream out; + out << "File" << i << "_inSet.txt"; + fi.name = out.str(); + if (i % 2 == 0) + { + fi.age = 10 * i; + } + else + { + fi.age = 0; + } + fi.pop = 0; + + s1.items.push_back(fi); + } + + CHECK(test_SerialiseTlvItem(std::cerr, &s1, &s2)); + + /* check the data is the same - TODO */ + + REPORT("Serialise/Deserialise RsTlvFileSet"); + + return 1; +} + + +int test_RsTlvFileData() +{ + RsTlvFileData d1; + RsTlvFileData d2; + + /* initialise */ + d1.file.filesize = 101010; + d1.file.hash = "ABCDEFEGHE"; + d1.file.name = ""; + d1.file.age = 0; + d1.file.pop = 0; + + char data[15]; + d1.binData.setBinData(data, 15); + + d1.file_offset = 222; + + CHECK(test_SerialiseTlvItem(std::cerr, &d1, &d2)); + + /* check the data is the same */ + CHECK(d1.file.filesize == d2.file.filesize); + CHECK(d1.file.hash == d2.file.hash); + CHECK(d1.file.name == d2.file.name); + CHECK(d1.file.path == d2.file.path); + CHECK(d1.file.pop == d2.file.pop); + CHECK(d1.file.age == d2.file.age); + + CHECK(d1.file_offset == d2.file_offset); + CHECK(d1.binData.bin_len == d2.binData.bin_len); + + REPORT("Serialise/Deserialise RsTlvFileData"); + + return 1; +} + + diff --git a/libretroshare/src/serialiser/tlvitems_test.cc b/libretroshare/src/serialiser/tlvitems_test.cc new file mode 100644 index 000000000..7b34b597b --- /dev/null +++ b/libretroshare/src/serialiser/tlvitems_test.cc @@ -0,0 +1,88 @@ + +/* + * libretroshare/src/serialiser: tlvitems_test.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +/****************************************************************** + * tlvfileitem test. + * + * + */ + +#include +#include "serialiser/rstlvtypes.h" +#include "serialiser/rstlvutil.h" +#include "util/utest.h" + +INITTEST(); + +static int test_RsTlvBinData(); +static int test_RsTlvStepping(); + +int main() +{ + std::cerr << "RsTlvItems Tests" << std::endl; + + test_RsTlvBinData(); + + FINALREPORT("RsTlvItems Tests"); + + return TESTRESULT(); +} + +#define BIN_LEN 523456 /* bigger than 64k */ + +int test_RsTlvBinData() +{ + RsTlvBinaryData d1(1023); + RsTlvBinaryData d2(1023); + + char data[BIN_LEN] = {0}; + int i, j; + for(i = 0; i < BIN_LEN; i++) + { + data[i] = i%13; + } + + for(j = 1; j < BIN_LEN; j *= 2) + { + d1.setBinData(data, j); + CHECK(test_SerialiseTlvItem(std::cerr, &d1, &d2)); + + CHECK(d1.bin_len == d2.bin_len); + CHECK(0 == memcmp(d1.bin_data, d2.bin_data, d1.bin_len)); + } + + REPORT("Serialise/Deserialise RsTlvBinData"); + + return 1; +} + +int test_RsTlvStepping() +{ + + + return 1; +} + diff --git a/libretroshare/src/serialiser/tlvstack_test.cc b/libretroshare/src/serialiser/tlvstack_test.cc new file mode 100644 index 000000000..fe174f37e --- /dev/null +++ b/libretroshare/src/serialiser/tlvstack_test.cc @@ -0,0 +1,104 @@ + +/* + * libretroshare/src/serialiser: tlvstack_test.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +/****************************************************************** + * tlvfileitem test. + * + * + */ + +#include +#include "serialiser/rstlvtypes.h" +#include "serialiser/rstlvutil.h" +#include "util/utest.h" + +INITTEST(); + +static int test_RsTlvStack(); + +int main() +{ + std::cerr << "RsTlvItem Stack Tests" << std::endl; + + test_RsTlvStack(); + + FINALREPORT("RsTlvItem Stack Tests"); + + return TESTRESULT(); +} + + +#define BIN_LEN 53 + +int test_RsTlvStack() +{ + + /* now create a set of TLV items for the random generator */ + + RsTlvBinaryData *bd1 = new RsTlvBinaryData(123); + RsTlvBinaryData *bd2 = new RsTlvBinaryData(125); + + char data[BIN_LEN] = {0}; + int i; + for(i = 0; i < BIN_LEN; i++) + { + data[i] = i%13; + } + + bd1->setBinData(data, 5); + bd2->setBinData(data, 21); + + RsTlvFileItem *fi1 = new RsTlvFileItem(); + RsTlvFileItem *fi2 = new RsTlvFileItem(); + + /* initialise */ + fi1->filesize = 101010; + fi1->hash = "ABCDEFEGHE"; + fi1->name = "TestFile.txt"; + fi1->pop = 12; + fi1->age = 456; + + fi2->filesize = 101010; + fi2->hash = "ABCDEFEGHE"; + fi2->name = "TestFile.txt"; + fi2->pop = 0; + fi2->age = 0;; + + std::vector items; + items.resize(4); + items[0] = bd1; + items[1] = bd2; + items[2] = fi1; + items[3] = fi2; + + test_TlvSet(items, 1024); + + REPORT("Serialise/Deserialise RsTlvBinData"); + + return 1; +} + + diff --git a/libretroshare/src/util/exampletst.c b/libretroshare/src/util/exampletst.c new file mode 100644 index 000000000..e96cd037e --- /dev/null +++ b/libretroshare/src/util/exampletst.c @@ -0,0 +1,40 @@ + +#include "utest.h" + +#include + +/* must define the global variables */ +INITTEST(); + +int main(int argc, char **argv) +{ + int a = 2; + int b = 3; + int c = 2; + + CHECK( a == c ); + + REPORT( "Initial Tests"); + + CHECK( (0 == strcmp("123", "123")) ); + + REPORT( "Successful Tests"); + + CHECK( a == b ); + CHECK( (0 == strcmp("123", "12345")) ); + + REPORT( "Failed Tests" ); + + CHECK( 1 ); + CHECK( a == c ); + + REPORT( "Later Successful Tests"); + + + FINALREPORT( "Example Tests" ); + + return TESTRESULT(); +} + + + diff --git a/libretroshare/src/util/utest.h b/libretroshare/src/util/utest.h new file mode 100644 index 000000000..1ebd9875a --- /dev/null +++ b/libretroshare/src/util/utest.h @@ -0,0 +1,23 @@ +#ifndef _UNIT_TEST_MACROS_H__ +#define _UNIT_TEST_MACROS_H__ + +#include + +#define TFAILURE( s ) printf( "FAILURE: " __FILE__ ":%-4d %s\n", __LINE__, s ) +#define TSUCCESS( s ) printf( "SUCCESS: " __FILE__ ":%-4d %s\n", __LINE__, s ) + +/* careful with this line (no protection) */ +#define INITTEST() int ok = 1; int gok = 1; + +/* declare the variables */ +extern int ok; +extern int gok; + +#define CHECK( b ) do { if ( ! (b) ) { ok = 0; TFAILURE( #b ); } } while(0) +#define FAILED( s ) do { ok = 0; TFAILURE( s ); } while(0) +#define REPORT( s ) do { if ( ! (ok) ) { ok = 0; TFAILURE( s ); } else { TSUCCESS( s );} gok &= ok; ok = 1; } while(0) +#define REPORT2( b, s ) do { if ( ! (b) ) { ok = 0; TFAILURE( s ); } else { TSUCCESS( s );} gok &= ok; ok = 1; } while(0) +#define FINALREPORT( s ) do { gok &= ok; ok = 1; if ( ! (gok) ) { TFAILURE( s ); } else { TSUCCESS( s );} } while(0) +#define TESTRESULT() (!gok) + +#endif