/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE Versions 3.13.7 * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ #ifndef GDD_H #define GDD_H /* * Author: Jim Kowalkowski * Date: 2/96 * * Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd * */ // 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 #include #include #if defined(_WIN32) #elif defined(vxWorks) # include #elif defined(UNIX) // hopefully a posix compliant OS # include # include #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 gddArray; class gddScalar; struct epicsTimeStamp; struct timespec; // 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. // --------------------------------------------------------------------- // class structure for DDs: // // gddScalar // | // 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 epicsShareClass 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); enum { GDD_MANAGED_MASK=0x01, GDD_FLAT_MASK=0x02, GDD_NET_MASK=0x04, GDD_NOREF_MASK=0x08, GDD_CONSTANT_MASK=0x10 }; unsigned applicationType(void) const; aitEnum primitiveType(void) const; unsigned dimension(void) const; aitType& getData(void); const aitType& getData(void) const; aitType* dataUnion(void); const aitType* dataUnion(void) const; const gddDestructor* destructor(void) const; gdd* next(void); const gdd* next(void) const; void setNext(gdd*); const gddBounds* getBounds(void) const; const gddBounds* getBounds(int bn) const; void dump(void) const; void test(void); void setPrimType(aitEnum t); void setApplType(int t); void setDimension(int d,const gddBounds* = NULL); 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) const; gddStatus registerDestructor(gddDestructor*); gddStatus replaceDestructor(gddDestructor*); const void* dataVoid(void) const; void* dataVoid(void); const void* dataAddress(void) const; void* dataAddress(void); const void* dataPointer(void) const; void* dataPointer(void); const void* dataPointer(aitIndex element_offset) const; void* dataPointer(aitIndex element_offset); void getTimeStamp(struct timespec* const ts) const; void getTimeStamp(aitTimeStamp* const ts) const; void getTimeStamp(struct epicsTimeStamp* const ts) const; void setTimeStamp(const struct timespec* const ts); void setTimeStamp(const aitTimeStamp* const ts); void setTimeStamp(const struct epicsTimeStamp* const ts); void setStatus(aitUint32); void setStatus(aitUint16 high, aitUint16 low); void getStatus(aitUint32&) const; void getStatus(aitUint16& high, aitUint16& low) const; void setStat(aitUint16); void setSevr(aitUint16); aitUint16 getStat(void) const; aitUint16 getSevr(void) const; void setStatSevr(aitInt16 stat, aitInt16 sevr); void getStatSevr(aitInt16& stat, aitInt16& sevr) const; 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. Scalar 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(const gdd*); gddStatus copy(const gdd*); gddStatus Dup(const 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 isScalar(void) const; int isContainer(void) const; int isAtomic(void) const; int isManaged(void) const; int isFlat(void) const; int isLocalDataFormat(void) const; int isNetworkDataFormat(void) const; int isConstant(void) const; int isNoRef(void) const; void markConstant(void); void markManaged(void); void markUnmanaged(void); void markLocalDataFormat(void); void markNotLocalDataFormat(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) const; gddStatus unreference(void) const; gdd& operator=(const gdd& v); // get a pointer to the data in the DD void getRef(const aitFloat64*& d) const; void getRef(const aitFloat32*& d) const; void getRef(const aitUint32*& d) const; void getRef(const aitInt32*& d) const; void getRef(const aitUint16*& d) const; void getRef(const aitInt16*& d) const; void getRef(const aitUint8*& d) const; void getRef(const aitInt8*& d) const; void getRef(const aitString*& d) const; void getRef(const aitFixedString*& d) const; void getRef(const void*& d) const; 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*,aitEnum,gddDestructor* =0); void putRef(aitFloat64*,gddDestructor* =0); void putRef(aitFloat32*,gddDestructor* =0); void putRef(aitUint8*,gddDestructor* =0); void putRef(aitInt8*,gddDestructor* =0); void putRef(aitUint16*,gddDestructor* =0); void putRef(aitInt16*,gddDestructor* =0); void putRef(aitUint32*,gddDestructor* =0); void putRef(aitInt32*,gddDestructor* =0); void putRef(aitString*,gddDestructor* =0); void putRef(aitFixedString*,gddDestructor* =0); // work with constants void putRef(const aitFloat64*,gddDestructor* =0); void putRef(const aitFloat32*,gddDestructor* =0); void putRef(const aitUint8*,gddDestructor* =0); void putRef(const aitInt8*,gddDestructor* =0); void putRef(const aitUint16*,gddDestructor* =0); void putRef(const aitInt16*,gddDestructor* =0); void putRef(const aitUint32*,gddDestructor* =0); void putRef(const aitInt32*,gddDestructor* =0); void putRef(const aitString*,gddDestructor* =0); void putRef(const aitFixedString*,gddDestructor* =0); gddStatus putRef(const gdd*); // get the data in the form the user wants (do conversion) void getConvert(aitFloat64& d) const; void getConvert(aitFloat32& d) const; void getConvert(aitUint32& d) const; void getConvert(aitInt32& d) const; void getConvert(aitUint16& d) const; void getConvert(aitInt16& d) const; void getConvert(aitUint8& d) const; void getConvert(aitInt8& d) const; void getConvert(aitString& d) const; void getConvert(aitFixedString& d) const; // 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(const aitString& d); void putConvert(const 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 gddStatus put(aitFloat64 d); gddStatus put(aitFloat32 d); gddStatus put(aitUint32 d); gddStatus put(aitInt32 d); gddStatus put(aitUint16 d); gddStatus put(aitInt16 d); gddStatus put(aitUint8 d); gddStatus put(aitInt8 d); gddStatus put(const aitString& d); gddStatus put(const aitFixedString& d); gddStatus put(aitType* d); // copy the array data out of the DD void get(void* d) const; void get(void* d,aitEnum) const; void get(aitFloat64* d) const; void get(aitFloat32* d) const; void get(aitUint32* d) const; void get(aitInt32* d) const; void get(aitUint16* d) const; void get(aitInt16* d) const; void get(aitUint8* d) const; void get(aitInt8* d) const; void get(aitString* d) const; void get(aitFixedString* d) const; // copy the data out of the DD void get(aitFloat64& d) const; void get(aitFloat32& d) const; void get(aitUint32& d) const; void get(aitInt32& d) const; void get(aitUint16& d) const; void get(aitInt16& d) const; void get(aitUint8& d) const; void get(aitInt8& d) const; void get(aitString& d) const; void get(aitFixedString& d) const; void get(aitType& d) const; // 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=(const aitString& d); // gdd& operator=(aitFixedString d); // not present // Same as getRef() methods operator const aitFloat64*(void) const; operator const aitFloat32*(void) const; operator const aitUint32*(void) const; operator const aitInt32*(void) const; operator const aitUint16*(void) const; operator const aitInt16*(void) const; operator const aitUint8*(void) const; operator const aitInt8*(void) const; operator const aitString*(void) const; operator const aitFixedString*(void) const; operator aitFloat64*(void); operator aitFloat32*(void); operator aitUint32*(void); operator aitInt32*(void); operator aitUint16*(void); operator aitInt16*(void); operator aitUint8*(void); operator aitInt8*(void); operator aitString*(void); operator aitFixedString*(void); // Same as get() methods operator aitFloat64(void) const; operator aitFloat32(void) const; operator aitUint32(void) const; operator aitInt32(void) const; operator aitUint16(void) const; operator aitInt16(void) const; operator aitUint8(void) const; operator aitInt8(void) const; operator aitString(void) const; // operator aitFixedString(void); // not present // // added by JOH 4-23-99 so that the correct method // is used if the container gdd is not organized // as an array of GDDs in memory // // note that this requires a reference (pointers // do not invoke this function) // gdd & operator [] (aitIndex index); const gdd & operator [] (aitIndex index) const; gdd & operator [] (int index); const gdd & operator [] (int index) const; // // The following can be slow and inefficient // if the GDD isnt "flat" // // Only appropriate for container GDDs // const gdd* getDD(aitIndex index) const; const gdd* getDD(aitIndex index, const gddScalar*&) const; const gdd* getDD(aitIndex index, const gddArray*&) const; const gdd* getDD(aitIndex index, const gddContainer*&) const; gdd* getDD(aitIndex index); gdd* getDD(aitIndex index,gddScalar*&); gdd* getDD(aitIndex index,gddArray*&); gdd* getDD(aitIndex index,gddContainer*&); gddStatus genCopy(aitEnum t, const void* d, aitDataFormat f=aitLocalDataFormat); void adjust(gddDestructor* d,void* v,aitEnum type, aitDataFormat f=aitLocalDataFormat); void get(aitEnum t,void* v,aitDataFormat f=aitLocalDataFormat) const; void set(aitEnum t,const void* v,aitDataFormat f=aitLocalDataFormat); // following methods are used to import and export data into and out // of this gdd. For the out methods, the returned count in the number // of bytes put into the user's buffer. For the in methods, the // returned count in the number of bytes put into the gdd from the // user's buffer. The in methods always change the data format to local // from whatever input format is specified with the argument. The out // methods convert the gdd to whatever format is specified with the // aitDataFormat argument. If aitEnum argument left as invalid, then // data in the user's buffer will be assumed to be the same as the // type defined in the gdd. size_t out(void* buf,aitUint32 bufsize,aitDataFormat =aitNetworkDataFormat) const; size_t outHeader(void* buf,aitUint32 bufsize) const; size_t outData(void* buf,aitUint32 bufsize, aitEnum = aitEnumInvalid, aitDataFormat = aitNetworkDataFormat) const; size_t in(void* buf, aitDataFormat =aitNetworkDataFormat); size_t inHeader(void* buf); size_t inData(void* buf,aitUint32 number_of_elements = 0, aitEnum = aitEnumInvalid, aitDataFormat = aitNetworkDataFormat); gdd_NEWDEL_FUNC(bounds) // 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) const; gddStatus copyStuff(const gdd*,int type); gddStatus clearData(void); 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 setData(void* d); aitType data; // array pointer or scaler data gddBounds* bounds; // array of bounds information length dim gdd* nextgdd; mutable 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 gdd_NEWDEL_DATA // required for using generic new and remove private: mutable aitUint32 ref_cnt; aitUint8 flags; static epicsMutex * pGlobalMutex; const gdd* indexDD (aitIndex index) const; }; // include these to be backward compatible with first gdd library version #include "gddArray.h" #include "gddScalar.h" #include "gddContainer.h" #include "gddI.h" #include "gddArrayI.h" #include "gddScalarI.h" #include "gddContainerI.h" #endif