From 10c2be9a3f75f4423c7682b7a54cff725cd8c116 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Fri, 17 Sep 2010 09:31:44 -0400 Subject: [PATCH] Still working on initial version --- pvDataApp/factory/AbstractPVField.h | 89 ++++++++++++ pvDataApp/factory/FieldCreateFactory.cpp | 115 ++++++++++------ pvDataApp/factory/Makefile | 3 + pvDataApp/factory/PVDataCreateFactory.cpp | 99 ++++++++++++++ pvDataApp/factory/TypeFunc.cpp | 2 - pvDataApp/factory/factory.h | 17 +++ pvDataApp/pv/Makefile | 4 + pvDataApp/pv/bitSet.h | 11 ++ pvDataApp/pv/byteBuffer.h | 37 +++++ pvDataApp/pv/pvData.h | 159 ++++++++++++++++++++++ pvDataApp/pv/pvIntrospect.h | 20 ++- pvDataApp/pv/requester.h | 18 +++ pvDataApp/pv/serialize.h | 40 ++++++ pvDataApp/test/Makefile | 6 + pvDataApp/test/testDumpStdString.cpp | 116 ++++++++++++++++ pvDataApp/test/testPVScalar.cpp | 64 +++++++++ 16 files changed, 748 insertions(+), 52 deletions(-) create mode 100644 pvDataApp/factory/AbstractPVField.h create mode 100644 pvDataApp/factory/PVDataCreateFactory.cpp create mode 100644 pvDataApp/factory/factory.h create mode 100644 pvDataApp/pv/bitSet.h create mode 100644 pvDataApp/pv/byteBuffer.h create mode 100644 pvDataApp/pv/requester.h create mode 100644 pvDataApp/pv/serialize.h create mode 100644 pvDataApp/test/testDumpStdString.cpp create mode 100644 pvDataApp/test/testPVScalar.cpp diff --git a/pvDataApp/factory/AbstractPVField.h b/pvDataApp/factory/AbstractPVField.h new file mode 100644 index 0000000..9f321e7 --- /dev/null +++ b/pvDataApp/factory/AbstractPVField.h @@ -0,0 +1,89 @@ +/*AbstractPVField.cpp*/ +#include +#include +#include +#include +#include "pvData.h" +#include "factory.h" + +namespace epics { namespace pvData { + + class AbstractPVField : public PVField { + public: + AbstractPVField(PVStructure *parent,FieldConstPtr field); + virtual ~AbstractPVField(); + // from Requester + virtual StringConstPtr getRequesterName() const; + virtual void message(StringConstPtr message,MessageType messageType) const; + // from PVField + virtual void setRequester(Requester *prequester); + virtual int getFieldOffset() const; + virtual int getNextFieldOffset() const; + virtual int getNumberFields() const; + virtual PVAuxInfo * getPVAuxInfo() const; + virtual epicsBoolean isImmutable() const; + virtual void setImmutable(); + virtual FieldConstPtr getField() const; + virtual PVStructure * getParent() const; + virtual void replacePVField(PVField * newPVField); + virtual void renameField(StringConstPtr newName); + virtual void postPut() const; + virtual void setPostHandler(PostHandler *ppostHandler); + virtual void toString(StringPtr buf) const; + virtual void toString(StringPtr buf,int indentLevel) const; + protected: + void replaceStructure(); + private: + AbstractPVField(AbstractPVField const & ); // not implemented + AbstractPVField & operator=(AbstractPVField const &); //not implemented + int fieldOffset; + int nextFieldOffset; + PVAuxInfo *pvAuxInfo; + epicsBoolean immutable; + PVStructure *parent; + FieldConstPtr field; + Requester *requester; + PostHandler *postHandler; + }; + + AbstractPVField::AbstractPVField(PVStructure *parent,FieldConstPtr field) + : fieldOffset(0),nextFieldOffset(0),pvAuxInfo(0),immutable(epicsFalse), + parent(parent),field(field),requester(0),postHandler(0) + { + field->incReferenceCount(); + } + + AbstractPVField::~AbstractPVField() + { + field->decReferenceCount(); + } + + StringConstPtr AbstractPVField::getRequesterName() const + { + static std::string none("none"); + if(requester!=0) return requester->getRequesterName(); + return &none; + } + + void AbstractPVField::message(StringConstPtr message,MessageType messageType) const + { + if(requester) { + requester->message(message,messageType); + } else { + printf("%s %s %s\n", + messageTypeName[messageType].c_str(), + field->getFieldName()->c_str(), + message->c_str()); + } + } + void AbstractPVField::setRequester(Requester *prequester) + { + static std::string requesterPresent = "Logic Error. requester is already present"; + if(requester==0) { + requester = prequester; + return; + } + throw std::logic_error(requesterPresent); + } + +}} diff --git a/pvDataApp/factory/FieldCreateFactory.cpp b/pvDataApp/factory/FieldCreateFactory.cpp index 6a174b1..fb09c84 100644 --- a/pvDataApp/factory/FieldCreateFactory.cpp +++ b/pvDataApp/factory/FieldCreateFactory.cpp @@ -1,43 +1,52 @@ - +/*FieldCreateFactory.cpp*/ #include #include #include #include -#include #include "pvData.h" +#include "factory.h" namespace epics { namespace pvData { - static void newLine(StringPtr buffer,int indentLevel) { - *buffer += "\n"; - for(int i=0; igetFieldName(); + StringConstPtr name = fields[i]->getFieldName(); + // look for duplicates + for(int j=i+1; jgetFieldName(); + int result = name->compare(*otherName); + if(result==0) { + std::string message("duplicate fieldName "); + message += *name; + throw std::invalid_argument(message); + } + } + // inc reference counter + fields[i]->incReferenceCount(); } } BaseStructure::~BaseStructure() { + if(debugLevel==highDebug) printf("~BaseStructure %s\n",BaseField::getFieldName()->c_str()); for(int i=0; idecReferenceCount(); } - delete[] fieldNames; - delete[] fields; } FieldConstPtr BaseStructure::getField(StringConstPtr fieldName) const { @@ -181,6 +201,9 @@ namespace epics { namespace pvData { public: BaseStructureArray(StringConstPtr fieldName,StructureConstPtr structure); virtual ~BaseStructureArray(); + virtual void incReferenceCount() const {BaseField::incReferenceCount();} + virtual void decReferenceCount() const {BaseField::decReferenceCount();} + virtual int getReferenceCount() const {return BaseField::getReferenceCount();} virtual StringConstPtr getFieldName() const{ return BaseField::getFieldName(); } @@ -193,9 +216,15 @@ namespace epics { namespace pvData { }; BaseStructureArray::BaseStructureArray(StringConstPtr fieldName,StructureConstPtr structure) - : BaseField(fieldName,structureArray),pstructure(structure) {} + : BaseField(fieldName,structureArray),pstructure(structure) + { + pstructure->incReferenceCount(); + } - BaseStructureArray::~BaseStructureArray() {} + BaseStructureArray::~BaseStructureArray() { + if(debugLevel==highDebug) printf("~BaseStructureArray\n"); + pstructure->decReferenceCount(); + } void BaseStructureArray::toString(StringPtr buffer,int indentLevel) const { @@ -204,9 +233,6 @@ namespace epics { namespace pvData { pstructure->toString(buffer,indentLevel + 1); } -static std::string notImplemented = "not implemented"; -static std::string logicError = "Logic Error. Should never get here"; - FieldCreate::FieldCreate(){}; ScalarConstPtr FieldCreate::createScalar(StringConstPtr fieldName, @@ -233,7 +259,8 @@ static std::string logicError = "Logic Error. Should never get here"; StructureArrayConstPtr FieldCreate::createStructureArray( StringConstPtr fieldName,StructureConstPtr structure) const { - throw std::invalid_argument(notImplemented); + BaseStructureArray *baseStructureArray = new BaseStructureArray(fieldName,structure); + return baseStructureArray; } FieldConstPtr FieldCreate::create(StringConstPtr fieldName, @@ -258,7 +285,9 @@ static std::string logicError = "Logic Error. Should never get here"; return createStructureArray(fieldName,pstructureArray->getStructure()); } } - throw std::logic_error(logicError); + std::string message("field "); + message += *fieldName; + throw std::logic_error(message); } static FieldCreate* instance = 0; diff --git a/pvDataApp/factory/Makefile b/pvDataApp/factory/Makefile index b8eba6e..dae7346 100644 --- a/pvDataApp/factory/Makefile +++ b/pvDataApp/factory/Makefile @@ -2,8 +2,11 @@ TOP=../.. include $(TOP)/configure/CONFIG +INC += factory.h +INC += AbstractPVField.h LIBSRCS += TypeFunc.cpp LIBSRCS += FieldCreateFactory.cpp +LIBSRCS += PVDataCreateFactory.cpp LIBRARY=pvFactory diff --git a/pvDataApp/factory/PVDataCreateFactory.cpp b/pvDataApp/factory/PVDataCreateFactory.cpp new file mode 100644 index 0000000..6d336e2 --- /dev/null +++ b/pvDataApp/factory/PVDataCreateFactory.cpp @@ -0,0 +1,99 @@ +/*PVDataCreateFactory.cpp*/ +#include +#include +#include +#include +#include "pvData.h" +#include "factory.h" +#include "AbstractPVField.h" + +namespace epics { namespace pvData { + + static std::string notImplemented("not implemented"); + + PVDataCreate::PVDataCreate(){}; + + PVField *PVDataCreate::createPVField(PVStructure *parent, + FieldConstPtr field) const + { + throw std::logic_error(notImplemented); + }; + + PVField *PVDataCreate::createPVField(PVStructure *parent, + StringConstPtr fieldName,FieldConstPtr fieldToClone) const + { + throw std::logic_error(notImplemented); + }; + + PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,ScalarConstPtr scalar) const + { + throw std::logic_error(notImplemented); + }; + + PVScalar *PVDataCreate::createPVScalar(PVStructure *parent, + StringConstPtr fieldName,ScalarType scalarType) + { + throw std::logic_error(notImplemented); + }; + + PVScalar *PVDataCreate::createPVScalar(PVStructure *parent, + StringConstPtr fieldName,ScalarConstPtr scalarToClone) const + { + throw std::logic_error(notImplemented); + }; + + PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, + ScalarArrayConstPtr scalarArray) const + { + throw std::logic_error(notImplemented); + }; + + PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, + StringConstPtr fieldName,ScalarType elementType) + { + throw std::logic_error(notImplemented); + }; + + PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, + StringConstPtr fieldName,ScalarArrayConstPtr scalarArrayToClone) const + { + throw std::logic_error(notImplemented); + }; + + PVStructureArray *PVDataCreate::createPVStructureArray(PVStructure *parent, + StructureArrayConstPtr structureArray) const + { + throw std::logic_error(notImplemented); + }; + + PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, + StructureConstPtr structure) + { + throw std::logic_error(notImplemented); + }; + + PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, + StringConstPtr fieldName,FieldConstPtrArray fields) + { + throw std::logic_error(notImplemented); + }; + + PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, + StringConstPtr fieldName,PVStructure *structToClone) + { + throw std::logic_error(notImplemented); + }; + + static PVDataCreate* instance = 0; + + class PVDataCreateExt : public PVDataCreate { + public: + PVDataCreateExt(): PVDataCreate(){}; + }; + + PVDataCreate * getPVDataCreate() { + if(instance==0) instance = new PVDataCreateExt(); + return instance; + } + +}} diff --git a/pvDataApp/factory/TypeFunc.cpp b/pvDataApp/factory/TypeFunc.cpp index 829a75e..4d2771f 100644 --- a/pvDataApp/factory/TypeFunc.cpp +++ b/pvDataApp/factory/TypeFunc.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include "pvData.h" namespace epics { namespace pvData { diff --git a/pvDataApp/factory/factory.h b/pvDataApp/factory/factory.h new file mode 100644 index 0000000..f4e95bc --- /dev/null +++ b/pvDataApp/factory/factory.h @@ -0,0 +1,17 @@ +/*factory.h*/ +#ifndef FACTORY_H +#define FACTORY_H + +namespace epics { namespace pvData { + + enum DebugLevel{noDebug,lowDebug,highDebug}; + + static DebugLevel debugLevel = highDebug; + + static void newLine(StringPtr buffer,int indentLevel) { + *buffer += "\n"; + for(int i=0; i +#ifndef BYTEBUFFER_H +#define BYTEBUFFER_H +#include "epicsTypes.h" +#include "pvIntrospect.h" +namespace epics { namespace pvData { + +// not sure why I have to define epicsInt64 +typedef long long epicsInt64; + +class ByteBuffer { + public: + virtual ~ByteBuffer(); + virtual int getSize() const = 0; + virtual int getArrayOffset() const = 0; + virtual epicsBoolean getBoolean() const = 0; + virtual epicsInt8 getByte() const = 0; + virtual epicsInt16 geShort() const = 0; + virtual epicsInt32 getInt() const = 0; + virtual epicsInt64 getLong() const = 0; + virtual float getFloat() const = 0; + virtual double getDouble() const = 0; + virtual StringConstPtr getString() const = 0; + virtual ByteBuffer * putBoolean(epicsBoolean value) const = 0; + virtual ByteBuffer * putByte(epicsInt8 value) const = 0; + virtual ByteBuffer * geShort(epicsInt16 value) const = 0; + virtual ByteBuffer * putInt(epicsInt32 value) const = 0; + virtual ByteBuffer * putLong(epicsInt64 value) const = 0; + virtual ByteBuffer * putFloat(float value) const = 0; + virtual ByteBuffer * putDouble(double value) const = 0; + virtual ByteBuffer * putString(StringConstPtr value) const = 0; + // Must define arrays +}; + +}} +#endif /* BYTEBUFFER_H */ diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index 064e008..91699e5 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -1,10 +1,169 @@ /* pvData.h */ #include #include +#include #ifndef PVDATA_H #define PVDATA_H #include "pvIntrospect.h" +#include "requester.h" +#include "byteBuffer.h" +#include "serialize.h" namespace epics { namespace pvData { + class PVField; + class PVScalar; + class PVBoolean; + class PVByte; + class PVShort; + class PVInt; + class PVLong; + class PVFloat; + class PVDouble; + class PVString; + + class PVScalarArray; + class PVBooleanArray; + class PVByteArray; + class PVShortArray; + class PVIntArray; + class PVLongArray; + class PVFloatArray; + class PVDoubleArray; + class PVStringArray; + + class PVStructure; + class PVStructureArray; + + class PVAuxInfo { + public: + virtual ~PVAuxInfo(); + virtual PVField * getPVField() const = 0; + virtual PVScalar * createInfo(StringConstPtr key,ScalarType scalarType) = 0; + /* following caused compiler error + virtual map getInfos() = 0; + */ + virtual PVScalar * getInto(StringConstPtr key) = 0; + virtual void toString(StringPtr buf) const = 0; + virtual void toString(StringPtr buf,int indentLevel) const = 0; + }; + + class PostHandler { + virtual void postPut() = 0; + }; + + class PVField : public Requester, public Serializable { + public: + virtual ~PVField(); + virtual void setRequester(Requester *prequester) = 0; + virtual int getFieldOffset() const = 0; + virtual int getNextFieldOffset() const = 0; + virtual int getNumberFields() const = 0; + virtual PVAuxInfo * getPVAuxInfo() const = 0; + virtual epicsBoolean isImmutable() const = 0; + virtual void setImmutable() = 0; + virtual FieldConstPtr getField() const = 0; + virtual PVStructure * getParent() const = 0; + virtual void replacePVField(PVField * newPVField) = 0; + virtual void renameField(StringConstPtr newName) = 0; + virtual void postPut() const = 0; + virtual void setPostHandler(PostHandler *ppostHandler) = 0; + virtual void toString(StringPtr buf) const = 0; + virtual void toString(StringPtr buf,int indentLevel) const = 0; + }; + + class PVScalar : public PVField { + public: + virtual ~PVScalar(); + virtual ScalarConstPtr getScalar() const = 0; + }; + + class PVBoolean : public PVScalar { + public: + virtual ~PVBoolean(); + virtual epicsBoolean get() const = 0; + virtual void put(epicsBoolean value) = 0; + }; + + class PVByte : public PVScalar { + public: + virtual ~PVByte(); + virtual epicsInt8 get() const = 0; + virtual void put(epicsInt8 value) = 0; + }; + + class PVShort : public PVScalar { + public: + virtual ~PVShort(); + virtual epicsInt16 get() const = 0; + virtual void put(epicsInt16 value) = 0; + }; + + class PVInt : public PVScalar { + public: + virtual ~PVInt(); + virtual epicsInt32 get() const = 0; + virtual void put(epicsInt32 value) = 0; + }; + + class PVLong : public PVScalar { + public: + virtual ~PVLong(); + virtual epicsInt64 get() const = 0; + virtual void put(epicsInt64 value) = 0; + }; + + class PVFloat : public PVScalar { + public: + virtual ~PVFloat(); + virtual float get() const = 0; + virtual void put(float value) = 0; + }; + + class PVDouble : public PVScalar { + public: + virtual ~PVDouble(); + virtual double get() const = 0; + virtual void put(double value) = 0; + }; + + class PVString : public PVScalar { + public: + virtual ~PVString(); + virtual StringConstPtr get() const = 0; + virtual void put(StringConstPtr value) = 0; + }; + + + class PVDataCreate { + public: + PVField *createPVField(PVStructure *parent, + FieldConstPtr field) const; + PVField *createPVField(PVStructure *parent, + StringConstPtr fieldName,FieldConstPtr fieldToClone) const; + PVScalar *createPVScalar(PVStructure *parent,ScalarConstPtr scalar) const; + PVScalar *createPVScalar(PVStructure *parent, + StringConstPtr fieldName,ScalarType scalarType); + PVScalar *createPVScalar(PVStructure *parent, + StringConstPtr fieldName,ScalarConstPtr scalarToClone) const; + PVScalarArray *createPVScalarArray(PVStructure *parent, + ScalarArrayConstPtr scalarArray) const; + PVScalarArray *createPVScalarArray(PVStructure *parent, + StringConstPtr fieldName,ScalarType elementType); + PVScalarArray *createPVScalarArray(PVStructure *parent, + StringConstPtr fieldName,ScalarArrayConstPtr scalarArrayToClone) const; + PVStructureArray *createPVStructureArray(PVStructure *parent, + StructureArrayConstPtr structureArray) const; + PVStructure *createPVStructure(PVStructure *parent, + StructureConstPtr structure); + PVStructure *createPVStructure(PVStructure *parent, + StringConstPtr fieldName,FieldConstPtrArray fields); + PVStructure *createPVStructure(PVStructure *parent, + StringConstPtr fieldName,PVStructure *structToClone); + protected: + PVDataCreate(); + }; + + extern PVDataCreate * getPVDataCreate(); + }} #endif /* PVDATA_H */ diff --git a/pvDataApp/pv/pvIntrospect.h b/pvDataApp/pv/pvIntrospect.h index 0a7e6c1..7ff80ff 100644 --- a/pvDataApp/pv/pvIntrospect.h +++ b/pvDataApp/pv/pvIntrospect.h @@ -1,4 +1,4 @@ -/* pvData.h */ +/* pvIntrospect.h */ #include #include #ifndef PVINTROSPECT_H @@ -9,12 +9,16 @@ namespace epics { namespace pvData { class ScalarArray; class Structure; class StructureArray; + typedef std::string * StringPtr; - typedef std::string const * StringConstPtr; //pointer to constant string - typedef StringConstPtr * StringConstPtrArray;//array of pointers to constant string - typedef Field const * FieldConstPtr; //pointer to constant field - typedef FieldConstPtr * FieldConstPtrArray; //array of pointers to const field - typedef Scalar const * ScalarConstPtr; //pointer to constant field + // pointer to constant string + typedef std::string const * StringConstPtr; + //array of pointers to constant string + typedef StringConstPtr * StringConstPtrArray; + + typedef Field const * FieldConstPtr; + typedef FieldConstPtr * FieldConstPtrArray; + typedef Scalar const * ScalarConstPtr; typedef ScalarArray const * ScalarArrayConstPtr; typedef Structure const * StructureConstPtr; typedef StructureArray const * StructureArrayConstPtr; @@ -54,6 +58,9 @@ namespace epics { namespace pvData { class Field { public: virtual ~Field(); + virtual void incReferenceCount() const = 0; + virtual void decReferenceCount() const = 0; + virtual int getReferenceCount() const = 0; virtual StringConstPtr getFieldName() const = 0; virtual Type getType() const = 0; virtual void toString(StringPtr buf) const = 0; @@ -78,7 +85,6 @@ namespace epics { namespace pvData { public: virtual ~Structure(); virtual int const getNumberFields() const = 0; - virtual StringConstPtrArray getFieldNames() const = 0; virtual FieldConstPtr getField(StringConstPtr fieldName) const = 0; virtual int getFieldIndex(StringConstPtr fieldName) const = 0; virtual FieldConstPtrArray getFields() const = 0; diff --git a/pvDataApp/pv/requester.h b/pvDataApp/pv/requester.h new file mode 100644 index 0000000..5ff87ec --- /dev/null +++ b/pvDataApp/pv/requester.h @@ -0,0 +1,18 @@ +/* requester.h */ +#include +#ifndef REQUESTER_H +#define REQUESTER_H +#include "pvIntrospect.h" +namespace epics { namespace pvData { + + enum MessageType {info,warning,error,fatalError}; + + static std::string messageTypeName[] = {"info","warning","error","fatalError"}; + + class Requester { + public: + virtual StringConstPtr getRequesterName() const = 0; + virtual void message(StringConstPtr message,MessageType messageType) const = 0; + }; +}} +#endif /* REQUESTER_H */ diff --git a/pvDataApp/pv/serialize.h b/pvDataApp/pv/serialize.h new file mode 100644 index 0000000..6fb5cfa --- /dev/null +++ b/pvDataApp/pv/serialize.h @@ -0,0 +1,40 @@ +/* serialize.h */ +#ifndef SERIALIZE_H +#define SERIALIZE_H +#include "bitSet.h" +#include "byteBuffer.h" +namespace epics { namespace pvData { + + + class SerializableControl { + virtual void flushSerializeBuffer() const =0; + virtual void ensureBuffer(int size) const =0; + }; + + class DeserializableControl { + virtual void ensureData(int size) =0; + }; + + class Serializable { + public: + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) const = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; + }; + + class BitSetSerializable { + public: + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher,BitSet *pbitSet) const = 0; + virtual void deserialize(ByteBuffer *pbuffer, + DeserializableControl*pflusher,BitSet *pbitSet) = 0; + }; + + + class SerializableArray : public Serializable { + public: + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, int offset, int count) const = 0; + }; + +}} +#endif /* SERIALIZE_H */ diff --git a/pvDataApp/test/Makefile b/pvDataApp/test/Makefile index 86fe7af..ba09daf 100644 --- a/pvDataApp/test/Makefile +++ b/pvDataApp/test/Makefile @@ -6,7 +6,13 @@ PROD_HOST = test test_SRCS += test.cpp test_LIBS += pvFactory +PROD_HOST += testDumpStdString +testDumpStdString_SRCS += testDumpStdString.cpp +testDumpStdString_LIBS += pvFactory +PROD_HOST = testPVScalar +testPVScalar_SRCS += testPVScalar.cpp +testPVScalar_LIBS += pvFactory include $(TOP)/configure/RULES #---------------------------------------- diff --git a/pvDataApp/test/testDumpStdString.cpp b/pvDataApp/test/testDumpStdString.cpp new file mode 100644 index 0000000..d9a0f18 --- /dev/null +++ b/pvDataApp/test/testDumpStdString.cpp @@ -0,0 +1,116 @@ +/* pvDataMain.cpp */ +/* Author: Marty Kraimer Date: 17MAR2000 */ + +#include +#include +#include +#include +#include + +#include "pvData.h" + +using namespace epics::pvData; +using namespace std; + +static void dumpString(char const prefix[],string const* value) { + printf("%s\n value %p",prefix,value); + // Just convert value to a pointer + int *pvalue = (int *)value; + // Now get what pvalue points to. It is the cstr. + char * cstr = (char *)*pvalue; + if(cstr==0) { printf("\n"); return; } + printf(" *value %p",cstr); + int * stuff = (int *)*pvalue; + //At least on my implementation the following is true + stuff -= 3; + printf(" length %d capacity %d refcount %d str %s\n", + stuff[0],stuff[1],stuff[2],cstr); +} + +int main(int argc,char *argv[]) +{ + FieldCreate * pfieldCreate = getFieldCreate(); + std::string valueName("value"); + std::string* myString= new std::string("type "); + int numberFields = 2; + FieldConstPtr fields[numberFields]; + std::string name0("high"); + std::string name1("low"); + dumpString("high",&name0); + dumpString("low",&name1); + printf("\ncreate field0 and field1\n"); + fields[0] = pfieldCreate->createScalar(&name0,pvDouble); + fields[1] = pfieldCreate->createScalar(&name1,pvDouble); + printf("referenceCounts field0 %d field1 %d\n", + fields[0]->getReferenceCount(), + fields[1]->getReferenceCount()); + dumpString("high",&name0); + dumpString("low",&name1); + printf("\ncreate scalarArray"); + std::string scalarArrayName("scalarArray"); + ScalarArrayConstPtr pscalarArray = pfieldCreate->createScalarArray( + &scalarArrayName,pvDouble); + myString->clear(); + pscalarArray->toString(myString); + printf("%s\n",myString->c_str()); + printf("referenceCount pscalarArray %d\n", pscalarArray->getReferenceCount()); + dumpString("scalarArray",&scalarArrayName); + pscalarArray->incReferenceCount(); + printf("after incReferenceCounnt referenceCount pscalarArray %d\n", + pscalarArray->getReferenceCount()); + dumpString("high",&name0); + pscalarArray->decReferenceCount(); + dumpString("after decReferenceCount scalarArray",&scalarArrayName); + + printf("\ncreate structure\n"); + StructureConstPtr pstructure = pfieldCreate->createStructure( + &valueName,numberFields,fields); + myString->clear(); + pstructure->toString(myString); + printf("%s\n",myString->c_str()); + FieldConstPtr pfield = pstructure; + myString->clear(); + pfield->toString(myString); + printf("as Field\n%s\n",myString->c_str()); + printf("referenceCounts pfield %d field0 %d field1 %d\n", + pfield->getReferenceCount(), + fields[0]->getReferenceCount(), + fields[1]->getReferenceCount()); + dumpString("high",&name0); + dumpString("low",&name1); + pfield->incReferenceCount(); + pfield->incReferenceCount(); + printf("after incReferenceCounter twice referenceCounts pfield %d field0 %d field1 %d\n", + pfield->getReferenceCount(), + fields[0]->getReferenceCount(), + fields[1]->getReferenceCount()); + dumpString("high",&name0); + dumpString("low",&name1); + pfield->decReferenceCount(); + printf("after decReferenceCount referenceCounts pfield %d field0 %d field1 %d\n", + pfield->getReferenceCount(), + fields[0]->getReferenceCount(), + fields[1]->getReferenceCount()); + dumpString("high",&name0); + dumpString("low",&name1); + StructureArrayConstPtr pstructureArray = pfieldCreate->createStructureArray( + &valueName,pstructure); + pstructureArray->incReferenceCount(); + printf("after createStructureArray referenceCounts pstructureArray %d pfield %d field0 %d field1 %d\n", + pstructureArray->getReferenceCount(), + pfield->getReferenceCount(), + fields[0]->getReferenceCount(), + fields[1]->getReferenceCount()); + pstructureArray->decReferenceCount(); + printf("after structureArray decReferenceCount referenceCounts pfield %d field0 %d field1 %d\n", + pfield->getReferenceCount(), + fields[0]->getReferenceCount(), + fields[1]->getReferenceCount()); + dumpString("high",&name0); + dumpString("low",&name1); + printf("field recReferenceCount\n"); + pfield->decReferenceCount(); + dumpString("high",&name0); + dumpString("low",&name1); + return(0); +} diff --git a/pvDataApp/test/testPVScalar.cpp b/pvDataApp/test/testPVScalar.cpp new file mode 100644 index 0000000..9b28ce8 --- /dev/null +++ b/pvDataApp/test/testPVScalar.cpp @@ -0,0 +1,64 @@ +/* pvDataMain.cpp */ +/* Author: Marty Kraimer Date: 17MAR2000 */ + +#include +#include +#include +#include +#include + +#include "pvData.h" + +using namespace epics::pvData; + +static FieldCreate * pfieldCreate = 0; +static PVDataCreate *pvDataCreate = 0; +static std::string theBuffer(""); +static std::string *buffer = &theBuffer; + +void testDouble() { + printf("\ntestDouble\n"); + std::string valueName("value"); + ScalarConstPtr pscalar = pfieldCreate->createScalar(&valueName,pvDouble); + PVScalar *pvScalar = pvDataCreate->createPVScalar(0,pscalar); + PVDouble *pvValue = (PVDouble *)pvScalar; + double value = 2; + pvValue->put(value); + double getValue = pvValue->get(); + if(value!=getValue) { + fprintf(stderr,"ERROR getValue put %f get %f\n",value,getValue); + } + buffer->clear(); + *buffer += "value "; + pvValue->toString(buffer); + printf("%s\n",buffer->c_str()); + int offset = pvValue->getFieldOffset(); + int nextOffset = pvValue->getNextFieldOffset(); + int numberFields = pvValue->getNumberFields(); + PVAuxInfo *auxInfo = pvValue->getPVAuxInfo(); + epicsBoolean isImmutable = pvValue->isImmutable(); + PVStructure *pvParent = pvValue->getParent(); + printf("offset %d nextOffset %d numberFields %d auxInfo %p immutable %s parent %p\n", + offset,nextOffset,numberFields,auxInfo, + ((isImmutable==epicsFalse) ? "false" : "true"), + pvParent); + FieldConstPtr field = pvValue->getField(); + buffer->clear(); + *buffer += "field "; + field->toString(buffer); + printf("%s\n",buffer->c_str()); + ScalarConstPtr scalar = dynamic_cast(field); + if(scalar!=field) { + fprintf(stderr,"ERROR field!=scalar field %p scalar %p\n",field,scalar); + } + delete pvValue; +} + +int main(int argc,char *argv[]) +{ + pfieldCreate = getFieldCreate(); + pvDataCreate = getPVDataCreate(); + testDouble(); + return(0); +} +