From 5fef80994101046801500f3350f85ca368d50aa6 Mon Sep 17 00:00:00 2001 From: richiesams Date: Thu, 27 Jun 2013 15:17:57 -0500 Subject: ZVISION: Convert union of pointers to union of values except for String. Instead of storing everything on the heap, only store Strings on the heap. For Strings, store a char array pointer instead of an actual String object since String objects are fairly large. --- engines/zvision/object.cpp | 293 ++++++++++++++++++++------------------------- engines/zvision/object.h | 18 +-- 2 files changed, 137 insertions(+), 174 deletions(-) (limited to 'engines') diff --git a/engines/zvision/object.cpp b/engines/zvision/object.cpp index 322d7f2ea6..b272320988 100644 --- a/engines/zvision/object.cpp +++ b/engines/zvision/object.cpp @@ -27,74 +27,43 @@ namespace ZVision { -Object::Object(ObjectType type) { - _objectType = type; - - switch (type) { - case BOOL: - _value.boolVal = new bool; - break; - case BYTE: - _value.byteVal = new byte; - break; - case INT16: - _value.int16Val = new int16; - break; - case UINT16: - _value.uint16Val = new uint16; - break; - case INT32: - _value.int32Val = new int32; - break; - case UINT32: - _value.uint32Val = new uint32; - break; - case FLOAT: - _value.floatVal = new float; - break; - case DOUBLE: - _value.doubleVal = new double; - break; - case STRING: - _value.stringVal = new Common::String; - break; - } -} +Object::Object(ObjectType type) : _objectType(type) { } Object::Object(bool value) : _objectType(BOOL) { - _value.boolVal = new bool(value); + _value.boolVal = value; } Object::Object(byte value) : _objectType(BYTE) { - _value.byteVal = new byte(value); + _value.byteVal = value; } Object::Object(int16 value) : _objectType(INT16) { - _value.int16Val = new int16(value); + _value.int16Val = value; } Object::Object(uint16 value) : _objectType(UINT16) { - _value.uint16Val = new uint16(value); + _value.uint16Val = value; } Object::Object(int32 value) : _objectType(INT32) { - _value.int32Val = new int32(value); + _value.int32Val = value; } Object::Object(uint32 value) : _objectType(UINT32) { - _value.uint32Val = new uint32(value); + _value.uint32Val = value; } Object::Object(float value) : _objectType(FLOAT) { - _value.floatVal = new float(value); + _value.floatVal = value; } Object::Object(double value) : _objectType(DOUBLE) { - _value.doubleVal = new double(value); + _value.doubleVal = value; } Object::Object(Common::String value) : _objectType(BYTE) { - _value.stringVal = new Common::String(value); + _value.stringVal = new char[value.size() + 1]; + memcpy(_value.stringVal, value.c_str(), value.size() + 1); } Object::Object(const Object &other) { @@ -102,178 +71,167 @@ Object::Object(const Object &other) { switch (_objectType) { case BOOL: - _value.boolVal = new bool(*other._value.boolVal); + _value.boolVal = other._value.boolVal; break; case BYTE: - _value.byteVal = new byte(*other._value.byteVal); + _value.byteVal = other._value.byteVal; break; case INT16: - _value.int16Val = new int16(*other._value.int16Val); + _value.int16Val = other._value.int16Val; break; case UINT16: - _value.uint16Val = new uint16(*other._value.uint16Val); + _value.uint16Val = other._value.uint16Val; break; case INT32: - _value.int32Val = new int32(*other._value.int32Val); + _value.int32Val = other._value.int32Val; break; case UINT32: - _value.uint32Val = new uint32(*other._value.uint32Val); + _value.uint32Val = other._value.uint32Val; break; case FLOAT: - _value.floatVal = new float(*other._value.floatVal); + _value.floatVal = other._value.floatVal; break; case DOUBLE: - _value.doubleVal = new double(*other._value.doubleVal); + _value.doubleVal = other._value.doubleVal; break; case STRING: - _value.stringVal = new Common::String(*other._value.stringVal); + uint32 length = strlen(other._value.stringVal); + _value.stringVal = new char[length + 1]; + memcpy(_value.stringVal, other._value.stringVal, length + 1); break; } } Object::~Object() { - deleteValue(); + deleteCharPointer(); } -void Object::deleteValue() { - // Call delete on the correct part of the union. - // Even though they all point to the same memory and will all be cast - // to a void *, this can still cause undefined behavior. - switch (_objectType) { - case BOOL: - delete _value.boolVal; - break; - case BYTE: - delete _value.byteVal; - break; - case INT16: - delete _value.int16Val; - break; - case UINT16: - delete _value.uint16Val; - break; - case INT32: - delete _value.int32Val; - break; - case UINT32: - delete _value.uint32Val; - break; - case FLOAT: - delete _value.floatVal; - break; - case DOUBLE: - delete _value.doubleVal; - break; - case STRING: - delete _value.stringVal; - break; - } +void Object::deleteCharPointer() { + if (_objectType == STRING) + delete[] _value.stringVal; } Object &Object::operator=(const bool &rhs) { - if (_objectType == BOOL) - *_value.boolVal = rhs; - else { - deleteValue(); - _objectType = BOOL; - _value.boolVal = new bool(rhs); + if (_objectType == BOOL) { + _value.boolVal = rhs; + return *this; } + deleteCharPointer(); + _objectType = BOOL; + _value.boolVal = rhs; + return *this; } Object &Object::operator=(const byte &rhs) { - if (_objectType == BYTE) - *_value.byteVal = rhs; - else { - deleteValue(); - _objectType = BYTE; - _value.byteVal = new byte(rhs); + if (_objectType == BYTE) { + _value.byteVal = rhs; + return *this; } + deleteCharPointer(); + _objectType = BYTE; + _value.byteVal = rhs; + return *this; } Object &Object::operator=(const int16 &rhs) { - if (_objectType == INT16) - *_value.int16Val = rhs; - else { - deleteValue(); - _objectType = INT16; - _value.int16Val = new int16(rhs); + if (_objectType == INT16) { + _value.int16Val = rhs; + return *this; } + deleteCharPointer(); + _objectType = INT16; + _value.int16Val = rhs; + return *this; } Object &Object::operator=(const uint16 &rhs) { - if (_objectType == UINT16) - *_value.uint16Val = rhs; - else { - deleteValue(); - _objectType = UINT16; - _value.uint16Val = new uint16(rhs); + if (_objectType == UINT16) { + _value.uint16Val = rhs; + return *this; } + deleteCharPointer(); + _objectType = UINT16; + _value.uint16Val = rhs; + return *this; } Object &Object::operator=(const int32 &rhs) { - if (_objectType == INT32) - *_value.int32Val = rhs; - else { - deleteValue(); - _objectType = INT32; - _value.int32Val = new int32(rhs); + if (_objectType == INT32) { + _value.int32Val = rhs; + return *this; } + deleteCharPointer(); + _objectType = INT32; + _value.int32Val = rhs; + return *this; } Object &Object::operator=(const uint32 &rhs) { - if (_objectType == UINT32) - *_value.uint32Val = rhs; - else { - deleteValue(); - _objectType = UINT32; - _value.uint32Val = new uint32(rhs); + if (_objectType == UINT32) { + _value.uint32Val = rhs; + return *this; } + deleteCharPointer(); + _objectType = UINT32; + _value.uint32Val = rhs; + return *this; } Object &Object::operator=(const float &rhs) { - if (_objectType == FLOAT) - *_value.floatVal = rhs; - else { - deleteValue(); - _objectType = FLOAT; - _value.floatVal = new float(rhs); + if (_objectType == FLOAT) { + _value.floatVal = rhs; + return *this; } + deleteCharPointer(); + _objectType = FLOAT; + _value.floatVal = rhs; + return *this; } Object &Object::operator=(const double &rhs) { - if (_objectType == DOUBLE) - *_value.doubleVal = rhs; - else { - deleteValue(); - _objectType = DOUBLE; - _value.doubleVal = new double(rhs); + if (_objectType == DOUBLE) { + _value.doubleVal = rhs; + return *this; } + deleteCharPointer(); + _objectType = DOUBLE; + _value.doubleVal = rhs; + return *this; } Object &Object::operator=(const Common::String &rhs) { - if (_objectType == STRING) - *_value.stringVal = rhs; - else { - deleteValue(); + if (_objectType != STRING) { _objectType = STRING; - _value.stringVal = new Common::String(rhs); + _value.stringVal = new char[rhs.size() + 1]; + memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1); + + return *this; + } + + uint32 length = strlen(_value.stringVal); + if (length <= rhs.size() + 1) { + memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1); + } else { + delete[] _value.stringVal; + _value.stringVal = new char[rhs.size() + 1]; + memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1); } return *this; @@ -282,23 +240,28 @@ Object &Object::operator=(const Common::String &rhs) { Object &Object::operator=(const Object &rhs) { switch (_objectType) { case BOOL: - return operator=(*rhs._value.boolVal); + return operator=(rhs._value.boolVal); case BYTE: - return operator=(*rhs._value.byteVal); + return operator=(rhs._value.byteVal); case INT16: - return operator=(*rhs._value.int16Val); + return operator=(rhs._value.int16Val); case UINT16: - return operator=(*rhs._value.uint16Val); + return operator=(rhs._value.uint16Val); case INT32: - return operator=(*rhs._value.int32Val); + return operator=(rhs._value.int32Val); case UINT32: - return operator=(*rhs._value.uint32Val); + return operator=(rhs._value.uint32Val); case FLOAT: - return operator=(*rhs._value.floatVal); + return operator=(rhs._value.floatVal); case DOUBLE: - return operator=(*rhs._value.doubleVal); + return operator=(rhs._value.doubleVal); case STRING: - return operator=(*rhs._value.stringVal); + uint32 length = strlen(rhs._value.stringVal); + + _value.stringVal = new char[length + 1]; + memcpy(_value.stringVal, rhs._value.stringVal, length + 1); + + return *this; } return *this; @@ -307,75 +270,75 @@ Object &Object::operator=(const Object &rhs) { bool Object::getBoolValue(bool *returnValue) const { if (_objectType != BOOL) { - warning("'Object' not of type bool."); + warning("'Object' is not storing a bool."); return false; } - *returnValue = *_value.boolVal; + *returnValue = _value.boolVal; return true; } bool Object::getByteValue(byte *returnValue) const { if (_objectType != BYTE) - warning("'Object' not of type byte."); + warning("'Object' is not storing a byte."); - *returnValue = *_value.byteVal; + *returnValue = _value.byteVal; return true; } bool Object::getInt16Value(int16 *returnValue) const { if (_objectType != INT16) - warning("'Object' not of type int16."); + warning("'Object' is not storing an int16."); - *returnValue = *_value.int16Val; + *returnValue = _value.int16Val; return true; } bool Object::getUInt16Value(uint16 *returnValue) const { if (_objectType != UINT16) - warning("'Object' not of type uint16."); + warning("'Object' is not storing a uint16."); - *returnValue = *_value.uint16Val; + *returnValue = _value.uint16Val; return true; } bool Object::getInt32Value(int32 *returnValue) const { if (_objectType != INT32) - warning("'Object' not of type int32."); + warning("'Object' is not storing an int32."); - *returnValue = *_value.int32Val; + *returnValue = _value.int32Val; return true; } bool Object::getUInt32Value(uint32 *returnValue) const { if (_objectType != UINT32) - warning("'Object' not of type uint32."); + warning("'Object' is not storing a uint32."); - *returnValue = *_value.uint32Val; + *returnValue = _value.uint32Val; return true; } bool Object::getFloatValue(float *returnValue) const { if (_objectType != FLOAT) - warning("'Object' not of type float."); + warning("'Object' is not storing a float."); - *returnValue = *_value.floatVal; + *returnValue = _value.floatVal; return true; } bool Object::getDoubleValue(double *returnValue) const { if (_objectType != DOUBLE) - warning("'Object' not of type double."); + warning("'Object' is not storing a double."); - *returnValue = *_value.doubleVal; + *returnValue = _value.doubleVal; return true; } bool Object::getStringValue(Common::String *returnValue) const { if (_objectType != STRING) - warning("'Object' not of type Common::String."); + warning("'Object' is not storing a Common::String."); - *returnValue = *_value.stringVal; + *returnValue = _value.stringVal; return true; } diff --git a/engines/zvision/object.h b/engines/zvision/object.h index 6e4b98a814..dc5905b052 100644 --- a/engines/zvision/object.h +++ b/engines/zvision/object.h @@ -73,15 +73,15 @@ private: ObjectType _objectType; union { - bool *boolVal; - byte *byteVal; - int16 *int16Val; - uint16 *uint16Val; - int32 *int32Val; - uint32 *uint32Val; - float *floatVal; - double *doubleVal; - Common::String *stringVal; + bool boolVal; + byte byteVal; + int16 int16Val; + uint16 uint16Val; + int32 int32Val; + uint32 uint32Val; + float floatVal; + double doubleVal; + char *stringVal; } _value; public: -- cgit v1.2.3