Status changes

This commit is contained in:
Matej Sekoranja
2011-02-17 01:21:16 +01:00
parent bb6cf7c00b
commit b0c04eea53
13 changed files with 208 additions and 293 deletions

View File

@@ -41,7 +41,6 @@ LIBSRCS += timer.cpp
LIBSRCS += queueVoid.cpp
LIBSRCS += messageQueue.cpp
LIBSRCS += status.cpp
LIBSRCS += StatusCreateFactory.cpp
SRC_DIRS += $(PVDATA)/pv

View File

@@ -32,11 +32,11 @@ namespace epics { namespace pvData {
virtual bool operator!=(PVField &pv);
virtual void shareData( PVStructurePtrArray value,int capacity,int length);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher);
SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *buffer,
DeserializableControl *pflusher);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, int offset, int count);
SerializableControl *pflusher, int offset, int count) const;
private:
StructureArrayConstPtr structureArray;
StructureArrayData *structureArrayData;
@@ -213,7 +213,7 @@ namespace epics { namespace pvData {
}
void BasePVStructureArray::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) {
SerializableControl *pflusher) const {
serialize(pbuffer, pflusher, 0, getLength());
}
@@ -247,7 +247,7 @@ namespace epics { namespace pvData {
}
void BasePVStructureArray::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, int offset, int count) {
SerializableControl *pflusher, int offset, int count) const {
// cache
int length = getLength();

View File

@@ -32,9 +32,9 @@ namespace epics { namespace pvData {
delete pImpl;
}
int PVArray::getLength() {return pImpl->length;}
int PVArray::getLength() const {return pImpl->length;}
int PVArray::getCapacity() {return pImpl->capacity;}
int PVArray::getCapacity() const {return pImpl->capacity;}
static String fieldImmutable("field is immutable");

View File

@@ -40,7 +40,7 @@ public:
virtual T get();
virtual void put(T val);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher);
SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *pbuffer,
DeserializableControl *pflusher);
virtual bool operator==(PVField& pv) ;
@@ -66,7 +66,7 @@ void BasePVScalar<T>::put(T val){value = val;}
template<typename T>
void BasePVScalar<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) {
SerializableControl *pflusher) const {
pflusher->ensureBuffer(1);
pbuffer->put<T>(value);
}
@@ -100,7 +100,7 @@ BasePVScalar<String>::BasePVScalar(PVStructure *parent,ScalarConstPtr scalar)
template<>
void BasePVScalar<String>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) {
SerializableControl *pflusher) const {
SerializeHelper::serializeString(value, pbuffer, pflusher);
}
@@ -137,10 +137,10 @@ public:
int fromOffset);
virtual void shareData(pointer value,int capacity,int length);
// from Serializable
virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) ;
virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, int offset, int count) ;
SerializableControl *pflusher, int offset, int count) const;
virtual bool operator==(PVField& pv) ;
virtual bool operator!=(PVField& pv) ;
private:
@@ -231,7 +231,7 @@ void DefaultPVArray<T>::shareData(pointer shareValue,int capacity,int length)
template<typename T>
void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) {
SerializableControl *pflusher) const {
serialize(pbuffer, pflusher, 0, this->getLength());
}
@@ -262,7 +262,7 @@ void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
template<typename T>
void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, int offset, int count) {
SerializableControl *pflusher, int offset, int count) const {
// cache
int length = this->getLength();
@@ -324,7 +324,7 @@ void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
template<>
void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, int offset, int count) {
SerializableControl *pflusher, int offset, int count) const {
int length = getLength();
// check bounds

View File

@@ -432,7 +432,7 @@ namespace epics { namespace pvData {
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) {
SerializableControl *pflusher) const {
for(int i = 0; i<pImpl->numberFields; i++)
pImpl->pvFields[i]->serialize(pbuffer, pflusher);
}
@@ -445,9 +445,9 @@ namespace epics { namespace pvData {
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, BitSet *pbitSet) {
int offset = getFieldOffset();
int numberFields = getNumberFields();
SerializableControl *pflusher, BitSet *pbitSet) const {
int offset = const_cast<PVStructure*>(this)->getFieldOffset();
int numberFields = const_cast<PVStructure*>(this)->getNumberFields();
int next = pbitSet->nextSetBit(offset);
// no more changes or no changes in this structure

View File

@@ -1,196 +0,0 @@
/*StatusCreateFactory.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include "lock.h"
#include "factory.h"
#include "byteBuffer.h"
#include "CDRMonitor.h"
#include "status.h"
#include "serializeHelper.h"
#include <epicsThread.h>
namespace epics { namespace pvData {
// TODO disabled due to problem with static initialization (order)
//PVDATA_REFCOUNT_MONITOR_DEFINE(status);
class StatusImpl : public Status
{
public:
StatusImpl(StatusType type, String message) :
m_type(type), m_message(message)
{
// PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
StatusImpl(StatusType type, String message, String stackDump) :
m_type(type), m_message(message), m_stackDump(stackDump)
{
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
virtual ~StatusImpl() {
//PVDATA_REFCOUNT_MONITOR_DESTRUCT(status);
}
virtual StatusType getType()
{
return m_type;
}
virtual epics::pvData::String getMessage()
{
return m_message;
}
virtual epics::pvData::String getStackDump()
{
return m_stackDump;
}
virtual bool isOK()
{
return (m_type == STATUSTYPE_OK);
}
virtual bool isSuccess()
{
return (m_type == STATUSTYPE_OK || m_type == STATUSTYPE_WARNING);
}
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher)
{
flusher->ensureBuffer(1);
if (this == getStatusCreate()->getStatusOK())
{
// special code for okStatus (optimization)
buffer->putByte((int8)-1);
}
else
{
buffer->putByte((int8)m_type);
SerializeHelper::serializeString(m_message, buffer, flusher);
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
}
}
virtual void deserialize(ByteBuffer *pbuffer, DeserializableControl *pflusher)
{
throw new std::runtime_error("use getStatusCreate()->deserialize()");
}
virtual String toString()
{
String str;
toString(&str, 0);
return str;
}
virtual void toString(StringBuilder buffer, int indentLevel)
{
*buffer += "StatusImpl [type=";
*buffer += StatusTypeName[m_type];
if (!m_message.empty())
{
*buffer += ", message=";
*buffer += m_message;
}
if (!m_stackDump.empty())
{
*buffer += ", stackDump=";
*buffer += '\n';
*buffer += m_stackDump;
}
*buffer += ']';
}
private:
StatusType m_type;
String m_message;
String m_stackDump;
};
static epicsThreadOnceId statusFactoryInit = EPICS_THREAD_ONCE_INIT;
class StatusCreateImpl : public StatusCreate {
public:
StatusCreateImpl()
{
m_ok = createStatus(STATUSTYPE_OK, "OK", 0);
}
~StatusCreateImpl()
{
delete m_ok;
}
virtual Status* getStatusOK() {
return m_ok;
}
virtual Status* createStatus(StatusType type, String message, BaseException* cause) {
if (cause == 0)
return new StatusImpl(type, message);
else
{
return new StatusImpl(type, message, cause->what());
}
}
virtual Status* deserializeStatus(ByteBuffer* buffer, DeserializableControl* control) {
control->ensureData(1);
int8 typeCode = buffer->getByte();
if (typeCode == (int8)-1)
return m_ok;
else {
String message = SerializeHelper::deserializeString(buffer, control);
String stackDump = SerializeHelper::deserializeString(buffer, control);
return new StatusImpl((StatusType)typeCode, message, stackDump);
}
}
static StatusCreateImpl* getInstance()
{
epicsThreadOnce(&statusFactoryInit, &StatusCreateImpl::init, 0);
assert(singleton);
return singleton;
}
private:
Status* m_ok;
static StatusCreateImpl *singleton;
static void init(void*) {
singleton = new StatusCreateImpl();
}
};
StatusCreateImpl* StatusCreateImpl::singleton = 0;
StatusCreate* getStatusCreate() {
return StatusCreateImpl::getInstance();
}
}}

View File

@@ -341,7 +341,7 @@ namespace epics { namespace pvData {
*buffer += '}';
}
void BitSet::serialize(ByteBuffer* buffer, SerializableControl* flusher) {
void BitSet::serialize(ByteBuffer* buffer, SerializableControl* flusher) const {
uint32 n = wordsInUse;
if (n == 0) {

View File

@@ -217,7 +217,7 @@ namespace epics { namespace pvData {
void toString(StringBuilder buffer, int indentLevel = 0) const;
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher);
SerializableControl *flusher) const;
virtual void deserialize(ByteBuffer *buffer,
DeserializableControl *flusher);

View File

@@ -30,7 +30,7 @@ namespace epics { namespace pvData {
class Serializable {
public:
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher) = 0;
SerializableControl *flusher) const = 0;
virtual void deserialize(ByteBuffer *buffer,
DeserializableControl *flusher) = 0;
};
@@ -38,7 +38,7 @@ namespace epics { namespace pvData {
class BitSetSerializable {
public:
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher,BitSet *bitSet) = 0;
SerializableControl *flusher,BitSet *bitSet) const = 0;
virtual void deserialize(ByteBuffer *buffer,
DeserializableControl *flusher,BitSet *bitSet) = 0;
};
@@ -47,7 +47,7 @@ namespace epics { namespace pvData {
class SerializableArray : virtual public Serializable {
public:
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher, int offset, int count) = 0;
SerializableControl *flusher, int offset, int count) const = 0;
};
}}

View File

@@ -4,10 +4,132 @@
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <pvData.h>
#include "status.h"
#include "epicsException.h"
#include "serializeHelper.h"
namespace epics { namespace pvData {
const char* StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
const char* Status::StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
epics::pvData::String Status::m_emptyString;
Status Status::OK;
//PVDATA_REFCOUNT_MONITOR_DEFINE(status);
Status::Status() :
m_type(STATUSTYPE_OK), m_message(m_emptyString), m_stackDump(m_emptyString)
{
}
Status::Status(StatusType type, String message) :
m_type(type), m_message(message), m_stackDump(m_emptyString)
{
if (type == STATUSTYPE_OK)
throw std::invalid_argument("type == STATUSTYPE_OK");
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
Status::Status(StatusType type, String message, String stackDump) :
m_type(type), m_message(message), m_stackDump(stackDump)
{
if (type == STATUSTYPE_OK)
throw std::invalid_argument("type == STATUSTYPE_OK");
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
Status::~Status() {
//PVDATA_REFCOUNT_MONITOR_DESTRUCT(status);
}
Status::StatusType Status::getType() const
{
return m_type;
}
epics::pvData::String Status::getMessage() const
{
return m_message;
}
epics::pvData::String Status::getStackDump() const
{
return m_stackDump;
}
bool Status::isOK() const
{
return (m_type == STATUSTYPE_OK);
}
bool Status::isSuccess() const
{
return (m_type == STATUSTYPE_OK || m_type == STATUSTYPE_WARNING);
}
void Status::serialize(ByteBuffer *buffer, SerializableControl *flusher) const
{
flusher->ensureBuffer(1);
if (m_type == STATUSTYPE_OK)
{
// special code for okStatus (optimization)
buffer->putByte((int8)-1);
}
else
{
buffer->putByte((int8)m_type);
SerializeHelper::serializeString(m_message, buffer, flusher);
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
}
}
void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
{
flusher->ensureData(1);
int8 typeCode = buffer->getByte();
if (typeCode == (int8)-1)
{
// in most of the cases status will be OK, we statistically optimize
if (m_type != STATUSTYPE_OK)
{
m_type = STATUSTYPE_OK;
m_message = m_stackDump = m_emptyString;
}
}
else
{
m_type = (StatusType)typeCode;
m_message = SerializeHelper::deserializeString(buffer, flusher);
m_stackDump = SerializeHelper::deserializeString(buffer, flusher);
}
}
String Status::toString() const
{
String str;
toString(&str, 0);
return str;
}
void Status::toString(StringBuilder buffer, int indentLevel) const
{
*buffer += "Status [type=";
*buffer += StatusTypeName[m_type];
if (!m_message.empty())
{
*buffer += ", message=";
*buffer += m_message;
}
if (!m_stackDump.empty())
{
*buffer += ", stackDump=";
*buffer += '\n';
*buffer += m_stackDump;
}
*buffer += ']';
}
}}

View File

@@ -8,53 +8,69 @@
#define STATUS_H
#include "serialize.h"
#include "epicsException.h"
#include "byteBuffer.h"
#include "noDefaultMethods.h"
namespace epics { namespace pvData {
/**
* Status type enum.
*/
enum StatusType {
/** Operation completed successfully. */
STATUSTYPE_OK,
/** Operation completed successfully, but there is a warning message. */
STATUSTYPE_WARNING,
/** Operation failed due to an error. */
STATUSTYPE_ERROR,
/** Operation failed due to an unexpected error. */
STATUSTYPE_FATAL
};
extern const char* StatusTypeName[];
/**
* Status interface.
* Status.
* @author mse
*/
class Status : public epics::pvData::Serializable {
public:
virtual ~Status() {};
/**
* Status type enum.
*/
enum StatusType {
/** Operation completed successfully. */
STATUSTYPE_OK,
/** Operation completed successfully, but there is a warning message. */
STATUSTYPE_WARNING,
/** Operation failed due to an error. */
STATUSTYPE_ERROR,
/** Operation failed due to an unexpected error. */
STATUSTYPE_FATAL
};
static const char* StatusTypeName[];
static Status OK;
/**
* Creates OK status; STATUSTYPE_OK, empty message and stackDump.
*/
Status();
/**
* Create non-OK status.
*/
Status(StatusType type, epics::pvData::String message);
/**
* Create non-OK status.
*/
Status(StatusType type, epics::pvData::String message, epics::pvData::String stackDump);
~Status();
/**
* Get status type.
* @return status type, non-<code>null</code>.
*/
virtual StatusType getType() = 0;
StatusType getType() const;
/**
* Get error message describing an error. Required if error status.
* @return error message.
*/
virtual epics::pvData::String getMessage() = 0;
epics::pvData::String getMessage() const;
/**
* Get stack dump where error (exception) happened. Optional.
* @return stack dump.
*/
virtual epics::pvData::String getStackDump() = 0;
epics::pvData::String getStackDump() const;
/**
* Convenient OK test. Same as <code>(getType() == StatusType.OK)</code>.
@@ -63,54 +79,28 @@ namespace epics { namespace pvData {
* @return OK status.
* @see #isSuccess()
*/
virtual bool isOK() = 0;
bool isOK() const;
/**
* Check if operation succeeded.
* @return operation success status.
*/
virtual bool isSuccess() = 0;
bool isSuccess() const;
virtual String toString() = 0;
virtual void toString(StringBuilder buffer, int indentLevel = 0) = 0;
String toString() const;
void toString(StringBuilder buffer, int indentLevel = 0) const;
void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
private:
static epics::pvData::String m_emptyString;
StatusType m_type;
String m_message;
String m_stackDump;
};
/**
* Interface for creating status.
* @author mse
*/
class StatusCreate : private epics::pvData::NoDefaultMethods {
public:
/**
* Get OK status. Static instance should be returned.
* @return OK <code>Status</code> instance.
*/
virtual Status* getStatusOK() = 0;
/**
* Create status.
* @param type status type, non-<code>null</code>.
* @param message message describing an error, non-<code>null</code>.
* NOTE: Do NOT use <code>throwable.getMessage()</code> as message, since it will be supplied with the <code>cause</code>.
* @param cause exception that caused an error. Optional.
* @return status instance.
*/
virtual Status* createStatus(StatusType type, String message, BaseException* cause = 0) = 0;
/**
* Deserialize status.
* NOTE: use this method instead of <code>Status.deserialize()</code>, since this allows OK status optimization.
* @param buffer deserialization buffer.
* @param control deserialization control.
* @return status instance.
*/
virtual Status* deserializeStatus(ByteBuffer* buffer, DeserializableControl* control) = 0;
};
extern StatusCreate* getStatusCreate();
}}
#endif /* STATUS_H */

View File

@@ -46,12 +46,12 @@ namespace epics { namespace pvData {
* Start monitoring.
* @return completion status.
*/
virtual Status* start() = 0;
virtual Status start() = 0;
/**
* Stop Monitoring.
* @return completion status.
*/
virtual Status* stop() = 0;
virtual Status stop() = 0;
/**
* If monitor has occurred return data.
* @return monitorElement for modified data on null if no monitors have occurred.
@@ -77,7 +77,7 @@ namespace epics { namespace pvData {
* @param monitor The monitor
* @param structure The structure defining the data.
*/
virtual void monitorConnect(Status* status, Monitor* monitor, Structure* structure) = 0;
virtual void monitorConnect(const Status &status, Monitor* monitor, Structure* structure) = 0;
/**
* A monitor event has occurred. The requester must call Monitor.poll to get data.
* @param monitor The monitor.

View File

@@ -126,10 +126,10 @@ typedef PVScalarValue<String> PVString;
class PVArray : public PVField, public SerializableArray {
public:
virtual ~PVArray();
int getLength() ;
int getLength() const;
void setLength(int length);
int getCapacity() ;
bool isCapacityMutable() ;
int getCapacity() const;
bool isCapacityMutable();
void setCapacityMutable(bool isMutable);
virtual void setCapacity(int capacity) = 0;
@@ -212,11 +212,11 @@ public:
virtual bool operator==(PVField &pv) ;
virtual bool operator!=(PVField &pv) ;
virtual void serialize(
ByteBuffer *pbuffer,SerializableControl *pflusher) ;
ByteBuffer *pbuffer,SerializableControl *pflusher) const;
virtual void deserialize(
ByteBuffer *pbuffer,DeserializableControl *pflusher);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher,BitSet *pbitSet) ;
SerializableControl *pflusher,BitSet *pbitSet) const;
virtual void deserialize(ByteBuffer *pbuffer,
DeserializableControl*pflusher,BitSet *pbitSet);
protected: