Files
pvData/pvDataApp/misc/StatusCreateFactory.cpp
Michael Davidsaver a67a9a5eaa Merge
update test baselines
  rename showConstructDestruct.h to CDRMonitor.h
  undercounting field
  switch tests to CDRMonitor
  switch remaining to use REFCOUNT macros
  Use epicsThreadOnce for safe lazy initialization
  replace ShowConstructDestruct with simpler CDRMonitor
  executor: remove redundant allocations
  lock: Partial implementation of Boost lock templates

Conflicts:
	pvDataApp/misc/StatusCreateFactory.cpp
	pvDataApp/misc/bitSet.cpp
2011-02-02 11:16:03 -05:00

196 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 {
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();
}
}}