pull from sourceforge
This commit is contained in:
@@ -80,3 +80,5 @@ pvDataApp/misc/bitSet.cpp
|
||||
pvDataApp/test/testByteBuffer.cpp
|
||||
pvDataApp/test/testBitSet.cpp
|
||||
pvDataApp/test/testBaseException.cpp
|
||||
pvDataApp/misc/serializeHelper.h
|
||||
pvDataApp/misc/serializeHelper.cpp
|
||||
|
||||
@@ -9,9 +9,11 @@ INC += serialize.h
|
||||
INC += bitSet.h
|
||||
INC += byteBuffer.h
|
||||
INC += epicsException.h
|
||||
INC += serializeHelper.h
|
||||
|
||||
LIBSRCS += byteBuffer.cpp
|
||||
LIBSRCS += bitSet.cpp
|
||||
LIBSRCS += serializeHelper.cpp
|
||||
|
||||
LIBRARY=pvMisc
|
||||
|
||||
|
||||
@@ -101,6 +101,19 @@ 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");
|
||||
strncpy(&dst[offset], &_buffer[_position], count);
|
||||
_position += count;
|
||||
}
|
||||
|
||||
ByteBuffer* ByteBuffer::putBoolean(bool value) {
|
||||
if(_position<_limit)
|
||||
_buffer[_position++] = value ? 1 : 0;
|
||||
|
||||
@@ -133,9 +133,34 @@ namespace epics {
|
||||
*/
|
||||
double getDouble();
|
||||
|
||||
/**
|
||||
* Relative bulk @em get method. It transfers {@code count} bytes
|
||||
* from the buffer into the {@code dst}.
|
||||
*
|
||||
* @param[out] dst Destination buffer
|
||||
* @param[in] offset Offset in the destination buffer
|
||||
* @param[in] count The number of bytes to copy
|
||||
* @throws EpicsException - Buffer underflow if there are fewer
|
||||
* than count bytes remaining in the buffer.
|
||||
*/
|
||||
void get(char* dst, int offset, int count);
|
||||
|
||||
//virtual String getString() = 0; // TODO
|
||||
|
||||
|
||||
/**
|
||||
* Relative bulk @em put method. It transfers {@code count} bytes
|
||||
* from the {@code src} into the the buffer.
|
||||
*
|
||||
* @param[in] src Source buffer
|
||||
* @param[in] offset Offset in the source buffer
|
||||
* @param[in] count The number of bytes to copy
|
||||
* @returns Pointer to this ByteBuffer instance.
|
||||
* @throws EpicsException - Buffer overflow if there are not
|
||||
* enough bytes remaining in the buffer.
|
||||
*/
|
||||
ByteBuffer* put(const char* src, int offset, int count);
|
||||
|
||||
/**
|
||||
* Relative boolean write, {@code position} is incremented by
|
||||
* {@code 1}.
|
||||
|
||||
@@ -12,11 +12,13 @@ namespace epics { namespace pvData {
|
||||
class SerializableArray;
|
||||
|
||||
class SerializableControl {
|
||||
public:
|
||||
virtual void flushSerializeBuffer() =0;
|
||||
virtual void ensureBuffer(int size) =0;
|
||||
};
|
||||
|
||||
class DeserializableControl {
|
||||
public:
|
||||
virtual void ensureData(int size) =0;
|
||||
};
|
||||
|
||||
|
||||
120
pvDataApp/misc/serializeHelper.cpp
Normal file
120
pvDataApp/misc/serializeHelper.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* serializeHelper.cpp
|
||||
*
|
||||
* Created on: Oct 22, 2010
|
||||
* Author: Miha vitorovic
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <epicsTypes.h>
|
||||
|
||||
#include "epicsException.h"
|
||||
#include "byteBuffer.h"
|
||||
#include "serializeHelper.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace epics {
|
||||
namespace pvData {
|
||||
|
||||
void SerializeHelper::writeSize(int s, ByteBuffer* buffer,
|
||||
SerializableControl* flusher) {
|
||||
flusher->ensureBuffer(sizeof(epicsInt64)+1);
|
||||
SerializeHelper::writeSize(s, buffer);
|
||||
}
|
||||
|
||||
void SerializeHelper::writeSize(int s, ByteBuffer* buffer) {
|
||||
if(s==-1) // null
|
||||
buffer->putByte(-1);
|
||||
else if(s<254)
|
||||
buffer->putByte(s);
|
||||
else
|
||||
buffer->putByte(-2)->putInt(s); // (byte)-2 + size
|
||||
}
|
||||
|
||||
int SerializeHelper::readSize(ByteBuffer* buffer,
|
||||
DeserializableControl* control) {
|
||||
control->ensureData(1);
|
||||
epicsInt8 b = buffer->getByte();
|
||||
if(b==-1)
|
||||
return -1;
|
||||
else if(b==-2) {
|
||||
control->ensureData(sizeof(epicsInt32));
|
||||
epicsInt32 s = buffer->getInt();
|
||||
if(s<0) throw EpicsException("negative array size");
|
||||
return s;
|
||||
}
|
||||
else
|
||||
return (int)(b<0 ? b+256 : b);
|
||||
}
|
||||
|
||||
void SerializeHelper::serializeString(const String& value,
|
||||
ByteBuffer* buffer, SerializableControl* flusher) {
|
||||
int len = value.length();
|
||||
SerializeHelper::writeSize(len, buffer, flusher);
|
||||
int i = 0;
|
||||
while(true) {
|
||||
int maxToWrite = min(len-i, buffer->getRemaining());
|
||||
buffer->put(value.data(), i, maxToWrite); // UTF-8
|
||||
i += maxToWrite;
|
||||
if(i<len)
|
||||
flusher->flushSerializeBuffer();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeHelper::serializeSubstring(const String& value,
|
||||
int offset, int count, ByteBuffer* buffer,
|
||||
SerializableControl* flusher) {
|
||||
if(offset<0)
|
||||
offset = 0;
|
||||
else if(offset>(int)value.length()) offset = value.length();
|
||||
|
||||
if(offset+count>(int)value.length()) count = value.length()-offset;
|
||||
|
||||
SerializeHelper::writeSize(count, buffer, flusher);
|
||||
int i = 0;
|
||||
while(true) {
|
||||
int maxToWrite = min(count-i, buffer->getRemaining());
|
||||
buffer->put(value.data(), offset+i, maxToWrite); // UTF-8
|
||||
i += maxToWrite;
|
||||
if(i<count)
|
||||
flusher->flushSerializeBuffer();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String SerializeHelper::deserializeString(ByteBuffer* buffer,
|
||||
DeserializableControl* control) {
|
||||
|
||||
int size = SerializeHelper::readSize(buffer, control);
|
||||
if(size>=0) {
|
||||
char* retBuffer = new char[size]; // get the return buffer
|
||||
try {
|
||||
int i = 0;
|
||||
while(true) {
|
||||
int toRead = min(size-i, buffer->getRemaining());
|
||||
buffer->get(retBuffer, i, toRead);
|
||||
i += toRead;
|
||||
if(i<size)
|
||||
control->ensureData(1);
|
||||
else
|
||||
break;
|
||||
}
|
||||
String s = String(retBuffer, size);
|
||||
delete retBuffer;
|
||||
return s;
|
||||
} catch(...) {
|
||||
delete retBuffer; // remove the buffer
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
return String("");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
98
pvDataApp/misc/serializeHelper.h
Normal file
98
pvDataApp/misc/serializeHelper.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* serializeHelper.h
|
||||
*
|
||||
* Created on: Oct 21, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#ifndef SERIALIZEHELPER_H_
|
||||
#define SERIALIZEHELPER_H_
|
||||
|
||||
#include "serialize.h"
|
||||
#include "byteBuffer.h"
|
||||
#include "noDefaultMethods.h"
|
||||
#include "../pv/pvIntrospect.h"
|
||||
|
||||
namespace epics {
|
||||
namespace pvData {
|
||||
|
||||
class SerializeHelper : public NoDefaultMethods {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Serialize array size.
|
||||
*
|
||||
* @param[in] s size to encode
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void writeSize(int s, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
* Deserialize array size.
|
||||
*
|
||||
* @param[in] buffer deserialization buffer.
|
||||
* @returns array size.
|
||||
*/
|
||||
static int readSize(ByteBuffer* buffer,
|
||||
DeserializableControl* control);
|
||||
|
||||
/**
|
||||
* String serialization helper method.
|
||||
*
|
||||
* @param[in] value String to serialize
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void serializeString(const String& value, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
* String serialization helper method.
|
||||
*
|
||||
* @param[in] value String to serialize
|
||||
* @param[in] offset start of the substring in {@code value}
|
||||
* @param[in] count the number of characters to write
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void serializeSubstring(const String& value, int offset,
|
||||
int count, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
* String deserialization helper method.
|
||||
* TODO This method cannot return "null", but Java implementation
|
||||
* could have serialized "null" value as well. We need to decide
|
||||
* how to deserialize "null".
|
||||
*
|
||||
* @param[in] buffer deserialization buffer
|
||||
* @param[in] control control
|
||||
* @returns deserialized string
|
||||
*
|
||||
* @todo This method cannot return "null", but Java implementation
|
||||
* could have serialized "null" value as well. We need to decide
|
||||
* how to deserialize "null".
|
||||
*/
|
||||
static String deserializeString(ByteBuffer* buffer,
|
||||
DeserializableControl* control);
|
||||
|
||||
private:
|
||||
SerializeHelper() {};
|
||||
~SerializeHelper() {};
|
||||
|
||||
/**
|
||||
* Serialize array size.
|
||||
*
|
||||
* @param[in] s size to encode
|
||||
* @param[in] buffer serialization buffer
|
||||
*/
|
||||
static void writeSize(int s, ByteBuffer* buffer);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SERIALIZEHELPER_H_ */
|
||||
@@ -12,115 +12,137 @@
|
||||
#include <epicsEndian.h>
|
||||
|
||||
#include "byteBuffer.h"
|
||||
#include "pvIntrospect.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::cout;
|
||||
|
||||
void testBasicOperations() {
|
||||
cout<<"Basic operation tests...\n";
|
||||
cout<<"Basic operation tests...\n";
|
||||
|
||||
ByteBuffer* buff = new ByteBuffer();
|
||||
assert(buff->getSize()==32);
|
||||
assert(buff->getByteOrder()==EPICS_BYTE_ORDER);
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getLimit()==32);
|
||||
assert(buff->getRemaining()==32);
|
||||
ByteBuffer* buff = new ByteBuffer();
|
||||
assert(buff->getSize()==32);
|
||||
assert(buff->getByteOrder()==EPICS_BYTE_ORDER);
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getLimit()==32);
|
||||
assert(buff->getRemaining()==32);
|
||||
|
||||
buff->putBoolean(true);
|
||||
assert(buff->getPosition()==1);
|
||||
assert(buff->getRemaining()==31);
|
||||
buff->putBoolean(true);
|
||||
assert(buff->getPosition()==1);
|
||||
assert(buff->getRemaining()==31);
|
||||
|
||||
buff->putByte(-12);
|
||||
assert(buff->getPosition()==2);
|
||||
assert(buff->getRemaining()==30);
|
||||
buff->putByte(-12);
|
||||
assert(buff->getPosition()==2);
|
||||
assert(buff->getRemaining()==30);
|
||||
|
||||
buff->putShort(10516);
|
||||
assert(buff->getPosition()==4);
|
||||
assert(buff->getRemaining()==28);
|
||||
buff->putShort(10516);
|
||||
assert(buff->getPosition()==4);
|
||||
assert(buff->getRemaining()==28);
|
||||
|
||||
buff->putInt(0x1937628B);
|
||||
assert(buff->getPosition()==8);
|
||||
assert(buff->getRemaining()==24);
|
||||
buff->putInt(0x1937628B);
|
||||
assert(buff->getPosition()==8);
|
||||
assert(buff->getRemaining()==24);
|
||||
|
||||
buff->putLong(2345678123LL);
|
||||
assert(buff->getPosition()==16);
|
||||
assert(buff->getRemaining()==16);
|
||||
buff->putLong(2345678123LL);
|
||||
assert(buff->getPosition()==16);
|
||||
assert(buff->getRemaining()==16);
|
||||
|
||||
float testFloat = 34.67;
|
||||
buff->putFloat(testFloat);
|
||||
assert(buff->getPosition()==20);
|
||||
assert(buff->getRemaining()==12);
|
||||
float testFloat = 34.67;
|
||||
buff->putFloat(testFloat);
|
||||
assert(buff->getPosition()==20);
|
||||
assert(buff->getRemaining()==12);
|
||||
|
||||
double testDouble = -512.23974;
|
||||
buff->putDouble(testDouble);
|
||||
assert(buff->getPosition()==28);
|
||||
assert(buff->getRemaining()==4);
|
||||
double testDouble = -512.23974;
|
||||
buff->putDouble(testDouble);
|
||||
assert(buff->getPosition()==28);
|
||||
assert(buff->getRemaining()==4);
|
||||
|
||||
buff->flip();
|
||||
assert(buff->getLimit()==28);
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getRemaining()==28);
|
||||
buff->flip();
|
||||
assert(buff->getLimit()==28);
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getRemaining()==28);
|
||||
|
||||
assert(buff->getBoolean()==true);
|
||||
assert(buff->getPosition()==1);
|
||||
assert(buff->getBoolean()==true);
|
||||
assert(buff->getPosition()==1);
|
||||
|
||||
assert(buff->getByte()==-12);
|
||||
assert(buff->getPosition()==2);
|
||||
assert(buff->getByte()==-12);
|
||||
assert(buff->getPosition()==2);
|
||||
|
||||
assert(buff->getShort()==10516);
|
||||
assert(buff->getPosition()==4);
|
||||
assert(buff->getShort()==10516);
|
||||
assert(buff->getPosition()==4);
|
||||
|
||||
assert(buff->getInt()==0x1937628B);
|
||||
assert(buff->getPosition()==8);
|
||||
assert(buff->getInt()==0x1937628B);
|
||||
assert(buff->getPosition()==8);
|
||||
|
||||
assert(buff->getLong()==2345678123LL);
|
||||
assert(buff->getPosition()==16);
|
||||
assert(buff->getLong()==2345678123LL);
|
||||
assert(buff->getPosition()==16);
|
||||
|
||||
assert(buff->getFloat()==testFloat);
|
||||
assert(buff->getPosition()==20);
|
||||
assert(buff->getFloat()==testFloat);
|
||||
assert(buff->getPosition()==20);
|
||||
|
||||
assert(buff->getDouble()==testDouble);
|
||||
assert(buff->getPosition()==28);
|
||||
assert(buff->getDouble()==testDouble);
|
||||
assert(buff->getPosition()==28);
|
||||
|
||||
buff->clear();
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getLimit()==32);
|
||||
assert(buff->getRemaining()==32);
|
||||
buff->clear();
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getLimit()==32);
|
||||
assert(buff->getRemaining()==32);
|
||||
|
||||
delete buff;
|
||||
char src[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
'm' };
|
||||
char dst[] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||
' ' };
|
||||
|
||||
cout<<" PASSED\n";
|
||||
buff->put(src, 2, 6);
|
||||
assert(buff->getPosition()==6);
|
||||
assert(strncmp(buff->getArray(),&src[2],6)==0);
|
||||
|
||||
buff->flip();
|
||||
assert(buff->getLimit()==6);
|
||||
assert(buff->getPosition()==0);
|
||||
assert(buff->getRemaining()==6);
|
||||
|
||||
buff->get(dst, 2, 6);
|
||||
assert(buff->getLimit()==6);
|
||||
assert(buff->getPosition()==6);
|
||||
assert(strncmp(&src[2],&dst[2],6)==0);
|
||||
|
||||
cout<<" First 10 characters of destination: >>"<<String(dst, 10)<<"<<\n";
|
||||
|
||||
delete buff;
|
||||
|
||||
cout<<"!!! PASSED\n";
|
||||
}
|
||||
|
||||
void testInverseEndianness() {
|
||||
cout<<"Testing inverse endianness...\n";
|
||||
cout<<"Testing inverse endianness...\n";
|
||||
|
||||
#if EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG
|
||||
ByteBuffer* buff = new ByteBuffer(32,EPICS_ENDIAN_LITTLE);
|
||||
char refBuffer[] =
|
||||
{ (char)0x02, (char)0x01, (char)0x0D, (char)0x0C, (char)0x0B, (char)0x0A};
|
||||
ByteBuffer* buff = new ByteBuffer(32,EPICS_ENDIAN_LITTLE);
|
||||
char refBuffer[] =
|
||||
{ (char)0x02, (char)0x01, (char)0x0D, (char)0x0C, (char)0x0B, (char)0x0A};
|
||||
#else
|
||||
ByteBuffer* buff = new ByteBuffer(32, EPICS_ENDIAN_BIG);
|
||||
char refBuffer[] = { (char)0x01, (char)0x02, (char)0x0A, (char)0x0B,
|
||||
(char)0x0C, (char)0x0D };
|
||||
ByteBuffer* buff = new ByteBuffer(32, EPICS_ENDIAN_BIG);
|
||||
char refBuffer[] = { (char)0x01, (char)0x02, (char)0x0A, (char)0x0B,
|
||||
(char)0x0C, (char)0x0D };
|
||||
#endif
|
||||
|
||||
buff->putShort(0x0102);
|
||||
buff->putInt(0x0A0B0C0D);
|
||||
buff->putShort(0x0102);
|
||||
buff->putInt(0x0A0B0C0D);
|
||||
|
||||
assert(strncmp(buff->getArray(),refBuffer,6)==0);
|
||||
assert(strncmp(buff->getArray(),refBuffer,6)==0);
|
||||
|
||||
buff->flip();
|
||||
buff->flip();
|
||||
|
||||
assert(buff->getShort()==0x0102);
|
||||
assert(buff->getInt()==0x0A0B0C0D);
|
||||
assert(buff->getShort()==0x0102);
|
||||
assert(buff->getInt()==0x0A0B0C0D);
|
||||
|
||||
delete buff;
|
||||
cout<<" PASSED\n";
|
||||
delete buff;
|
||||
cout<<"!!! PASSED\n";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
testBasicOperations();
|
||||
testInverseEndianness();
|
||||
return (0);
|
||||
testBasicOperations();
|
||||
testInverseEndianness();
|
||||
return (0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user