197 lines
4.3 KiB
C++
197 lines
4.3 KiB
C++
/*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();
|
|
}
|
|
|
|
}}
|