diff --git a/pvDataApp/factory/BasePVBoolean.h b/pvDataApp/factory/BasePVBoolean.h index 674124c..0ce3e55 100644 --- a/pvDataApp/factory/BasePVBoolean.h +++ b/pvDataApp/factory/BasePVBoolean.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -21,13 +22,13 @@ namespace epics { namespace pvData { virtual bool get(); virtual void put(bool val); virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) ; + SerializableControl *pflusher); virtual void deserialize(ByteBuffer *pbuffer, DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: bool value; }; @@ -43,33 +44,34 @@ namespace epics { namespace pvData { void BasePVBoolean::put(bool val){value = val;} void BasePVBoolean::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(1); + pbuffer->putBoolean(value); } void BasePVBoolean::deserialize(ByteBuffer *pbuffer, DeserializableControl *pflusher) { - throw std::logic_error(notImplemented); + pflusher->ensureData(1); + value = pbuffer->getBoolean(); } void BasePVBoolean::toString(StringBuilder buf) {toString(buf,0);} - void BasePVBoolean::toString(StringBuilder buf,int indentLevel) + void BasePVBoolean::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVBoolean::operator==(PVField *pvField) + bool BasePVBoolean::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVBoolean::operator!=(PVField *pvField) + bool BasePVBoolean::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVBooleanArray.h b/pvDataApp/factory/BasePVBooleanArray.h index 8b201d2..95ed369 100644 --- a/pvDataApp/factory/BasePVBooleanArray.h +++ b/pvDataApp/factory/BasePVBooleanArray.h @@ -5,10 +5,14 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" + +using std::min; namespace epics { namespace pvData { @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: bool *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVBooleanArray::BasePVBooleanArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVBooleanArray(parent,scalarArray),value(new bool[0]) - { } + { } BasePVBooleanArray::~BasePVBooleanArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - bool *newValue = new bool[capacity]; + bool *newValue = new bool[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int maxIndex = min(size-i, pbuffer->getRemaining())+i; + for(; igetBoolean(); + if(iensureData(1); // // TODO is there a better way to ensureData? + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVBooleanArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, pbuffer->getRemaining())+i; + for(; iputBoolean(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVBooleanArray::toString(StringBuilder buf) @@ -145,14 +189,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVBooleanArray::operator==(PVField *pv) + bool BasePVBooleanArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVBooleanArray::operator!=(PVField *pv) + bool BasePVBooleanArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVBOOLEANARRAY_H */ diff --git a/pvDataApp/factory/BasePVByte.h b/pvDataApp/factory/BasePVByte.h index dd3bf7c..4ad3be6 100644 --- a/pvDataApp/factory/BasePVByte.h +++ b/pvDataApp/factory/BasePVByte.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -26,14 +27,14 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt8 value; }; BasePVByte::BasePVByte(PVStructure *parent,ScalarConstPtr scalar) - : PVByte(parent,scalar),value(0.0) + : PVByte(parent,scalar),value(0) {} BasePVByte::~BasePVByte() {} @@ -43,33 +44,33 @@ namespace epics { namespace pvData { void BasePVByte::put(epicsInt8 val){value = val;} void BasePVByte::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(1); + pbuffer->putByte(value); } void BasePVByte::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + pflusher->ensureData(1); + value = pbuffer->getByte(); } void BasePVByte::toString(StringBuilder buf) {toString(buf,0);} - void BasePVByte::toString(StringBuilder buf,int indentLevel) + void BasePVByte::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVByte::operator==(PVField *pvField) + bool BasePVByte::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVByte::operator!=(PVField *pvField) + bool BasePVByte::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVByteArray.h b/pvDataApp/factory/BasePVByteArray.h index 1b8c611..f77f0df 100644 --- a/pvDataApp/factory/BasePVByteArray.h +++ b/pvDataApp/factory/BasePVByteArray.h @@ -5,10 +5,14 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" + +using std::min; namespace epics { namespace pvData { @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt8 *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVByteArray::BasePVByteArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVByteArray(parent,scalarArray),value(new epicsInt8[0]) - { } + { } BasePVByteArray::~BasePVByteArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - epicsInt8 *newValue = new epicsInt8[capacity]; + epicsInt8 *newValue = new epicsInt8[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int toRead = min(size-i, pbuffer->getRemaining()); + pbuffer->get(value, i, toRead); + i += toRead; + if(iensureData(1); // TODO: is there a better way to ensureData? + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVByteArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, pbuffer->getRemaining())+i; + for(; iputByte(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVByteArray::toString(StringBuilder buf) @@ -145,14 +189,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVByteArray::operator==(PVField *pv) + bool BasePVByteArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVByteArray::operator!=(PVField *pv) + bool BasePVByteArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVBYTEARRAY_H */ diff --git a/pvDataApp/factory/BasePVDouble.h b/pvDataApp/factory/BasePVDouble.h index dd9988b..518d9c4 100644 --- a/pvDataApp/factory/BasePVDouble.h +++ b/pvDataApp/factory/BasePVDouble.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -26,8 +27,8 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: double value; }; @@ -43,33 +44,33 @@ namespace epics { namespace pvData { void BasePVDouble::put(double val){value = val;} void BasePVDouble::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(sizeof(double)); + pbuffer->putDouble(value); } void BasePVDouble::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + pflusher->ensureData(sizeof(double)); + value = pbuffer->getDouble(); } void BasePVDouble::toString(StringBuilder buf) {toString(buf,0);} - void BasePVDouble::toString(StringBuilder buf,int indentLevel) + void BasePVDouble::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVDouble::operator==(PVField *pvField) + bool BasePVDouble::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVDouble::operator!=(PVField *pvField) + bool BasePVDouble::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVDoubleArray.h b/pvDataApp/factory/BasePVDoubleArray.h index 43c30f9..68c35e8 100644 --- a/pvDataApp/factory/BasePVDoubleArray.h +++ b/pvDataApp/factory/BasePVDoubleArray.h @@ -5,10 +5,14 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" + +using std::min; namespace epics { namespace pvData { @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: double *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVDoubleArray::BasePVDoubleArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVDoubleArray(parent,scalarArray),value(new double[0]) - { } + { } BasePVDoubleArray::~BasePVDoubleArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - double *newValue = new double[capacity]; + double *newValue = new double[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int maxIndex = min(size-i, (int)(pbuffer->getRemaining() + /sizeof(double)))+i; + for(; igetDouble(); + if(iensureData(sizeof(double)); + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVDoubleArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, (int)(pbuffer->getRemaining() + /sizeof(double)))+i; + for(; iputDouble(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVDoubleArray::toString(StringBuilder buf) @@ -146,14 +192,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVDoubleArray::operator==(PVField *pv) + bool BasePVDoubleArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVDoubleArray::operator!=(PVField *pv) + bool BasePVDoubleArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVDOUBLEARRAY_H */ diff --git a/pvDataApp/factory/BasePVFloat.h b/pvDataApp/factory/BasePVFloat.h index 961b04c..3a6e6ce 100644 --- a/pvDataApp/factory/BasePVFloat.h +++ b/pvDataApp/factory/BasePVFloat.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -26,8 +27,8 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: float value; }; @@ -43,33 +44,33 @@ namespace epics { namespace pvData { void BasePVFloat::put(float val){value = val;} void BasePVFloat::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(sizeof(float)); + pbuffer->putFloat(value); } void BasePVFloat::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + pflusher->ensureData(sizeof(float)); + value = pbuffer->getFloat(); } void BasePVFloat::toString(StringBuilder buf) {toString(buf,0);} - void BasePVFloat::toString(StringBuilder buf,int indentLevel) + void BasePVFloat::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVFloat::operator==(PVField *pvField) + bool BasePVFloat::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVFloat::operator!=(PVField *pvField) + bool BasePVFloat::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVFloatArray.h b/pvDataApp/factory/BasePVFloatArray.h index 0e38a5f..5ca9aef 100644 --- a/pvDataApp/factory/BasePVFloatArray.h +++ b/pvDataApp/factory/BasePVFloatArray.h @@ -5,13 +5,17 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" namespace epics { namespace pvData { + using std::min; + PVFloatArray::~PVFloatArray() {} PVFloatArray::PVFloatArray(PVStructure *parent,ScalarArrayConstPtr scalar) @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: float *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVFloatArray::BasePVFloatArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVFloatArray(parent,scalarArray),value(new float[0]) - { } + { } BasePVFloatArray::~BasePVFloatArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - float *newValue = new float[capacity]; + float *newValue = new float[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int maxIndex = min(size-i, (int)(pbuffer->getRemaining() + /sizeof(float)))+i; + for(; igetFloat(); + if(iensureData(sizeof(float)); // TODO: is there a better way to ensureData? + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVFloatArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, (int)(pbuffer->getRemaining() + /sizeof(float)))+i; + for(; iputFloat(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVFloatArray::toString(StringBuilder buf) @@ -146,14 +192,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVFloatArray::operator==(PVField *pv) + bool BasePVFloatArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVFloatArray::operator!=(PVField *pv) + bool BasePVFloatArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVFLOATARRAY_H */ diff --git a/pvDataApp/factory/BasePVInt.h b/pvDataApp/factory/BasePVInt.h index a68465e..517bc12 100644 --- a/pvDataApp/factory/BasePVInt.h +++ b/pvDataApp/factory/BasePVInt.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -26,14 +27,14 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt32 value; }; BasePVInt::BasePVInt(PVStructure *parent,ScalarConstPtr scalar) - : PVInt(parent,scalar),value(0.0) + : PVInt(parent,scalar),value(0) {} BasePVInt::~BasePVInt() {} @@ -43,33 +44,33 @@ namespace epics { namespace pvData { void BasePVInt::put(epicsInt32 val){value = val;} void BasePVInt::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(sizeof(epicsInt32)); + pbuffer->putInt(value); } void BasePVInt::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + pflusher->ensureData(sizeof(epicsInt32)); + value = pbuffer->getInt(); } void BasePVInt::toString(StringBuilder buf) {toString(buf,0);} - void BasePVInt::toString(StringBuilder buf,int indentLevel) + void BasePVInt::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVInt::operator==(PVField *pvField) + bool BasePVInt::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVInt::operator!=(PVField *pvField) + bool BasePVInt::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVIntArray.h b/pvDataApp/factory/BasePVIntArray.h index aa97aa2..1ec230d 100644 --- a/pvDataApp/factory/BasePVIntArray.h +++ b/pvDataApp/factory/BasePVIntArray.h @@ -5,10 +5,14 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" + +using std::min; namespace epics { namespace pvData { @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt32 *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVIntArray::BasePVIntArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVIntArray(parent,scalarArray),value(new epicsInt32[0]) - { } + { } BasePVIntArray::~BasePVIntArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - epicsInt32 *newValue = new epicsInt32[capacity]; + epicsInt32 *newValue = new epicsInt32[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int maxIndex = min(size-i, (int)(pbuffer->getRemaining() + /sizeof(epicsInt32)))+i; + for(; igetInt(); + if(iensureData(sizeof(epicsInt32)); // TODO: is there a better way to ensureData? + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVIntArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, (int)(pbuffer->getRemaining() + /sizeof(epicsInt32)))+i; + for(; iputInt(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVIntArray::toString(StringBuilder buf) @@ -146,14 +192,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVIntArray::operator==(PVField *pv) + bool BasePVIntArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVIntArray::operator!=(PVField *pv) + bool BasePVIntArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVINTARRAY_H */ diff --git a/pvDataApp/factory/BasePVLong.h b/pvDataApp/factory/BasePVLong.h index 860a7b9..dd2fe69 100644 --- a/pvDataApp/factory/BasePVLong.h +++ b/pvDataApp/factory/BasePVLong.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -26,14 +27,14 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt64 value; }; BasePVLong::BasePVLong(PVStructure *parent,ScalarConstPtr scalar) - : PVLong(parent,scalar),value(0.0) + : PVLong(parent,scalar),value(0) {} BasePVLong::~BasePVLong() {} @@ -43,33 +44,33 @@ namespace epics { namespace pvData { void BasePVLong::put(epicsInt64 val){value = val;} void BasePVLong::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(sizeof(epicsInt64)); + pbuffer->putLong(value); } void BasePVLong::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + pflusher->ensureData(sizeof(epicsInt64)); + value = pbuffer->getLong(); } void BasePVLong::toString(StringBuilder buf) {toString(buf,0);} - void BasePVLong::toString(StringBuilder buf,int indentLevel) + void BasePVLong::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVLong::operator==(PVField *pvField) + bool BasePVLong::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVLong::operator!=(PVField *pvField) + bool BasePVLong::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVLongArray.h b/pvDataApp/factory/BasePVLongArray.h index bafa09e..147a6d6 100644 --- a/pvDataApp/factory/BasePVLongArray.h +++ b/pvDataApp/factory/BasePVLongArray.h @@ -5,10 +5,14 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" + +using std::min; namespace epics { namespace pvData { @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt64 *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVLongArray::BasePVLongArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVLongArray(parent,scalarArray),value(new epicsInt64[0]) - { } + { } BasePVLongArray::~BasePVLongArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - epicsInt64 *newValue = new epicsInt64[capacity]; + epicsInt64 *newValue = new epicsInt64[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int maxIndex = min(size-i, (int)(pbuffer->getRemaining() + /sizeof(epicsInt64)))+i; + for(; igetLong(); + if(iensureData(sizeof(epicsInt64)); // TODO: is there a better way to ensureData? + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVLongArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, (int)(pbuffer->getRemaining() + /sizeof(epicsInt64)))+i; + for(; iputLong(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVLongArray::toString(StringBuilder buf) @@ -146,14 +192,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVLongArray::operator==(PVField *pv) + bool BasePVLongArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVLongArray::operator!=(PVField *pv) + bool BasePVLongArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVLONGARRAY_H */ diff --git a/pvDataApp/factory/BasePVShort.h b/pvDataApp/factory/BasePVShort.h index cd48e7c..e94966b 100644 --- a/pvDataApp/factory/BasePVShort.h +++ b/pvDataApp/factory/BasePVShort.h @@ -9,6 +9,7 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" namespace epics { namespace pvData { @@ -26,14 +27,14 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt16 value; }; BasePVShort::BasePVShort(PVStructure *parent,ScalarConstPtr scalar) - : PVShort(parent,scalar),value(0.0) + : PVShort(parent,scalar),value(0) {} BasePVShort::~BasePVShort() {} @@ -43,33 +44,33 @@ namespace epics { namespace pvData { void BasePVShort::put(epicsInt16 val){value = val;} void BasePVShort::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + pflusher->ensureBuffer(sizeof(epicsInt16)); + pbuffer->putShort(value); } void BasePVShort::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + pflusher->ensureData(sizeof(epicsInt16)); + value = pbuffer->getShort(); } void BasePVShort::toString(StringBuilder buf) {toString(buf,0);} - void BasePVShort::toString(StringBuilder buf,int indentLevel) + void BasePVShort::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVShort::operator==(PVField *pvField) + bool BasePVShort::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVShort::operator!=(PVField *pvField) + bool BasePVShort::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVShortArray.h b/pvDataApp/factory/BasePVShortArray.h index 04a9dc9..c293efa 100644 --- a/pvDataApp/factory/BasePVShortArray.h +++ b/pvDataApp/factory/BasePVShortArray.h @@ -5,10 +5,14 @@ #include #include #include +#include #include #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" + +using std::min; namespace epics { namespace pvData { @@ -33,8 +37,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: epicsInt16 *value; }; @@ -42,7 +46,7 @@ namespace epics { namespace pvData { BasePVShortArray::BasePVShortArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVShortArray(parent,scalarArray),value(new epicsInt16[0]) - { } + { } BasePVShortArray::~BasePVShortArray() { @@ -59,14 +63,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - epicsInt16 *newValue = new epicsInt16[capacity]; + epicsInt16 *newValue = new epicsInt16[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + int i = 0; + while(true) { + int maxIndex = min(size-i, (int)(pbuffer->getRemaining() + /sizeof(epicsInt16)))+i; + for(; igetShort(); + if(iensureData(sizeof(epicsInt16)); // TODO: is there a better way to ensureData? + else + break; + } + // set new length + setLength(size); + postPut(); + } + // TODO null arrays (size == -1) not supported } void BasePVShortArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + int i = offset; + while(true) { + int maxIndex = min(end-i, (int)(pbuffer->getRemaining() + /sizeof(epicsInt16)))+i; + for(; iputShort(value[i]); + if(iflushSerializeBuffer(); + else + break; + } } void BasePVShortArray::toString(StringBuilder buf) @@ -146,14 +192,14 @@ namespace epics { namespace pvData { PVField::toString(buf,indentLevel); } - bool BasePVShortArray::operator==(PVField *pv) + bool BasePVShortArray::operator==(PVField& pv) { - return getConvert()->equals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVShortArray::operator!=(PVField *pv) + bool BasePVShortArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVSHORTARRAY_H */ diff --git a/pvDataApp/factory/BasePVString.h b/pvDataApp/factory/BasePVString.h index 52b57f7..e0d6093 100644 --- a/pvDataApp/factory/BasePVString.h +++ b/pvDataApp/factory/BasePVString.h @@ -9,6 +9,8 @@ #include "convert.h" #include "factory.h" #include "AbstractPVField.h" +#include "byteBuffer.h" +#include "serializeHelper.h" namespace epics { namespace pvData { @@ -26,8 +28,8 @@ namespace epics { namespace pvData { DeserializableControl *pflusher); virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: String value; }; @@ -43,33 +45,31 @@ namespace epics { namespace pvData { void BasePVString::put(String val){value = val;} void BasePVString::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher) { + SerializeHelper::serializeString(value, pbuffer, pflusher); } void BasePVString::deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + DeserializableControl *pflusher) { + value = SerializeHelper::deserializeString(pbuffer, pflusher); } void BasePVString::toString(StringBuilder buf) {toString(buf,0);} - void BasePVString::toString(StringBuilder buf,int indentLevel) + void BasePVString::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - bool BasePVString::operator==(PVField *pvField) + bool BasePVString::operator==(PVField& pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this, &pvField); } - bool BasePVString::operator!=(PVField *pvField) + bool BasePVString::operator!=(PVField& pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this, &pvField)); } }} diff --git a/pvDataApp/factory/BasePVStringArray.h b/pvDataApp/factory/BasePVStringArray.h index 2d9f92d..f3b1183 100644 --- a/pvDataApp/factory/BasePVStringArray.h +++ b/pvDataApp/factory/BasePVStringArray.h @@ -9,6 +9,7 @@ #include "pvData.h" #include "factory.h" #include "AbstractPVScalarArray.h" +#include "serializeHelper.h" namespace epics { namespace pvData { @@ -33,8 +34,8 @@ namespace epics { namespace pvData { SerializableControl *pflusher, int offset, int count) ; virtual void toString(StringBuilder buf); virtual void toString(StringBuilder buf,int indentLevel); - virtual bool operator==(PVField *pv) ; - virtual bool operator!=(PVField *pv) ; + virtual bool operator==(PVField& pv) ; + virtual bool operator!=(PVField& pv) ; private: String *value; }; @@ -42,7 +43,7 @@ namespace epics { namespace pvData { BasePVStringArray::BasePVStringArray(PVStructure *parent, ScalarArrayConstPtr scalarArray) : PVStringArray(parent,scalarArray),value(new String[0]) - { } + { } BasePVStringArray::~BasePVStringArray() { @@ -59,14 +60,14 @@ namespace epics { namespace pvData { } int length = PVArray::getLength(); if(length>capacity) length = capacity; - String *newValue = new String[capacity]; + String *newValue = new String[capacity]; for(int i=0; i=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + // retrieve value from the buffer + for(int i = 0; ilength) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + int end = offset+count; + for(int i = offset; iequals(this,pv); + return getConvert()->equals(this, &pv); } - bool BasePVStringArray::operator!=(PVField *pv) + bool BasePVStringArray::operator!=(PVField& pv) { - return !(getConvert()->equals(this,pv)); + return !(getConvert()->equals(this, &pv)); } }} #endif /* BASEPVSTRINGARRAY_H */ diff --git a/pvDataApp/factory/BasePVStructure.h b/pvDataApp/factory/BasePVStructure.h index d74124d..12137c6 100644 --- a/pvDataApp/factory/BasePVStructure.h +++ b/pvDataApp/factory/BasePVStructure.h @@ -30,7 +30,7 @@ namespace epics { namespace pvData { for(int i=0; inumberFields; i++) + pImpl->pvFields[i]->serialize(pbuffer, pflusher); } void PVStructure::deserialize(ByteBuffer *pbuffer, - DeserializableControl*pflusher,BitSet *pbitSet) - { + DeserializableControl *pcontrol) { + for(int i = 0; inumberFields; i++) + pImpl->pvFields[i]->deserialize(pbuffer, pcontrol); + + } + + void PVStructure::serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, int offset, int count) { throw std::logic_error(notImplemented); } - bool PVStructure::operator==(PVField *obj) + void PVStructure::serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, BitSet *pbitSet) { + int offset = getFieldOffset(); + int numberFields = getNumberFields(); + int next = pbitSet->nextSetBit(offset); + + // no more changes or no changes in this structure + if(next<0||next>=offset+numberFields) return; + + // entire structure + if(offset==next) { + serialize(pbuffer, pflusher); + return; + } + + for(int i = 0; inumberFields; i++) { + PVField* pvField = pImpl->pvFields[i]; + offset = pvField->getFieldOffset(); + numberFields = pvField->getNumberFields(); + next = pbitSet->nextSetBit(offset); + // no more changes + if(next<0) return; + // no change in this pvField + if(next>=offset+numberFields) continue; + + // serialize field or fields + if(numberFields==1) + pvField->serialize(pbuffer, pflusher); + else + ((PVStructure*)pvField)->serialize(pbuffer, pflusher, + pbitSet); + } + } + + void PVStructure::deserialize(ByteBuffer *pbuffer, + DeserializableControl *pcontrol, BitSet *pbitSet) { + int offset = getFieldOffset(); + int numberFields = getNumberFields(); + int next = pbitSet->nextSetBit(offset); + + // no more changes or no changes in this structure + if(next<0||next>=offset+numberFields) return; + + // entire structure + if(offset==next) { + deserialize(pbuffer, pcontrol); + return; + } + + for(int i = 0; inumberFields; i++) { + PVField* pvField = pImpl->pvFields[i]; + offset = pvField->getFieldOffset(); + numberFields = pvField->getNumberFields(); + next = pbitSet->nextSetBit(offset); + // no more changes + if(next<0) return; + // no change in this pvField + if(next>=offset+numberFields) continue; + + // deserialize field or fields + if(numberFields==1) + pvField->deserialize(pbuffer, pcontrol); + else + ((PVStructure*)pvField)->deserialize(pbuffer, pcontrol, + pbitSet); + } + } + + + bool PVStructure::operator==(PVField &obj) { - PVStructure *b = dynamic_cast(obj); - if(b==0) return false; - PVFieldPtrArray bFields = b->getPVFields(); + PVStructure &b = dynamic_cast(obj); + PVFieldPtrArray bFields = b.pImpl->pvFields; PVFieldPtrArray pvFields = pImpl->pvFields; - int len = b->getNumberFields(); + int len = b.pImpl->numberFields; if(len!=pImpl->numberFields) return false; for (int i = 0; i < len; i++) { - if (!(pvFields[i]==bFields[i])) return false; + if (!(*pvFields[i]==*bFields[i])) return false; } return true; } - bool PVStructure::operator!=(PVField *pv) + bool PVStructure::operator!=(PVField &pv) { - return !(this==pv); + return !(*this==pv); } static PVField *findSubField(String fieldName,PVStructure *pvStructure) { diff --git a/pvDataApp/factory/BasePVStructureArray.h b/pvDataApp/factory/BasePVStructureArray.h index 55290ca..265821a 100644 --- a/pvDataApp/factory/BasePVStructureArray.h +++ b/pvDataApp/factory/BasePVStructureArray.h @@ -7,6 +7,7 @@ #include #include "pvData.h" #include "factory.h" +#include "serializeHelper.h" namespace epics { namespace pvData { @@ -30,8 +31,8 @@ namespace epics { namespace pvData { PVStructurePtrArray from, int fromOffset); virtual void toString(StringBuilder buf) ; virtual void toString(StringBuilder buf,int indentLevel) ; - virtual bool operator==(PVField *pv); - virtual bool operator!=(PVField *pv); + virtual bool operator==(PVField &pv); + virtual bool operator!=(PVField &pv); virtual void shareData( PVStructurePtrArray value,int capacity,int length); virtual void serialize(ByteBuffer *pbuffer, SerializableControl *pflusher); @@ -72,21 +73,21 @@ namespace epics { namespace pvData { int limit = length; if(length>capacity) limit = capacity; for(int i=0; icapacity) length = capacity; delete[] value; value = newValue; setCapacityLength(capacity,length); } - - StructureArrayConstPtr BasePVStructureArray::getStructureArray() + + StructureArrayConstPtr BasePVStructureArray::getStructureArray() { return structureArray; } int BasePVStructureArray::get( - int offset, int len, StructureArrayData *data) + int offset, int len, StructureArrayData *data) { int n = len; int length = getLength(); @@ -135,7 +136,7 @@ namespace epics { namespace pvData { value[i+offset] = frompv; } postPut(); - return len; + return len; } void BasePVStructureArray::shareData( @@ -148,38 +149,79 @@ namespace epics { namespace pvData { void BasePVStructureArray::toString(StringBuilder buf) {toString(buf,0);} - void BasePVStructureArray::toString(StringBuilder buf,int indentLevel) + void BasePVStructureArray::toString(StringBuilder buf,int indentLevel) { getConvert()->getString(buf,this,indentLevel); PVField::toString(buf,indentLevel); } - void BasePVStructureArray::serialize( - ByteBuffer *pbuffer,SerializableControl *pflusher) - { - throw std::logic_error(notImplemented); + void BasePVStructureArray::serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher) { + serialize(pbuffer, pflusher, 0, getLength()); } - void BasePVStructureArray::deserialize( - ByteBuffer *pbuffer,DeserializableControl *pflusher) - { - throw std::logic_error(notImplemented); + void BasePVStructureArray::deserialize(ByteBuffer *pbuffer, + DeserializableControl *pcontrol) { + int size = SerializeHelper::readSize(pbuffer, pcontrol); + if(size>=0) { + // prepare array, if necessary + if(size>getCapacity()) setCapacity(size); + for(int i = 0; iensureData(1); + epicsInt8 temp = pbuffer->getByte(); + if(temp==0) { + value[i] = NULL; + } + else { + if(value[i]==NULL) { + value[i] = getPVDataCreate()->createPVStructure( + NULL, structureArray->getStructure()); + } + value[i]->deserialize(pbuffer, pcontrol); + } + } + setLength(size); + postPut(); + } } void BasePVStructureArray::serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) - { - throw std::logic_error(notImplemented); + SerializableControl *pflusher, int offset, int count) { + // cache + int length = getLength(); + + // check bounds + if(offset<0) + offset = 0; + else if(offset>length) offset = length; + if(count<0) count = length; + + int maxCount = length-offset; + if(count>maxCount) count = maxCount; + + // write + SerializeHelper::writeSize(count, pbuffer, pflusher); + for(int i = 0; igetRemaining()<1) pflusher->flushSerializeBuffer(); + PVStructure* pvStructure = value[i+offset]; + if(pvStructure==NULL) { + pbuffer->putByte(0); + } + else { + pbuffer->putByte(1); + pvStructure->serialize(pbuffer, pflusher); + } + } } - bool BasePVStructureArray::operator==(PVField *pvField) + bool BasePVStructureArray::operator==(PVField &pvField) { - return getConvert()->equals(this,pvField); + return getConvert()->equals(this,&pvField); } - bool BasePVStructureArray::operator!=(PVField *pvField) + bool BasePVStructureArray::operator!=(PVField &pvField) { - return !(getConvert()->equals(this,pvField)); + return !(getConvert()->equals(this,&pvField)); } }} diff --git a/pvDataApp/factory/Makefile b/pvDataApp/factory/Makefile index 259c822..7899b2f 100644 --- a/pvDataApp/factory/Makefile +++ b/pvDataApp/factory/Makefile @@ -37,6 +37,7 @@ LIBSRCS += StandardPVField.cpp LIBRARY=pvFactory pvFactory_LIBS += Com +pvFactory_LIBS += pvMisc include $(TOP)/configure/RULES #---------------------------------------- diff --git a/pvDataApp/misc/byteBuffer.cpp b/pvDataApp/misc/byteBuffer.cpp index 731d0aa..d99891f 100644 --- a/pvDataApp/misc/byteBuffer.cpp +++ b/pvDataApp/misc/byteBuffer.cpp @@ -101,17 +101,17 @@ namespace epics { return val; } - ByteBuffer* ByteBuffer::put(const char* src, int offset, int count) { - if(count>getRemaining()) throw EpicsException("buffer overflow"); - strncpy(&_buffer[_position], &src[offset], count); - _position += count; - return this; + void ByteBuffer::get(char* dst, int offset, int count) { + if(count>getRemaining()) throw EpicsException("buffer underflow"); + for(int i = 0; igetRemaining()) throw EpicsException("buffer underflow"); - strncpy(&dst[offset], &_buffer[_position], count); - _position += count; + ByteBuffer* ByteBuffer::put(const char* src, int offset, int count) { + if(count>getRemaining()) throw EpicsException("buffer overflow"); + for(int i = 0; i + +#include + +#include "pvIntrospect.h" +#include "pvData.h" +#include "serialize.h" +#include "noDefaultMethods.h" +#include "byteBuffer.h" + +#define BYTE_MAX_VALUE 127 +#define BYTE_MIN_VALUE -128 +#define SHORT_MAX_VALUE 32767 +#define SHORT_MIN_VALUE -32768 +#define INT_MAX_VALUE 2147483647 +#define INT_MIN_VALUE -2147483648 +#define LONG_MAX_VALUE 9223372036854775807LL +#define LONG_MIN_VALUE -9223372036854775808LL +#define FLOAT_MAX_VALUE 3.4028235E38 +#define FLOAT_MIN_VALUE 1.4E-45 +#define DOUBLE_MAX_VALUE 1.7976931348623157E308 +#define DOUBLE_MIN_VALUE 4.9E-324 + +using namespace epics::pvData; +using std::cout; + +namespace epics { + namespace pvData { + + class SerializableControlImpl : public SerializableControl, + public NoDefaultMethods { + public: + virtual void flushSerializeBuffer() { + } + + virtual void ensureBuffer(int size) { + } + + SerializableControlImpl() { + } + + virtual ~SerializableControlImpl() { + } + }; + + class DeserializableControlImpl : public DeserializableControl, + public NoDefaultMethods { + public: + virtual void ensureData(int size) { + } + + DeserializableControlImpl() { + } + + virtual ~DeserializableControlImpl() { + } + }; + + } +} + +static SerializableControl* flusher; +static DeserializableControl* control; +static ByteBuffer* buffer; + +void serializationTest(PVField* field) { + buffer->clear(); + + // serialize + field->serialize(buffer, flusher); + + buffer->flip(); + + // create new instance and deserialize + PVField* deserializedField = getPVDataCreate()->createPVField(NULL, + field->getField()); + deserializedField->deserialize(buffer, control); + + // must equal + assert((*field)==(*deserializedField)); + + delete deserializedField; // clean up +} + +void testScalar() { + cout<<"Testing scalars...\n"; + PVDataCreate* factory = getPVDataCreate(); + assert(factory!=NULL); + + cout<<"\tPVBoolean\n"; + PVBoolean* pvBoolean = (PVBoolean*)factory->createPVScalar(NULL, + "pvBoolean", epics::pvData::pvBoolean); + pvBoolean->put(false); + serializationTest(pvBoolean); + pvBoolean->put(true); + serializationTest(pvBoolean); + delete pvBoolean; + + cout<<"\tPVByte\n"; + PVByte* pvByte = (PVByte*)factory->createPVScalar(NULL, "pvByte", + epics::pvData::pvByte); + pvByte->put(0); + serializationTest(pvByte); + pvByte->put(12); + serializationTest(pvByte); + pvByte->put(BYTE_MAX_VALUE); + serializationTest(pvByte); + pvByte->put(BYTE_MIN_VALUE); + serializationTest(pvByte); + delete pvByte; + + cout<<"\tPVShort\n"; + PVShort* pvShort = (PVShort*)factory->createPVScalar(NULL, "pvShort", + epics::pvData::pvShort); + pvShort->put(0); + serializationTest(pvShort); + pvShort->put(123); + serializationTest(pvShort); + pvShort->put(BYTE_MAX_VALUE); + serializationTest(pvShort); + pvShort->put(BYTE_MIN_VALUE); + serializationTest(pvShort); + pvShort->put(SHORT_MAX_VALUE); + serializationTest(pvShort); + pvShort->put(SHORT_MIN_VALUE); + serializationTest(pvShort); + delete pvShort; + + cout<<"\tPVInt\n"; + PVInt* pvInt = (PVInt*)factory->createPVScalar(NULL, "pvInt", + epics::pvData::pvInt); + pvInt->put(0); + serializationTest(pvInt); + pvInt->put(123456); + serializationTest(pvInt); + pvInt->put(BYTE_MAX_VALUE); + serializationTest(pvInt); + pvInt->put(BYTE_MIN_VALUE); + serializationTest(pvInt); + pvInt->put(SHORT_MAX_VALUE); + serializationTest(pvInt); + pvInt->put(SHORT_MIN_VALUE); + serializationTest(pvInt); + pvInt->put(INT_MAX_VALUE); + serializationTest(pvInt); + pvInt->put(INT_MIN_VALUE); + serializationTest(pvInt); + delete pvInt; + + cout<<"\tPVLong\n"; + PVLong* pvLong = (PVLong*)factory->createPVScalar(NULL, "pvLong", + epics::pvData::pvLong); + pvLong->put(0); + serializationTest(pvLong); + pvLong->put(12345678901LL); + serializationTest(pvLong); + pvLong->put(BYTE_MAX_VALUE); + serializationTest(pvLong); + pvLong->put(BYTE_MIN_VALUE); + serializationTest(pvLong); + pvLong->put(SHORT_MAX_VALUE); + serializationTest(pvLong); + pvLong->put(SHORT_MIN_VALUE); + serializationTest(pvLong); + pvLong->put(INT_MAX_VALUE); + serializationTest(pvLong); + pvLong->put(INT_MIN_VALUE); + serializationTest(pvLong); + pvLong->put(LONG_MAX_VALUE); + serializationTest(pvLong); + pvLong->put(LONG_MIN_VALUE); + serializationTest(pvLong); + delete pvLong; + + cout<<"\tPVFloat\n"; + PVFloat* pvFloat = (PVFloat*)factory->createPVScalar(NULL, "pvFloat", + epics::pvData::pvFloat); + pvFloat->put(0); + serializationTest(pvFloat); + pvFloat->put(12.345); + serializationTest(pvFloat); + pvFloat->put(FLOAT_MAX_VALUE); + serializationTest(pvFloat); + pvFloat->put(FLOAT_MIN_VALUE); + serializationTest(pvFloat); + delete pvFloat; + + cout<<"\tPVDouble\n"; + PVDouble* pvDouble = (PVDouble*)factory->createPVScalar(NULL, "pvDouble", + epics::pvData::pvDouble); + pvDouble->put(0); + serializationTest(pvDouble); + pvDouble->put(12.345); + serializationTest(pvDouble); + pvDouble->put(DOUBLE_MAX_VALUE); + serializationTest(pvDouble); + pvDouble->put(DOUBLE_MIN_VALUE); + serializationTest(pvDouble); + delete pvDouble; + + cout<<"\tPVString\n"; + PVString* pvString = (PVString*)factory->createPVScalar(NULL, "pvString", + epics::pvData::pvString); + pvString->put(""); + serializationTest(pvString); + pvString->put("s"); + serializationTest(pvString); + pvString->put("string"); + serializationTest(pvString); + pvString->put("string with spaces"); + serializationTest(pvString); + pvString->put("string with spaces and special characters\f\n"); + serializationTest(pvString); + + // huge string test + pvString->put(String(10000, 'a')); + serializationTest(pvString); + + delete pvString; + + cout<<"!!! PASSED\n\n"; +} + +void testArray() { + cout<<"Testing arrays...\n"; + + PVDataCreate* factory = getPVDataCreate(); + assert(factory!=NULL); + + cout<<"\tPVBooleanArray\n"; + bool boolEmpty[] = { }; + bool bv[] = { false, true, false, true, true }; + PVBooleanArray* pvBoolean = (PVBooleanArray*)factory->createPVScalarArray( + NULL, "pvBooleanArray", epics::pvData::pvBoolean); + pvBoolean->put(0, 0, boolEmpty, 0); + serializationTest(pvBoolean); + pvBoolean->put(0, 5, bv, 0); + serializationTest(pvBoolean); + delete pvBoolean; + + cout<<"\tPVByteArray\n"; + epicsInt8 byteEmpty[] = { }; + epicsInt8 byv[] = { 0, 1, 2, -1, BYTE_MAX_VALUE, BYTE_MAX_VALUE-1, + BYTE_MIN_VALUE+1, BYTE_MIN_VALUE }; + PVByteArray* pvByte = (PVByteArray*)factory->createPVScalarArray(NULL, + "pvByteArray", epics::pvData::pvByte); + pvByte->put(0, 0, byteEmpty, 0); + serializationTest(pvByte); + pvByte->put(0, 8, byv, 0); + serializationTest(pvByte); + delete pvByte; + + cout<<"\tPVShortArray\n"; + epicsInt16 shortEmpty[] = { }; + epicsInt16 sv[] = { 0, 1, 2, -1, SHORT_MAX_VALUE, SHORT_MAX_VALUE-1, + SHORT_MIN_VALUE+1, SHORT_MIN_VALUE }; + PVShortArray* pvShort = (PVShortArray*)factory->createPVScalarArray(NULL, + "pvShortArray", epics::pvData::pvShort); + pvShort->put(0, 0, shortEmpty, 0); + serializationTest(pvShort); + pvShort->put(0, 8, sv, 0); + serializationTest(pvShort); + delete pvShort; + + cout<<"\tPVIntArray\n"; + epicsInt32 intEmpty[] = { }; + epicsInt32 iv[] = { 0, 1, 2, -1, INT_MAX_VALUE, INT_MAX_VALUE-1, + INT_MIN_VALUE+1, INT_MIN_VALUE }; + PVIntArray* pvInt = (PVIntArray*)factory->createPVScalarArray(NULL, + "pvIntArray", epics::pvData::pvInt); + pvInt->put(0, 0, intEmpty, 0); + serializationTest(pvInt); + pvInt->put(0, 8, iv, 0); + serializationTest(pvInt); + delete pvInt; + + cout<<"\tPVLongArray\n"; + epicsInt64 longEmpty[] = { }; + epicsInt64 lv[] = { 0, 1, 2, -1, LONG_MAX_VALUE, LONG_MAX_VALUE-1, + LONG_MIN_VALUE+1, LONG_MIN_VALUE }; + PVLongArray* pvLong = (PVLongArray*)factory->createPVScalarArray(NULL, + "pvLongArray", epics::pvData::pvLong); + pvLong->put(0, 0, longEmpty, 0); + serializationTest(pvLong); + pvLong->put(0, 8, lv, 0); + serializationTest(pvLong); + delete pvLong; + + cout<<"\tPVFloatArray\n"; + float floatEmpty[] = { }; + float fv[] = { (float)0.0, (float)1.1, (float)2.3, (float)-1.4, + FLOAT_MAX_VALUE, FLOAT_MAX_VALUE-(float)123456.789, FLOAT_MIN_VALUE + +(float)1.1, FLOAT_MIN_VALUE }; + PVFloatArray* pvFloat = (PVFloatArray*)factory->createPVScalarArray(NULL, + "pvFloatArray", epics::pvData::pvFloat); + pvFloat->put(0, 0, floatEmpty, 0); + serializationTest(pvFloat); + pvFloat->put(0, 8, fv, 0); + serializationTest(pvFloat); + delete pvFloat; + + cout<<"\tPVDoubleArray\n"; + double doubleEmpty[] = { }; + double dv[] = { (double)0.0, (double)1.1, (double)2.3, (double)-1.4, + DOUBLE_MAX_VALUE, DOUBLE_MAX_VALUE-(double)123456.789, + DOUBLE_MIN_VALUE+(double)1.1, DOUBLE_MIN_VALUE }; + PVDoubleArray* pvDouble = (PVDoubleArray*)factory->createPVScalarArray( + NULL, "pvDoubleArray", epics::pvData::pvDouble); + pvDouble->put(0, 0, doubleEmpty, 0); + serializationTest(pvDouble); + pvDouble->put(0, 8, dv, 0); + serializationTest(pvDouble); + delete pvDouble; + + cout<<"\tPVStringArray\n"; + String stringEmpty[] = { }; + String + strv[] = + { + "", + "a", + "a b", + " ", + "test", + "smile", + "this is a little longer string... maybe a little but longer... this makes test better" }; + PVStringArray* pvString = (PVStringArray*)factory->createPVScalarArray( + NULL, "pvStringArray", epics::pvData::pvString); + pvString->put(0, 0, stringEmpty, 0); + serializationTest(pvString); + pvString->put(0, 7, strv, 0); + serializationTest(pvString); + delete pvString; + + cout<<"!!! PASSED\n\n"; +} + +void testScalarEquals() { + cout<<"Testing scalar equals...\n"; + PVDataCreate* factory = getPVDataCreate(); + assert(factory!=NULL); + + PVScalar *scalar1, *scalar2; + + scalar1 = factory->createPVScalar(NULL, "pvBoolean", + epics::pvData::pvBoolean); + scalar2 = factory->createPVScalar(NULL, "pvBoolean", + epics::pvData::pvBoolean); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 = factory->createPVScalar(NULL, "pvByte", epics::pvData::pvByte); + scalar2 = factory->createPVScalar(NULL, "pvByte", epics::pvData::pvByte); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 = factory->createPVScalar(NULL, "pvShort", epics::pvData::pvShort); + scalar2 = factory->createPVScalar(NULL, "pvShort", epics::pvData::pvShort); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 = factory->createPVScalar(NULL, "pvInt", epics::pvData::pvInt); + scalar2 = factory->createPVScalar(NULL, "pvInt", epics::pvData::pvInt); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 = factory->createPVScalar(NULL, "pvLong", epics::pvData::pvLong); + scalar2 = factory->createPVScalar(NULL, "pvLong", epics::pvData::pvLong); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 = factory->createPVScalar(NULL, "pvFloat", epics::pvData::pvFloat); + scalar2 = factory->createPVScalar(NULL, "pvFloat", epics::pvData::pvFloat); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 + = factory->createPVScalar(NULL, "pvDouble", epics::pvData::pvDouble); + scalar2 + = factory->createPVScalar(NULL, "pvDouble", epics::pvData::pvDouble); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + scalar1 + = factory->createPVScalar(NULL, "pvString", epics::pvData::pvString); + scalar2 + = factory->createPVScalar(NULL, "pvString", epics::pvData::pvString); + assert((*scalar1)==(*scalar2)); + delete scalar1; + delete scalar2; + + FieldCreate* fieldCreate = getFieldCreate(); + FieldConstPtr fields[2]; + fields[0] = fieldCreate->createScalar("secondsSinceEpoch", + epics::pvData::pvLong); + fields[1] = fieldCreate->createScalar("nanoSeconds", epics::pvData::pvInt); + StructureConstPtr structure = fieldCreate->createStructure("timeStamp", 2, + fields); + + PVStructure* pvStruct1 = factory->createPVStructure(NULL, structure); + PVStructure* pvStruct2 = factory->createPVStructure(NULL, structure); + assert((*pvStruct1)==(*pvStruct2)); + delete pvStruct2; + delete pvStruct1; + // 'structure' and 'fields' are deleted implicitly + + cout<<"!!! PASSED\n\n"; +} + +void testScalarNonInitialized() { + cout<<"Testing scalar non-initialized...\n"; + PVDataCreate* factory = getPVDataCreate(); + assert(factory!=NULL); + + PVScalar* scalar; + + scalar = factory->createPVScalar(NULL, "pvBoolean", + epics::pvData::pvBoolean); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvByte", epics::pvData::pvByte); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvShort", epics::pvData::pvShort); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvInt", epics::pvData::pvInt); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvLong", epics::pvData::pvLong); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvFloat", epics::pvData::pvFloat); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvDouble", epics::pvData::pvDouble); + serializationTest(scalar); + delete scalar; + + scalar = factory->createPVScalar(NULL, "pvString", epics::pvData::pvString); + serializationTest(scalar); + delete scalar; + + FieldCreate* fieldCreate = getFieldCreate(); + FieldConstPtr fields[2]; + fields[0] = fieldCreate->createScalar("secondsSinceEpoch", + epics::pvData::pvLong); + fields[1] = fieldCreate->createScalar("nanoSeconds", epics::pvData::pvInt); + StructureConstPtr structure = fieldCreate->createStructure("timeStamp", 2, + fields); + + PVStructure* pvStruct = factory->createPVStructure(NULL, structure); + serializationTest(pvStruct); + delete pvStruct; // 'structure' and 'fields' are deleted implicitly + + cout<<"!!! PASSED\n\n"; +} + +void testArrayNonInitialized() { + cout<<"Testing array non-initialized...\n"; + PVDataCreate* factory = getPVDataCreate(); + assert(factory!=NULL); + + PVArray* array; + + array = factory->createPVScalarArray(NULL, "pvBooleanArray", + epics::pvData::pvBoolean); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvByteArray", + epics::pvData::pvByte); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvShortArray", + epics::pvData::pvShort); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvIntArray", + epics::pvData::pvInt); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvLongArray", + epics::pvData::pvLong); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvFloatArray", + epics::pvData::pvFloat); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvDoubleArray", + epics::pvData::pvDouble); + serializationTest(array); + delete array; + + array = factory->createPVScalarArray(NULL, "pvStringArray", + epics::pvData::pvString); + serializationTest(array); + delete array; + + FieldCreate* fieldCreate = getFieldCreate(); + FieldConstPtr fields[2]; + fields[0] = fieldCreate->createScalar("secondsSinceEpoch", + epics::pvData::pvLong); + fields[1] = fieldCreate->createScalar("nanoSeconds", epics::pvData::pvInt); + StructureConstPtr structure = fieldCreate->createStructure("timeStamp", 2, + fields); + + StructureArrayConstPtr structureArray = fieldCreate->createStructureArray( + "timeStampArray", structure); + PVStructureArray* pvStructArray = factory->createPVStructureArray(NULL, + structureArray); + serializationTest(pvStructArray); + delete pvStructArray; // also deletes 'structureArray', + //'structureArray' also deletes 'structure' + //'structure' also deletes 'fields' + + cout<<"!!! PASSED\n\n"; +} + +void testStructure() { + cout<<"Testing structure...\n"; + + FieldCreate* fieldCreate = getFieldCreate(); + PVDataCreate* pvDataCreate = getPVDataCreate(); + assert(fieldCreate!=NULL); + assert(pvDataCreate!=NULL); + + cout<<"\tSimple structure serialization\n"; + FieldConstPtr fields[2]; + fields[0] = fieldCreate->createScalar("secondsSinceEpoch", + epics::pvData::pvLong); + fields[1] = fieldCreate->createScalar("nanoSeconds", epics::pvData::pvInt); + PVStructure* pvStructure = pvDataCreate->createPVStructure(NULL, + "timestamp", 2, fields); + pvStructure->getLongField(fields[0]->getFieldName())->put(123); + pvStructure->getIntField(fields[1]->getFieldName())->put(456); + + serializationTest(pvStructure); + //serializationTest(pvStructure->getStructure()); + + cout<<"\tComplex structure serialization\n"; + // and more complex :) + FieldConstPtr fields2[4]; + fields2[0] = fieldCreate->createScalar("longVal", epics::pvData::pvLong); + fields2[1] = fieldCreate->createScalar("intVal", epics::pvData::pvInt); + fields2[2] = fieldCreate->createScalarArray("values", epics::pvData::pvDouble); + fields2[3] = fieldCreate->createStructure("timeStamp", 2, fields); + PVStructure* pvStructure2 = pvDataCreate->createPVStructure(NULL, + "complexStructure", 4, fields2); + pvStructure2->getLongField(fields2[0]->getFieldName())->put(1234); + pvStructure2->getIntField(fields2[1]->getFieldName())->put(4567); + PVDoubleArray* da = (PVDoubleArray*)pvStructure2->getScalarArrayField( + fields2[2]->getFieldName(), epics::pvData::pvDouble); + double dd[] = { 1.2, 3.4, 4.5 }; + da->put(0, 3, dd, 0); + + PVStructure* ps = pvStructure2->getStructureField( + fields2[3]->getFieldName()); + ps->getLongField(fields[0]->getFieldName())->put(789); + ps->getIntField(fields[1]->getFieldName())->put(1011); + + serializationTest(pvStructure2); + //serializationTest(pvStructure2->getStructure()); + delete pvStructure2; + delete pvStructure; + + cout<<"!!! PASSED\n\n"; +} + +/* + void testIntrospectionSerialization() { + cout<<"Testing introspection serialization...\n"; + FieldCreate* factory = getFieldCreate(); + assert(factory!=NULL); + + ScalarConstPtr scalar = factory->createScalar("scalar", epics::pvData::pvDouble); + serializatioTest(scalar); + delete scalar; + + ScalarArrayConstPtr array = factory->createScalarArray("array", epics::pvData::pvDouble); + serializatioTest(array); + delete array; + + cout<<"!!! PASSED\n\n"; + } + */ + +int main(int argc, char *argv[]) { + flusher = new SerializableControlImpl(); + control = new DeserializableControlImpl(); + buffer = new ByteBuffer(1<<16); + + testScalarEquals(); + testScalar(); + testArray(); + testScalarNonInitialized(); + testArrayNonInitialized(); + testStructure(); + //testIntrospectionSerialization(); + + delete buffer; + delete control; + delete flusher; + + cout<<"\nDone!\n"; + + return (0); +} +