blob: 7bb3294e29d16eb3fc2cb75c988fa4f50109e31f [file] [log] [blame]
// umlrtobjectclass.cc
/*******************************************************************************
* Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
#include "umlrtobjectclass.hh"
#include "basedebugtype.hh"
#include "basedebug.hh"
#include <stdlib.h>
// Type descriptor used for encoding/decoding data of a given type.
// A number of UMLRTType_xxx descriptors are pre-defined by the library.
// Default initializer - zeros the data and returns a pointer to next byte.
void * UMLRTObject_initialize( const UMLRTObject_class * desc, void * data )
{
uint8_t * s = (uint8_t *)data;
if (desc->fields == NULL)
{
memset(s, 0, desc->size);
s += desc->size;
}
else
{
for (size_t i = 0; i < desc->size; ++i)
{
desc->fields[i].desc->initialize(desc->fields[i].desc, s + desc->fields[i].offset);
}
}
return (void *)s;
}
// Default copy - copies the data and returns a pointer to the byte following the src data.
// The return value is the byte following the last byte copied to the destination.
void * UMLRTObject_copy( const UMLRTObject_class * desc, const void * src, void * dst )
{
uint8_t * s = (uint8_t *)src;
uint8_t * end_p = (uint8_t *)dst;
uint8_t * d = (uint8_t *)dst;
if (desc->fields == NULL)
{
memcpy(d, s, desc->size);
end_p += desc->size;
}
else
{
for (size_t i = 0; i < desc->size; ++i)
{
// overwrite end_p here - the return value for the last field is the one that is relevant.
end_p = (uint8_t *)desc->fields[i].desc->copy(desc->fields[i].desc, s + desc->fields[i].offset, d + desc->fields[i].offset);
}
}
return (void *)end_p;
}
// Default decode is a copy (returns a pointer to the byte after the src data).
// For now, we'll use the return value of the copy (a value relative to dst) to compute what the return value should be.
size_t UMLRTObject_getSize( const UMLRTObject_class * desc )
{
size_t size = desc->size;
if (desc->fields != NULL)
{
size = desc->fields[desc->size - 1].offset +
desc->fields[desc->size - 1].desc->getSize(desc->fields[desc->size - 1].desc);
}
return size;
}
void * UMLRTObject_decode( const UMLRTObject_class * desc, const void * src, void * dst )
{
desc->copy(desc, src, dst); // ignore return value.
return (void *)((uint8_t *)src + UMLRTObject_getSize(desc));
}
// Default encode is a copy (returns a pointer to the byte after the dst data).
void * UMLRTObject_encode( const UMLRTObject_class * desc, const void * src, void * dst )
{
return desc->copy(desc, src, dst);
}
// Default destroy does nothing (but returns a pointer to the byte after the data).
void * UMLRTObject_destroy( const UMLRTObject_class * desc, void * data )
{
uint8_t * s = (uint8_t *)data;
uint8_t * end_p = (uint8_t *)data;
if (desc->fields != NULL)
{
for (size_t i = 0; i < desc->size; ++i)
{
end_p = (uint8_t *)desc->fields[i].desc->destroy(desc->fields[i].desc, s + desc->fields[i].offset);
}
}
else
{
end_p += desc->size;
}
return (void *)end_p;
}
int UMLRTObject_fprintf( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
uint8_t * s = (uint8_t *)data;
if (desc->fields != NULL)
{
nchar += fprintf(ostream, "{%s:", desc->name);
for (size_t i = 0; i < desc->size; ++i)
{
nchar += fprintf(ostream, "{%s:", desc->fields[i].name);
nchar += UMLRTObject_fprintf(ostream, desc->fields[i].desc, s + desc->fields[i].offset);
nchar += fprintf(ostream, "}");
}
nchar += fprintf(ostream, "}");
}
else if (desc->fprintf != 0)
{
nchar += desc->fprintf(ostream, desc, data);
}
else
{
nchar += fprintf(ostream, "{%s: (unable to print)}", desc->name);
}
return nchar;
}
int UMLRTObject_fprintf_bool( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
bool b;
desc->copy(desc, data, &b);
nchar += fprintf(ostream, "{bool %s}", b ? "true" : "false");
return nchar;
}
int UMLRTObject_fprintf_char( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
char c;
desc->copy(desc, data, &c);
nchar += fprintf(ostream, "{char %c}", c);
return nchar;
}
int UMLRTObject_fprintf_double( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
double d;
desc->copy(desc, data, &d);
nchar += fprintf(ostream, "{double %f}", d);
return nchar;
}
int UMLRTObject_fprintf_float( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
float f;
desc->copy(desc, data, &f);
nchar += fprintf(ostream, "{float %f}", f);
return nchar;
}
int UMLRTObject_fprintf_int( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
int i;
desc->copy(desc, data, &i);
nchar += fprintf(ostream, "{int %d}", i);
return nchar;
}
int UMLRTObject_fprintf_long( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
long l;
desc->copy(desc, data, &l);
nchar += fprintf(ostream, "{long %ld}", l);
return nchar;
}
int UMLRTObject_fprintf_longlong( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
long long ll;
desc->copy(desc, data, &ll);
nchar += fprintf(ostream, "{longlong %lld}", ll);
return nchar;
}
int UMLRTObject_fprintf_ptr( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
void * p;
desc->copy(desc, data, &p);
// Pointer de-referencing tracked by Bug 97.
nchar += fprintf(ostream, "{ptr %p}", p);
return nchar;
}
int UMLRTObject_fprintf_short( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
short sh;
desc->copy(desc, data, &sh);
nchar += fprintf(ostream, "{short %d}", sh);
return nchar;
}
int UMLRTObject_fprintf_uchar( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
unsigned char c;
desc->copy(desc, data, &c);
nchar += fprintf(ostream, "{char %u}", c);
return nchar;
}
int UMLRTObject_fprintf_uint( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
unsigned int i;
desc->copy(desc, data, &i);
nchar += fprintf(ostream, "{uint %u}", i);
return nchar;
}
int UMLRTObject_fprintf_ulong( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
unsigned long l;
desc->copy(desc, data, &l);
nchar += fprintf(ostream, "{ulong %lu}", l);
return nchar;
}
int UMLRTObject_fprintf_ulonglong( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
unsigned long long ll;
desc->copy(desc, data, &ll);
nchar += fprintf(ostream, "{ulonglong %llu}", ll);
return nchar;
}
int UMLRTObject_fprintf_ushort( FILE *ostream, const UMLRTObject_class * desc, const void * data )
{
int nchar = 0;
unsigned short sh;
desc->copy(desc, data, &sh);
nchar += fprintf(ostream, "{ushort %u}", sh);
return nchar;
}
const UMLRTObject_class UMLRTType_bool_
= {
"bool",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_bool,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(bool),
NULL // fields
};
const UMLRTObject_class UMLRTType_char_
= {
"char",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_char,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(char),
NULL, // fields
};
const UMLRTObject_class UMLRTType_double_
= {
"double",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_double,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(double),
NULL, // fields
};
const UMLRTObject_class UMLRTType_float_
= {
"float",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_float,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(float),
NULL, // fields
};
const UMLRTObject_class UMLRTType_int_
= {
"int",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_int,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(int),
NULL, // fields
};
const UMLRTObject_class UMLRTType_long_
= {
"long",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_long,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(long),
NULL, // fields
};
const UMLRTObject_class UMLRTType_longlong_
= {
"longlong",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_longlong,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(long long),
NULL, // fields
};
const UMLRTObject_class UMLRTType_ptr_
= {
"ptr",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_ptr,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(void *),
NULL // fields
};
const UMLRTObject_class UMLRTType_short_
= {
"short",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_short,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(short),
NULL, // fields
};
const UMLRTObject_class UMLRTType_uchar_
= {
"uchar",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_uchar,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned char),
NULL, // fields
};
const UMLRTObject_class UMLRTType_uint_
= {
"uint",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_uint,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned int),
NULL, // fields
};
const UMLRTObject_class UMLRTType_ulong_
= {
"ulong",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_ulong,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned long),
NULL, // fields
};
const UMLRTObject_class UMLRTType_ulonglong_
= {
"ulonglong",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_ulonglong,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned long long),
NULL, // fields
};
const UMLRTObject_class UMLRTType_ushort_
= {
"ushort",
UMLRTObject_initialize,
UMLRTObject_copy,
UMLRTObject_decode,
UMLRTObject_encode,
UMLRTObject_destroy,
UMLRTObject_getSize,
UMLRTObject_fprintf_ushort,
NULL, // super
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned short),
NULL, // fields
};
const UMLRTObject_class * const UMLRTType_bool = &UMLRTType_bool_;
const UMLRTObject_class * const UMLRTType_char = &UMLRTType_char_;
const UMLRTObject_class * const UMLRTType_double = &UMLRTType_double_;
const UMLRTObject_class * const UMLRTType_float = &UMLRTType_float_;
const UMLRTObject_class * const UMLRTType_int = &UMLRTType_int_;
const UMLRTObject_class * const UMLRTType_long = &UMLRTType_long_;
const UMLRTObject_class * const UMLRTType_longlong = &UMLRTType_longlong_;
const UMLRTObject_class * const UMLRTType_ptr = &UMLRTType_ptr_;
const UMLRTObject_class * const UMLRTType_short = &UMLRTType_short_;
const UMLRTObject_class * const UMLRTType_uchar = &UMLRTType_uchar_;
const UMLRTObject_class * const UMLRTType_uint = &UMLRTType_uint_;
const UMLRTObject_class * const UMLRTType_ulong = &UMLRTType_ulong_;
const UMLRTObject_class * const UMLRTType_ulonglong = &UMLRTType_ulonglong_;
const UMLRTObject_class * const UMLRTType_ushort = &UMLRTType_ushort_;