bounded string

This commit is contained in:
Matej Sekoranja
2014-08-19 20:42:15 +02:00
parent baf8832fc9
commit 37f6dff065
7 changed files with 185 additions and 4 deletions
+7
View File
@@ -134,6 +134,13 @@ bool operator==(const UnionArray& a, const UnionArray& b)
return *(a.getUnion().get())==*(b.getUnion().get());
}
bool operator==(const BoundedString& a, const BoundedString& b)
{
if(&a==&b)
return true;
return a.getMaximumLength()==b.getMaximumLength();
}
// PVXXX object comparison
namespace {
+65 -1
View File
@@ -111,6 +111,38 @@ void Scalar::deserialize(ByteBuffer* /*buffer*/, DeserializableControl* /*contro
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
std::string BoundedString::getID() const
{
std::ostringstream id;
id << Scalar::getID() << '(' << maxLength << ')';
return id.str();
}
void BoundedString::serialize(ByteBuffer *buffer, SerializableControl *control) const
{
control->ensureBuffer(1);
buffer->putByte(0x83);
SerializeHelper::writeSize(maxLength, buffer, control);
}
std::size_t BoundedString::getMaximumLength() const
{
return maxLength;
}
BoundedString::BoundedString(std::size_t maxStringLength) :
Scalar(pvString), maxLength(maxStringLength)
{
if (maxLength == 0)
throw std::invalid_argument("maxLength == 0");
}
BoundedString::~BoundedString() {}
static string emptyStringtring;
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
@@ -684,6 +716,12 @@ FieldBuilderPtr FieldBuilder::add(string const & name, ScalarType scalarType)
return shared_from_this();
}
FieldBuilderPtr FieldBuilder::addBoundedString(std::string const & name, std::size_t maxLength)
{
fields.push_back(fieldCreate->createBoundedString(maxLength)); fieldNames.push_back(name);
return shared_from_this();
}
FieldBuilderPtr FieldBuilder::add(string const & name, FieldConstPtr const & field)
{
fields.push_back(field); fieldNames.push_back(name);
@@ -719,6 +757,10 @@ FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const
fields.push_back(fieldCreate->createUnionArray(static_pointer_cast<const Union>(element)));
break;
case scalar:
if (std::tr1::dynamic_pointer_cast<const BoundedString>(element).get())
throw std::invalid_argument("bounded string arrays are not supported");
fields.push_back(fieldCreate->createScalarArray(static_pointer_cast<const Scalar>(element)->getScalarType()));
break;
// scalarArray?
@@ -828,7 +870,15 @@ ScalarConstPtr FieldCreate::createScalar(ScalarType scalarType) const
return scalars[scalarType];
}
BoundedStringConstPtr FieldCreate::createBoundedString(std::size_t maxLength) const
{
// TODO use std::make_shared
std::tr1::shared_ptr<BoundedString> s(new BoundedString(maxLength), Field::Deleter());
BoundedStringConstPtr sa = s;
return sa;
}
ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
{
if(elementType<0 || elementType>MAX_SCALAR_TYPE)
@@ -1047,6 +1097,20 @@ FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl
// Type type = Type.union; variant union (aka any type)
return variantUnion;
}
else if (typeCode == 0x83)
{
// TODO cache?
// bounded string
size_t size = SerializeHelper::readSize(buffer, control);
// TODO use std::make_shared
std::tr1::shared_ptr<Field> sp(
new BoundedString(size),
Field::Deleter());
FieldConstPtr p = sp;
return p;
}
else
throw std::invalid_argument("invalid type encoding");
}
+11 -1
View File
@@ -145,11 +145,18 @@ public:
SerializableControl *pflusher, size_t offset, size_t count) const;
private:
string value;
std::size_t maxLength;
};
BasePVString::BasePVString(ScalarConstPtr const & scalar)
: PVString(scalar),value()
{}
{
BoundedStringConstPtr boundedString = std::tr1::dynamic_pointer_cast<const BoundedString>(scalar);
if (boundedString.get())
maxLength = boundedString->getMaximumLength();
else
maxLength = 0;
}
BasePVString::~BasePVString() {}
@@ -157,6 +164,9 @@ string BasePVString::get() const { return value;}
void BasePVString::put(string val)
{
if (maxLength > 0 && val.length() > maxLength)
throw std::overflow_error("string too long");
value = val;
postPut();
}
+3
View File
@@ -35,6 +35,7 @@ bool epicsShareExtern operator==(const Structure&, const Structure&);
bool epicsShareExtern operator==(const StructureArray&, const StructureArray&);
bool epicsShareExtern operator==(const Union&, const Union&);
bool epicsShareExtern operator==(const UnionArray&, const UnionArray&);
bool epicsShareExtern operator==(const BoundedString&, const BoundedString&);
static inline bool operator!=(const Field& a, const Field& b)
{return !(a==b);}
@@ -50,6 +51,8 @@ static inline bool operator!=(const Union& a, const Union& b)
{return !(a==b);}
static inline bool operator!=(const UnionArray& a, const UnionArray& b)
{return !(a==b);}
static inline bool operator!=(const BoundedString& a, const BoundedString& b)
{return !(a==b);}
/**
+48
View File
@@ -93,6 +93,8 @@ class StructureArray;
class Union;
class UnionArray;
class BoundedString;
/**
* typedef for a shared pointer to an immutable Field.
*/
@@ -129,6 +131,10 @@ typedef std::tr1::shared_ptr<const Union> UnionConstPtr;
* typedef for a shared pointer to an immutable UnionArray.
*/
typedef std::tr1::shared_ptr<const UnionArray> UnionArrayConstPtr;
/**
* typedef for a shared pointer to an immutable BoundedString.
*/
typedef std::tr1::shared_ptr<const BoundedString> BoundedStringConstPtr;
/**
* Definition of support field types.
@@ -366,6 +372,33 @@ private:
friend class ScalarArray;
friend class BoundedScalarArray;
friend class FixedScalarArray;
friend class BoundedString;
};
/**
* This class implements introspection object for BoundedString.
*/
class epicsShareClass BoundedString : public Scalar{
public:
POINTER_DEFINITIONS(BoundedString);
/**
* Destructor.
*/
virtual ~BoundedString();
typedef BoundedString& reference;
typedef const BoundedString& const_reference;
virtual std::string getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
std::size_t getMaximumLength() const;
protected:
BoundedString(std::size_t maxStringLength);
private:
std::size_t maxLength;
friend class FieldCreate;
};
/**
@@ -812,6 +845,14 @@ public:
*/
FieldBuilderPtr add(std::string const & name, ScalarType scalarType);
/**
* Add a {@code BoundedString}.
* @param name name of the array.
* @param maxLength a string maximum length.
* @return this instance of a {@code FieldBuilder}.
*/
FieldBuilderPtr addBoundedString(std::string const & name, std::size_t maxLength);
/**
* Add a {@code Field} (e.g. {@code Structure}, {@code Union}).
* @param name name of the array.
@@ -961,6 +1002,13 @@ public:
* @throws An {@code IllegalArgumentException} if an illegal type is specified.
*/
ScalarConstPtr createScalar(ScalarType scalarType) const;
/**
* Create a {@code BoundedString}.
* @param maxLength a string maximum length.
* @return a {@code BoundedString} interface for the newly created object.
* @throws An {@code IllegalArgumentException} if maxLength == 0.
*/
BoundedStringConstPtr createBoundedString(std::size_t maxLength) const;
/**
* Create an {@code Array} field, variable size array.
* @param elementType The {@code scalarType} for array elements
+34 -1
View File
@@ -720,6 +720,38 @@ void testArraySizeType() {
serializationTest(pvs);
}
void testBoundedString() {
testDiag("Testing bounded string...");
FieldCreatePtr fieldCreate = getFieldCreate();
StructureConstPtr s = fieldCreate->createFieldBuilder()->
add("str", pvString)->
addBoundedString("boundedStr", 8)->
add("scalar", pvDouble)->
createStructure();
testOk1(s.get() != 0);
testOk1(Structure::DEFAULT_ID == s->getID());
testOk1(3 == s->getFields().size());
serializationFieldTest(s);
PVStructurePtr pvs = getPVDataCreate()->createPVStructure(s);
serializationTest(pvs);
PVStringPtr pvStr = pvs->getSubField<PVString>("boundedStr");
pvStr->put("");
pvStr->put("small");
pvStr->put("exact123");
try {
pvStr->put("tooLargeString");
testFail("too large string accepted");
} catch (std::overflow_error oe) {
// OK
}
}
void testStringCopy() {
string s1 = "abc";
string s2 = s1;
@@ -731,7 +763,7 @@ void testStringCopy() {
MAIN(testSerialization) {
testPlan(221);
testPlan(226);
flusher = new SerializableControlImpl();
control = new DeserializableControlImpl();
@@ -751,6 +783,7 @@ MAIN(testSerialization) {
testUnion();
testArraySizeType();
testBoundedString();
delete buffer;
+17 -1
View File
@@ -225,6 +225,21 @@ static void testUnion()
}
static void testBoundedString()
{
testDiag("testBoundedString");
BoundedStringConstPtr bs = fieldCreate->createBoundedString(8);
Type type = bs->getType();
testOk1(type==scalar);
ScalarType scalarType = bs->getScalarType();
testOk1(scalarType==pvString);
testOk1(bs->getMaximumLength()==8);
}
#define testExcept(EXCEPT, CMD) try{ CMD; testFail( "No exception from: " #CMD); } \
catch(EXCEPT& e) {testPass("Got expected exception from: " #CMD);} \
@@ -296,7 +311,7 @@ static void testMapping()
MAIN(testIntrospect)
{
testPlan(324);
testPlan(327);
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
@@ -304,6 +319,7 @@ MAIN(testIntrospect)
testScalarArray();
testStructure();
testUnion();
testBoundedString();
testError();
testMapping();
return testDone();