228 lines
6.0 KiB
C++
228 lines
6.0 KiB
C++
//!;;Rpy::+
|
|
//!;;Rpy::ModelElement: idd_blob
|
|
//!;;Rpy::
|
|
//!;;Rpy::Component: IDDComponent
|
|
//!;;Rpy::Configuration: IDDConfig
|
|
//!;;Rpy::Project: IDD
|
|
//!;;Rpy::
|
|
//!;;Rpy::FilePath: idd_blob.h
|
|
//!;;Rpy::Tag: $Tag
|
|
//!;;Rpy::
|
|
//!;;Rpy::Copyright: Leonardocompany - COMPANY RESTRICTED
|
|
//!;;Rpy::
|
|
//!;;Rpy::Generated by Rhapsody: 7.5.3
|
|
//!;;Rpy::-
|
|
|
|
|
|
#ifndef idd_blob_H
|
|
#define idd_blob_H
|
|
|
|
//## dependency IddIFParameter
|
|
#include "IddIFParameter.h"
|
|
//## dependency stdint
|
|
#include <stdint.h>
|
|
namespace idd_blob
|
|
{
|
|
//## package idd_blob
|
|
|
|
|
|
//#[ type chunk_types
|
|
struct ChunkHeader
|
|
{
|
|
typedef unsigned int raw_field_t;
|
|
|
|
raw_field_t marker;
|
|
raw_field_t len;
|
|
raw_field_t update_cookie;
|
|
raw_field_t spare;
|
|
|
|
enum { k_record_marker=0xFFFFU, k_record_marker_shift=16U,k_record_id_mask=0x0FFFFU, k_record_size_mask=0x0FFFFU, k_record_size_round=0x3U};
|
|
|
|
unsigned int recordMarker() const { return marker>>k_record_marker_shift;}
|
|
unsigned int recordId() const { return marker & k_record_id_mask;}
|
|
unsigned int recordSize() const { return len & k_record_size_mask;}
|
|
|
|
bool isRecordMarkerValid() const { return recordMarker()==k_record_marker;}
|
|
bool isRecordSizeValid() const { return (recordSize() & (~k_record_size_round))==recordSize();}
|
|
|
|
unsigned int updateCounter() const { return update_cookie;}
|
|
|
|
void updated() { ++update_cookie;}
|
|
|
|
ChunkHeader()
|
|
{
|
|
initialize(0, 0);
|
|
}
|
|
|
|
ChunkHeader(unsigned int size, unsigned int id)
|
|
{
|
|
initialize(size, id);
|
|
}
|
|
void initialize(unsigned int size, unsigned int id)
|
|
{
|
|
marker=(static_cast<raw_field_t>(k_record_marker)<<static_cast<raw_field_t>(k_record_marker_shift))|id;
|
|
len=size;
|
|
update_cookie=0;
|
|
spare=0;
|
|
}
|
|
void setId(unsigned int id)
|
|
{
|
|
marker=(static_cast<raw_field_t>(k_record_marker)<<static_cast<raw_field_t>(k_record_marker_shift))|id;
|
|
}
|
|
void setSize(unsigned int size)
|
|
{
|
|
len=size;
|
|
}
|
|
};
|
|
|
|
template<typename T_> struct ChunkType
|
|
{
|
|
public:
|
|
typedef T_ value_t;
|
|
|
|
ChunkHeader _header;
|
|
value_t _data;
|
|
|
|
ChunkHeader& header() { return _header;}
|
|
|
|
const value_t& constData() const { return _data;}
|
|
value_t& data() { return _data;}
|
|
void setData(const value_t src) { _data=src;}
|
|
};
|
|
|
|
template<typename T_> struct ChunkWriter: public ChunkType<T_>
|
|
{
|
|
ChunkWriter()
|
|
{
|
|
ChunkType<T_>::header().initialize(sizeof(T_), 0);
|
|
}
|
|
void setId(unsigned int id)
|
|
{
|
|
ChunkType<T_>::header().initialize(sizeof(T_), id);
|
|
}
|
|
};
|
|
|
|
//Specialization
|
|
template<typename T_> struct GlobalChunkType: public ChunkType<T_>
|
|
{
|
|
public:
|
|
void** globalPointer;
|
|
|
|
GlobalChunkType(void** global_pointer) //:globalPointer(global_pointer) {}
|
|
{
|
|
globalPointer=global_pointer;
|
|
}
|
|
|
|
void setData(const T_ src)
|
|
{
|
|
ChunkType<T_>::setData(src);
|
|
void* tmp=const_cast<void*>(src);
|
|
*globalPointer=tmp;
|
|
}
|
|
};
|
|
|
|
typedef GlobalChunkType<void*> ChunkOpaqueReference;
|
|
typedef GlobalChunkType<const void*> ChunkOpaqueConstReference;
|
|
|
|
/*
|
|
template<typename T_> class IddIFParameter
|
|
{
|
|
public:
|
|
static T_* data;
|
|
};
|
|
*/
|
|
|
|
template<typename T_> T_* IddIFParameter<T_>::data;
|
|
|
|
template<typename T_> class ChunkOpaqueReaderReference: public ChunkOpaqueConstReference
|
|
{
|
|
public:
|
|
ChunkOpaqueReaderReference():
|
|
ChunkOpaqueConstReference(reinterpret_cast<void**>(&IddIFParameter<T_>::data))
|
|
{
|
|
_header.setSize(sizeof(T_));
|
|
_data=0;
|
|
}
|
|
const T_& constData() const { return *reinterpret_cast<const T_*>(_data);}
|
|
|
|
static T_* staticDataPointer() { return IddIFParameter<T_>::data;}
|
|
};
|
|
|
|
//#]
|
|
|
|
//#[ type chunk_codec
|
|
class InputBlobDecoderBase
|
|
{
|
|
public:
|
|
|
|
static void blobDecode(idd_blob::ChunkOpaqueConstReference* cr, unsigned int items, const void* src, unsigned int src_size)
|
|
{
|
|
unsigned int sindex=0;
|
|
const unsigned char* s=reinterpret_cast<const unsigned char*>(src);
|
|
for(unsigned int i=0; i<items; ++i)
|
|
{
|
|
if (sindex>src_size)
|
|
{
|
|
break; //TODO: too short, add log and fix-up
|
|
}
|
|
const idd_blob::ChunkHeader& h=*reinterpret_cast<const idd_blob::ChunkHeader*>(&s[sindex]);
|
|
if (h.isRecordMarkerValid())
|
|
{
|
|
if (h.recordId()==i)
|
|
{
|
|
idd_blob::ChunkOpaqueConstReference& c=cr[i];
|
|
if (c.header().recordSize()>=h.recordSize())
|
|
{
|
|
c.header()=h;
|
|
c.setData(reinterpret_cast<const void*>(&s[sindex+(sizeof h)]));//c.data()=reinterpret_cast<const void*>(&s[sindex+(sizeof h)]);
|
|
}
|
|
}
|
|
if (!h.isRecordSizeValid())
|
|
{
|
|
break;//TODO: add error log and fix-up
|
|
}
|
|
sindex+=(sizeof(h)+h.recordSize());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class InputBlobDecoder
|
|
{
|
|
public:
|
|
template<class T_> bool decode(T_& dst, const void* raw, unsigned int size)
|
|
{
|
|
idd_blob::ChunkOpaqueConstReference& dref=dst.structIdentifier;
|
|
unsigned int items=sizeof(dst)/sizeof(dref);//unsigned int items=sizeof(dst)/sizeof(dst.structIdentifier);
|
|
InputBlobDecoderBase::blobDecode(&dref, items, raw, size);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class OutputBlobEncoder
|
|
{
|
|
public:
|
|
template<class T_> bool prepareId(T_& dst)
|
|
{
|
|
unsigned char* s=reinterpret_cast<unsigned char*>(&dst);
|
|
|
|
unsigned int size=sizeof(dst);
|
|
unsigned int id=0;
|
|
for(unsigned int i=0; i<size; ++id)
|
|
{
|
|
idd_blob::ChunkHeader& dref=*reinterpret_cast<idd_blob::ChunkHeader*>(&s[i]);
|
|
dref.setId(id);
|
|
i+=(sizeof(dref)+dref.recordSize());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//#]
|
|
}
|
|
|
|
#endif
|
|
//;;Rpy:: end
|
|
|
|
|