From 54d746e3f342a5105c478e0173fc6f2b2daddd7b Mon Sep 17 00:00:00 2001 From: Jim Kowalkowski Date: Tue, 25 Jun 1996 19:11:52 +0000 Subject: [PATCH] new in EPICS base --- src/gdd/MAKE_TAR_FILE | 11 + src/gdd/Makefile | 22 + src/gdd/Makefile.Unix | 76 ++ src/gdd/Makefile.standalone | 251 +++++++ src/gdd/README | 123 ++++ src/gdd/aitConvert.cc | 109 +++ src/gdd/aitConvert.h | 137 ++++ src/gdd/aitGen.c | 439 ++++++++++++ src/gdd/aitHelpers.cc | 60 ++ src/gdd/aitHelpers.h | 217 ++++++ src/gdd/aitTypes.c | 64 ++ src/gdd/aitTypes.h | 133 ++++ src/gdd/dbMapper.cc | 1294 +++++++++++++++++++++++++++++++++++ src/gdd/dbMapper.h | 59 ++ src/gdd/gdd.cc | 1225 +++++++++++++++++++++++++++++++++ src/gdd/gdd.h | 1145 +++++++++++++++++++++++++++++++ src/gdd/gddAppDefs.cc | 253 +++++++ src/gdd/gddAppTable.cc | 528 ++++++++++++++ src/gdd/gddAppTable.h | 194 ++++++ src/gdd/gddErrorCodes.h | 32 + src/gdd/gddNewDel.cc | 49 ++ src/gdd/gddNewDel.h | 125 ++++ src/gdd/gddTest.cc | 499 ++++++++++++++ src/gdd/gddUtils.h | 91 +++ src/gdd/genApps.cc | 51 ++ src/gdd/vxldscript.MRI | 21 + 26 files changed, 7208 insertions(+) create mode 100755 src/gdd/MAKE_TAR_FILE create mode 100644 src/gdd/Makefile create mode 100644 src/gdd/Makefile.Unix create mode 100644 src/gdd/Makefile.standalone create mode 100644 src/gdd/README create mode 100644 src/gdd/aitConvert.cc create mode 100644 src/gdd/aitConvert.h create mode 100644 src/gdd/aitGen.c create mode 100644 src/gdd/aitHelpers.cc create mode 100644 src/gdd/aitHelpers.h create mode 100644 src/gdd/aitTypes.c create mode 100644 src/gdd/aitTypes.h create mode 100644 src/gdd/dbMapper.cc create mode 100644 src/gdd/dbMapper.h create mode 100644 src/gdd/gdd.cc create mode 100644 src/gdd/gdd.h create mode 100644 src/gdd/gddAppDefs.cc create mode 100644 src/gdd/gddAppTable.cc create mode 100644 src/gdd/gddAppTable.h create mode 100644 src/gdd/gddErrorCodes.h create mode 100644 src/gdd/gddNewDel.cc create mode 100644 src/gdd/gddNewDel.h create mode 100644 src/gdd/gddTest.cc create mode 100644 src/gdd/gddUtils.h create mode 100644 src/gdd/genApps.cc create mode 100644 src/gdd/vxldscript.MRI diff --git a/src/gdd/MAKE_TAR_FILE b/src/gdd/MAKE_TAR_FILE new file mode 100755 index 000000000..0c266b24c --- /dev/null +++ b/src/gdd/MAKE_TAR_FILE @@ -0,0 +1,11 @@ +# $Id$ +# $Log$ +# +# *Revision 1.2 1996/06/24 03:15:25 jbk +# *name changes and fixes for aitString and fixed string functions +# *Revision 1.1 1996/05/31 13:15:12 jbk +# *add new stuff +# + +tar zcvf /tmp/gdd.tar.gz *.c *.cc *.h *.MRI Makefile* MAKE* README + diff --git a/src/gdd/Makefile b/src/gdd/Makefile new file mode 100644 index 000000000..cf41ec043 --- /dev/null +++ b/src/gdd/Makefile @@ -0,0 +1,22 @@ +# +# Author: Jim Kowalkowski +# Date: 2/96 +# +# $Id$ +# +# $Log$ +# +# *Revision 1.2 1996/06/25 18:58:55 jbk +# *more fixes for the aitString management functions and mapping menus +# *Revision 1.1 1996/05/31 13:15:13 jbk +# *add new stuff +# +# + +EPICS=../../.. +# EPICS=/usr/local/epics/R3.12.2 + +include $(EPICS)/config/CONFIG_EXTENSIONS + +include $(EPICS)/config/RULES_ARCHS + diff --git a/src/gdd/Makefile.Unix b/src/gdd/Makefile.Unix new file mode 100644 index 000000000..269923239 --- /dev/null +++ b/src/gdd/Makefile.Unix @@ -0,0 +1,76 @@ +# +# Author: Jim Kowalkowski +# Date: 2/96 +# +# $Id$ +# +# $Log$ +# +# *Revision 1.4 1996/06/25 18:58:56 jbk +# *more fixes for the aitString management functions and mapping menus +# *Revision 1.3 1996/06/24 03:15:26 jbk +# *name changes and fixes for aitString and fixed string functions +# *Revision 1.2 1996/06/11 01:55:18 jbk +# *completed ful build +# *Revision 1.1 1996/05/31 13:15:14 jbk +# *add new stuff + +VPATH=.:.. + +EPICS = ../../../.. +# EPICS = /usr/local/epics/R3.12.2 + +include Target.include +include $(EPICS)/config/CONFIG_EXTENSIONS + +OPTIM_YES=-g +ifeq ($(HOST_ARCH),sun4) +CCC=purify CC +CC=purify acc +endif + +DEPENDS_RULE.cc = -$(COMPILE.cc) -xM $(SRCS.cc) >> .DEPENDS + +USR_LDFLAGS = -L$(EPICS_EXTENSIONS_LIB) -L. +USR_CFLAGS = -L$(EPICS_EXTENSIONS_LIB) -L. + +SRCS.cc = ../aitGen.c ../aitTypes.c ../aitHelpers.cc \ + ../gdd.cc ../gddAppDefs.cc ../gddAppTable.cc ../gddNewDel.cc \ + ../gddTest.cc ../genApps.cc + # ../dbMapper.cc + +LIBOBJS = gdd.o gddTest.o gddAppTable.o gddNewDel.o gddAppDefs.o \ + aitTypes.o aitConvert.o aitHelpers.o + # dbMapper.o + +LIBNAME = libgdd.a + +TARGETS = dbMapper.o + +# cannot generate dependencies for aitConvert automatically + +aitConvert.o: aitConvert.cc aitConvert.h aitConvertGenerated.cc aitTypes.h + +aitConvertGenerated.cc: aitGen aitTypes.h + aitGen + +aitGen: aitGen.o aitTypes.o + $(LINK.c) -o $@ $^ $(LDLIBS) + +# cannot generate dependencies for dbMapper.o automatically + +dbMapper.o: ../dbMapper.cc gdd.h gddAppTable.h dbMapper.h gddApps.h aitTypes.h + $(COMPILE.cc) $< + $(AR) r $(LIBNAME) $@ + +gddApps.h: genApps + genApps $@ + +genApps: genApps.o $(LIBOBJS) + $(LINK.cc) -o $@ $^ $(LDLIBS) + +clean:: + /bin/rm -f aitConvertGenerated.cc aitGen genApps + +include $(EPICS)/config/RULES.Unix + diff --git a/src/gdd/Makefile.standalone b/src/gdd/Makefile.standalone new file mode 100644 index 000000000..0dba5dbbc --- /dev/null +++ b/src/gdd/Makefile.standalone @@ -0,0 +1,251 @@ +# +# Author: Jim Kowalkowski +# Date: 2/96 +# +# $Id$ +# +# $Log$ +# + +# Simple build system for all the platforms I've tested on + +VPATH=.:.. + +# ifdef IN_OBJ_DIR +# ifeq ($(VX_BUILD),vw) +# CCTYPE = $(VX_BUILD) +# else +# CCTYPE = $(HOST_ARCH) +# endif +# +# else +ifdef HOST_ARCH +CCTYPE = $(HOST_ARCH) +else +# CCTYPE = solaris +# CCTYPE = sun4 +# CCTYPE = linux +# CCTYPE = hp700 +# CCTYPE = vw +# VX_BUILD = vw +endif +# endif + +ifeq ($(CCTYPE),vw) + +GNU_DIR = /home/phoebus/HIDEOS/gnu_install +# GNU_DIR = /home/hideos/gnu_install +GNU_BIN = $(GNU_DIR)/bin +VERBOSE = -Wall -Winline +OPTIM = -O # -DNO_DUMP_TEST -g +VX_DIR = /usr/local/vw/vxV52/vw +VX_INCLUDE = $(VX_DIR)/h + +ifeq ($(CCTYPE),sun4) +CC_NORMAL = acc +else +CC_NORMAL = cc +endif + +CC = $(GNU_BIN)/sun3-gcc +CCC = $(GNU_BIN)/sun3-g++ +LD = $(GNU_BIN)/sun3-ld +AR = $(GNU_BIN)/sun3-ar +RANLIB = $(GNU_BIN)/sun3-ranlib + +LIB_FLAGS = +LDFLAGS = -L. -r -N -T../vxldscript.MRI +CCFLAGS = -B$(GNU_DIR)/lib/gcc-lib/ $(OPTIM) -W \ + $(VERBOSE) -nostdinc --no-builtin -m68040 -Wa,"-m68040" \ + -DCPU_FAMILY=MC680X0 -DCPU=MC68040 -DvxWorks -DV5_vxWorks \ + -I. -I.. -I$(VX_INCLUDE) + +else + +ifeq ($(CCTYPE),solaris) +VERBOSE = +w -D__EXTENSIONS__ +CC = cc +CCC = CC +CC_NORMAL = $(CC) +LIB_FLAGS = # -lposix4 +POSIX_LEVEL = 2 # 4 +EPICS = /home/phoebus/JBK/test3.12/include +RANLIB = echo +endif + +ifeq ($(CCTYPE),sun4) +VERBOSE = +CC=purify acc +CCC=purify CC +# CCC = CC +# CC = acc +CC_NORMAL = acc +LIB_FLAGS = +POSIX_LEVEL = 2 +EPICS = /home/phoebus/JBK/test3.12/include +RANLIB = ranlib +endif + +ifeq ($(CCTYPE),linux) +VERBOSE = -Wall -Winline +CC = gcc +CCC = g++ +CC_NORMAL = $(CC) +LIB_FLAGS = +POSIX_LEVEL = 2 +EPICS = /home/jbk/include +RANLIB = ranlib +endif + +ifeq ($(CCTYPE),hp700) +VERBOSE = +CC = c89 -Aa +CCC = CC +a1 +CC_NORMAL = $(CC) +LIB_FLAGS = +POSIX_LEVEL = 2 +RANLIB = ranlib +endif + +LD = ld +AR = ar + +# -p is for profiling +OPTIM = -g # -O -p +COMP_FLAGS = -D_POSIX_C_SOURCE=$(POSIX_LEVEL) -D$(CCTYPE) +BOTH_FLAGS = -I. -I.. $(VERBOSE) $(OPTIM) -I$(EPICS) $(COMP_FLAGS) +LDFLAGS = $(BOTH_FLAGS) -L. +CCFLAGS = $(BOTH_FLAGS) + +endif + +CXXFLAGS = $(CCFLAGS) +CFLAGS = $(CXXFLAGS) +CXX = $(CCC) + +DEPLIB = libgdd_t.a +DEST_DEPLIB = libgdd.a +LIBFLAGS = -lgdd $(LIB_FLAGS) +LIBFLAGS_T = -lgdd_t $(LIB_FLAGS) + +# modules that go into the library +SRCS = gdd.cc gddTest.cc aitConvert.cc gddAppTable.cc gddNewDel.cc \ + gddAppDefs.cc aitTypes.c +OBJS = gdd.o gddTest.o aitConvert.o gddAppTable.o gddNewDel.o \ + gddAppDefs.o aitTypes.o +INCS = gdd.h aitConvert.h aitTypes.h gddNewDel.h gddUtils.h + +# ----------------------------- +ifndef HOST_ARCH +problem: + @echo "you must set the HOST_ARCH environment variable" + @echo "set VX_BUILD=vw to build for vxWorks" +endif + +# ----------------------------- +ifndef IN_OBJ_DIR +ifdef VX_BUILD +first_rule: $(HOST_ARCH)/Makefile $(VX_BUILD)/Makefile +else +first_rule: $(HOST_ARCH)/Makefile +endif + (cd $(HOST_ARCH); gnumake all) +ifdef VX_BUILD + (HOST_ARCH=$(VX_BUILD); cd $(VX_BUILD); gnumake HOST_ARCH=$(VX_BUILD)) + # (HOST_ARCH=$(VX_BUILD); gnumake HOST_ARCH=$(VX_BUILD)) +endif + +$(HOST_ARCH)/Makefile: Makefile + if [ ! -d "$(HOST_ARCH)" ]; \ + then \ + mkdir $(HOST_ARCH); \ + fi + echo "IN_OBJ_DIR=1" > $@ + cat $< >> $@ + +ifdef VX_BUILD +$(VX_BUILD)/Makefile: Makefile + if [ ! -d "$(VX_BUILD)" ]; \ + then \ + mkdir $(VX_BUILD); \ + fi + echo "IN_OBJ_DIR=1" > $@ + cat $< >> $@ +endif +endif + +# ----------------------------- +all: aitGen gddApps.h $(DEPLIB) dbMapper.o $(DEST_DEPLIB) + +check_arch: + @echo "architecture=$(CCTYPE)" + +$(DEST_DEPLIB): $(DEPLIB) + cp $^ $@ + +# ----------------------------- +$(DEPLIB): $(OBJS) + /bin/rm -f $@ + $(AR) r $@ $^ + cp $@ $(DEST_DEPLIB) +ifeq ($(CCTYPE),sun4) + $(RANLIB) $@ + $(RANLIB) $(DEST_DEPLIB) +endif +ifeq ($(CCTYPE),vw) + $(RANLIB) $@ + $(RANLIB) $(DEST_DEPLIB) +endif + +# ----------------------------- +ifneq ($(CCTYPE),vw) +genApps: genApps.o $(OBJS) $(DEPLIB) + $(CCC) $(LDFLAGS) -o $@ $< $(LIBFLAGS_T) + +gddApps.h: genApps + $< gddApps.h + cp gddApps.h .. + +genApps.o: genApps.cc gddAppTable.h aitTypes.h $(INCS) + +else +genApps: + @echo "Not going to build $@ for vw" +endif + +aitGen: aitGen.o aitTypes.o + $(CC_NORMAL) -O -o $@ $^ + +aitGen.o: aitGen.c aitTypes.h + $(CC_NORMAL) -D$(CCTYPE) -O -c -I. $< + +aitConvertGenerated.cc: aitGen aitTypes.h aitConvert.h aitConvert.cc aitTypes.c + aitGen + +# ----------------------------- +gdd.o: gdd.cc $(INCS) +gddTest.o: gddTest.cc $(INCS) +gddNewDel.o: gddNewDel.cc gddNewDel.h gddUtils.h +gddAppTable.o: gddAppTable.cc gddAppTable.h $(INCS) +gddAppDefs.o: gddAppDefs.cc gddAppTable.h $(INCS) +aitTypes.o: aitTypes.c aitTypes.h +aitConvert.o: aitConvert.cc aitConvertGenerated.cc aitConvert.h aitTypes.h + +dbMapper.o: dbMapper.cc dbMapper.h gddApps.h + $(CCC) $(CCFLAGS) -c $< +ifeq ($(CCTYPE),solaris) + # $(CCC) -xar -o $(DEST_DEPLIB) $(CCFLAGS) $< + # $(CCC) -xar -o $(DEST_DEPLIB) $(CCFLAGS) $@ +endif + $(AR) r $(DEST_DEPLIB) $@ + $(RANLIB) $(DEST_DEPLIB) + +ifdef IN_OBJ_DIR +clean: + /bin/rm -f *.o *.a aitGen genApps + /bin/rm -f *pure* p.out mon.out + /bin/rm -rf Templates.DB ptrepository +else +clean: + /bin/rm -rf $(HOST_ARCH) $(VX_BUILD) gddApps.h +endif diff --git a/src/gdd/README b/src/gdd/README new file mode 100644 index 000000000..21e9fe4a9 --- /dev/null +++ b/src/gdd/README @@ -0,0 +1,123 @@ +# +# Author: Jim Kowalkowski +# Date: 2/96 +# +# $Id$ +# +# $Log$ +# Revision 1.4 1996/06/25 18:58:57 jbk +# more fixes for the aitString management functions and mapping menus +# +# Revision 1.3 1996/06/24 03:15:27 jbk +# name changes and fixes for aitString and fixed string functions +# +# Revision 1.2 1996/06/13 21:31:51 jbk +# Various fixes and correction - including ref_cnt change to unsigned short +# +# Revision 1.1 1996/05/31 13:15:16 jbk +# add new stuff +# +# + +Some Notes: + +****** +The following function described in gddAppTable.h and defined in gddAppDefs.cc: + + gddApplicationTypeTable* gddGenerateApplicationTypeTable(void); + +is designed to be called in an application to create the type table +with a default set of attributes already registered. The current mechanism +for generating the default registered attributes is the C++ code in +gddAppDefs.cc. See this file for a list of registered attributes. + +Creating am application type table using new will perform the same function. + +****** +The gddCleanUp object will automatically clean up the free list storage +when it is destructed. There should only be one of these in an application. +It is not required. + +****** +To build for vxWorks, define an environment variable "VX_BUILD=vw" and type +make. It will build for the HOST_ARCH architecture and then vxWorks. + +You must have gcc/g++ 2.5.8 or later available to cross compile to 68k object +code and vxWorks. You can get the gcc 2.5.8 package from the HiDEOS home +page along with instructions on building it. + +The vxldscript.MRI file instructs the gnu loader on how to propare +object files to load under vxWorks. + +You must use the ldpp program under vxWorks shell to load g++ generated +object modules. The ldpp program is available in the EPICS base package. +Contact me if you want a copy of it. + +It is really not difficult to get g++ object files to load under vxWorks +or to get the g++ compiled installed and running. The makefile is set up +to handle builds for vxWorks. + +****** +aitTypes.h: Definitions of the architecture independant types. +aitTypes.c: definitions of several lookup tables +aitConvert.h: conversion table description,byte ordering routines +aitConvert.c: conversion information not generated +aitGen.c: creates the general conversion functions +aitConvertGenerated.c: file of generated conversion functions + +dbMapper.cc: mappings from DBR types to ait types and GDDs +dbMapper.h: mappings from DBR types to ait types and GDDs + +gddApps.h: + This file contains "#define" statements for quick indexing into + managed containers. Generated by program genApps.cc. + +******* +Still needed: + +1) AppTable method to map application type to offset (index) into a + managed container. +* mostly complete + +2) Function to map DBRxxxx types to Application types and back. +* still working on mapping method + +3) Methods for managing network byte order conversions in gdd class. + +4) Method to extract data (and bounds information) from a gdd into a + user's buffer. + +6) #defines to remove extra checks and make the programs run faster. + +************ 6/13/96 ************* + +ref_cnt should be an unsigned short instead of char + +menus need to be fixed - use aitFixedString or aitString + +get/operator=() should be smarter, do conversion if types do not match + +************ 6/20/96 ************** + +fix the flatten functions so they work properly with aitString and fixed +string + +fix the aitString class, add the install string method and change others + +*********** 6/21/96 ************ + +fixe the aitString::compact function, and all other stuff that works with +string info so that if the string that the aitString is holding is NULL, +then the system will act correctly. The flatten functions have trouble +with this when the described string is NULL. + +*********** 6/24/96 ************* + +still need to fix the transfer of aitString data into a pre-made gdd. +If only array of 5 aitString is placed into a pre-made array of 16, +then the last 11 should be initialized to NULLs or something, same for +fixed string - especially the fixed string + +Jim + + diff --git a/src/gdd/aitConvert.cc b/src/gdd/aitConvert.cc new file mode 100644 index 000000000..46d9b3ee4 --- /dev/null +++ b/src/gdd/aitConvert.cc @@ -0,0 +1,109 @@ + +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// +// *Revision 0.4 1996/06/25 18:58:58 jbk +// *more fixes for the aitString management functions and mapping menus +// *Revision 0.3 1996/06/24 03:15:28 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 0.2 1996/06/17 15:24:04 jbk +// *many mods, string class corrections. +// *gdd operator= protection. +// *dbmapper uses aitString array for menus now +// *Revision 0.1 1996/05/31 13:15:17 jbk +// *add new stuff + +#define AIT_CONVERT_SOURCE 1 +#include +#include +#include "aitConvert.h" + +extern "C" { +void aitNoConvert(void* /*dest*/,const void* /*src*/,aitIndex /*count*/) { } +} + +#ifdef AIT_CONVERT +#undef AIT_CONVERT +#endif +#ifdef AIT_TO_NET_CONVERT +#undef AIT_TO_NET_CONVERT +#endif +#ifdef AIT_FROM_NET_CONVERT +#undef AIT_FROM_NET_CONVERT +#endif + +/* put the fixed conversion functions here (ones not generated) */ + +/* ------- extra string conversion functions --------- */ +static void aitConvertStringString(void* d,const void* s,aitIndex c) +{ + // does not work - need to be fixed + int i; + aitString *in=(aitString*)s, *out=(aitString*)d; + + for(i=0;i +#include +#include "aitTypes.h" + +#if defined(__i386) || defined(i386) +#define AIT_NEED_BYTE_SWAP 1 +#endif + +/* all conversion functions have this prototype */ +typedef void (*aitFunc)(void* dest,const void* src,aitIndex count); + +#ifdef __cplusplus +extern "C" { +#endif + +/* main conversion table */ +extern aitFunc aitConvertTable[aitTotal][aitTotal]; +/* do not make conversion table if not needed */ +#ifdef AIT_NEED_BYTE_SWAP +extern aitFunc aitConvertToNetTable[aitTotal][aitTotal]; +extern aitFunc aitConvertFromNetTable[aitTotal][aitTotal]; +#else +#define aitConvertToNetTable aitConvertTable +#define aitConvertFromNetTable aitConvertTable +#endif /* AIT_NEED_BYTE_SWAP */ + +#ifdef __cplusplus +} +#endif + +/* ---------- convenience routines for performing conversions ---------- */ + +#if defined(__cplusplus) && !defined(__GNUC__) + +inline void aitConvert(aitEnum desttype, void* dest, + aitEnum srctype, const void* src, aitIndex count) + { aitConvertTable[desttype][srctype](dest,src,count); } + +inline void aitConvertToNet(aitEnum desttype, void* dest, + aitEnum srctype, const void* src, aitIndex count) + { aitConvertToNetTable[desttype][srctype](dest,src,count); } + +inline void aitConvertFromNet(aitEnum desttype, void* dest, + aitEnum srctype, const void* src, aitIndex count) + { aitConvertFromNetTable[desttype][srctype](dest,src,count); } + +#else + +#define aitConvert(DESTTYPE,DEST,SRCTYPE,SRC,COUNT) \ + aitConvertTable[DESTTYPE][SRCTYPE](DEST,SRC,COUNT) + +#define aitConvertToNet(DESTTYPE,DEST,SRCTYPE,SRC,COUNT) \ + aitConvertToNetTable[DESTTYPE][SRCTYPE](DEST,SRC,COUNT) + +#define aitConvertFromNet(DESTTYPE,DEST,SRCTYPE,SRC,COUNT) \ + aitConvertFromNetTable[DESTTYPE][SRCTYPE](DEST,SRC,COUNT) + +#endif + +/* ----------- byte order conversion definitions ------------ */ + +#define aitUint64 aitUint32 + +#if defined(__cplusplus) && !defined(__GNUC__) + +inline void aitToNetOrder16(aitUint16* dest,aitUint16* src) + { *dest=htons(*src); } +inline void aitToNetOrder32(aitUint32* dest,aitUint32* src) + { *dest=htonl(*src); } +inline void aitFromNetOrder16(aitUint16* dest,aitUint16* src) + { *dest=ntohs(*src); } +inline void aitFromNetOrder32(aitUint32* dest,aitUint32* src) + { *dest=ntohl(*src); } +inline void aitToNetOrder64(aitUint64* dest, aitUint64* src) +{ + aitUint32 ait_temp_var_; + ait_temp_var_=(aitUint32)htonl(src[1]); + dest[1]=(aitUint32)htonl(src[0]); + dest[0]=ait_temp_var_; +} +inline void aitFromNetOrder64(aitUint64* dest, aitUint64* src) +{ + aitUint32 ait_temp_var_; + ait_temp_var_=(aitUint32)ntohl(src[1]); + dest[1]=(aitUint32)ntohl(src[0]); + dest[0]=ait_temp_var_; +} + +#else + +/* !The following generate code! */ +#define aitToNetOrder16(dest,src) (*(dest)=htons(*(src))) +#define aitToNetOrder32(dest,src) (*(dest)=htonl(*(src))) +#define aitFromNetOrder16(dest,src) (*(dest)=ntohs(*(src))) +#define aitFromNetOrder32(dest,src) (*(dest)=ntohl(*(src))) + +/* be careful using these because of brackets, these should be functions */ +#define aitToNetOrder64(dest,src) \ +{ \ + aitUint32 ait_temp_var_; \ + ait_temp_var_=(aitUint32)htonl((src)[1]); \ + (dest)[1]=(aitUint32)htonl((src)[0]); \ + (dest)[0]=ait_temp_var_; \ +} +#define aitFromNetOrder64(dest,src) \ +{ \ + aitUint32 ait_temp_var_; \ + ait_temp_var_=(aitUint32)ntohl((src)[1]); \ + (dest)[1]=(aitUint32)ntohl((src)[0]); \ + (dest)[0]=ait_temp_var_; \ +} + +#endif /* __cpluspluc && !__GNUC__ */ + +#define aitToNetFloat64 aitToNetOrder64 +#define aitToNetFloat32 aitToNetOrder32 +#define aitFromNetFloat64 aitFromNetOrder64 +#define aitFromNetFloat32 aitFromNetOrder32 + +#endif + diff --git a/src/gdd/aitGen.c b/src/gdd/aitGen.c new file mode 100644 index 000000000..d5d70a7f7 --- /dev/null +++ b/src/gdd/aitGen.c @@ -0,0 +1,439 @@ +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * Revision 1.3 1996/06/17 15:24:05 jbk + * many mods, string class corrections. + * gdd operator= protection. + * dbmapper uses aitString array for menus now + * + * Revision 1.2 1996/06/13 21:31:52 jbk + * Various fixes and correction - including ref_cnt change to unsigned short + * + * Revision 1.1 1996/05/31 13:15:19 jbk + * add new stuff + * + */ + +#include +#include +#include + +#include "aitTypes.h" + +/* + Still need to generate to "FromNet" matrix and rename the "Net" conversions + to "ToNet". +*/ + +void MakeNormalFunc(int i,int j,int k); +void MakeToFunc(int i,int j,int k); +void MakeFromFunc(int i,int j,int k); +void GenName(int i,int j,int k); +void GenVars(int i,int j); +void MakeStringFuncFrom(int i,int j,int k); +void MakeStringFuncTo(int i,int j,int k); +void MakeFStringFuncFrom(int i,int j,int k); +void MakeFStringFuncTo(int i,int j,int k); + +#define FILE_NAME "aitConvertGenerated.cc" +#define pr fprintf + +#define AIT_TO_NET 0 +#define AIT_FROM_NET 1 +#define AIT_NORMAL 2 + +#define AIT_SWAP_NONE 0 +#define AIT_SWAP_16 1 +#define AIT_SWAP_32 2 +#define AIT_SWAP_64 3 + +static const char* table_type[] = { + "aitConvertToNet", + "aitConvertFromNet", + "aitConvert" }; +static const char* table_def[] = { + "#if defined(AIT_TO_NET_CONVERT)", + "#elif defined(AIT_FROM_NET_CONVERT)", + "#else /* AIT_CONVERT */" }; + +static FILE *dfd; + +int main(int argc,char* argv[]) +{ + int i,j,k; + + if((dfd=fopen(FILE_NAME,"w"))==NULL) + { + pr(stderr,"file %s failed to open\n",FILE_NAME); + return -1; + } + + /* -----------------------------------------------------------------*/ + /* generate basic conversion functions */ + + pr(dfd,"\n"); + + /* generate each group - to/from/normal */ + for(k=0;k<3;k++) + { + pr(dfd,"%s\n",table_def[k]); + for(i=aitConvertAutoFirst;i<=aitConvertAutoLast;i++) + for(j=aitConvertAutoFirst;j<=aitConvertAutoLast;j++) + { + switch(k) + { + case AIT_TO_NET: MakeToFunc(i,j,k); break; + case AIT_FROM_NET: MakeFromFunc(i,j,k); break; + case AIT_NORMAL: MakeNormalFunc(i,j,k); break; + default: break; + } + } + } + pr(dfd,"#endif\n\n"); + + for(k=0;k<3;k++) + { + pr(dfd,"%s\n",table_def[k]); + for(i=aitConvertAutoFirst;i<=aitConvertAutoLast;i++) + { + MakeStringFuncTo(i,aitEnumString,k); + MakeStringFuncFrom(aitEnumString,i,k); + MakeFStringFuncTo(i,aitEnumFixedString,k); + MakeFStringFuncFrom(aitEnumFixedString,i,k); + } + } + pr(dfd,"#endif\n\n"); + + /* generate the three conversion table matrices */ + for(k=0;k<3;k++) + { + pr(dfd,"%s\n",table_def[k]); + pr(dfd,"aitFunc %sTable[aitTotal][aitTotal]={\n",table_type[k]); + + /* generate network conversion matrix */ + for(i=aitFirst;i<=aitLast;i++) + { + pr(dfd," {\n"); + for(j=aitFirst;j<=aitLast;j++) + { + if(iaitConvertLast || + jaitConvertLast) + pr(dfd,"aitNoConvert"); + else + pr(dfd,"%s%s%s",table_type[k], + &(aitName[i])[3],&(aitName[j])[3]); + + if(j +#include +#ifndef assert // allows use of epicsAssert.h +#include +#endif + +const unsigned NSecPerSec = 1000000000u; +const unsigned NSecPerUSec = 1000u; +const unsigned SecPerMin = 60u; + +class aitTimeStamp { + friend aitTimeStamp operator+ (const aitTimeStamp &lhs, const aitTimeStamp &rhs); + friend aitTimeStamp operator- (const aitTimeStamp &lhs, const aitTimeStamp &rhs); + friend int operator>= (const aitTimeStamp &lhs, const aitTimeStamp &rhs); +public: + aitTimeStamp () : tv_sec(0u), tv_nsec(0u) {} + aitTimeStamp (const aitTimeStamp &t) : tv_sec(t.tv_sec), tv_nsec(t.tv_nsec) {} + aitTimeStamp (const unsigned long tv_secIn, const unsigned long tv_nsecIn) : + tv_sec(tv_secIn), tv_nsec(tv_nsecIn) + { + if (tv_nsecIn>=NSecPerSec) { + this->tv_sec += this->tv_nsec/NSecPerSec; + this->tv_nsec = this->tv_nsec%NSecPerSec; + } + } + + // + // fetched as fields so this file is not required + // to include os dependent struct timeval + // + void getTV(long &tv_secOut, long &uSecOut) { + assert (this->tv_sec<=LONG_MAX); + tv_secOut = (long) this->tv_sec; + assert (this->tv_nsec<=LONG_MAX); + uSecOut = (long) this->tv_nsec/NSecPerUSec; + } + // + // for use when loading struct timeval + // + void get(unsigned long &tv_secOut, unsigned long &tv_nsecOut) { + tv_secOut = this->tv_sec; + tv_nsecOut = this->tv_nsec; + } + + operator double() + { + return ((double)this->tv_nsec)/NSecPerSec+this->tv_sec; + } + + operator float() + { + return ((float)this->tv_nsec)/NSecPerSec+this->tv_sec; + } + + static aitTimeStamp getCurrent(); +// private: + unsigned long tv_sec; + unsigned long tv_nsec; +}; + +inline aitTimeStamp operator+ (const aitTimeStamp &lhs, const aitTimeStamp &rhs) +{ + return aitTimeStamp(lhs.tv_sec + rhs.tv_sec, lhs.tv_nsec + rhs.tv_nsec); +} + +// +// like data type unsigned this assumes that the lhs > rhs +// (otherwise we assume tv_sec wrap around) +// +inline aitTimeStamp operator- (const aitTimeStamp &lhs, const aitTimeStamp &rhs) +{ + unsigned long tv_nsec, tv_sec; + + if (lhs.tv_sec= (const aitTimeStamp &lhs, const aitTimeStamp &rhs) +{ + if (lhs.tv_sec>rhs.tv_sec) { + return 1; + } + else if (lhs.tv_sec==rhs.tv_sec) { + if (lhs.tv_nsec>=rhs.tv_nsec) { + return 1; + } + } + return 0; +} + + +// --------------------------------------------------------------------------- +// very simple class for string storage (for now) +// +// +class aitString +{ +private: + enum aitStrType {aitStrMalloc, aitStrConst}; + + int set(const char* p) + { + if(p) + { + len=strlen(p); + str=(const char*)new char[len+1]; + if(str) + { + strcpy((char*)str, p); + type=aitStrMalloc; + } + else + { + // If malloc fails set it to + // an empty constant str + str = ""; + len = 0u; + type = aitStrConst; + printf("aitString: no pool => continuing with nill str\n"); + return -1; + } + } + else + { + str=NULL; + len=0u; + type=aitStrConst; + } + return 0; + } + + void cset(const char* p) + { + str=p; + type=aitStrConst; + if(str) + len=strlen(str); + else + len = 0u; + } + +public: + + aitString(void) { cset((char*)NULL); } + aitString(const char* x) { cset(x); } + aitString(char* x) { cset(x); } + + operator aitUint16(void) { return len; } + operator const char*(void) { return str; } + aitUint32 length(void) { return len; } + const char* string(void) const { return str; } + void force(char* x) { str=x; } + void force(unsigned char* x) { str=(char*)x; } + void force(unsigned long x) { str=(char*)x; } + + void clear(void) + { + if (str && type==aitStrMalloc) + { + char *pStr=(char*)str; + delete [] pStr; + } + } + + int installString(const char* p) { clear(); return set(p); } + int installString(char* p) { clear(); return set(p); } + void copy(const char* p) { clear(); cset(p); } + void copy(char* p) { clear(); cset(p); } + aitString& operator=(const char* p) { this->copy(p); return *this; } + aitString& operator=(char* p) { this->copy(p); return *this; } + + // take the aitString array, and put it and all the string into buf, + // return the total length the data copied + static aitUint32 totalLength(aitString* array,aitIndex arraySize); + static aitUint32 stringsLength(aitString* array,aitIndex arraySize); + static aitIndex compact(aitString* array, aitIndex arraySize, + void* buf, aitIndex bufSize); + +private: + const char * str; + aitUint16 len; + aitUint16 type; // aitStrType goes here +}; + +#endif // aitHelpersInclude diff --git a/src/gdd/aitTypes.c b/src/gdd/aitTypes.c new file mode 100644 index 000000000..db4419f94 --- /dev/null +++ b/src/gdd/aitTypes.c @@ -0,0 +1,64 @@ +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * Revision 1.1 1996/05/31 13:15:21 jbk + * add new stuff + * + */ + +#define AIT_TYPES_SOURCE 1 +#include +#include "aitTypes.h" + +const size_t aitSize[aitTotal] = { + 0, + sizeof(aitInt8), + sizeof(aitUint8), + sizeof(aitInt16), + sizeof(aitUint16), + sizeof(aitEnum16), + sizeof(aitInt32), + sizeof(aitUint32), + sizeof(aitFloat32), + sizeof(aitFloat64), + sizeof(aitFixedString), + sizeof(aitString), + 0 +}; + +const char* aitName[aitTotal] = { + "aitInvalid", + "aitInt8", + "aitUint8", + "aitInt16", + "aitUint16", + "aitEnum16", + "aitInt32", + "aitUint32", + "aitFloat32", + "aitFloat64", + "aitFixedString", + "aitString", + "aitContainer" +}; + +const char* aitStringType[aitTotal] = { + "%8.8x", + "%2.2x", + "%2.2x", + "%hd", + "%hu", + "%hu", + "%d", + "%u", + "%f", + "%lf", + "%s", + "%s", + "%8.8x" +}; + diff --git a/src/gdd/aitTypes.h b/src/gdd/aitTypes.h new file mode 100644 index 000000000..dafdf7710 --- /dev/null +++ b/src/gdd/aitTypes.h @@ -0,0 +1,133 @@ +#ifndef AIT_TYPES_H +#define AIT_TYPES_H 1 + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.2 1996/06/17 15:24:07 jbk + * *many mods, string class corrections. + * *gdd operator= protection. + * *dbmapper uses aitString array for menus now + * *Revision 1.1 1996/05/31 13:15:22 jbk + * *add new stuff + * + */ + +/* This is the file the user sets up for a given architecture */ + +#define AIT_FIXED_STRING_SIZE 40 + +#include +#include + +typedef char aitInt8; +typedef unsigned char aitUint8; +typedef short aitInt16; +typedef unsigned short aitUint16; +typedef aitUint16 aitEnum16; +typedef int aitInt32; +typedef unsigned int aitUint32; +typedef float aitFloat32; +typedef double aitFloat64; +typedef aitUint32 aitIndex; +typedef void* aitPointer; +typedef aitUint32 aitStatus; + +/* should the bool be added as a conversion type? it currently is not */ +typedef enum { + aitFalse=0, + aitTrue +} aitBool; + +typedef struct { + char fixed_string[AIT_FIXED_STRING_SIZE]; +} aitFixedString; + +#ifdef __cplusplus +#include "aitHelpers.h" +#else +/* need time stamp structure different from posix unfortunetly */ +typedef struct { + aitUint32 tv_sec; + aitUint32 tv_nsec; +} aitTimeStamp; + +/* strings are a struct so they are different then aitInt8 */ +typedef struct { + char* string; + aitUint32 len; +} aitString; +#endif + +/* all normal types */ +#define aitTotal 13 +#define aitFirst aitEnumInvalid +#define aitLast aitEnumContainer +#define aitValid(x) ((x)<=aitLast) + +/* all conversion types */ +#define aitConvertTotal 11 +#define aitConvertFirst aitEnumInt8 +#define aitConvertLast aitEnumString +#define aitConvertAutoFirst aitEnumInt8 +#define aitConvertAutoLast aitEnumFloat64 +#define aitConvertValid(x) ((x)>=aitConvertFirst && (x)<=aitConvertLast) + +/* currently no 64-bit integer support */ +typedef enum { + aitEnumInvalid=0, + aitEnumInt8, + aitEnumUint8, + aitEnumInt16, + aitEnumUint16, + aitEnumEnum16, + aitEnumInt32, + aitEnumUint32, + aitEnumFloat32, + aitEnumFloat64, + aitEnumFixedString, + aitEnumString, + aitEnumContainer +} aitEnum; + +typedef union { + aitInt8 Int8; + aitUint8 Uint8; + aitInt16 Int16; + aitUint16 Uint16; + aitEnum16 Enum16; + aitInt32 Int32; + aitUint32 Uint32; + aitFloat32 Float32; + aitFloat64 Float64; + aitIndex Index; + aitPointer Pointer; + aitFixedString* FString; + aitUint8 Dumb1[sizeof(aitString)]; /* aitString String; */ + aitUint8 Dumb3[sizeof(aitTimeStamp)]; /* aitTimeStamp Stamp; */ +} aitType; + +/* + classes are not allowed in union that required construction/destruction + so I am insuring that the size of aitType is large enough to hold + strings and timestamps in an obsure, horrible way with the Dumb variables +*/ + +#ifndef AIT_TYPES_SOURCE +#ifdef __cplusplus +extern "C" { +#endif +extern const size_t aitSize[aitTotal]; +extern const char* aitName[aitTotal]; +extern const char* aitStringType[aitTotal]; +#ifdef __cplusplus +} +#endif +#endif + +#endif diff --git a/src/gdd/dbMapper.cc b/src/gdd/dbMapper.cc new file mode 100644 index 000000000..469844d12 --- /dev/null +++ b/src/gdd/dbMapper.cc @@ -0,0 +1,1294 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// + +// *Revision 1.5 1996/06/25 18:59:00 jbk +// *more fixes for the aitString management functions and mapping menus +// *Revision 1.4 1996/06/24 03:15:30 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.3 1996/06/17 15:24:08 jbk +// *many mods, string class corrections. +// *gdd operator= protection. +// *dbMapper uses aitString array for menus now +// *Revision 1.2 1996/06/13 21:31:54 jbk +// *Various fixes and correction - including ref_cnt change to unsigned short +// *Revision 1.1 1996/05/31 13:15:23 jbk +// *add new stuff + +#define DB_MAPPER_SOURCE 1 +#include + +#include "gddApps.h" +#include "gddAppTable.h" +#include "dbMapper.h" +// #include "templates/dbMapperTempl.h" + +// hardcoded in same order as aitConvert.h +// no way to detect a string type!!!!!!! + +static gddApplicationTypeTable* type_table = NULL; + +const chtype gddAitToDbr[] = { + 0, + DBR_CHAR, + DBR_CHAR, + DBR_SHORT, + DBR_SHORT, + DBR_ENUM, + DBR_LONG, + DBR_LONG, + DBR_FLOAT, + DBR_DOUBLE, + DBR_STRING, + DBR_STRING, + 999 +}; + +gddDbrToAitTable gddDbrToAit[] = { + // normal + { aitEnumFixedString, 0, "value" }, + { aitEnumInt16, 0, "value" }, + { aitEnumFloat32, 0, "value" }, + { aitEnumEnum16, 0, "enums" }, + { aitEnumInt8, 0, "value" }, + { aitEnumInt32, 0, "value" }, + { aitEnumFloat64, 0, "value" }, + // STS + { aitEnumFixedString, 0, "value" }, + { aitEnumInt16, 0, "value" }, + { aitEnumFloat32, 0, "value" }, + { aitEnumEnum16, 0, "enums" }, + { aitEnumInt8, 0, "value" }, + { aitEnumInt32, 0, "value" }, + { aitEnumFloat64, 0, "value" }, + // TIME + { aitEnumFixedString, 0, "value" }, + { aitEnumInt16, 0, "value" }, + { aitEnumFloat32, 0, "value" }, + { aitEnumEnum16, 0, "enums" }, + { aitEnumInt8, 0, "value" }, + { aitEnumInt32, 0, "value" }, + { aitEnumFloat64, 0, "value" }, + // Graphic + { aitEnumFixedString, 0, "dbr_gr_string" }, + { aitEnumInt16, 0, "dbr_gr_short" }, + { aitEnumFloat32, 0, "dbr_gr_float" }, + { aitEnumEnum16, 0, "dbr_gr_enum" }, + { aitEnumInt8, 0, "dbr_gr_char" }, + { aitEnumInt32, 0, "dbr_gr_long" }, + { aitEnumFloat64, 0, "dbr_gr_double" }, + // control + { aitEnumFixedString, 0, "dbr_ctrl_string" }, + { aitEnumInt16, 0, "dbr_ctrl_short" }, + { aitEnumFloat32, 0, "dbr_ctrl_float" }, + { aitEnumEnum16, 0, "dbr_ctrl_enum" }, + { aitEnumInt8, 0, "dbr_ctrl_char" }, + { aitEnumInt32, 0, "dbr_ctrl_long" }, + { aitEnumFloat64, 0, "dbr_ctrl_double" } +}; + +// I generated a container for each of the important DBR types. This +// includes all the control and graphic structures. The others are +// not needed become you can get time stamp and status in each gdd. +// Currently the containers are build here with c++ code. + +// string type needs to be written special and not use template +// maybe create a template for the string type +// the problem is that the value of a string structure is an array, +// not just a single element + +static gdd* mapStringToGdd(void* v,aitIndex count) { + aitFixedString* db = (aitFixedString*)v; + aitEnum to_type = gddDbrToAit[DBR_STRING].type; + aitUint16 to_app = gddDbrToAit[DBR_STRING].app; + gdd* dd; + + if(count<=1) + { + dd=new gddScaler(to_app,to_type); + dd->put(*db); + } + else + { + dd=new gddAtomic(to_app,to_type,1,count); + dd->putRef(db); + } + return dd; +} + +static int mapGddToString(void* v, gdd* dd) { + aitFixedString* db = (aitFixedString*)v; + aitFixedString* dbx = (aitFixedString*)dd->dataPointer(); + int len = dd->getDataSizeElements(); + if(dbx!=db) dd->get(db); + return len; +} + +static gdd* mapShortToGdd(void* v,aitIndex count) { + dbr_short_t* sv = (dbr_short_t*)v; + gdd* dd; + + if(count>1) { + dd=new gddAtomic(gddDbrToAit[DBR_SHORT].app, + gddDbrToAit[DBR_SHORT].type,1,count); + dd->putRef(sv); + } else { + dd=new gddScaler(gddDbrToAit[DBR_SHORT].app); + *dd=*sv; + } + return dd; +} + +static int mapGddToShort(void* v, gdd* dd) { + dbr_short_t* sv = (dbr_short_t*)v; + int sz=1; + + if(dd->getBounds()) { + sz=dd->getDataSizeElements(); + if(dd->dataPointer()!=sv) + memcpy(sv,dd->dataPointer(),dd->getDataSizeBytes()); + } else + *sv=*dd; + return sz; +} + +static gdd* mapFloatToGdd(void* v,aitIndex count) { + dbr_float_t* sv = (dbr_float_t*)v; + gdd* dd; + + if(count>1) { + dd=new gddAtomic(gddDbrToAit[DBR_FLOAT].app, + gddDbrToAit[DBR_FLOAT].type,1,count); + dd->putRef(sv); + } else { + dd=new gddScaler(gddDbrToAit[DBR_FLOAT].app); + *dd=*sv; + } + return dd; +} + +static int mapGddToFloat(void* v, gdd* dd) { + dbr_float_t* sv = (dbr_float_t*)v; + int sz=1; + + if(dd->getBounds()) { + sz=dd->getDataSizeElements(); + if(dd->dataPointer()!=sv) + memcpy(sv,dd->dataPointer(),dd->getDataSizeBytes()); + } else + *sv=*dd; + return sz; +} + +static gdd* mapEnumToGdd(void* v,aitIndex count) { + dbr_enum_t* sv = (dbr_enum_t*)v; + gdd* dd; + + if(count>1) { + dd=new gddAtomic(gddDbrToAit[DBR_ENUM].app, + gddDbrToAit[DBR_ENUM].type,1,count); + dd->putRef(sv); + } else { + dd=new gddScaler(gddDbrToAit[DBR_ENUM].app); + *dd=*sv; + } + return dd; +} + +static int mapGddToEnum(void* v, gdd* dd) { + dbr_enum_t* sv = (dbr_enum_t*)v; + aitEnum16* e; + int sz=1; + + if(dd->dimension()) { + dd->getRef(e); + sv=*e; + } else + *sv=*dd; + return sz; +} + +static gdd* mapCharToGdd(void* v,aitIndex count) { + dbr_char_t* sv = (dbr_char_t*)v; + gdd* dd; + + if(count>1) { + dd=new gddAtomic(gddDbrToAit[DBR_CHAR].app, + gddDbrToAit[DBR_CHAR].type,1,count); + dd->putRef(sv); + } else { + dd=new gddScaler(gddDbrToAit[DBR_CHAR].app); + *dd=*sv; + } + return dd; +} + +static int mapGddToChar(void* v, gdd* dd) { + dbr_char_t* sv = (dbr_char_t*)v; + int sz=1; + + if(dd->dimension()) { + sz=dd->getDataSizeElements(); + if(dd->dataPointer()!=sv) + memcpy(sv,dd->dataPointer(),dd->getDataSizeBytes()); + } else + *sv=*dd; + return sz; +} + +static gdd* mapLongToGdd(void* v,aitIndex count) { + dbr_long_t* sv = (dbr_long_t*)v; + gdd* dd; + + if(count>1) { + dd=new gddAtomic(gddDbrToAit[DBR_LONG].app, + gddDbrToAit[DBR_LONG].type,1,count); + dd->putRef(sv); + } else { + dd=new gddScaler(gddDbrToAit[DBR_LONG].app); + *dd=*sv; + } + return dd; +} + +static int mapGddToLong(void* v, gdd* dd) { + dbr_long_t* sv = (dbr_long_t*)v; + int sz=1; + + if(dd->dimension()) { + sz=dd->getDataSizeElements(); + if(dd->dataPointer()!=sv) + memcpy(sv,dd->dataPointer(),dd->getDataSizeBytes()); + } else + *sv=*dd; + return sz; +} + +static gdd* mapDoubleToGdd(void* v,aitIndex count) { + dbr_double_t* sv = (dbr_double_t*)v; + gdd* dd; + + if(count>1) { + dd=new gddAtomic(gddDbrToAit[DBR_DOUBLE].app, + gddDbrToAit[DBR_DOUBLE].type,1,count); + dd->putRef(sv); + } else { + dd=new gddScaler(gddDbrToAit[DBR_DOUBLE].app); + *dd=*sv; + } + return dd; +} + +static int mapGddToDouble(void* v, gdd* dd) { + dbr_double_t* sv = (dbr_double_t*)v; + int sz=1; + + if(dd->dimension()) { + sz=dd->getDataSizeElements(); + if(dd->dataPointer()!=sv) + memcpy(sv,dd->dataPointer(),dd->getDataSizeBytes()); + } else + *sv=*dd; + return sz; +} + +// ******************************************************************** +// sts structure mappings +// ******************************************************************** + +static gdd* mapStsStringToGdd(void* v,aitIndex count) +{ + dbr_sts_string* db = (dbr_sts_string*)v; + aitFixedString* dbv = (aitFixedString*)db->value; + aitEnum to_type = gddDbrToAit[DBR_STS_STRING].type; + aitUint16 to_app = gddDbrToAit[DBR_STS_STRING].app; + gdd* dd; + + if(count<=1) + { + dd=new gddScaler(to_app,to_type); + dd->put(*dbv); + } + else + { + dd=new gddAtomic(to_app,to_type,1,count); + dd->putRef(dbv); + } + + dd->setStatSevr(db->status,db->severity); + return dd; +} + +static int mapStsGddToString(void* v, gdd* dd) +{ + dbr_sts_string* db = (dbr_sts_string*)v; + aitFixedString* dbv = (aitFixedString*)db->value; + aitFixedString* dbx = (aitFixedString*)dd->dataPointer(); + + // copy string into user buffer for now if not the same as one in gdd + if(dbx!=dbv) dd->get(dbv); + dd->getStatSevr(db->status,db->severity); + return dd->getDataSizeElements(); +} + +static gdd* mapStsShortToGdd(void* v,aitIndex count) +{ + dbr_sts_short* dbv = (dbr_sts_short*)v; + gdd* dd=mapShortToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + return dd; +} + +static int mapStsGddToShort(void* v, gdd* dd) +{ + dbr_sts_short* dbv = (dbr_sts_short*)v; + int sz=mapGddToShort(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + return sz; +} + +static gdd* mapStsFloatToGdd(void* v,aitIndex count) +{ + dbr_sts_float* dbv = (dbr_sts_float*)v; + gdd* dd=mapFloatToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + return dd; +} + +static int mapStsGddToFloat(void* v, gdd* dd) +{ + dbr_sts_float* dbv = (dbr_sts_float*)v; + int sz=mapGddToFloat(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + return sz; +} + +static gdd* mapStsEnumToGdd(void* v,aitIndex count) +{ + dbr_sts_enum* dbv = (dbr_sts_enum*)v; + gdd* dd=mapEnumToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + return dd; +} + +static int mapStsGddToEnum(void* v, gdd* dd) +{ + dbr_sts_enum* dbv = (dbr_sts_enum*)v; + int sz=mapGddToEnum(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + return sz; +} + +static gdd* mapStsCharToGdd(void* v,aitIndex count) +{ + dbr_sts_char* dbv = (dbr_sts_char*)v; + gdd* dd=mapCharToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + return dd; +} + +static int mapStsGddToChar(void* v, gdd* dd) +{ + dbr_sts_char* dbv = (dbr_sts_char*)v; + int sz=mapGddToChar(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + return sz; +} + +static gdd* mapStsLongToGdd(void* v,aitIndex count) +{ + dbr_sts_long* dbv = (dbr_sts_long*)v; + gdd* dd=mapLongToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + return dd; +} + +static int mapStsGddToLong(void* v, gdd* dd) +{ + dbr_sts_long* dbv = (dbr_sts_long*)v; + int sz=mapGddToLong(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + return sz; +} + +static gdd* mapStsDoubleToGdd(void* v,aitIndex count) +{ + dbr_sts_double* dbv = (dbr_sts_double*)v; + gdd* dd=mapDoubleToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + return dd; +} + +static int mapStsGddToDouble(void* v, gdd* dd) +{ + dbr_sts_double* dbv = (dbr_sts_double*)v; + int sz=mapGddToDouble(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + return sz; +} + +// ******************************************************************** +// time structure mappings +// ******************************************************************** + +static gdd* mapTimeStringToGdd(void* v,aitIndex count) +{ + dbr_time_string* db = (dbr_time_string*)v; + aitFixedString* dbv = (aitFixedString*)db->value; + aitEnum to_type = gddDbrToAit[DBR_TIME_STRING].type; + aitUint16 to_app = gddDbrToAit[DBR_TIME_STRING].app; + gdd* dd; + + if(count<=1) + { + dd=new gddScaler(to_app,to_type); + dd->put(*dbv); + } + else + { + dd=new gddAtomic(to_app,to_type,1,count); + dd->putRef(dbv); + } + + dd->setStatSevr(db->status,db->severity); + dd->setTimeStamp((aitTimeStamp*)&db->stamp); + return dd; +} + +static int mapTimeGddToString(void* v, gdd* dd) +{ + dbr_time_string* db = (dbr_time_string*)v; + aitFixedString* dbv = (aitFixedString*)db->value; + + // copy string into user buffer for now if not the same as one in gdd + if(v!=dd->dataPointer()) dd->get(dbv); + + dd->getStatSevr(db->status,db->severity); + dd->getTimeStamp((aitTimeStamp*)&db->stamp); + return dd->getDataSizeBytes(); +} + +static gdd* mapTimeShortToGdd(void* v,aitIndex count) +{ + dbr_time_short* dbv = (dbr_time_short*)v; + gdd* dd=mapShortToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + dd->setTimeStamp((aitTimeStamp*)&dbv->stamp); + return dd; +} + +static int mapTimeGddToShort(void* v, gdd* dd) +{ + dbr_time_short* dbv = (dbr_time_short*)v; + int sz=mapGddToShort(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + dd->getTimeStamp((aitTimeStamp*)&dbv->stamp); + return sz; +} + +static gdd* mapTimeFloatToGdd(void* v,aitIndex count) +{ + dbr_time_float* dbv = (dbr_time_float*)v; + gdd* dd=mapFloatToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + dd->setTimeStamp((aitTimeStamp*)&dbv->stamp); + return dd; +} + +static int mapTimeGddToFloat(void* v, gdd* dd) +{ + dbr_time_float* dbv = (dbr_time_float*)v; + int sz=mapGddToFloat(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + dd->getTimeStamp((aitTimeStamp*)&dbv->stamp); + return sz; +} + +static gdd* mapTimeEnumToGdd(void* v,aitIndex count) +{ + dbr_time_enum* dbv = (dbr_time_enum*)v; + gdd* dd=mapEnumToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + dd->setTimeStamp((aitTimeStamp*)&dbv->stamp); + return dd; +} + +static int mapTimeGddToEnum(void* v, gdd* dd) +{ + dbr_time_enum* dbv = (dbr_time_enum*)v; + int sz=mapGddToEnum(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + dd->getTimeStamp((aitTimeStamp*)&dbv->stamp); + return sz; +} + +static gdd* mapTimeCharToGdd(void* v,aitIndex count) +{ + dbr_time_char* dbv = (dbr_time_char*)v; + gdd* dd=mapCharToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + dd->setTimeStamp((aitTimeStamp*)&dbv->stamp); + return dd; +} + +static int mapTimeGddToChar(void* v, gdd* dd) +{ + dbr_time_char* dbv = (dbr_time_char*)v; + int sz=mapGddToChar(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + dd->getTimeStamp((aitTimeStamp*)&dbv->stamp); + return sz; +} + +static gdd* mapTimeLongToGdd(void* v,aitIndex count) +{ + dbr_time_long* dbv = (dbr_time_long*)v; + gdd* dd=mapLongToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + dd->setTimeStamp((aitTimeStamp*)&dbv->stamp); + return dd; +} + +static int mapTimeGddToLong(void* v, gdd* dd) +{ + dbr_time_long* dbv = (dbr_time_long*)v; + int sz=mapGddToLong(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + dd->getTimeStamp((aitTimeStamp*)&dbv->stamp); + return sz; +} + +static gdd* mapTimeDoubleToGdd(void* v,aitIndex count) +{ + dbr_time_double* dbv = (dbr_time_double*)v; + gdd* dd=mapDoubleToGdd(&dbv->value,count); + dd->setStatSevr(dbv->status,dbv->severity); + dd->setTimeStamp((aitTimeStamp*)&dbv->stamp); + return dd; +} + +static int mapTimeGddToDouble(void* v, gdd* dd) +{ + dbr_time_double* dbv = (dbr_time_double*)v; + int sz=mapGddToDouble(&dbv->value,dd); + dd->getStatSevr(dbv->status,dbv->severity); + dd->getTimeStamp((aitTimeStamp*)&dbv->stamp); + return sz; +} + +// ******************************************************************** +// graphic structure mappings +// ******************************************************************** + +// -------------map the short structures---------------- +static gdd* mapGraphicShortToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_gr_short* db = (dbr_gr_short*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_GR_SHORT].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_short_value]; + + dd[gddAppTypeIndex_dbr_gr_short_units].put(db->units); + dd[gddAppTypeIndex_dbr_gr_short_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_gr_short_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_gr_short_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_short_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_short_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_gr_short_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static gdd* mapControlShortToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_ctrl_short* db = (dbr_ctrl_short*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_CTRL_SHORT].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_short_value]; + + dd[gddAppTypeIndex_dbr_ctrl_short_units].put(db->units); + dd[gddAppTypeIndex_dbr_ctrl_short_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_controlLow]=db->lower_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_controlHigh]=db->upper_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_ctrl_short_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static int mapGraphicGddToShort(void* v, gdd* dd) +{ + dbr_gr_short* db = (dbr_gr_short*)v; + int sz=1; + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_short_value]; + + dd[gddAppTypeIndex_dbr_gr_short_units].get(db->units); + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_short_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_short_graphicHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +static int mapControlGddToShort(void* v, gdd* dd) +{ + dbr_ctrl_short* db = (dbr_ctrl_short*)v; + int sz=1; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_short_value]; + + dd[gddAppTypeIndex_dbr_ctrl_short_units].get(db->units); + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_short_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_short_graphicHigh]; + db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_short_controlLow]; + db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_short_controlHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +// -------------map the float structures---------------- +static gdd* mapGraphicFloatToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_gr_float* db = (dbr_gr_float*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_GR_FLOAT].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_float_value]; + + dd[gddAppTypeIndex_dbr_gr_float_units].put(db->units); + dd[gddAppTypeIndex_dbr_gr_float_precision]=db->precision; + dd[gddAppTypeIndex_dbr_gr_float_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_gr_float_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_gr_float_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_float_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_float_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_gr_float_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static gdd* mapControlFloatToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_ctrl_float* db = (dbr_ctrl_float*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_CTRL_FLOAT].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_float_value]; + + dd[gddAppTypeIndex_dbr_ctrl_float_units].put(db->units); + dd[gddAppTypeIndex_dbr_ctrl_float_precision]=db->precision; + dd[gddAppTypeIndex_dbr_ctrl_float_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_controlLow]=db->lower_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_controlHigh]=db->upper_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_ctrl_float_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static int mapGraphicGddToFloat(void* v, gdd* dd) +{ + dbr_gr_float* db = (dbr_gr_float*)v; + int sz=1; + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_float_value]; + + dd[gddAppTypeIndex_dbr_gr_float_units].get(db->units); + db->precision=dd[gddAppTypeIndex_dbr_gr_float_precision]; + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_float_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_float_graphicHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +static int mapControlGddToFloat(void* v, gdd* dd) +{ + dbr_ctrl_float* db = (dbr_ctrl_float*)v; + int sz=1; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_float_value]; + + dd[gddAppTypeIndex_dbr_ctrl_float_units].get(db->units); + db->precision=dd[gddAppTypeIndex_dbr_ctrl_float_precision]; + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_float_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_float_graphicHigh]; + db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_float_controlLow]; + db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_float_controlHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +// -------------map the enum structures---------------- +static gdd* mapGraphicEnumToGdd(void* v, aitIndex count) +{ + dbr_gr_enum* db = (dbr_gr_enum*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_GR_ENUM].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_enum_value]; + gdd& menu = dd[gddAppTypeIndex_dbr_gr_enum_enums]; + aitString* str = menu; + aitIndex l; + int i; + + for(i=0;ino_str;i++) str[i]=((const char*)&(db->strs[i][0])); + menu.setBound(0,0,db->no_str); + vdd.setStatSevr(db->status,db->severity); + + // should always be a scaler + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + return dd; +} + +static gdd* mapControlEnumToGdd(void* v, aitIndex count) +{ + dbr_ctrl_enum* db = (dbr_ctrl_enum*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_CTRL_ENUM].app); + gdd& menu = dd[gddAppTypeIndex_dbr_ctrl_enum_enums]; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_enum_value]; + aitString* str = menu; + aitIndex l; + int i; + + for(i=0;ino_str;i++) str[i]=((const char*)&(db->strs[i][0])); + menu.setBound(0,0,db->no_str); + vdd.setStatSevr(db->status,db->severity); + + // should always be a scaler + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + return dd; +} + +static int mapGraphicGddToEnum(void* v, gdd* dd) +{ + dbr_gr_enum* db = (dbr_gr_enum*)v; + gdd& menu = dd[gddAppTypeIndex_dbr_gr_enum_enums]; + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_enum_value]; + aitString* str = menu; + int i; + + vdd.getStatSevr(db->status,db->severity); + db->no_str=menu.getDataSizeElements(); + + for(i=0;ino_str;i++) strcpy(&(db->strs[i][0]),str[i]); + + db->value=vdd; // always scaler + return 1; +} + +static int mapControlGddToEnum(void* v, gdd* dd) +{ + dbr_ctrl_enum* db = (dbr_ctrl_enum*)v; + gdd& menu = dd[gddAppTypeIndex_dbr_ctrl_enum_enums]; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_enum_value]; + aitString* str = menu; + int i; + + vdd.getStatSevr(db->status,db->severity); + db->no_str=menu.getDataSizeElements(); + + for(i=0;ino_str;i++) strcpy(&(db->strs[i][0]),str[i]); + + db->value=vdd; // always scaler + return 1; +} + +// -------------map the char structures---------------- +static gdd* mapGraphicCharToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_gr_char* db = (dbr_gr_char*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_GR_CHAR].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_char_value]; + + dd[gddAppTypeIndex_dbr_gr_char_units].put(db->units); + dd[gddAppTypeIndex_dbr_gr_char_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_gr_char_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_gr_char_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_char_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_char_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_gr_char_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static gdd* mapControlCharToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_ctrl_char* db = (dbr_ctrl_char*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_CTRL_CHAR].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_char_value]; + + dd[gddAppTypeIndex_dbr_ctrl_char_units].put(db->units); + dd[gddAppTypeIndex_dbr_ctrl_char_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_controlLow]=db->lower_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_controlHigh]=db->upper_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_ctrl_char_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static int mapGraphicGddToChar(void* v, gdd* dd) +{ + dbr_gr_char* db = (dbr_gr_char*)v; + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_char_value]; + int sz=1; + + dd[gddAppTypeIndex_dbr_gr_char_units].get(db->units); + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_char_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_char_graphicHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +static int mapControlGddToChar(void* v, gdd* dd) +{ + dbr_ctrl_char* db = (dbr_ctrl_char*)v; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_char_value]; + int sz=1; + + dd[gddAppTypeIndex_dbr_ctrl_char_units].get(db->units); + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_char_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_char_graphicHigh]; + db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_char_controlLow]; + db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_char_controlHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +// -------------map the long structures---------------- +static gdd* mapGraphicLongToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_gr_long* db = (dbr_gr_long*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_GR_LONG].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_long_value]; + + dd[gddAppTypeIndex_dbr_gr_long_units].put(db->units); + dd[gddAppTypeIndex_dbr_gr_long_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_gr_long_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_gr_long_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_long_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_long_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_gr_long_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static gdd* mapControlLongToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_ctrl_long* db = (dbr_ctrl_long*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_CTRL_LONG].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_long_value]; + + dd[gddAppTypeIndex_dbr_ctrl_long_units].put(db->units); + dd[gddAppTypeIndex_dbr_ctrl_long_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_controlLow]=db->lower_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_controlHigh]=db->upper_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_ctrl_long_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static int mapGraphicGddToLong(void* v, gdd* dd) +{ + dbr_gr_long* db = (dbr_gr_long*)v; + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_long_value]; + int sz=1; + + dd[gddAppTypeIndex_dbr_gr_long_units].get(db->units); + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_long_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_long_graphicHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +static int mapControlGddToLong(void* v, gdd* dd) +{ + dbr_ctrl_long* db = (dbr_ctrl_long*)v; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_long_value]; + int sz=1; + + dd[gddAppTypeIndex_dbr_ctrl_long_units].get(db->units); + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_long_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_long_graphicHigh]; + db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_long_controlLow]; + db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_long_controlHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +// -------------map the double structures---------------- +static gdd* mapGraphicDoubleToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_gr_double* db = (dbr_gr_double*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_GR_DOUBLE].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_double_value]; + + dd[gddAppTypeIndex_dbr_gr_double_units].put(db->units); + dd[gddAppTypeIndex_dbr_gr_double_precision]=db->precision; + dd[gddAppTypeIndex_dbr_gr_double_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_gr_double_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_gr_double_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_double_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_gr_double_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_gr_double_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static gdd* mapControlDoubleToGdd(void* v, aitIndex count) +{ + // must be a container + dbr_ctrl_double* db = (dbr_ctrl_double*)v; + gdd* dd = type_table->getDD(gddDbrToAit[DBR_CTRL_DOUBLE].app); + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_double_value]; + + dd[gddAppTypeIndex_dbr_ctrl_double_units].put(db->units); + dd[gddAppTypeIndex_dbr_ctrl_double_precision]=db->precision; + dd[gddAppTypeIndex_dbr_ctrl_double_graphicLow]=db->lower_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_graphicHigh]=db->upper_disp_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_controlLow]=db->lower_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_controlHigh]=db->upper_ctrl_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_alarmLow]=db->lower_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_alarmHigh]=db->upper_alarm_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_alarmLowWarning]=db->lower_warning_limit; + dd[gddAppTypeIndex_dbr_ctrl_double_alarmHighWarning]=db->upper_warning_limit; + + vdd.setStatSevr(db->status,db->severity); + + if(count==1) { + if(vdd.dimension()) vdd.clear(); + vdd=db->value; + } else { + if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); + else vdd.setPrimType(aitEnumInt16); + vdd.setBound(0,0,count); + vdd.putRef(&db->value); + } + return dd; +} + +static int mapGraphicGddToDouble(void* v, gdd* dd) +{ + dbr_gr_double* db = (dbr_gr_double*)v; + gdd& vdd = dd[gddAppTypeIndex_dbr_gr_double_value]; + int sz=1; + + dd[gddAppTypeIndex_dbr_gr_double_units].get(db->units); + db->precision=dd[gddAppTypeIndex_dbr_gr_double_precision]; + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_double_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_double_graphicHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +static int mapControlGddToDouble(void* v, gdd* dd) +{ + dbr_ctrl_double* db = (dbr_ctrl_double*)v; + gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_double_value]; + int sz=1; + + dd[gddAppTypeIndex_dbr_ctrl_double_units].get(db->units); + db->precision=dd[gddAppTypeIndex_dbr_ctrl_double_precision]; + db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_double_graphicLow]; + db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_double_graphicHigh]; + db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_double_controlLow]; + db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_double_controlHigh]; + db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmLow]; + db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmHigh]; + db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmLowWarning]; + db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmHighWarning]; + + vdd.getStatSevr(db->status,db->severity); + + if(vdd.dimension()) { + sz=vdd.getDataSizeElements(); + if(vdd.dataPointer()!=v) + memcpy(&db->value, vdd.dataPointer(), vdd.getDataSizeBytes()); + } else + db->value=vdd; + return sz; +} + +// ----------------must run this to use mapping functions-------------- +void gddMakeMapDBR(gddApplicationTypeTable* tt); +void gddMakeMapDBR(gddApplicationTypeTable& tt) { gddMakeMapDBR(&tt); } +void gddMakeMapDBR(gddApplicationTypeTable* tt) +{ + type_table=tt; + int i; + + // Storing the DBRxxx type code in the app table will not work + // for most of the types. This is because many share the same + // app type "value", this includes the normal, sts, and time structures + + for(i=0;igetApplicationType(gddDbrToAit[i].app_name); + tt->storeValue(gddDbrToAit[i].app,i); + } +} + +// An array of one function per DBR structure is provided here so conversions +// can take place quickly by knowing the DBR enumerated type. + +gddDbrMapFuncTable gddMapDbr[] = { + { mapStringToGdd, mapGddToString }, // DBR_STRING + { mapShortToGdd, mapGddToShort }, // DBR_SHORT + { mapFloatToGdd, mapGddToFloat }, // DBR_FLOAT + { mapEnumToGdd, mapGddToEnum }, // DBR_ENUM + { mapCharToGdd, mapGddToChar }, // DBR_CHAR + { mapLongToGdd, mapGddToLong }, // DBR_LONG + { mapDoubleToGdd, mapGddToDouble }, // DBR_DOUBLE + { mapStsStringToGdd, mapStsGddToString }, // DBR_STS_STRING + { mapStsShortToGdd, mapStsGddToShort }, // DBR_STS_SHORT + { mapStsFloatToGdd, mapStsGddToFloat }, // DBR_STS_FLOAT + { mapStsEnumToGdd, mapStsGddToEnum }, // DBR_STS_ENUM + { mapStsCharToGdd, mapStsGddToChar }, // DBR_STS_CHAR + { mapStsLongToGdd, mapStsGddToLong }, // DBR_STS_LONG + { mapStsDoubleToGdd, mapStsGddToDouble }, // DBR_STS_DOUBLE + { mapTimeStringToGdd, mapTimeGddToString }, // DBR_TIME_STRING + { mapTimeShortToGdd, mapTimeGddToShort }, // DBR_TIME_SHORT + { mapTimeFloatToGdd, mapTimeGddToFloat }, // DBR_TIME_FLOAT + { mapTimeEnumToGdd, mapTimeGddToEnum }, // DBR_TIME_ENUM + { mapTimeCharToGdd, mapTimeGddToChar }, // DBR_TIME_CHAR + { mapTimeLongToGdd, mapTimeGddToLong }, // DBR_TIME_LONG + { mapTimeDoubleToGdd, mapTimeGddToDouble }, // DBR_TIME_DOUBLE + { mapStsStringToGdd, mapStsGddToString }, // DBR_GR_STRING + { mapGraphicShortToGdd, mapGraphicGddToShort }, // DBR_GR_SHORT + { mapGraphicFloatToGdd, mapGraphicGddToFloat }, // DBR_GR_FLOAT + { mapGraphicEnumToGdd, mapGraphicGddToEnum }, // DBR_GR_ENUM + { mapGraphicCharToGdd, mapGraphicGddToChar }, // DBR_GR_CHAR + { mapGraphicLongToGdd, mapGraphicGddToLong }, // DBR_GR_LONG + { mapGraphicDoubleToGdd,mapGraphicGddToDouble }, // DBR_GR_DOUBLE + { mapStsStringToGdd, mapStsGddToString }, // DBR_CTRL_STRING + { mapControlShortToGdd, mapControlGddToShort }, // DBR_CTRL_SHORT + { mapControlFloatToGdd, mapControlGddToFloat }, // DBR_CTRL_FLOAT + { mapControlEnumToGdd, mapControlGddToEnum }, // DBR_CTRL_ENUM + { mapControlCharToGdd, mapControlGddToChar }, // DBR_CTRL_CHAR + { mapControlLongToGdd, mapControlGddToLong }, // DBR_CTRL_LONG + { mapControlDoubleToGdd,mapControlGddToDouble } // DBR_CTRL_DOUBLE +}; + diff --git a/src/gdd/dbMapper.h b/src/gdd/dbMapper.h new file mode 100644 index 000000000..409b43894 --- /dev/null +++ b/src/gdd/dbMapper.h @@ -0,0 +1,59 @@ +#ifndef DB_MAPPER_H +#define DB_MAPPER_H + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.1 1996/05/31 13:15:24 jbk + * *add new stuff + * + */ + +#include "aitTypes.h" +#include "gdd.h" + +extern "C" { +#include "db_access.h" +#include "cadef.h" +} + +class gddApplicationTypeTable; + +// Function proto to convert from a db_struct to a gdd. The gdd will +// reference the data in the db_struct if the db_struct points to an +// array. The second argument is the number of elements if db_struct +// represents an array, or zero if the db_struct is a scaler. +typedef gdd* (*to_gdd)(void* db_struct, aitIndex element_count); + +// Function proto to convert from a gdd to a dbr structure, returns the +// number of elements that the value field of db_struct points to if the +// gdd points to an array. The db_struct will reference the data +// contained within the gdd (which is probably also referenced from the user). +typedef int (*to_dbr)(void* db_struct, gdd*); + +struct gddDbrMapFuncTable { + to_gdd conv_gdd; + to_dbr conv_dbr; +}; +typedef struct gddDbrMapFuncTable gddDbrMapFuncTable; + +struct gddDbrToAitTable { + aitEnum type; + aitUint16 app; + char* app_name; +}; +typedef struct gddDbrToAitTable gddDbrToAitTable; + +extern gddDbrToAitTable gddDbrToAit[]; +extern const chtype gddAitToDbr[]; +extern gddDbrMapFuncTable gddMapDbr[]; +void gddMakeMapDBR(gddApplicationTypeTable& tt); +void gddMakeMapDBR(gddApplicationTypeTable* tt); + +#endif + diff --git a/src/gdd/gdd.cc b/src/gdd/gdd.cc new file mode 100644 index 000000000..16b2296a7 --- /dev/null +++ b/src/gdd/gdd.cc @@ -0,0 +1,1225 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// + +// *Revision 1.4 1996/06/25 18:59:01 jbk +// *more fixes for the aitString management functions and mapping menus +// *Revision 1.3 1996/06/24 03:15:32 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.2 1996/06/13 21:31:55 jbk +// *Various fixes and correction - including ref_cnt change to unsigned short +// *Revision 1.1 1996/05/31 13:15:24 jbk +// *add new stuff + +#include +#include +#include +#include "gdd.h" + +gdd_NEWDEL_NEW(gddBounds1D) +gdd_NEWDEL_DEL(gddBounds1D) +gdd_NEWDEL_STAT(gddBounds1D) + +gdd_NEWDEL_NEW(gddBounds2D) +gdd_NEWDEL_DEL(gddBounds2D) +gdd_NEWDEL_STAT(gddBounds2D) + +gdd_NEWDEL_NEW(gddBounds3D) +gdd_NEWDEL_DEL(gddBounds3D) +gdd_NEWDEL_STAT(gddBounds3D) + +gdd_NEWDEL_NEW(gddDestructor) +gdd_NEWDEL_DEL(gddDestructor) +gdd_NEWDEL_STAT(gddDestructor) + +gdd_NEWDEL_NEW(gdd) +gdd_NEWDEL_DEL(gdd) +gdd_NEWDEL_STAT(gdd) + +// --------------------------The gddBounds functions------------------- + +// gddBounds::gddBounds(void) { first=0; count=0; } + +// --------------------------The gddDestructor functions------------------- + +gddStatus gddDestructor::destroy(void* thing) +{ + if(ref_cnt==0 || --ref_cnt==0) + { + run(thing); + delete this; + } + return 0; +} + +void gddDestructor::run(void* thing) +{ + aitInt8* pd = (aitInt8*)thing; + delete [] pd; +} + +void gddFlattenDestructor::run(void*) +{ + return; +} + +void gddContainerCleaner::run(void* v) +{ + gddContainer* cdd = (gddContainer*)v; + int tot = cdd->total(); + int i; + for(i=0;iremove(0); +} + +// --------------------------The gdd functions------------------------- + +gdd::gdd(int app, aitEnum prim, int dimen) +{ + init(app,prim,dimen); +} + +gdd::gdd(int app, aitEnum prim, int dimen, aitUint32* val) +{ + int i; + init(app,prim,dimen); + for(i=0;iset(0,0); break; + case 2: bounds=(gddBounds*)new gddBounds2D; break; + case 3: bounds=(gddBounds*)new gddBounds3D; break; + default: bounds=(gddBounds*)new gddBounds[dim]; break; + } + } +} + +gdd::gdd(gdd* dd) +{ + ref_cnt=1; + copyInfo(dd); +} + +gdd::~gdd(void) +{ + gdd* dd; + gdd* temp; + + // fprintf(stderr,"A gdd is really being deleted %8.8x!!\n",this); + + // this function need to be corrected for use of aitEnumString! + + if(isScaler()) + { + if(primitiveType()==aitEnumFixedString) + { + // aitString type could have destructors + if(destruct) + destruct->destroy(dataPointer()); + else + if(data.FString) delete [] data.FString; + } + else if(primitiveType()==aitEnumString) + { + // aitString type could have destructors + if(destruct) + destruct->destroy(dataAddress()); + else + { + aitString* s = (aitString*)&data; + s->clear(); + } + } + } + else if(isContainer()) + { + if(destruct) + destruct->destroy(voidData()); + else + { + for(dd=(gdd*)voidData();dd;) + { + temp=dd; + dd=dd->next(); + temp->unreference(); + } + freeBounds(); + } + } + else + { + if(destruct) destruct->destroy(voidData()); + if(bounds) freeBounds(); + } +} + +void gdd::freeBounds(void) +{ + if(bounds) + { + switch(dim) + { + case 0: break; + case 1: { gddBounds1D* d1=(gddBounds1D*)bounds; delete d1; } break; + case 2: { gddBounds2D* d2=(gddBounds2D*)bounds; delete d2; } break; + case 3: { gddBounds3D* d3=(gddBounds3D*)bounds; delete d3; } break; + default: delete bounds; break; + } + bounds=NULL; + } +} + +gddStatus gdd::registerDestructor(gddDestructor* dest) +{ + // this is funky, will not register a destructor if one is present + if(destruct) + return gddErrorAlreadyDefined; + else + return replaceDestructor(dest); +} + +gddStatus gdd::replaceDestructor(gddDestructor* dest) +{ + destruct=dest; + + if(isContainer()||isFlat()) + markManaged(); + + return 0; +} + +gddStatus gdd::genCopy(aitEnum t, const void* d) +{ + size_t sz; + aitInt8* buf; + gddStatus rc=0; + + if(isScaler()) + aitConvert(primitiveType(),&data,t,d,1); + else if(isAtomic()) + { + if(!voidData()) + { + sz=DescribedDataSizeBytes(); + if((buf=new aitInt8[sz])==NULL) + rc=gddErrorNewFailed; + else + { + setData(buf); + destruct=new gddDestructor; + aitConvert(primitiveType(),voidData(),t,d,getDataSizeElements()); + } + } + else + aitConvert(primitiveType(),voidData(),t,d,getDataSizeElements()); + } + else + rc=gddErrorTypeMismatch; + + return rc; +} + + +gddStatus gdd::changeType(int app,aitEnum prim) +{ + gddStatus rc=0; + + // this should only be allowed for setting the type if it is + // undefined or if the data is a scaler + + if(isScaler() || primitiveType()==aitEnumInvalid) + { + setApplType(app); + setPrimType(prim); + } + else + rc=gddErrorTypeMismatch; + + return rc; +} + +gddStatus gdd::setBound(unsigned index_dim, aitIndex first, aitIndex count) +{ + gddStatus rc=0; + if(index_dimisContainer()) + { + changeType(dd->applicationType(),dd->primitiveType()); + cdd=(gddContainer*)dd; + gddCursor cur=cdd->getCursor(); + + for(ndd=cur.first();ndd;ndd=cur.next()) + { + pdd=new gdd(ndd->applicationType(), + ndd->primitiveType(),ndd->dimension()); + pdd->setNext((gdd*)voidData()); + setData(pdd); + bounds->setSize(bounds->size()+1); + pdd->copyStuff(ndd,ctype); + } + } + else + { + init(dd->applicationType(),dd->primitiveType(),dd->dimension()); + + if(dd->isScaler()) + data=dd->data; + else // atomic + { + const gddBounds* bnds = dd->getBounds(); + for(i=0;idimension();i++) bounds[i]=bnds[i]; + + switch(ctype) + { + case 1: // copy() + aitUint8* array; + size_t a_size; + a_size=dd->getDataSizeBytes(); + if(array=new aitUint8[a_size]) + { + destruct=new gddDestructor; + memcpy(array,dd->voidData(),a_size); + setData(array); + } + else + rc=gddErrorNewFailed; + break; + case 2: // Dup() + data=dd->getData(); // copy the data reference + destruct=dd->destruct; + if(destruct) destruct->reference(); + break; + case 0: // copyInfo() + default: break; + } + } + } + return rc; +} + +size_t gdd::getDataSizeBytes(void) const +{ + size_t sz=0; + gdd* pdd; + + if(isContainer()) + { + const gddContainer* cdd=(const gddContainer*)this; + gddCursor cur=cdd->getCursor(); + for(pdd=cur.first();pdd;pdd=cur.next()) + sz+=pdd->getTotalSizeBytes(); + } + else + { + if(aitValid(primitiveType())) + { + if(primitiveType()==aitEnumString) + sz+=(size_t)(aitString::totalLength((aitString*)dataAddress(), + getDataSizeElements())); + else + sz+=(size_t)(getDataSizeElements())*aitSize[primitiveType()]; + } + } + return sz; +} + +size_t gdd::DescribedDataSizeBytes(void) const +{ + size_t sz=0; + + // does not work well for aitString - only reports the aitString info + + if(!isContainer()) + sz+=(size_t)(DescribedDataSizeElements())*aitSize[primitiveType()]; + + return sz; +} + +size_t gdd::getTotalSizeBytes(void) const +{ + size_t sz; + unsigned long tmp,tsize; + gdd* pdd; + + // add up size of bounds + size of this DD + sz=sizeof(gdd)+(sizeof(gddBounds)*dimension()); + + // special case the aitString/aitFixedString here - sucks bad + if(isScaler()) + { + if(primitiveType()==aitEnumString) + { + aitString* str=(aitString*)dataAddress(); + sz+=str->length()+1; // include the NULL + } + else if(primitiveType()==aitEnumFixedString) + sz+=sizeof(aitFixedString); + } + else if(isAtomic()) + { + if(aitValid(primitiveType())) + { + if(primitiveType()==aitEnumString) + { + // special case the aitString here + tsize=(size_t)(aitString::totalLength((aitString*)dataPointer(), + getDataSizeElements())); + } + else + tsize=(size_t)(getDataSizeElements())*aitSize[primitiveType()]; + + sz+=(size_t)align8(tsize); // include alignment + } + } + else if(isContainer()) + { + const gddContainer* cdd=(const gddContainer*)this; + gddCursor cur=cdd->getCursor(); + for(pdd=cur.first();pdd;pdd=cur.next()) + sz+=pdd->getTotalSizeBytes(); + } + return sz; +} + +aitUint32 gdd::getDataSizeElements(void) const +{ + unsigned long total=0; + unsigned i; + + if(dimension()==0) + total=1; + else + { + if(voidData()) + for(i=0;i0) flat_dd->convertAddressToOffsets(); + return sz; +} + +// IMPORTANT NOTE: +// Currently the user cannot register an empty container as a prototype. +// The destructor will not be installed to clean up the container when +// it is freed. + +// This is an important function +// Data should be flattened as follows: +// 1) all the GDDs, seen as an array an GDDs +// 2) all the bounds info for all the GDDs +// 3) all the data for all GDDs +// +// In addition, the user should be able to flatten GDDs without the data +// and flatten portions or all the data without flattening GDDs + +size_t gdd::flattenWithAddress(void* buf, size_t size, aitIndex* total_dd) +{ + gdd* pdd = (gdd*)buf; + size_t pos,sz,spos; + aitUint32 i; + gddBounds* bnds; + + // copy this gdd (first one) to get things started + // this is done in two passes - one to copy DDs, one for bounds/data + // need to be able to check if the DD has been flattened already + + if((sz=getTotalSizeBytes())>size) return 0; + pdd[0]=*this; + pdd[0].destruct=NULL; + pdd[0].flags=0; + pos=1; + + // not enough to just copy the gdd info if the primitive type is + // aitString or aitFixedString (even if scaler gdd) + // must special case the strings - that really sucks + + if(isScaler()) + { + // here is special case for the string types + if(primitiveType()==aitEnumFixedString) + { + if(data.FString) + memcpy((char*)&pdd[pos],data.FString,sizeof(aitFixedString)); + else + pdd[0].data.FString=(aitFixedString*)&pdd[pos]; + } + else if(primitiveType()==aitEnumString) + { + aitString* str=(aitString*)pdd[0].dataAddress(); + if(str->string()) + { + memcpy((char*)&pdd[pos],str->string(),str->length()+1); + *str=(char*)&pdd[pos]; + } + } + } + else if(isContainer()) + { + // need to check for bounds in the container and flatten them + if(voidData()) + { + // process all the container's DDs + spos=pos; + pos+=flattenDDs((gddContainer*)this,&pdd[pos], + size-(pos*sizeof(gdd))); + + // copy all the data from the entire container into the buffer + flattenData(&pdd[0],pos,&pdd[pos],size-(pos*sizeof(gdd))); + + pdd[0].markFlat(); + pdd[0].setData(&pdd[spos]); + } + else + sz=0; // failure should occur - cannot flatten an empty container + } + else if(isAtomic()) + { + // Just copy the data from this DD into the buffer, copy bounds + if(bounds) + { + pdd[0].markFlat(); + bnds=(gddBounds*)(&pdd[pos]); + for(i=0;istring()) + { + memcpy(ptr,str->string(),str->length()+1); + *str=(char*)ptr; + ptr+=str->length()+1; + } + } + else if(dd[i].primitiveType()==aitEnumFixedString) + { + if(dd[i].data.FString) + memcpy(ptr,dd[i].data.FString,sizeof(aitFixedString)); + dd[i].data.FString=(aitFixedString*)ptr; + ptr+=sizeof(aitFixedString); + } + } + } + return 0; +} + +int gdd::flattenDDs(gddContainer* dd, void* buf, size_t size) +{ + gdd* ptr=(gdd*)buf; + int i,tot,pos,spos; + gdd *pdd; + gddCursor cur; + + cur=dd->getCursor(); + + // make first pass to copy all the container's DDs into the buffer + for(tot=0,pdd=cur.first();pdd;pdd=pdd->next(),tot++) + { + ptr[tot]=*pdd; + ptr[tot].destruct=NULL; + ptr[tot].setNext(&ptr[tot+1]); + ptr[tot].noReferencing(); + } + ptr[tot-1].setNext(NULL); + + // make second pass to copy all child containers into buffer + for(pos=tot,i=0;igetCursor(); + + for(tdd=cur.first();tdd;tdd=cur.next()) + { + if(tdd->next()) tdd->setNext((gdd*)(pdd+(aitUint32)tdd->next())); + tdd->convertOffsetsToAddress(); + } + } + else + { + if(isAtomic()) + { + bounds=(gddBounds*)(pdd+bnds); + setData(pdd+dp); + if(primitiveType()==aitEnumString) + { + // force all the strings in the array to offsets + str=(aitString*)dataPointer(); + for(i=0;istring()) + { + cstr=str->string(); + str->force(pdd+(unsigned long)cstr); + } + } + } + } + return 0; +} + +gddStatus gdd::convertAddressToOffsets(void) +{ + aitUint8* pdd = (aitUint8*)this; + aitUint8* bnds = (aitUint8*)(bounds); + aitUint8* dp = (aitUint8*)(voidData()); + gddContainer* tdd; + gddCursor cur; + gdd *cdd,*ddd; + aitString* str; + aitIndex i; + const char* cstr; + + // does not ensure that all the members of a container are flat! + if(!isFlat()) + return gddErrorNotAllowed; + + if(isContainer()) + { + tdd=(gddContainer*)this; + cur=tdd->getCursor(); + + for(cdd=cur.first();cdd;) + { + ddd=cdd; + cdd=cur.next(); + ddd->convertAddressToOffsets(); + if(cdd) ddd->setNext((gdd*)((aitUint8*)(ddd->next())-pdd)); + } + + // bounds and data of container to offsets + setData((gdd*)(dp-pdd)); + bounds=(gddBounds*)(bnds-pdd); + } + else + { + if(isAtomic()) + { + if(primitiveType()==aitEnumString) + { + // force all the strings in the array to offsets + str=(aitString*)dataPointer(); + for(i=0;istring(); + if(cstr) str->force(cstr-(const char*)pdd); + } + } + } + return 0; +} + +gddStatus gdd::clear(void) +{ + if(isFlat()||isManaged()) + return gddErrorNotAllowed; + + if(isAtomic()) + { + if(destruct) + { + destruct->destroy(voidData()); + destruct=NULL; + } + freeBounds(); + changeType(0,aitEnumInvalid); + setData(NULL); + } + else if(isContainer()) + { + gddContainer* cdd = (gddContainer*)this; + gddCursor cur = cdd->getCursor(); + gdd *dd,*tdd; + + for(dd=cur.first();dd;) + { + tdd=dd; + dd=cur.next(); + if(tdd->unreference()<0) delete tdd; + } + setBound(0,0,0); + setData(NULL); + } + + return 0; +} + +// Curently gives no indication of failure, which is bad. +// Obviously managed or flattened DDs cannot be redone. +// However, a DD that is within a managed or flattened container can +// use this to describe data - how's that for obscure +// This is required if the "value" is to be allowed within a container +// The "value" could be scaler or an array of unknown size. The same is +// true of the enum strings and "units" attribute. + +gddStatus gdd::reset(aitEnum prim, int dimen, aitIndex* cnt) +{ + int i,app; + gddStatus rc; + + if(isFlat()||isManaged()||isContainer()) + return gddErrorNotAllowed; + + app=applicationType(); + + if((rc=clear())<0) + return rc; + + init(app,prim,dimen); + + for(i=0;iisContainer()) + rc=gddErrorNotSupported; + if(isScaler() && dd->isScaler()) + { + // this is the simple case - just make this scaler look like the other + // not protected against screwing up the string type + setPrimType(dd->primitiveType()); + put(((aitType*)dd->dataAddress())); + } + else if(isAtomic() && dd->isAtomic()) + { + // carefully place values from dd into this + if(dd->getDataSizeElements()>getDataSizeElements()) + rc=gddErrorOutOfBounds; + else + { + if(dd->dimension()>1) + return gddErrorNotSupported; + else + { + aitUint8* arr = (aitUint8*)dataPointer(); + aitConvert( + primitiveType(), + &arr[aitSize[primitiveType()]*dd->getBounds()->first()], + dd->primitiveType(), + dd->dataPointer(), + dd->getBounds()->size()); + } +#if 0 + // should handle single dimensional array as a special case + const Bounds* b = dd->getBounds(); + const Bounds* bs = getBounds(); + aitIndex x[dd->dimension()]; + aitIndex offset,mult; + aitUint8* arr_dest=(aitUint8*)dataPointer(); + aitUint8* arr_src=(aitUint8*)dd->dataPointer(); + int d = dd->dimension(); + int i,j; + + for(i=0;iprimitiveType()], + dd->primitiveType(),arr_src[j],1); + + if(++x[0]>=b[0].size()) + { + for(i=0;i<(d-1);i++) + { + if(x[i]>=b[i].size()) + { + ++x[i+1]; + x[i]=b[i].first(); + } + } + } + j++; + } +#endif + } + } + else if(isScaler()) + { + // just put first element of dd into this scaler - sucks + if(dd->getDataSizeElements()>0) + aitConvert(primitiveType(),dataAddress(), + dd->primitiveType(),dd->dataPointer(),1); + } + else + { + // just put dd scaler into first element of this - sucks + if(getDataSizeElements()>0) + aitConvert(primitiveType(),dataPointer(), + dd->primitiveType(),dd->dataAddress(),1); + } + + return rc; +} + +// ----------------------The gddAtomic functions------------------------- + +gddAtomic::gddAtomic(int app, aitEnum prim, int dimen, ...): + gdd(app,prim,dimen) +{ + va_list ap; + int i; + aitIndex val; + + va_start(ap,dimen); + for(i=0;i0) + for(i=0;i0) + for(i=0;i0) + for(i=0;i0) + for(i=0;inoReferencing(); + temp->setNext(dd_list); + dd_list=temp; + } + setData(dd_list); +} + +gddContainer::gddContainer(gddContainer* ec) +{ + unsigned i; + gdd* dd_list; + gdd* temp; + + copy(ec); + dd_list=NULL; + + // this needs to recursively add to the container, only copy the + // info and bounds information and scaler data, not arrays + + for(i=0;inoReferencing(); + temp->setNext(dd_list); + dd_list=temp; + } + setData(dd_list); +} + +gdd* gddContainer::getDD(aitIndex index) +{ + aitIndex i; + gdd* dd=(gdd*)voidData(); + for(i=0;isize();i++) dd=(gdd*)dd->next(); + return dd; +} + +gddStatus gddContainer::insert(gdd* dd) +{ + dd->setNext(cData()); + setData(dd); + bounds->setSize(bounds->size()+1); + return 0; +} + +gddStatus gddContainer::remove(aitIndex index) +{ + gddCursor cur = getCursor(); + gdd *dd,*prev_dd; + aitIndex i; + + prev_dd=NULL; + + for(i=0; (dd=cur[i]) && i!=index; i++) prev_dd=dd; + + if(i==index && dd) + { + if(prev_dd) + prev_dd->setNext(dd->next()); + else + setData(dd->next()); + + dd->unreference(); + bounds->setSize(bounds->size()-1); + return 0; + } + else + return gddErrorOutOfBounds; +} + +// ------------------------cursor functions------------------------------- + +gdd* gddCursor::operator[](int index) +{ + int i,start; + gdd* dd; + + if(index>=curr_index) + { + start=curr_index; + dd=curr; + } + else + { + start=0; + dd=list->cData(); + } + + for(i=start;inext(); + curr_index=index; + curr=dd; + return dd; +} + diff --git a/src/gdd/gdd.h b/src/gdd/gdd.h new file mode 100644 index 000000000..26f8e542c --- /dev/null +++ b/src/gdd/gdd.h @@ -0,0 +1,1145 @@ +#ifndef GDD_H +#define GDD_H + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.4 1996/06/24 03:15:33 jbk + * *name changes and fixes for aitString and fixed string functions + * *Revision 1.3 1996/06/17 15:24:09 jbk + * *many mods, string class corrections. + * *gdd operator= protection. + * *dbmapper uses aitString array for menus now + * *Revision 1.2 1996/06/13 21:31:56 jbk + * *Various fixes and correction - including ref_cnt change to unsigned short + * *Revision 1.1 1996/05/31 13:15:25 jbk + * *add new stuff + * + */ + +// Still need to handle to network byte order stuff. +// Should always be marked net byte order on CPUs with native network byte +// order. No extra code should be run in this case. This should be +// easy with #defines since the AIT library defines a macro if network +// byte order is not native byte order + +#include +#include +#include +#ifndef vxWorks +#include +#include +#include +#else +#include +#endif + +// strdup is not defined under POSIX +#if defined(_POSIX_C_SOURCE) || defined(vxWorks) +#ifdef __GNUC__ +#define strdup(X) strcpy(new char[strlen(X)+1],X) +#else +#ifndef __EXTENSIONS__ +inline char* strdup(const char* x) +{ + char* y; + y = new char[strlen(x)+1]; + strcpy(y,x); + return y; +} +#endif +#endif +#endif + +#ifndef vxWorks +#if (_POSIX_C_SOURCE < 3) && !defined(solaris) && !defined(SOLARIS) +struct timespec +{ + time_t tv_sec; + long tv_nsec; +}; +typedef struct timespec timespec; +#endif +#endif + +// gddNewDel.h - a simple bunch of macros to make a class use free lists +// with new/remove operators + +#include "gddNewDel.h" +#include "gddUtils.h" +#include "gddErrorCodes.h" +#include "aitTypes.h" +#include "aitConvert.h" + +class gddContainer; +class gddAtomic; +class gddScaler; + +// Not Complete in this prototype: +// - Read only DD. +// - Small array management using free lists + +// - need bit in DD to indicate that no referencing is allowed for the DD +// - need bit to indicate that DD should not be modified, for a container +// this means that the container cannot be added to or removed from. + +// Notes: +// gdds do not need to be linked lists. I could have used a container +// to describe arrays of DDs, and manage the commonly used ones (DD array +// sizes on free lists when the container was destroyed. The constructor +// to the container could take the number of DDs the container will +// manage. This would be similar to the gddBounds method. +// +// Has weak support for changing the dimension of a DD. In other words +// it is not easy to get a "value" DD (defaulting to scaler) and change +// the dimension to a two dimensional array. Need to add routines to +// restructure the bounds. +// +// Need to add methods for inserting const pointers into the DD. +// +// Overriding the operator[] can make the linked list contained in the +// container appear as an array. + +// --------------------------------------------------------------------- +// Describe the bounds of a single dimension in terms of the first +// element and the number of elements in the dimension. + +class gddBounds +{ +public: + // I found a weird memory management quirk with SunOS when constructors + // are present in a class that is used as an array in another class + // as it is in gddBounds2D. The memory manager reallocates the entire + // gddBounds2D in some sort of buffer pool which stays allocated when the + // program completes + + // gddBounds(void); + // gddBounds(aitIndex c); + // gddBounds(aitIndex f, aitIndex c); + + void setSize(aitIndex c); + void set(aitIndex f, aitIndex c); + void get(aitIndex& f, aitIndex& c); + aitIndex size(void) const; + aitIndex first(void) const; + +private: + aitIndex start; + aitIndex count; +}; + +// inline gddBounds::gddBounds(aitIndex c) { start=0; count=c; } +// inline gddBounds::gddBounds(aitIndex f, aitIndex c) { start=f; count=c; } + +inline void gddBounds::setSize(aitIndex c) { count=c; } +inline void gddBounds::set(aitIndex f, aitIndex c) { start=f; count=c; } +inline void gddBounds::get(aitIndex& f, aitIndex& c){ f=start; c=count; } +inline aitIndex gddBounds::size(void) const { return count; } +inline aitIndex gddBounds::first(void) const { return start; } + +// --------------------------------------------------------------------- +// Special managment for 1D-2D-3D bounds - others use normal new/remove. +// Since bounds are maintained as arrays, where the length of the array is +// the dimension of the data, we will manage the normal cases using +// free lists. + +class gddBounds1D +{ +public: + gddBounds1D(void) { } + gddBounds* boundArray(void); + gdd_NEWDEL_FUNC(gddBounds1D) // required for using generic new and remove +private: + gddBounds b[1]; + gdd_NEWDEL_DATA(gddBounds1D) // required for using generic new/remove +}; +inline gddBounds* gddBounds1D::boundArray(void) { return (gddBounds*)b; } + +class gddBounds2D +{ +public: + gddBounds2D(void) { } + gddBounds* boundArray(void); + gdd_NEWDEL_FUNC(gddBounds2D) // required for using generic new and remove +private: + gddBounds b[2]; + gdd_NEWDEL_DATA(gddBounds2D) // required for using generic new/remove +}; +inline gddBounds* gddBounds2D::boundArray(void) { return (gddBounds*)b; } + +class gddBounds3D +{ +public: + gddBounds3D(void) { } + gddBounds* boundArray(void); + gdd_NEWDEL_FUNC(gddBounds3D) // for using generic new and remove +private: + gddBounds b[3]; + gdd_NEWDEL_DATA(gddBounds3D) // required for using generic new/remove +}; +inline gddBounds* gddBounds3D::boundArray(void) { return (gddBounds*)b; } + +// --------------------------------------------------------------------- +// This is a class for managing the destruction of user data held within +// a DD. It allows multiple DDs to reference the same chunk of user +// data. The data would remain alive until the reference count goes to +// zero, at this time the user destructor function will be called with +// a pointer to the piece of data to deal with. The intention here is +// that user will create a subclass of this and supply the virtual +// function run(void*). The default behavior will be to treat the void* +// data as an array of aitInt8 and call remove. + +class gddDestructor +{ +public: + gddDestructor(void); + gddDestructor(void* user_arg); + + void reference(void); + int refCount(void) const; + + gddStatus destroy(void* thing_to_remove); + virtual void run(void* thing_to_remove); + + gdd_NEWDEL_FUNC(gddDestructor) // for using generic new and remove +protected: + aitUint16 ref_cnt; + void* arg; +private: + gdd_NEWDEL_DATA(gddDestructor) +}; + +inline gddDestructor::gddDestructor(void) { ref_cnt=1; arg=NULL; } +inline gddDestructor::gddDestructor(void* usr_arg) { ref_cnt=1; arg=usr_arg; } +inline void gddDestructor::reference(void) { ref_cnt++; } +inline int gddDestructor::refCount(void) const { return ref_cnt; } + +class gddFlattenDestructor : public gddDestructor +{ +public: + gddFlattenDestructor(void) { } + gddFlattenDestructor(void* user_arg):gddDestructor(user_arg) { } + void run(void*); +}; + +class gddContainerCleaner : public gddDestructor +{ +public: + gddContainerCleaner(void) { } + gddContainerCleaner(void* user_arg):gddDestructor(user_arg) { } + void run(void*); +}; + +#define GDD_MANAGED_MASK 0x01 +#define GDD_FLAT_MASK 0x02 +#define GDD_NET_MASK 0x04 +#define GDD_NOREF_MASK 0x08 +#define GDD_CONSTANT_MASK 0x10 + +// --------------------------------------------------------------------- +// class structure for DDs: +// +// gddScaler +// \ +// gddAtomic gddContainer +// \ / +// gdd +// +// All the subclasses of gdd are around to simplify creation and use of +// DDs. + +// --------------------------------------------------------------------- +// This is the main Data Descriptor (DD). + +class gdd +{ +public: + gdd(void); + gdd(gdd*); + gdd(int app); + gdd(int app,aitEnum prim); + gdd(int app,aitEnum prim,int dimen); + gdd(int app,aitEnum prim,int dimen,aitUint32* size_array); + + unsigned applicationType(void) const; + aitEnum primitiveType(void) const; + unsigned dimension(void) const; + aitType& getData(void); + aitType* dataUnion(void); + gddDestructor* destructor(void) const; + + const gddBounds* getBounds(void) const; + const gddBounds* getBounds(int bn) const; + + void dump(void); + void test(void); + + void setPrimType(aitEnum t); + void setApplType(int t); + void destroyData(void); + gddStatus reset(aitEnum primtype,int dimension, aitIndex* dim_counts); + gddStatus clear(void); // clear all fields of the DD, including arrays + gddStatus changeType(int appltype, aitEnum primtype); + gddStatus setBound(unsigned dim_to_set, aitIndex first, aitIndex count); + gddStatus getBound(unsigned dim_to_get, aitIndex& first, aitIndex& count); + gddStatus registerDestructor(gddDestructor*); + gddStatus replaceDestructor(gddDestructor*); + void* dataAddress(void) const; + void* dataPointer(void) const; + void* dataPointer(aitIndex element_offset) const; + + void getTimeStamp(struct timespec* ts); + void getTimeStamp(aitTimeStamp* ts); + void setTimeStamp(struct timespec* ts); + void setTimeStamp(aitTimeStamp* ts); + void setStatus(aitUint32); + void setStatus(aitUint16 high, aitUint16 low); + void getStatus(aitUint32&); + void getStatus(aitUint16& high, aitUint16& low); + + void setStat(aitUint16); + void setSevr(aitUint16); + aitUint16 getStat(void); + aitUint16 getSevr(void); + void setStatSevr(aitInt16 stat, aitInt16 sevr); + void getStatSevr(aitInt16& stat, aitInt16& sevr); + + size_t getTotalSizeBytes(void) const; + size_t getDataSizeBytes(void) const; + aitUint32 getDataSizeElements(void) const; + + // Note for all copy operations: + // Cannot change a container into atomic or scaler type, cannot change + // scaler or atomic type to container + + // copyInfo() will copy DD info only, this means appl, primitive type + // and bounds. Scaler data will be copied, but no arrays. + // copy() will copy DD info, bounds, allocate array data buffer and + // copy data into it. + // Dup() will copy DD info. bounds, data references copied only. + + gddStatus copyInfo(gdd*); + gddStatus copy(gdd*); + gddStatus Dup(gdd*); + + // copy the entire DD structure into a contiguous buffer, return the + // last byte of the buffer that was used. + size_t flattenWithAddress(void* buffer,size_t size,aitIndex* total_dd=0); + size_t flattenWithOffsets(void* buffer,size_t size,aitIndex* total_dd=0); + gddStatus convertOffsetsToAddress(void); + gddStatus convertAddressToOffsets(void); + + int isScaler(void) const; + int isContainer(void) const; + int isAtomic(void) const; + + int isManaged(void) const; + int isFlat(void) const; + int isNetworkByteOrder(void) const; + int isConstant(void) const; + int isNoRef(void) const; + + void markConstant(void); + void markManaged(void); + void markUnmanaged(void); + + // The only way for a user to get rid of a DD is to Unreference it. + // NoReferencing() means that the DD cannot be referenced. + gddStatus noReferencing(void); + gddStatus reference(void); + gddStatus unreference(void); + + gdd& operator=(const gdd& v); + + // get a pointer to the data in the DD + void getRef(aitFloat64*& d); + void getRef(aitFloat32*& d); + void getRef(aitUint32*& d); + void getRef(aitInt32*& d); + void getRef(aitUint16*& d); + void getRef(aitInt16*& d); + void getRef(aitUint8*& d); + void getRef(aitInt8*& d); + void getRef(aitString*& d); + void getRef(aitFixedString*& d); + void getRef(void*& d); + + // make the DD points to user data with a destroy method, + // put the referenced in and adjust the primitive type + void putRef(void* v,aitEnum code, gddDestructor* d = NULL); + void putRef(aitFloat64* v, gddDestructor* d = NULL); + void putRef(aitFloat32* v, gddDestructor* d = NULL); + void putRef(aitUint8* v, gddDestructor* d = NULL); + void putRef(aitInt8* v, gddDestructor* d = NULL); + void putRef(aitUint16* v, gddDestructor* d = NULL); + void putRef(aitInt16* v, gddDestructor* d = NULL); + void putRef(aitUint32* v, gddDestructor* d = NULL); + void putRef(aitInt32* v, gddDestructor* d = NULL); + void putRef(aitString* v, gddDestructor* d = NULL); + void putRef(aitFixedString* v, gddDestructor* d = NULL); + // work with constants + void putRef(const aitFloat64* v, gddDestructor* d = NULL); + void putRef(const aitFloat32* v, gddDestructor* d = NULL); + void putRef(const aitUint8* v, gddDestructor* d = NULL); + void putRef(const aitInt8* v, gddDestructor* d = NULL); + void putRef(const aitUint16* v, gddDestructor* d = NULL); + void putRef(const aitInt16* v, gddDestructor* d = NULL); + void putRef(const aitUint32* v, gddDestructor* d = NULL); + void putRef(const aitInt32* v, gddDestructor* d = NULL); + void putRef(const aitString* v,gddDestructor* d=NULL); + void putRef(const aitFixedString* v,gddDestructor* d=NULL); + void putRef(const gdd*); + + // get the data in the form the user wants (do conversion) + void getConvert(aitFloat64& d); + void getConvert(aitFloat32& d); + void getConvert(aitUint32& d); + void getConvert(aitInt32& d); + void getConvert(aitUint16& d); + void getConvert(aitInt16& d); + void getConvert(aitUint8& d); + void getConvert(aitInt8& d); + void getConvert(aitString& d); + void getConvert(aitFixedString& d); + + // convert the user data to the type in the DD and set value + void putConvert(aitFloat64 d); + void putConvert(aitFloat32 d); + void putConvert(aitUint32 d); + void putConvert(aitInt32 d); + void putConvert(aitUint16 d); + void putConvert(aitInt16 d); + void putConvert(aitUint8 d); + void putConvert(aitInt8 d); + void putConvert(aitString d); + void putConvert(aitFixedString& d); + + // copy the user data into the already set up DD array + gddStatus put(const aitFloat64* const d); + gddStatus put(const aitFloat32* const d); + gddStatus put(const aitUint32* const d); + gddStatus put(const aitInt32* const d); + gddStatus put(const aitUint16* const d); + gddStatus put(const aitInt16* const d); + gddStatus put(const aitUint8* const d); + gddStatus put(const aitInt8* const d); + gddStatus put(const aitString* const d); + gddStatus put(const aitFixedString* const d); + gddStatus put(const gdd* dd); + + // put the user data into the DD and reset the primitive type + void put(aitFloat64 d); + void put(aitFloat32 d); + void put(aitUint32 d); + void put(aitInt32 d); + void put(aitUint16 d); + void put(aitInt16 d); + void put(aitUint8 d); + void put(aitInt8 d); + void put(aitString d); + void put(aitFixedString& d); + void put(aitType* d); + + // copy the array data out of the DD + void get(void* d); + void get(void* d,aitEnum); + void get(aitFloat64* d); + void get(aitFloat32* d); + void get(aitUint32* d); + void get(aitInt32* d); + void get(aitUint16* d); + void get(aitInt16* d); + void get(aitUint8* d); + void get(aitInt8* d); + void get(aitString* d); + void get(aitFixedString* d); + + // copy the data out of the DD + void get(aitFloat64& d); + void get(aitFloat32& d); + void get(aitUint32& d); + void get(aitInt32& d); + void get(aitUint16& d); + void get(aitInt16& d); + void get(aitUint8& d); + void get(aitInt8& d); + void get(aitString& d); + void get(aitFixedString& d); + void get(aitType& d); + + // Same as putRef() methods + gdd& operator=(aitFloat64* v); + gdd& operator=(aitFloat32* v); + gdd& operator=(aitUint32* v); + gdd& operator=(aitInt32* v); + gdd& operator=(aitUint16* v); + gdd& operator=(aitInt16* v); + gdd& operator=(aitUint8* v); + gdd& operator=(aitInt8* v); + gdd& operator=(aitString* v); + gdd& operator=(aitFixedString* v); + + // Same as put() methods + gdd& operator=(aitFloat64 d); + gdd& operator=(aitFloat32 d); + gdd& operator=(aitUint32 d); + gdd& operator=(aitInt32 d); + gdd& operator=(aitUint16 d); + gdd& operator=(aitInt16 d); + gdd& operator=(aitUint8 d); + gdd& operator=(aitInt8 d); + gdd& operator=(aitString d); + // gdd& operator=(aitFixedString d); // not present + + // Same as getRef() methods + gdd::operator aitFloat64*(void) const; + gdd::operator aitFloat32*(void) const; + gdd::operator aitUint32*(void) const; + gdd::operator aitInt32*(void) const; + gdd::operator aitUint16*(void) const; + gdd::operator aitInt16*(void) const; + gdd::operator aitUint8*(void) const; + gdd::operator aitInt8*(void) const; + gdd::operator aitString*(void) const; + gdd::operator aitFixedString*(void) const; + + // Same as get() methods + gdd::operator aitFloat64(void); + gdd::operator aitFloat32(void); + gdd::operator aitUint32(void); + gdd::operator aitInt32(void); + gdd::operator aitUint16(void); + gdd::operator aitInt16(void); + gdd::operator aitUint8(void); + gdd::operator aitInt8(void); + gdd::operator aitString(void); + // gdd::operator aitFixedString(void); // not present + + gddStatus genCopy(aitEnum t, const void* d); + void adjust(gddDestructor* d, void* v, aitEnum type); + void get(aitEnum t,void* v); + void set(aitEnum t,void* v); + + gdd_NEWDEL_FUNC(gdd) // managed on free lists + +protected: + ~gdd(void); // users must call Unreference() + + void init(int app, aitEnum prim, int dimen); + void freeBounds(void); + void dumpInfo(void); + gddStatus copyStuff(gdd*,int type); + + size_t DescribedDataSizeBytes(void) const; + aitUint32 DescribedDataSizeElements(void) const; + + void markFlat(void); + gddStatus flattenData(gdd* dd, int tot_dds, void* buf, size_t size); + int flattenDDs(gddContainer* dd, void* buf, size_t size); + aitUint32 align8(unsigned long count) const; + + void* voidData(void) const; + void setData(void* d); + + aitType data; // array pointer or scaler data + gdd_NEWDEL_DATA(gdd) // required for using generic new and remove + gddBounds* bounds; // array of bounds information length dim + gddDestructor* destruct; // NULL=none supplied, use remove + aitTimeStamp time_stamp; + aitStatus status; + aitUint16 appl_type; // application type code + aitUint8 prim_type; // primitive type code + aitUint8 dim; // 0=scaler, >0=array +private: + aitUint16 ref_cnt; + aitUint8 flags; +}; + +inline void* gdd::voidData(void) const { return data.Pointer; } +inline void gdd::setData(void* d) { data.Pointer=d; } +inline gddDestructor* gdd::destructor(void) const { return destruct; } + +inline gdd::gdd(void) { init(0,aitEnumInvalid,0); } +inline gdd::gdd(int app) { init(app,aitEnumInvalid,0); } +inline gdd::gdd(int app,aitEnum prim) { init(app,prim,0); } + +inline unsigned gdd::applicationType(void) const{ return appl_type; } +inline aitEnum gdd::primitiveType(void) const { return (aitEnum)prim_type; } +inline const gddBounds* gdd::getBounds(void) const { return bounds; } +inline const gddBounds* gdd::getBounds(int bn) const { return &bounds[bn]; } + +inline unsigned gdd::dimension(void) const { return dim; } +inline aitType& gdd::getData(void) { return data; } +inline aitType* gdd::dataUnion(void) { return &data; } +inline void gdd::setPrimType(aitEnum t) { prim_type=(aitUint8)t; } +inline void gdd::setApplType(int t) { appl_type=(aitUint16)t; } +inline gddStatus gdd::copyInfo(gdd* dd) { return copyStuff(dd,0); } +inline gddStatus gdd::copy(gdd* dd) { return copyStuff(dd,1); } +inline gddStatus gdd::Dup(gdd* dd) { return copyStuff(dd,2); } +inline void* gdd::dataAddress(void) const { return (void*)&data; } +inline void* gdd::dataPointer(void) const { return voidData(); } + +inline aitUint32 gdd::align8(unsigned long count) const +{ + unsigned long tmp=count&(~((unsigned long)0x07)); + return (tmp!=count)?tmp+8:tmp; +} + +inline void* gdd::dataPointer(aitIndex f) const + { return (void*)(((aitUint8*)voidData())+aitSize[primitiveType()]*f); } + +inline int gdd::isManaged(void) const { return flags&GDD_MANAGED_MASK; } +inline int gdd::isFlat(void) const { return flags&GDD_FLAT_MASK; } +inline int gdd::isNoRef(void) const { return flags&GDD_NOREF_MASK; } +inline int gdd::isConstant(void) const { return flags&GDD_CONSTANT_MASK; } +inline int gdd::isNetworkByteOrder(void) const { return flags&GDD_NET_MASK; } + +inline void gdd::markConstant(void) { flags|=GDD_CONSTANT_MASK; } +inline void gdd::markFlat(void) { flags|=GDD_FLAT_MASK; } +inline void gdd::markManaged(void) { flags|=GDD_MANAGED_MASK; } +inline void gdd::markUnmanaged(void) { flags&=~GDD_MANAGED_MASK; } + +inline void gdd::getTimeStamp(struct timespec* ts) + { ts->tv_sec=time_stamp.tv_sec; ts->tv_nsec=time_stamp.tv_nsec; } +inline void gdd::setTimeStamp(struct timespec* ts) { + time_stamp.tv_sec=(aitUint32)ts->tv_sec; + time_stamp.tv_nsec=(aitUint32)ts->tv_nsec; } +inline void gdd::getTimeStamp(aitTimeStamp* ts) { *ts=time_stamp; } +inline void gdd::setTimeStamp(aitTimeStamp* ts) { time_stamp=*ts; } +inline void gdd::setStatus(aitUint32 s) { status=s; } +inline void gdd::getStatus(aitUint32& s) { s=status; } +inline void gdd::setStatus(aitUint16 high, aitUint16 low) + { status=(((aitUint32)high)<<16)|low; } +inline void gdd::getStatus(aitUint16& high, aitUint16& low) + { high=(aitUint16)(status>>16); low=(aitUint16)(status&0x0000ffff); } + +inline void gdd::setStat(aitUint16 s) + { aitUint16* x = (aitUint16*)&status; x[0]=s; } +inline void gdd::setSevr(aitUint16 s) + { aitUint16* x = (aitUint16*)&status; x[1]=s; } +inline aitUint16 gdd::getStat(void) + { aitUint16* x = (aitUint16*)&status; return x[0]; } +inline aitUint16 gdd::getSevr(void) + { aitUint16* x = (aitUint16*)&status; return x[1]; } +inline void gdd::getStatSevr(aitInt16& st, aitInt16& se) + { st=getStat(); se=getSevr(); } +inline void gdd::setStatSevr(aitInt16 st, aitInt16 se) + { setStat(st); setSevr(se); } + +inline gdd& gdd::operator=(const gdd& v) + { memcpy(this,&v,sizeof(gdd)); return *this; } + +inline int gdd::isScaler(void) const { return dimension()==0?1:0; } +inline int gdd::isContainer(void) const + { return (primitiveType()==aitEnumContainer)?1:0; } +inline int gdd::isAtomic(void) const + { return (dimension()>0&&primitiveType()!=aitEnumContainer)?1:0; } +inline gddStatus gdd::noReferencing(void) +{ + int rc=0; + if(ref_cnt>1) rc=gddErrorNotAllowed; + else flags|=GDD_NOREF_MASK; + return rc; +} +inline gddStatus gdd::reference(void) +{ + int rc=0; + + if(isNoRef()) rc=gddErrorNotAllowed; + else ref_cnt++; + + if(ref_cnt>((1<run(this); + } + else if(!isFlat()) + delete this; + } + return rc; +} + +inline void gdd::destroyData(void) +{ + if(destruct) + { + // up to destructor to free the bounds + if(isContainer()) + destruct->run(this); + else + destruct->run(voidData()); + } +} + +inline void gdd::adjust(gddDestructor* d, void* v, aitEnum type) +{ + if(destruct) destruct->destroy(voidData()); + destruct=d; + if(destruct) destruct->reference(); + setPrimType(type); + setData(v); +} + +inline void gdd::get(aitEnum t,void* v) + { aitConvert(t,v,primitiveType(),&data,1); } +inline void gdd::set(aitEnum t,void* v) + { aitConvert(primitiveType(),&data,t,v,1); } + +inline void gdd::getRef(aitFloat64*& d) { d=(aitFloat64*)voidData(); } +inline void gdd::getRef(aitFloat32*& d) { d=(aitFloat32*)voidData(); } +inline void gdd::getRef(aitUint32*& d) { d=(aitUint32*)voidData(); } +inline void gdd::getRef(aitInt32*& d) { d=(aitInt32*)voidData(); } +inline void gdd::getRef(aitUint16*& d) { d=(aitUint16*)voidData(); } +inline void gdd::getRef(aitInt16*& d) { d=(aitInt16*)voidData(); } +inline void gdd::getRef(aitUint8*& d) { d=(aitUint8*)voidData(); } +inline void gdd::getRef(aitInt8*& d) { d=(aitInt8*)voidData(); } +inline void gdd::getRef(aitString*& d) { d=(aitString*)voidData(); } +inline void gdd::getRef(void*& d) { d=voidData(); } +inline void gdd::getRef(aitFixedString*& d) { d=(aitFixedString*)voidData(); } + +inline void gdd::putRef(void* v,aitEnum code, gddDestructor* d) + { adjust(d, v, code); } +inline void gdd::putRef(aitFloat64* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumFloat64); } +inline void gdd::putRef(aitFloat32* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumFloat32); } +inline void gdd::putRef(aitUint8* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumUint8); } +inline void gdd::putRef(aitInt8* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumInt8); } +inline void gdd::putRef(aitUint16* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumUint16); } +inline void gdd::putRef(aitInt16* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumInt16); } +inline void gdd::putRef(aitUint32* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumUint32); } +inline void gdd::putRef(aitInt32* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumInt32); } +inline void gdd::putRef(aitString* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumString); } +inline void gdd::putRef(aitFixedString* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumFixedString); } + +inline void gdd::putRef(const aitFloat64* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumFloat64); markConstant(); } +inline void gdd::putRef(const aitFloat32* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumFloat32); markConstant(); } +inline void gdd::putRef(const aitUint8* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumUint8); markConstant(); } +inline void gdd::putRef(const aitInt8* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumInt8); markConstant(); } +inline void gdd::putRef(const aitUint16* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumUint16); markConstant(); } +inline void gdd::putRef(const aitInt16* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumInt16); markConstant(); } +inline void gdd::putRef(const aitUint32* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumUint32); markConstant(); } +inline void gdd::putRef(const aitInt32* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumInt32); markConstant(); } +inline void gdd::putRef(const aitString* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumString); markConstant(); } +inline void gdd::putRef(const aitFixedString* v, gddDestructor* d) + { adjust(d, (void*)v, aitEnumFixedString); markConstant(); } + +inline void gdd::getConvert(aitFloat64& d) { get(aitEnumFloat64,&d); } +inline void gdd::getConvert(aitFloat32& d) { get(aitEnumFloat32,&d); } +inline void gdd::getConvert(aitUint32& d) { get(aitEnumUint32,&d); } +inline void gdd::getConvert(aitInt32& d) { get(aitEnumInt32,&d); } +inline void gdd::getConvert(aitUint16& d) { get(aitEnumUint16,&d); } +inline void gdd::getConvert(aitInt16& d) { get(aitEnumInt16,&d); } +inline void gdd::getConvert(aitUint8& d) { get(aitEnumUint8,&d); } +inline void gdd::getConvert(aitInt8& d) { get(aitEnumInt8,&d); } +inline void gdd::getConvert(aitString& d) { get(aitEnumString,&d); } +inline void gdd::getConvert(aitFixedString& d){get(aitEnumFixedString,d.fixed_string);} + +inline void gdd::putConvert(aitFloat64 d){ set(aitEnumFloat64,&d); } +inline void gdd::putConvert(aitFloat32 d){ set(aitEnumFloat32,&d); } +inline void gdd::putConvert(aitUint32 d) { set(aitEnumUint32,&d); } +inline void gdd::putConvert(aitInt32 d) { set(aitEnumInt32,&d); } +inline void gdd::putConvert(aitUint16 d) { set(aitEnumUint16,&d); } +inline void gdd::putConvert(aitInt16 d) { set(aitEnumInt16,&d); } +inline void gdd::putConvert(aitUint8 d) { set(aitEnumUint8,&d); } +inline void gdd::putConvert(aitInt8 d) { set(aitEnumInt8,&d); } +inline void gdd::putConvert(aitString d) { set(aitEnumString,&d); } +inline void gdd::putConvert(aitFixedString& d) { set(aitEnumFixedString,d.fixed_string); } + +inline gddStatus gdd::put(const aitFloat64* const d) + { return genCopy(aitEnumFloat64,d); } +inline gddStatus gdd::put(const aitFloat32* const d) + { return genCopy(aitEnumFloat32,d); } +inline gddStatus gdd::put(const aitUint32* const d) + { return genCopy(aitEnumUint32,d); } +inline gddStatus gdd::put(const aitInt32* const d) + { return genCopy(aitEnumInt32,d); } +inline gddStatus gdd::put(const aitUint16* const d) + { return genCopy(aitEnumUint16,d); } +inline gddStatus gdd::put(const aitInt16* const d) + { return genCopy(aitEnumInt16,d); } +inline gddStatus gdd::put(const aitUint8* const d) + { return genCopy(aitEnumUint8,d); } +inline gddStatus gdd::put(const aitInt8* const d) + { return genCopy(aitEnumInt8,d); } + +// currently unprotected from destroying an atomic gdd +inline void gdd::put(aitFloat64 d){ data.Float64=d;setPrimType(aitEnumFloat64);} +inline void gdd::put(aitFloat32 d){ data.Float32=d;setPrimType(aitEnumFloat32);} +inline void gdd::put(aitUint32 d) { data.Uint32=d; setPrimType(aitEnumUint32); } +inline void gdd::put(aitInt32 d) { data.Int32=d; setPrimType(aitEnumInt32); } +inline void gdd::put(aitUint16 d) { data.Uint16=d; setPrimType(aitEnumUint16); } +inline void gdd::put(aitInt16 d) { data.Int16=d; setPrimType(aitEnumInt16); } +inline void gdd::put(aitUint8 d) { data.Uint8=d; setPrimType(aitEnumUint8); } +inline void gdd::put(aitInt8 d) { data.Int8=d; setPrimType(aitEnumInt8); } +inline void gdd::put(aitType* d) { data=*d; } +inline void gdd::put(aitString d) + { aitString* s=(aitString*)&data; *s=d; setPrimType(aitEnumString); } +inline void gdd::put(aitFixedString& d) + { data.FString=&d; setPrimType(aitEnumFixedString); } + +inline void gdd::get(void* d) + { aitConvert(primitiveType(),d,primitiveType(),voidData(),getDataSizeElements());} +inline void gdd::get(void* d,aitEnum e) + { aitConvert(e,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitFloat64* d) + { aitConvert(aitEnumFloat64,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitFloat32* d) + { aitConvert(aitEnumFloat32,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitUint32* d) + { aitConvert(aitEnumUint32,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitInt32* d) + { aitConvert(aitEnumInt32,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitUint16* d) + { aitConvert(aitEnumUint16,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitInt16* d) + { aitConvert(aitEnumInt16,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitUint8* d) + { aitConvert(aitEnumUint8,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitInt8* d) + { aitConvert(aitEnumInt8,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitString* d) + { aitConvert(aitEnumString,d,primitiveType(),voidData(),getDataSizeElements()); } +inline void gdd::get(aitFixedString* d) + { aitConvert(aitEnumFixedString,d,primitiveType(),voidData(),getDataSizeElements()); } + +inline void gdd::get(aitFloat64& d) { + if(primitiveType()==aitEnumFloat64) d=getData().Float64; + else get(aitEnumFloat64,&d); +} +inline void gdd::get(aitFloat32& d) { + if(primitiveType()==aitEnumFloat32) d=getData().Float32; + else get(aitEnumFloat32,&d); +} +inline void gdd::get(aitUint32& d) { + if(primitiveType()==aitEnumUint32) d=getData().Uint32; + else get(aitEnumUint32,&d); +} +inline void gdd::get(aitInt32& d) { + if(primitiveType()==aitEnumInt32) d=getData().Int32; + else get(aitEnumInt32,&d); +} +inline void gdd::get(aitUint16& d) { + if(primitiveType()==aitEnumUint16) d=getData().Uint16; + else get(aitEnumUint16,&d); +} +inline void gdd::get(aitInt16& d) { + if(primitiveType()==aitEnumInt16) d=getData().Int16; + else get(aitEnumInt16,&d); +} +inline void gdd::get(aitUint8& d) { + if(primitiveType()==aitEnumUint8) d=getData().Uint8; + else get(aitEnumUint8,&d); +} +inline void gdd::get(aitInt8& d) { + if(primitiveType()==aitEnumInt8) d=getData().Int8; + else get(aitEnumInt8,&d); +} +inline void gdd::get(aitString& d) { + if(primitiveType()==aitEnumString) {aitString* s=(aitString*)&data; d=*s; } + else get(aitEnumString,&d); +} +inline void gdd::get(aitFixedString& d) { + if(primitiveType()==aitEnumFixedString) { d=*(getData().FString); } + else get(aitEnumFixedString,&d); +} +inline void gdd::get(aitType& d) { d=data; } + +inline gdd& gdd::operator=(aitFloat64* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitFloat32* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitUint32* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitInt32* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitUint16* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitInt16* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitUint8* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitInt8* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitString* v) { putRef(v); return *this;} +inline gdd& gdd::operator=(aitFixedString* v){ putRef(v); return *this;} + +inline gdd& gdd::operator=(aitFloat64 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitFloat32 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitUint32 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitInt32 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitUint16 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitInt16 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitUint8 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitInt8 d) { put(d); return *this; } +inline gdd& gdd::operator=(aitString d) { put(d); return *this; } + +inline gdd::operator aitFloat64*(void) const{ return (aitFloat64*)voidData(); } +inline gdd::operator aitFloat32*(void) const{ return (aitFloat32*)voidData(); } +inline gdd::operator aitUint32*(void) const { return (aitUint32*)voidData(); } +inline gdd::operator aitInt32*(void) const { return (aitInt32*)voidData(); } +inline gdd::operator aitUint16*(void) const { return (aitUint16*)voidData(); } +inline gdd::operator aitInt16*(void) const { return (aitInt16*)voidData(); } +inline gdd::operator aitUint8*(void) const { return (aitUint8*)voidData(); } +inline gdd::operator aitInt8*(void) const { return (aitInt8*)voidData(); } +inline gdd::operator aitString*(void) const { return (aitString*)voidData(); } +inline gdd::operator aitFixedString*(void) const + { return (aitFixedString*)voidData(); } + +inline gdd::operator aitFloat64(void) { aitFloat64 d; get(d); return d; } +inline gdd::operator aitFloat32(void) { aitFloat32 d; get(d); return d; } +inline gdd::operator aitUint32(void) { aitUint32 d; get(d); return d; } +inline gdd::operator aitInt32(void) { aitInt32 d; get(d); return d; } +inline gdd::operator aitUint16(void) { aitUint16 d; get(d); return d; } +inline gdd::operator aitInt16(void) { aitInt16 d; get(d); return d; } +inline gdd::operator aitUint8(void) { aitUint8 d; get(d); return d; } +inline gdd::operator aitInt8(void) { aitInt8 d; get(d); return d; } +inline gdd::operator aitString(void) { aitString d; get(d); return d; } + +// --------------------------------------------------------------------- +// Adds ability to put array data into a DD, get it out, and adjust it + +class gddAtomic : public gdd +{ +public: + gddAtomic(void) { } + gddAtomic(gddAtomic* ad) : gdd(ad) { } + gddAtomic(int app) : gdd(app) { } + gddAtomic(int app, aitEnum prim) : gdd(app,prim) { } + gddAtomic(int app, aitEnum prim, int dimen, aitUint32* size_array): + gdd(app,prim,dimen,size_array) { } + gddAtomic(int app, aitEnum prim, int dimen, ...); + + // view dimension size info as a bounding box instead of first/count + gddStatus getBoundingBoxSize(aitUint32* put_info_here); + gddStatus setBoundingBoxSize(const aitUint32* const get_info_from_here); + gddStatus getBoundingBoxOrigin(aitUint32* put_info_here); + gddStatus setBoundingBoxOrigin(const aitUint32* const get_info_from_here); + + void dump(void); + void test(void); + + gddAtomic& operator=(aitFloat64* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitFloat32* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitUint32* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitInt32* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitUint16* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitInt16* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitUint8* v) { *((gdd*)this)=v; return *this; } + gddAtomic& operator=(aitInt8* v) { *((gdd*)this)=v; return *this; } + +protected: + ~gddAtomic(void) { } +private: +}; + +// ------------------------------------------------------------------------ +// Add handling of the special case where the data is a scaler - the +// dimension is zero + +class gddScaler : public gddAtomic +{ +public: + gddScaler(void) { } + gddScaler(gddScaler* ad) : gddAtomic(ad) { } + gddScaler(int app) : gddAtomic(app) { } + gddScaler(int app,aitEnum prim) : gddAtomic(app,prim) { } + + void dump(void); + void test(void); + + gddScaler& operator=(aitFloat64 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitFloat32 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitUint32 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitInt32 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitUint16 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitInt16 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitUint8 d) { *((gdd*)this)=d; return *this; } + gddScaler& operator=(aitInt8 d) { *((gdd*)this)=d; return *this; } + +protected: + gddScaler(int app, aitEnum prim, int dimen, aitUint32* size_array): + gddAtomic(app,prim,dimen,size_array) { } + ~gddScaler(void) { } + + // disallow + const gddBounds* getBounds(void) { return NULL; } + gddStatus getBoundingBoxSize(aitUint32*) { return gddErrorNotAllowed; } + gddStatus setBoundingBoxSize(const aitUint32* const) + { return gddErrorNotAllowed; } + gddStatus getBoundingBoxOrigin(aitUint32*) { return gddErrorNotAllowed; } + gddStatus setBoundingBoxOrigin(const aitUint32* const) + { return gddErrorNotAllowed; } + gddStatus setBound(int,aitIndex,aitIndex) { return gddErrorNotAllowed; } + gddStatus getBound(int,aitIndex&,aitIndex&) { return gddErrorNotAllowed; } + + // disallow + void adjust(aitFloat64* const, gddDestructor*) { } + void adjust(aitFloat32* const, gddDestructor*) { } + void adjust(aitUint32* const, gddDestructor*) { } + void adjust(aitInt32* const, gddDestructor*) { } + void adjust(aitUint16* const, gddDestructor*) { } + void adjust(aitInt16* const, gddDestructor*) { } + void adjust(aitUint8* const, gddDestructor*) { } + void adjust(aitInt8* const, gddDestructor*) { } + +private: +}; + +// ------------------------------------------------------------------------ + +class gddCursor; + +// this class needs to be able to register a destructor for the container + +class gddContainer : public gdd +{ +public: + gddContainer(void); + gddContainer(int app); + gddContainer(gddContainer* ac); + gddContainer(int app,int number_of_things_in_it); + + gddStatus insert(gdd*); + gddStatus remove(aitIndex index); + int total(void); + + void dump(void); + void test(void); + + // The following are slow and inefficient + gdd* getDD(aitIndex index); + gdd* getDD(aitIndex index,gddScaler*&); + gdd* getDD(aitIndex index,gddAtomic*&); + gdd* getDD(aitIndex index,gddContainer*&); + gdd* operator[](aitIndex index); + + // preferred method for looking into a container + gddCursor getCursor(void) const; + gdd* cData(void) const; + +protected: + gddContainer(int,int,int,int*) { } + ~gddContainer(void) { } + + void cInit(int num_things_within); + gddStatus changeType(int,aitEnum) { return gddErrorNotAllowed; } + gddStatus setBound(int,aitIndex,aitIndex) { return gddErrorNotAllowed; } + gddStatus getBound(int,aitIndex&,aitIndex&) { return gddErrorNotAllowed; } + gddStatus setBound(aitIndex,aitIndex); + +private: + friend class gddCursor; +}; + +inline gdd* gddContainer::cData(void) const + { return (gdd*)voidData(); } +inline int gddContainer::total(void) + { return bounds->size(); } +inline gdd* gddContainer::operator[](aitIndex index) + { return getDD(index); } +inline gdd* gddContainer::getDD(aitIndex index,gddScaler*& dd) + { return (gdd*)(dd=(gddScaler*)getDD(index)); } +inline gdd* gddContainer::getDD(aitIndex index,gddAtomic*& dd) + { return (gdd*)(dd=(gddAtomic*)getDD(index)); } +inline gdd* gddContainer::getDD(aitIndex index,gddContainer*& dd) + { return (gdd*)(dd=(gddContainer*)getDD(index)); } +inline gddStatus gddContainer::setBound(aitIndex f, aitIndex c) + { bounds->set(f,c); return 0; } + +class gddCursor +{ +public: + gddCursor(void); + gddCursor(const gddContainer* ec); + + gdd* first(void); + gdd* first(gddScaler*&); + gdd* first(gddAtomic*&); + gdd* first(gddContainer*&); + + gdd* next(void); + gdd* next(gddScaler*&); + gdd* next(gddAtomic*&); + gdd* next(gddContainer*&); + + gdd* current(void); + gdd* current(gddScaler*&); + gdd* current(gddAtomic*&); + gdd* current(gddContainer*&); + + gdd* operator[](int index); +private: + const gddContainer* list; + gdd* curr; + int curr_index; +}; + +inline gddCursor::gddCursor(void):list(NULL) + { curr=NULL; } +inline gddCursor::gddCursor(const gddContainer* ec):list(ec) + { curr=ec->cData(); curr_index=0; } + +inline gdd* gddCursor::first(void) + { curr=list->cData(); curr_index=0; return curr; } +inline gdd* gddCursor::first(gddScaler*& dd) + { return (gdd*)(dd=(gddScaler*)first()); } +inline gdd* gddCursor::first(gddAtomic*& dd) + { return (gdd*)(dd=(gddAtomic*)first()); } +inline gdd* gddCursor::first(gddContainer*& dd) + { return (gdd*)(dd=(gddContainer*)first()); } + +inline gdd* gddCursor::next(void) + { if(curr) { curr_index++;curr=curr->next(); } return curr; } +inline gdd* gddCursor::next(gddScaler*& dd) + { return (gdd*)(dd=(gddScaler*)next()); } +inline gdd* gddCursor::next(gddAtomic*& dd) + { return (gdd*)(dd=(gddAtomic*)next()); } +inline gdd* gddCursor::next(gddContainer*& dd) + { return (gdd*)(dd=(gddContainer*)next()); } + +inline gdd* gddCursor::current(void) + { return curr; } +inline gdd* gddCursor::current(gddScaler*& dd) + { return (gdd*)(dd=(gddScaler*)current()); } +inline gdd* gddCursor::current(gddAtomic*& dd) + { return (gdd*)(dd=(gddAtomic*)current()); } +inline gdd* gddCursor::current(gddContainer*& dd) + { return (gdd*)(dd=(gddContainer*)current()); } + +#endif diff --git a/src/gdd/gddAppDefs.cc b/src/gdd/gddAppDefs.cc new file mode 100644 index 000000000..0ad6e5216 --- /dev/null +++ b/src/gdd/gddAppDefs.cc @@ -0,0 +1,253 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// + +// *Revision 1.3 1996/06/24 03:15:34 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.2 1996/06/17 15:24:11 jbk +// *many mods, string class corrections. +// *gdd operator= protection. +// *dbmapper uses aitString array for menus now +// *Revision 1.1 1996/05/31 13:15:26 jbk +// *add new stuff + +#include "gddAppTable.h" + +static char* thing = "12345678"; + +// useless utility function +gddApplicationTypeTable* gddGenerateApplicationTypeTable(long x/*=(1<<13)*/) +{ + gddApplicationTypeTable* tt = new gddApplicationTypeTable((unsigned int)x); + return tt; +} + +void gddApplicationTypeTable::GenerateTypes(void) +{ + gddScaler* add_units = new gddScaler(0); + gddAtomic* add_enum = new gddAtomic(0,aitEnumString,1,16); + + aitString add_enum_buf[16]; + aitString add_units_buf = thing; + + add_units->put(add_units_buf); + add_enum->putRef(add_enum_buf); + + // ---------------------------------------------------------------- + // register simple types + + // should I allow a dd retrieved through the tag table to be adjusted + // even though it is flattened? What if an array needs to change size + + // or type in a flattened dd? + + // value - filled by user no dd to register + // units - variable length of array of chars + + // not really required attributes - they are contained in DDs + registerApplicationType(GDD_NAME_STATUS); + registerApplicationType(GDD_NAME_SEVERITY); + registerApplicationType(GDD_NAME_SECONDS); + registerApplicationType(GDD_NAME_NANOSECONDS); + + // required attributes + int type_prec=registerApplicationType(GDD_NAME_PRECISION); + int type_ghigh=registerApplicationType(GDD_NAME_GRAPH_HIGH); + int type_glow=registerApplicationType(GDD_NAME_GRAPH_LOW); + int type_chigh=registerApplicationType(GDD_NAME_CONTROL_HIGH); + int type_clow=registerApplicationType(GDD_NAME_CONTROL_LOW); + int type_ahigh=registerApplicationType(GDD_NAME_ALARM_HIGH); + int type_alow=registerApplicationType(GDD_NAME_ALARM_LOW); + int type_awhigh=registerApplicationType(GDD_NAME_ALARM_WARN_HIGH); + int type_awlow=registerApplicationType(GDD_NAME_ALARM_WARN_LOW); + int type_maxele=registerApplicationType(GDD_NAME_MAX_ELEMENTS); + int type_value=registerApplicationType(GDD_NAME_VALUE); + int type_units=registerApplicationTypeWithProto(GDD_NAME_UNITS,add_units); + int type_menu=registerApplicationTypeWithProto(GDD_NAME_ENUM,add_enum); + + // ---------------------------------------------------------------- + // register container types - not as easy + + // container of all PV attributes + gddContainer* cdd_attr=new gddContainer(1); + cdd_attr->insert(getDD(type_prec)); + cdd_attr->insert(getDD(type_ghigh)); + cdd_attr->insert(getDD(type_glow)); + cdd_attr->insert(getDD(type_chigh)); + cdd_attr->insert(getDD(type_clow)); + cdd_attr->insert(getDD(type_ahigh)); + cdd_attr->insert(getDD(type_alow)); + cdd_attr->insert(getDD(type_awhigh)); + cdd_attr->insert(getDD(type_awlow)); + cdd_attr->insert(getDD(type_units)); + cdd_attr->insert(getDD(type_maxele)); + registerApplicationTypeWithProto(GDD_NAME_ATTRIBUTES,cdd_attr); + + // container of everything about a PV + gddContainer* cdd_all=new gddContainer(1); + cdd_all->insert(getDD(type_prec)); + cdd_all->insert(getDD(type_ghigh)); + cdd_all->insert(getDD(type_glow)); + cdd_all->insert(getDD(type_chigh)); + cdd_all->insert(getDD(type_clow)); + cdd_all->insert(getDD(type_ahigh)); + cdd_all->insert(getDD(type_alow)); + cdd_all->insert(getDD(type_awhigh)); + cdd_all->insert(getDD(type_awlow)); + cdd_all->insert(getDD(type_units)); + cdd_all->insert(getDD(type_value)); + registerApplicationTypeWithProto(GDD_NAME_ALL,cdd_all); + + // ------------- generate required dbr containers ----------------- + + // DBR_GR_SHORT + gddContainer* cdd_gr_short=new gddContainer(0); + cdd_gr_short->insert(new gddScaler(type_value,aitEnumInt16)); + cdd_gr_short->insert(new gddScaler(type_ghigh,aitEnumInt16)); + cdd_gr_short->insert(new gddScaler(type_glow,aitEnumInt16)); + cdd_gr_short->insert(new gddScaler(type_ahigh,aitEnumInt16)); + cdd_gr_short->insert(new gddScaler(type_alow,aitEnumInt16)); + cdd_gr_short->insert(new gddScaler(type_awhigh,aitEnumInt16)); + cdd_gr_short->insert(new gddScaler(type_awlow,aitEnumInt16)); + cdd_gr_short->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_gr_short",cdd_gr_short); + + // DBR_GR_FLOAT + gddContainer* cdd_gr_float=new gddContainer(0); + cdd_gr_float->insert(new gddScaler(type_value,aitEnumFloat32)); + cdd_gr_float->insert(new gddScaler(type_prec,aitEnumInt16)); + cdd_gr_float->insert(new gddScaler(type_ghigh,aitEnumFloat32)); + cdd_gr_float->insert(new gddScaler(type_glow,aitEnumFloat32)); + cdd_gr_float->insert(new gddScaler(type_ahigh,aitEnumFloat32)); + cdd_gr_float->insert(new gddScaler(type_alow,aitEnumFloat32)); + cdd_gr_float->insert(new gddScaler(type_awhigh,aitEnumFloat32)); + cdd_gr_float->insert(new gddScaler(type_awlow,aitEnumFloat32)); + cdd_gr_float->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_gr_float",cdd_gr_float); + + // DBR_GR_ENUM + gddContainer* cdd_gr_enum=new gddContainer(0); + cdd_gr_enum->insert(getDD(type_menu)); + cdd_gr_enum->insert(new gddScaler(type_value,aitEnumEnum16)); + registerApplicationTypeWithProto("dbr_gr_enum",cdd_gr_enum); + + // DBR_GR_CHAR + gddContainer* cdd_gr_char=new gddContainer(0); + cdd_gr_char->insert(new gddScaler(type_value,aitEnumInt8)); + cdd_gr_char->insert(new gddScaler(type_ghigh,aitEnumInt8)); + cdd_gr_char->insert(new gddScaler(type_glow,aitEnumInt8)); + cdd_gr_char->insert(new gddScaler(type_ahigh,aitEnumInt8)); + cdd_gr_char->insert(new gddScaler(type_alow,aitEnumInt8)); + cdd_gr_char->insert(new gddScaler(type_awhigh,aitEnumInt8)); + cdd_gr_char->insert(new gddScaler(type_awlow,aitEnumInt8)); + cdd_gr_char->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_gr_char",cdd_gr_char); + + // DBR_GR_LONG + gddContainer* cdd_gr_long=new gddContainer(0); + cdd_gr_long->insert(new gddScaler(type_value,aitEnumInt32)); + cdd_gr_long->insert(new gddScaler(type_ghigh,aitEnumInt32)); + cdd_gr_long->insert(new gddScaler(type_glow,aitEnumInt32)); + cdd_gr_long->insert(new gddScaler(type_ahigh,aitEnumInt32)); + cdd_gr_long->insert(new gddScaler(type_alow,aitEnumInt32)); + cdd_gr_long->insert(new gddScaler(type_awhigh,aitEnumInt32)); + cdd_gr_long->insert(new gddScaler(type_awlow,aitEnumInt32)); + cdd_gr_long->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_gr_long",cdd_gr_long); + + // DBR_GR_DOUBLE + gddContainer* cdd_gr_double=new gddContainer(0); + cdd_gr_double->insert(new gddScaler(type_value,aitEnumFloat64)); + cdd_gr_double->insert(new gddScaler(type_prec,aitEnumInt16)); + cdd_gr_double->insert(new gddScaler(type_ghigh,aitEnumFloat64)); + cdd_gr_double->insert(new gddScaler(type_glow,aitEnumFloat64)); + cdd_gr_double->insert(new gddScaler(type_ahigh,aitEnumFloat64)); + cdd_gr_double->insert(new gddScaler(type_alow,aitEnumFloat64)); + cdd_gr_double->insert(new gddScaler(type_awhigh,aitEnumFloat64)); + cdd_gr_double->insert(new gddScaler(type_awlow,aitEnumFloat64)); + cdd_gr_double->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_gr_double",cdd_gr_double); + + // DBR_CTRL_SHORT + gddContainer* cdd_ctrl_short=new gddContainer(0); + cdd_ctrl_short->insert(new gddScaler(type_value,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_ghigh,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_glow,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_chigh,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_clow,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_ahigh,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_alow,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_awhigh,aitEnumInt16)); + cdd_ctrl_short->insert(new gddScaler(type_awlow,aitEnumInt16)); + cdd_ctrl_short->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_ctrl_short",cdd_ctrl_short); + + // DBR_CTRL_FLOAT + gddContainer* cdd_ctrl_float=new gddContainer(0); + cdd_ctrl_float->insert(new gddScaler(type_value,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_prec,aitEnumInt16)); + cdd_ctrl_float->insert(new gddScaler(type_ghigh,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_glow,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_chigh,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_clow,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_ahigh,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_alow,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_awhigh,aitEnumFloat32)); + cdd_ctrl_float->insert(new gddScaler(type_awlow,aitEnumFloat32)); + cdd_ctrl_float->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_ctrl_float",cdd_ctrl_float); + + // DBR_CTRL_ENUM + gddContainer* cdd_ctrl_enum=new gddContainer(0); + cdd_ctrl_enum->insert(getDD(type_menu)); + cdd_ctrl_enum->insert(new gddScaler(type_value,aitEnumEnum16)); + registerApplicationTypeWithProto("dbr_ctrl_enum",cdd_ctrl_enum); + + // DBR_CTRL_CHAR + gddContainer* cdd_ctrl_char=new gddContainer(0); + cdd_ctrl_char->insert(new gddScaler(type_value,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_ghigh,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_glow,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_chigh,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_clow,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_ahigh,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_alow,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_awhigh,aitEnumInt8)); + cdd_ctrl_char->insert(new gddScaler(type_awlow,aitEnumInt8)); + cdd_ctrl_char->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_ctrl_char",cdd_ctrl_char); + + // DBR_CTRL_LONG + gddContainer* cdd_ctrl_long=new gddContainer(0); + cdd_ctrl_long->insert(new gddScaler(type_value,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_ghigh,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_glow,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_chigh,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_clow,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_ahigh,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_alow,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_awhigh,aitEnumInt32)); + cdd_ctrl_long->insert(new gddScaler(type_awlow,aitEnumInt32)); + cdd_ctrl_long->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_ctrl_long",cdd_ctrl_long); + + // DBR_CTRL_DOUBLE + gddContainer* cdd_ctrl_double=new gddContainer(0); + cdd_ctrl_double->insert(new gddScaler(type_value,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_prec,aitEnumInt16)); + cdd_ctrl_double->insert(new gddScaler(type_ghigh,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_glow,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_chigh,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_clow,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_ahigh,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_alow,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_awhigh,aitEnumFloat64)); + cdd_ctrl_double->insert(new gddScaler(type_awlow,aitEnumFloat64)); + cdd_ctrl_double->insert(getDD(type_units)); + registerApplicationTypeWithProto("dbr_ctrl_double",cdd_ctrl_double); +} + diff --git a/src/gdd/gddAppTable.cc b/src/gdd/gddAppTable.cc new file mode 100644 index 000000000..9c672241f --- /dev/null +++ b/src/gdd/gddAppTable.cc @@ -0,0 +1,528 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ + +// *Revision 1.3 1996/06/24 03:15:35 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.2 1996/06/13 21:31:57 jbk +// *Various fixes and correction - including ref_cnt change to unsigned short +// *Revision 1.1 1996/05/31 13:15:27 jbk +// *add new stuff + +#include "gddAppTable.h" + +// -----------------general destructor for managed gdds-------------------- + +void gddApplicationTypeDestructor::run(void* v) +{ + gdd* ec = (gdd*)v; + // fprintf(stderr," destructing %8.8x\n",v); + gddApplicationTypeTable* db = (gddApplicationTypeTable*)arg; + db->freeDD(ec); +} + +gddApplicationTypeElement::gddApplicationTypeElement(void) { } +gddApplicationTypeElement::~gddApplicationTypeElement(void) { } + +// --------------------------app table stuff----------------------------- + +gddApplicationTypeTable gddApplicationTypeTable::app_table; + +gddApplicationTypeTable& gddApplicationTypeTable::AppTable(void) +{ + return gddApplicationTypeTable::app_table; +} + +gddApplicationTypeTable::gddApplicationTypeTable(aitUint32 tot) +{ + aitUint32 i,total; + + // round tot up to nearest power of 2 + for(i=1<<31;i && !(tot&i);i>>=1); + if(i==0) + total=1; + else if(i==tot) + total=tot; + else + total=i<<1; + + max_groups=total/APPLTABLE_GROUP_SIZE; + if((max_groups*APPLTABLE_GROUP_SIZE) != total) ++max_groups; + max_allowed=total; + total_registered=1; + attr_table=new gddApplicationTypeElement*[max_groups]; + + for(i=0;inext(); + delete [] blk; + } + } + + if(attr_table[i][j].map) + delete [] attr_table[i][j].map; + break; + case gddApplicationTypeUndefined: break; + default: break; + } + } + delete [] attr_table[i]; + } + } + delete [] attr_table; +} + +int gddApplicationTypeTable::describeDD(gddContainer* dd, FILE* fd, + int level, char* tn) +{ + gddCursor cur = dd->getCursor(); + gdd* pdd; + char tmp[8]; + char* cp; + char* str; + + strcpy(tmp,"unknown"); + + for(pdd=cur.first();pdd;pdd=pdd->next()) + { + if((cp=getName(pdd->applicationType()))==NULL) cp=tmp; + fprintf(fd,"#define gddAppTypeIndex_%s_%s %d\n",tn,cp,level++); + } + + for(pdd=cur.first();pdd;pdd=pdd->next()) + { + if((cp=getName(pdd->applicationType()))==NULL) cp=tmp; + if(pdd->isContainer()) + { + str = new char[strlen(cp)+strlen(tn)+3]; + strcpy(str,tn); + strcat(str,"_"); + strcat(str,cp); + level=describeDD((gddContainer*)pdd,fd,level,str); + delete [] str; + } + } + return level; +} + +void gddApplicationTypeTable::describe(FILE* fd) +{ + int i,j; + gdd* dd; + char* tn; + + fprintf(fd,"\n"); + for(i=0;iisContainer()) + describeDD((gddContainer*)dd,fd,1,tn); + // fprintf(fd,"\n"); + } + break; + case gddApplicationTypeUndefined: break; + default: break; + } + } + } + } + fprintf(fd,"\n"); +} + +gddStatus gddApplicationTypeTable::registerApplicationType( + const char* const name,aitUint32& new_app) +{ + aitUint32 i,group,app,rapp; + gddStatus rc; + + if(new_app=getApplicationType(name)) + return gddErrorAlreadyDefined; + if(total_registered>max_allowed) + return gddErrorAtLimit; + + sem.take(); + rapp=total_registered++; + sem.give(); + + if((rc=splitApplicationType(rapp,group,app))<0) return rc; + + if(attr_table[group]) + { + // group already allocated - check is app already refined + if(attr_table[group][app].type!=gddApplicationTypeUndefined) + return gddErrorAlreadyDefined; + } + else + { + // group must be allocated + attr_table[group]=new gddApplicationTypeElement[APPLTABLE_GROUP_SIZE]; + + // initialize each element of the group as undefined + for(i=0;i %d\n",name,(int)new_app); + return 0; +} + +// registering a prototype of an empty container causes problems. +// The current implementation does not monitor this so the container +// is not cleared when free. A user may, however, include an empty +// container within a prototype container, and everything will work +// correctly. + +gddStatus gddApplicationTypeTable::registerApplicationTypeWithProto( + const char* const name, gdd* protoDD, aitUint32& new_app) +{ + aitUint32 group,app,rapp; + aitUint8* blk; + size_t sz; + aitIndex tot; + int i; + gddStatus rc; + + if(rc=registerApplicationType(name,new_app)) return rc; + + rapp=new_app; + protoDD->setApplType(rapp); + splitApplicationType(rapp,group,app); + + // user gives me the protoDD, so I should not need to reference it. + // Warning, it the user does unreference() on it unknowningly, it will + // go away and cause big problems + + // make sure that the currently registered destructor gets called + // before setting the new one, this should occur in protoDD. + + // be sure to copy data from DD and create buffer that can be copied + // easily when user asks for a DD with proto + + // important!! put destructor into each managed DD - what if atomic? + // protoDD->registerDestructor(new gddApplicationTypeDestructor(protoDD)); + + sz=protoDD->getTotalSizeBytes(); + blk=new aitUint8[sz]; + protoDD->flattenWithAddress(blk,sz,&tot); + attr_table[group][app].proto_size=sz; + attr_table[group][app].total_dds=tot; + protoDD->unreference(); + + attr_table[group][app].type=gddApplicationTypeProto; + attr_table[group][app].proto=(gdd*)blk; + attr_table[group][app].free_list=NULL; + + // create the stupid mapping table - bad implementation for now + attr_table[group][app].map=new aitUint16[total_registered]; + attr_table[group][app].map_size=total_registered; + for(i=0;inext(); + attr_table[group][app].sem.give(); + } + else + { + attr_table[group][app].sem.give(); + // copy the prototype + blk=new aitUint8[attr_table[group][app].proto_size]; + // fprintf(stderr,"Creating a new proto DD! %d %8.8x\n",app,blk); + attr_table[group][app].proto->flattenWithAddress(blk, + attr_table[group][app].proto_size); + dd=(gdd*)blk; + } + dd->registerDestructor(new gddApplicationTypeDestructor(this)); + dd->markManaged(); // must be sure to mark the thing as managed! + break; + case gddApplicationTypeNormal: + dd=new gdd(app); + // fprintf(stderr,"Creating a new normal DD! %d\n",app); + break; + case gddApplicationTypeUndefined: dd=NULL; break; + default: break; + } + + return dd; +} + +gddStatus gddApplicationTypeTable::freeDD(gdd* dd) +{ + aitUint32 group,app,i; + gddStatus rc; + + if((rc=splitApplicationType(dd->applicationType(),group,app))<0) return rc; + + if(attr_table[group][app].type==gddApplicationTypeProto) + { + // this can be time consuming, clear out all user data from the DD + // this is done because we are allowed to register atomic protos + // that user can attach data to - which causes problems because + // the actual structure of the DD is unknown + for(i=1;isetNext(attr_table[group][app].free_list); + attr_table[group][app].free_list=dd; + } + else + { + // fprintf(stderr,"freeDD a normal DD\n"); + dd->unreference(); + } + + return 0; +} + +gddStatus gddApplicationTypeTable::storeValue(aitUint32 ap, aitUint32 uv) +{ + aitUint32 group,app; + gddStatus rc; + + if((rc=splitApplicationType(ap,group,app))<0) return rc; + if(attr_table[group]==NULL || + attr_table[group][app].type==gddApplicationTypeUndefined) + return gddErrorNotDefined; + + attr_table[group][app].user_value=uv; + return 0; +} + +aitUint32 gddApplicationTypeTable::getValue(aitUint32 ap) +{ + aitUint32 group,app; + if(splitApplicationType(ap,group,app)<0) return 0; + if(attr_table[group]==NULL || + attr_table[group][app].type==gddApplicationTypeUndefined) + return 0; + + return attr_table[group][app].user_value; +} + +// the source in the container we must walk through is this called +gddStatus gddApplicationTypeTable::copyDD_src(gdd* dest, gdd* src) +{ + gddStatus rc=0; + gddStatus s; + gddContainer* cdd; + gddCursor cur; + gdd* dd; + aitIndex index; + + // this could be done better (faster) if we did not always recurse for + // each GDD. I could have checked for type container before recursing. + + if(src->isContainer()) + { + // go through src gdd and map app types to index into dest + cdd=(gddContainer*)src; + cur=cdd->getCursor(); + + for(dd=cur.first();dd;dd=dd->next()) copyDD_src(dest,dd); + } + else + { + // find src gdd in dest container and just do put() + s=mapAppToIndex(dest->applicationType(), + src->applicationType(),index); + + if(s==0) + rc=dest[index].put(src); + } + return rc; +} + +// the destination in the container we must walk through is this called +gddStatus gddApplicationTypeTable::copyDD_dest(gdd* dest, gdd* src) +{ + gddStatus rc=0; + gddStatus s; + gddContainer* cdd; + gddCursor cur; + gdd* dd; + aitIndex index; + + if(dest->isContainer()) + { + // go through dest gdd and map app types to index into src + cdd=(gddContainer*)dest; + cur=cdd->getCursor(); + + for(dd=cur.first();dd;dd=dd->next()) copyDD_dest(dd,src); + } + else + { + // find dest gdd in src container and just do put() + s=mapAppToIndex(src->applicationType(), + dest->applicationType(),index); + + if(s==0) + rc=dest->put(&src[index]); + } + return rc; +} + +gddStatus gddApplicationTypeTable::smartCopy(gdd* dest, gdd* src) +{ + gddStatus rc=0; + + if(dest->isContainer() && dest->isManaged()) + rc=copyDD_src(dest,src); + else if(src->isContainer() && src->isManaged()) + rc=copyDD_dest(dest,src); + else if(!src->isContainer() && !dest->isContainer()) + rc=dest->put(src); // both are not containers, let gdd handle it + else + rc=gddErrorNotAllowed; + + return rc; +} diff --git a/src/gdd/gddAppTable.h b/src/gdd/gddAppTable.h new file mode 100644 index 000000000..a57722068 --- /dev/null +++ b/src/gdd/gddAppTable.h @@ -0,0 +1,194 @@ +#ifndef GDD_APPLTYPE_TABLE_H +#define GDD_APPLTYPE_TABLE_H + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.3 1996/06/24 03:15:36 jbk + * *name changes and fixes for aitString and fixed string functions + * *Revision 1.2 1996/06/13 21:31:58 jbk + * *Various fixes and correction - including ref_cnt change to unsigned short + * *Revision 1.1 1996/05/31 13:15:29 jbk + * *add new stuff + * + */ + +#include "gdd.h" +#include "gddUtils.h" +#include + +// must be power of 2 for group size +#define APPLTABLE_GROUP_SIZE 64 +#define APPLTABLE_GROUP_SIZE_POW 6 + +// default set of application type names +#define GDD_UNITS_SIZE 8 +#define GDD_NAME_UNITS "units" +#define GDD_NAME_MAX_ELEMENTS "maxElements" +#define GDD_NAME_PRECISION "precision" +#define GDD_NAME_GRAPH_HIGH "graphicHigh" +#define GDD_NAME_GRAPH_LOW "graphicLow" +#define GDD_NAME_CONTROL_HIGH "controlHigh" +#define GDD_NAME_CONTROL_LOW "controlLow" +#define GDD_NAME_ALARM_HIGH "alarmHigh" +#define GDD_NAME_ALARM_LOW "alarmLow" +#define GDD_NAME_ALARM_WARN_HIGH "alarmHighWarning" +#define GDD_NAME_ALARM_WARN_LOW "alarmLowWarning" +#define GDD_NAME_VALUE "value" +#define GDD_NAME_ENUM "enums" +#define GDD_NAME_MENUITEM "menuitem" +#define GDD_NAME_STATUS "status" +#define GDD_NAME_SEVERITY "severity" +#define GDD_NAME_SECONDS "seconds" +#define GDD_NAME_NANOSECONDS "nanoseconds" +#define GDD_NAME_ALL "all" +#define GDD_NAME_ATTRIBUTES "attributes" + +typedef enum +{ + gddApplicationTypeUndefined, + gddApplicationTypeProto, + gddApplicationTypeNormal +} gddApplicationTypeType; + +class gddApplicationTypeTable; + +class gddApplicationTypeDestructor : public gddDestructor +{ +public: + gddApplicationTypeDestructor(gddApplicationTypeTable* v) : gddDestructor(v) { } + void run(void*); +}; + +class gddApplicationTypeElement +{ +public: + gddApplicationTypeElement(void); + ~gddApplicationTypeElement(void); + + char* app_name; + size_t proto_size; + aitIndex total_dds; + gdd* proto; + gdd* free_list; + gddSemaphore sem; + gddApplicationTypeType type; + aitUint32 user_value; + aitUint16* map; + aitUint16 map_size; +}; + +// The app table allows registering a prototype DD for app. This class +// allows the user to ask for a DD given a app. The class will manage +// a free list of DD buffers if the app has a prototype DD +// associated with it. The gddApplicationTypeDestructor allows the DD to be +// returned to the free list for the DD app in the app table. + +class gddApplicationTypeTable +{ +public: + gddApplicationTypeTable(aitUint32 total_number_of_apps=(1<<9)); + ~gddApplicationTypeTable(void); + + // standard method + gddStatus registerApplicationType(const char* const name, aitUint32& app); + gddStatus registerApplicationTypeWithProto(const char* const name, + gdd* protoDD, aitUint32& app); + + // alternative method to register types + aitUint32 registerApplicationType(const char* const name); + aitUint32 registerApplicationTypeWithProto(const char* const name, + gdd* protoDD); + + // hashing still not used for string names to app types + aitUint32 getApplicationType(const char* const name) const; + char* getName(aitUint32 app) const; + gddStatus mapAppToIndex(aitUint32 container_app, + aitUint32 app_to_map, aitUint32& index); + + // copy as best as possible from src to dest, one of the gdd must be + // managed for this to succeed + gddStatus smartCopy(gdd* dest, gdd* src); + + // old style interface + int tagC2I(const char* const ctag, int& tag); + int tagC2I(const char* const ctag, int* const tag); + int tagI2C(int tag, char* const ctag); + int insertApplicationType(int tag, const char* ctag); + + gdd* getDD(aitUint32 app); + + // This should be a protected function, users should + // always unreference a DD. Probably can occurs if there is another + // manager in the system. This function cannot distinguish between + // a DD managed by it or someone else. The AppDestructor will call + // this function indirectly by unreferencing the DD. + gddStatus freeDD(gdd*); + + aitUint32 maxAttributes(void) const { return max_allowed; } + aitUint32 totalregistered(void) const { return total_registered; } + void describe(FILE*); + gddStatus storeValue(aitUint32 app, aitUint32 user_value); + aitUint32 getValue(aitUint32 app); + + static gddApplicationTypeTable& AppTable(void); + static gddApplicationTypeTable app_table; + +protected: + void GenerateTypes(void); + + gddStatus copyDD_src(gdd* dest, gdd* src); + gddStatus copyDD_dest(gdd* dest, gdd* src); + +private: + gddStatus splitApplicationType(aitUint32 r,aitUint32& g,aitUint32& a) const; + aitUint32 group(aitUint32 rapp) const; + aitUint32 index(aitUint32 rapp) const; + int describeDD(gddContainer* dd, FILE* fd, int level, char* tn); + + aitUint32 total_registered; + aitUint32 max_allowed; + aitUint32 max_groups; + + gddApplicationTypeElement** attr_table; + gddSemaphore sem; +}; + +inline aitUint32 gddApplicationTypeTable::group(aitUint32 rapp) const + { return (rapp&(~(APPLTABLE_GROUP_SIZE-1)))>>APPLTABLE_GROUP_SIZE_POW; } +inline aitUint32 gddApplicationTypeTable::index(aitUint32 rapp) const + { return rapp&(APPLTABLE_GROUP_SIZE-1); } + +inline gddStatus gddApplicationTypeTable::splitApplicationType(aitUint32 rapp, + aitUint32& g, aitUint32& app) const +{ + g=group(rapp); + app=index(rapp); + if(rapp>=total_registered) return gddErrorOutOfBounds; else return 0; +} + +inline aitUint32 gddApplicationTypeTable::registerApplicationType( + const char* const name) +{ + aitUint32 app; + registerApplicationType(name,app); + return app; +} + +inline aitUint32 gddApplicationTypeTable::registerApplicationTypeWithProto( + const char* const name, gdd* protoDD) +{ + aitUint32 app; + registerApplicationTypeWithProto(name,protoDD,app); + return app; +} + +gddApplicationTypeTable* gddGenerateApplicationTypeTable(aitUint32 x=(1<<10)); + +#endif + diff --git a/src/gdd/gddErrorCodes.h b/src/gdd/gddErrorCodes.h new file mode 100644 index 000000000..19eefc78e --- /dev/null +++ b/src/gdd/gddErrorCodes.h @@ -0,0 +1,32 @@ +#ifndef GDD_ERROR_CODES_H +#define GDD_ERROR_CODES_H + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.2 1996/06/13 21:32:00 jbk + * *Various fixes and correction - including ref_cnt change to unsigned short + * *Revision 1.1 1996/05/31 13:15:30 jbk + * *add new stuff + * + */ + +typedef long gddStatus; + +#define gddErrorTypeMismatch -1 +#define gddErrorNotAllowed -2 +#define gddErrorAlreadyDefined -3 +#define gddErrorNewFailed -4 +#define gddErrorOutOfBounds -5 +#define gddErrorAtLimit -6 +#define gddErrorNotDefined -7 +#define gddErrorNotSupported -8 +#define gddErrorOverflow -9 +#define gddErrorUnderflow -10 + +#endif diff --git a/src/gdd/gddNewDel.cc b/src/gdd/gddNewDel.cc new file mode 100644 index 000000000..7e4e08f3d --- /dev/null +++ b/src/gdd/gddNewDel.cc @@ -0,0 +1,49 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// + +// *Revision 1.2 1996/06/24 03:15:37 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.1 1996/05/31 13:15:31 jbk +// *add new stuff + +#include "gddNewDel.h" +#include + +gddCleanUp gddBufferCleanUp; + +gddCleanUp::gddCleanUp(void) { } + +gddCleanUp::~gddCleanUp(void) { gddCleanUp::CleanUp(); } + +gddCleanUpNode* gddCleanUp::bufs = NULL; + +gddSemaphore gddCleanUp::lock; + +void gddCleanUp::CleanUp(void) +{ + gddCleanUpNode *p1,*p2; + + for(p1=gddCleanUp::bufs;p1;) + { + p2=p1; + p1=p1->next; + free((char*)p2->buffer); + delete p2; + } +} + +void gddCleanUp::Add(void* v) +{ + gddCleanUpNode* p = new gddCleanUpNode; + p->buffer=v; + lock.take(); + p->next=gddCleanUp::bufs; + gddCleanUp::bufs=p; + lock.give(); +} + diff --git a/src/gdd/gddNewDel.h b/src/gdd/gddNewDel.h new file mode 100644 index 000000000..e0a009ac2 --- /dev/null +++ b/src/gdd/gddNewDel.h @@ -0,0 +1,125 @@ +#ifndef GDD_NEWDEL_H +#define GDD_NEWDEL_H + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.2 1996/06/24 03:15:37 jbk + * *name changes and fixes for aitString and fixed string functions + * *Revision 1.1 1996/05/31 13:15:33 jbk + * *add new stuff + * + */ + +// this file if formatted with tab stop = 4 + +#include +#include "gddUtils.h" + +// Avoid using templates at the cost of very poor readability. +// This forces the user to have a static data member named "gddNewDel_freelist" +// This also forces the user to have a data member named "gddNewDel_next" + +// To use this stuff: +// +// ** In class description header file: +// class myClass +// { +// public: +// gdd_NEWDEL_FUNC(myClass) +// private: +// gdd_NEWDEL_DATA(myClass) +// }; +// +// ** In source file where functions for class are written: +// gdd_NEWDEL_STAT(myClass) +// gdd_NEWDEL_DEL(myClass) +// gdd_NEWDEL_NEW(myClass) + +#define gdd_CHUNK_NUM 20 +#define gdd_CHUNK(mine) (gdd_CHUNK_NUM*sizeof(mine)) + +// private data to add to a class +#define gdd_NEWDEL_DATA(clas) \ + clas* newdel_next; \ + static clas* newdel_freelist; \ + static gddSemaphore lock; + +// public interface for the new/delete stuff +#define gdd_NEWDEL_FUNC(clas) void* operator new(size_t); \ + void operator delete(void*); \ + clas* next(void) { return newdel_next; } \ + void setNext(clas* n) { newdel_next=n; } + +// declaration of the static variable for the free list +#define gdd_NEWDEL_STAT(clas) \ + clas* clas::newdel_freelist=NULL; \ + gddSemaphore clas::lock; + +// code for the delete function +#define gdd_NEWDEL_DEL(clas) void clas::operator delete(void* v) { \ + clas* dn = (clas*)v; \ + if(dn->newdel_next==(clas*)(-1)) free((char*)v); \ + else { \ + clas::lock.take(); \ + dn->newdel_next=clas::newdel_freelist; clas::newdel_freelist=dn; \ + clas::lock.give(); \ + } \ +} + +// following function assumes that reading/writing address is atomic + +// code for the new function +#define gdd_NEWDEL_NEW(clas) void* clas::operator new(size_t size) { \ + int tot; \ + clas *nn,*dn; \ + if(!clas::newdel_freelist) { \ + tot=gdd_CHUNK_NUM; \ + nn=(clas*)malloc(gdd_CHUNK(clas)); \ + gddCleanUp::Add(nn); \ + for(dn=nn;--tot;dn++) dn->newdel_next=dn+1; \ + clas::lock.take(); \ + (dn)->newdel_next=clas::newdel_freelist; \ + clas::newdel_freelist=nn; \ + clas::lock.give(); \ + } \ + if(size==sizeof(clas)) { \ + clas::lock.take(); \ + dn=clas::newdel_freelist; \ + clas::newdel_freelist=clas::newdel_freelist->newdel_next; \ + clas::lock.give(); \ + dn->newdel_next=NULL; \ + } else { \ + dn=(clas*)malloc(size); \ + dn->newdel_next=(clas*)(-1); \ + } \ + return (void*)dn; \ +} + +class gddCleanUpNode +{ +public: + void* buffer; + gddCleanUpNode* next; +}; + +class gddCleanUp +{ +public: + gddCleanUp(void); + ~gddCleanUp(void); + + static void Add(void*); + static void CleanUp(void); +private: + static gddCleanUpNode* bufs; + static gddSemaphore lock; +}; + +#endif + diff --git a/src/gdd/gddTest.cc b/src/gdd/gddTest.cc new file mode 100644 index 000000000..dbce5ad0a --- /dev/null +++ b/src/gdd/gddTest.cc @@ -0,0 +1,499 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// + +// *Revision 1.3 1996/06/24 03:15:38 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.2 1996/06/13 21:32:00 jbk +// *Various fixes and correction - including ref_cnt change to unsigned short +// *Revision 1.1 1996/05/31 13:15:35 jbk +// *add new stuff + +#include +#include "gdd.h" + +// -----------------------test routines------------------------ + +#ifdef NO_DUMP_TEST +void gdd::dump(void) { } +#else +void gdd::dump(void) +{ + gddScaler* sdd; + gddAtomic* add; + gddContainer* cdd; + + if(isScaler()) + { + sdd=(gddScaler*)this; + sdd->dump(); + return; + } + if(isAtomic()) + { + add=(gddAtomic*)this; + add->dump(); + return; + } + if(isContainer()) + { + cdd=(gddContainer*)this; + cdd->dump(); + return; + } +} +#endif + +#ifdef NO_DUMP_TEST +void gdd::dumpInfo(void) { } +#else +void gdd::dumpInfo(void) +{ + unsigned i; + aitIndex f,c; + long sz_tot,sz_data,sz_elem; + + sz_tot = getTotalSizeBytes(); + sz_data = getDataSizeBytes(); + sz_elem = getDataSizeElements(); + + fprintf(stderr,"----------dump This=%8.8x---------\n",(unsigned int)this); + fprintf(stderr," app=%d, prim=%d",applicationType(),primitiveType()); + fprintf(stderr," dim=%d\n",dimension()); + fprintf(stderr," tot=%ld, data=%ld, elem=%ld ",sz_tot,sz_data,sz_elem); + fprintf(stderr," ref count=%d\n",ref_cnt); + + for(i=0;i\n",str); + break; + default: + fprintf(stderr," unknown primitive type\n"); break; + } + fprintf(stderr,"-------------------------------------\n"); +} +#endif + +#ifdef NO_DUMP_TEST +void gddScaler::dump(void) { } +#else +void gddScaler::dump(void) +{ + aitFloat64 f64; aitFloat32 f32; aitUint32 ui32; aitInt32 i32; + aitUint16 ui16; aitInt16 i16; aitUint8 ui8; aitInt8 i8; + + gdd::dumpInfo(); + + switch(primitiveType()) + { + case aitEnumFloat64: + get(f64); if(f64) fprintf(stderr," Convert: float64 %lf ",f64); + f64=*this; if(f64) fprintf(stderr," Normal: float64 %lf\n",f64); + break; + case aitEnumFloat32: + get(f32); if(f32) fprintf(stderr," Convert: float32 %f ",f32); + f32=*this; if(f32) fprintf(stderr," Normal: float32 %f\n",f32); + break; + case aitEnumUint32: + get(ui32); if(ui32) fprintf(stderr," Convert: uint32 %d ",ui32); + ui32=*this; if(ui32) fprintf(stderr," Normal: uint32 %d\n",ui32); + break; + case aitEnumInt32: + get(i32); if(i32) fprintf(stderr," Convert: int32 %d ",i32); + i32=*this; if(i32) fprintf(stderr," Normal: int32 %d\n",i32); + break; + case aitEnumUint16: + get(ui16); if(ui16) fprintf(stderr," Convert: uint16 %hu ",ui16); + ui16=*this; if(ui16) fprintf(stderr," Normal: uint16 %hu\n",ui16); + break; + case aitEnumInt16: + get(i16); if(i16) fprintf(stderr," Convert: int16 %hd ",i16); + i16=*this; if(i16) fprintf(stderr," Normal: int16 %hd\n",i16); + break; + case aitEnumUint8: + get(ui8); if(ui8) fprintf(stderr," Convert: uint8 %2.2x ",ui8); + ui8=*this; if(ui8) fprintf(stderr," Normal: uint8 %2.2x\n",ui8); + break; + case aitEnumInt8: + get(i8); if(i8) fprintf(stderr," Convert: int8 %d ",i8); + i8=*this; if(i8) fprintf(stderr," Normal: int8 %d\n",i8); + break; + default: + fprintf(stderr," unknown primitive type\n"); break; + } + fprintf(stderr,"--------------------------------------\n"); +} +#endif + +#ifdef NO_DUMP_TEST +void gdd::test() { } +#else +void gdd::test() +{ + aitInt32 i32[3] = { -32,4,3 }; + aitIndex bnds = 3; + gddAtomic* add = (gddAtomic*)this; + gddAtomic* dd = new gddAtomic(98,aitEnumInt32,1,3); + + reset(aitEnumInt32,1,&bnds); + add->put(i32); + fprintf(stderr,"----TESTING DD DUMP:\n"); + add->dump(); + + // test copy(), copyInfo(), Dup() + fprintf(stderr,"----TESTING COPYINFO(): (1)COPYINFO, (2)ORIGINAL\n"); + dd->copyInfo(this); dd->dump(); add->dump(); + fprintf(stderr,"----TESTING DUP(): (1)DUP, (2)ORIGINAL\n"); + dd->clear(); dd->Dup(this); dd->dump(); add->dump(); + fprintf(stderr,"----TESTING COPY(): (1)COPY, (2)ORIGINAL\n"); + dd->clear(); dd->copy(this); dd->dump(); add->dump(); + dd->unreference(); + + // test flatten functions and Convert functions + size_t sz = getTotalSizeBytes(); + aitUint8* buf = new aitUint8[sz]; + gddAtomic* pdd = (gddAtomic*)buf; + flattenWithAddress(buf,sz); + fprintf(stderr,"----TESTING FLATTENWITHADDRESS():\n"); + pdd->dump(); + fprintf(stderr,"----CONVERTADDRESSTOOFFSETS() THEN BACK AND DUMP:\n"); + pdd->convertAddressToOffsets(); + pdd->convertOffsetsToAddress(); + pdd->dump(); + pdd->unreference(); + delete buf; +} +#endif + +#ifndef NO_DUMP_TEST +class gddAtomicDestr : public gddDestructor +{ +public: + gddAtomicDestr(void) { } + void run(void*); +}; + +void gddAtomicDestr::run(void* v) +{ + fprintf(stderr,"**** gddAtomicDestr::run from gddAtomic::test %8.8x\n",v); +} +#endif + +#ifdef NO_DUMP_TEST +void gddAtomic::test(void) { } +#else +void gddAtomic::test(void) +{ + aitFloat32 f32[6] = { 32.0,2.0,1.0, 7.0,8.0,9.0 }; + aitFloat64 f64[6] = { 64.0,5.0,4.0, 10.0,11.0,12.0 }; + aitInt8 i8[6] = { -8,2,1, 13,14,15 }; + aitInt16 i16[6] = { -16,3,2, 16,17,18 }; + aitInt32 i32[6] = { -32,4,3, 19,20,21 }; + aitUint8 ui8[6] = { 8,5,4, 22,23,24 }; + aitUint16 ui16[6] = { 16,6,5, 25,26,27 }; + aitUint32 ui32[6] = { 32,7,6, 28,29,30 }; + aitIndex bnds[2] = { 2,3 }; + + // Rules: + // reset() clear out everything and set data pointer to NULL + // put() will auto allocate if data pointer is NULL, otherwise copy + // putRef() will clear current data pointer and set new one + + // if the data pointer is NULL when put() is called, then a + // generic gddDestructor will be created to delete the buffer + + reset(aitEnumFloat32,2,bnds); + put(f32); dump(); + putRef(f32,new gddAtomicDestr); dump(); + + reset(aitEnumFloat64,2,bnds); + put(f64); dump(); + putRef(f64,new gddAtomicDestr); dump(); + + reset(aitEnumInt8,2,bnds); + put(i8); dump(); + putRef(i8,new gddAtomicDestr); dump(); + + reset(aitEnumUint8,2,bnds); + put(ui8); dump(); + putRef(ui8,new gddAtomicDestr); dump(); + + reset(aitEnumInt16,2,bnds); + put(i16); dump(); + putRef(i16,new gddAtomicDestr); dump(); + + reset(aitEnumUint16,2,bnds); + put(ui16); dump(); + putRef(ui16,new gddAtomicDestr); dump(); + + reset(aitEnumInt32,2,bnds); + put(i32); dump(); + putRef(i32,new gddAtomicDestr); dump(); + + reset(aitEnumUint32,2,bnds); + put(ui32); dump(); + putRef(ui32,new gddAtomicDestr); dump(); +} +#endif + +#ifdef NO_DUMP_TEST +void gddScaler::test(void) { } +#else +void gddScaler::test(void) +{ + int i; + aitFloat32 fa32,f32 = 32.0; + aitFloat64 fa64,f64 = 64.0; + aitInt8 ia8,i8 = -8; + aitInt16 ia16,i16 = -16; + aitInt32 ia32,i32 = -32; + aitUint8 uia8,ui8 = 8; + aitUint16 uia16,ui16 = 16; + aitUint32 uia32,ui32 = 32; + + // printf("get float32 = %f\n",fa32); + // printf("op= float32 = %f\n",fa32); + + fprintf(stderr,"float32===="); + for(i=0;iisAtomic()) { add=(gddAtomic*)dd; add->dump(); } + if(dd->isScaler()) { sdd=(gddScaler*)dd; sdd->dump(); } + if(dd->isContainer()) { cdd=(gddContainer*)dd; cdd->dump(); } + } +} +#endif + +#ifdef NO_DUMP_TEST +void gddContainer::test(void) { } +#else +void gddContainer::test(void) +{ + gddScaler* sdd1 = new gddScaler(1,aitEnumInt32); + gddScaler* sdd2 = new gddScaler(2,aitEnumInt16); + gddAtomic* add1 = new gddAtomic(3,aitEnumFloat32,1,3); + gddContainer* cdd1; + + aitInt16 i16 = 5; + aitInt32 i32 = 6; + aitFloat32 f32[3] = { 7.0, 8.0, 9.0 }; + aitUint8* buf; + size_t sz; + + *sdd1=i32; *sdd2=i16; *add1=f32; + + // insert two scalers and an atomic into the container + fprintf(stderr,"*INSERT %8.8x %8.8x %8.8x\n",sdd1,sdd2,add1); + clear(); + sdd1->reference(); add1->reference(); sdd2->reference(); + insert(sdd1); insert(sdd2); insert(add1); dump(); + + fprintf(stderr,"=====TESTING CURSOR:\n"); + gddCursor cur = getCursor(); + gdd* dd; + int i; + for(i=0;dd=cur[i];i++) fprintf(stderr,"%8.8x ",dd); + fprintf(stderr,"\n"); + for(dd=cur.first();dd;dd=cur.next()) fprintf(stderr,"%8.8x ",dd); + fprintf(stderr,"\n"); + + remove(0); remove(0); remove(0); dump(); + sdd1->reference(); add1->reference(); sdd2->reference(); + insert(add1); insert(sdd1); insert(sdd2); dump(); + + sz = getTotalSizeBytes(); + buf = new aitUint8[sz]; + + fprintf(stderr,"=====TESTING FLATTEN FUNCTION BUFFER=%8.8x:\n",buf); + flattenWithAddress(buf,sz); + cdd1=(gddContainer*)buf; + cdd1->dump(); + fprintf(stderr,"=====CHANGE ADDRESSES TO OFFSETS:\n"); + cdd1->convertAddressToOffsets(); + fprintf(stderr,"=====CHANGE OFFSETS TO ADDRESSES:\n"); + cdd1->convertOffsetsToAddress(); + fprintf(stderr,"=====RE-DUMP OF FLATTENED CONTAINER:\n"); + cdd1->dump(); + fprintf(stderr,"=====RE-DUMP OF ORIGINAL CONTAINER:\n"); + dump(); + cdd1->unreference(); + delete buf; + + // test copy(), Dup(), copyInfo() + fprintf(stderr,"=======CREATING TEST CONTAINER FOR *COPY* TEST:\n"); + cdd1 = new gddContainer; + fprintf(stderr,"=======COPYINFO():\n"); + cdd1->copyInfo(this); cdd1->dump(); + fprintf(stderr,"=======DUP():\n"); + cdd1->Dup(this); cdd1->dump(); + fprintf(stderr,"=======COPY():\n"); + cdd1->copy(this); cdd1->dump(); + fprintf(stderr,"=======UNREFERENCE THE TEST CONTAINER:\n"); + cdd1->unreference(); + + fprintf(stderr,"=====DUMPING ORIGINAL:\n"); + dump(); + clear(); + + fprintf(stderr,"=======TEST COMPLETE, DELETE STUFF:\n"); + fprintf(stderr," first scaler:\n "); sdd1->unreference(); + fprintf(stderr," first atomic:\n "); add1->unreference(); + fprintf(stderr," second scaler:\n "); sdd2->unreference(); + dump(); +} +#endif + diff --git a/src/gdd/gddUtils.h b/src/gdd/gddUtils.h new file mode 100644 index 000000000..3782e1920 --- /dev/null +++ b/src/gdd/gddUtils.h @@ -0,0 +1,91 @@ +#ifndef GDD_UTILS_H +#define GDD_UTILS_H + +/* + * Author: Jim Kowalkowski + * Date: 2/96 + * + * $Id$ + * + * $Log$ + * + * *Revision 1.2 1996/06/24 03:15:39 jbk + * *name changes and fixes for aitString and fixed string functions + * *Revision 1.1 1996/05/31 13:15:36 jbk + * *add new stuff + * + */ + +#ifdef vxWorks +#include +#include +#include +#include +#endif + +#include "aitTypes.h" + +typedef enum { gddSemEmpty, gddSemFull } gddSemType; + +#if 0 +#ifdef vxWorks +#undef vxWorks +#define __temp_vxWorks__ 1 +#endif +#endif + +// Semaphores default to "Full" + +class gddSemaphore +{ +public: + gddSemaphore(void); + gddSemaphore(gddSemType); + ~gddSemaphore(void); + + void give(void); + void take(void); + void take(aitUint32 usec); +private: +#ifdef vxWorks + SEM_ID sem; +#endif +}; + +#ifdef vxWorks +inline gddSemaphore::gddSemaphore(void) + { sem=semBCreate(SEM_Q_PRIORITY,SEM_FULL); } +inline gddSemaphore::gddSemaphore(gddSemType s) +{ + if(s==gddSemEmpty) sem=semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); + else sem=semBCreate(SEM_Q_PRIORITY,SEM_FULL); +} +inline gddSemaphore::~gddSemaphore(void) { semDelete(sem); } +inline void gddSemaphore::give(void) { semGive(sem); } +inline void gddSemaphore::take(void) { semTake(sem,WAIT_FOREVER); } +inline void gddSemaphore::take(aitUint32 usec) + { semTake(sem,usec/(sysClkRateGet()*1000000)); } +#else +inline gddSemaphore::gddSemaphore(void) { } +inline gddSemaphore::gddSemaphore(gddSemType) { } +inline gddSemaphore::~gddSemaphore(void) { } +inline void gddSemaphore::give(void) { } +inline void gddSemaphore::take(void) { } +inline void gddSemaphore::take(aitUint32) { } +#endif + +#if 0 +class gddIntLock +{ +public: +private: +}; +#endif + +#ifdef __temp_vxWorks__ +#define vxWorks 1 +#undef __temp_vxWorks__ +#endif + +#endif + diff --git a/src/gdd/genApps.cc b/src/gdd/genApps.cc new file mode 100644 index 000000000..bb77699fd --- /dev/null +++ b/src/gdd/genApps.cc @@ -0,0 +1,51 @@ +// Author: Jim Kowalkowski +// Date: 2/96 +// +// $Id$ +// +// $Log$ +// + +// *Revision 1.2 1996/06/24 03:15:40 jbk +// *name changes and fixes for aitString and fixed string functions +// *Revision 1.1 1996/05/31 13:15:37 jbk +// *add new stuff + +#include "gddAppTable.h" + +#if 0 +#ifndef GDD_NO_EPICS +#include "dbrMapper.h" +#endif +#endif + +int main(int argc, char* argv[]) +{ + FILE* fd; + + gddApplicationTypeTable& tt = gddApplicationTypeTable::AppTable(); + + if(argc<2) + { + fprintf(stderr,"You must enter a file name on command line\n"); + return -1; + } + + if((fd=fopen(argv[1],"w"))==NULL) + { + fprintf(stderr,"Cannot open file %s\n",argv[1]); + return -1; + } + +#if 0 +#ifndef GDD_NO_EPICS + gddMakeMapDBR(tt); +#endif +#endif + + tt.describe(fd); + fclose(fd); + + return 0; +} + diff --git a/src/gdd/vxldscript.MRI b/src/gdd/vxldscript.MRI new file mode 100644 index 000000000..f01726d6f --- /dev/null +++ b/src/gdd/vxldscript.MRI @@ -0,0 +1,21 @@ +OUTPUT_FORMAT("a.out-sunos-big") +OUTPUT_ARCH(m68k) +__DYNAMIC = 0; +SECTIONS +{ + .text 0x00: + { + CREATE_OBJECT_SYMBOLS + *(.text) + } + .data SIZEOF(.text) + ADDR(.text) : + { + *(.data) + CONSTRUCTORS + } + .bss SIZEOF(.data) + ADDR(.data) : + { + *(.bss) + *(COMMON) + } +}