| // 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_; |
| |