//===========================================================================// // File: MArray.hpp // // Project: MUNGA Brick: // // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 08/17/97 ECH Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #pragma once #include "Stuff.hpp" namespace Stuff { class MemoryStream; //########################################################################## //######################### ReadOnlyArrayOf ########################### //########################################################################## template class ReadOnlyArrayOf #if defined(_ARMOR) : public Stuff::Signature #endif { public: ReadOnlyArrayOf() {Check_Pointer(this); m_data = NULL; m_length = 0;} void TestInstance() const {} const T& operator[](size_t i) const { Check_Object(this); Check_Pointer(m_data); Verify(i < m_length); return m_data[i]; } void AssignData(const T *data, size_t length) {Check_Object(this); m_data = data; m_length = length;} size_t GetLength() const {return m_length;} size_t GetSize() const {return m_length * sizeof(T);} const T* GetData() const {return m_data;} friend MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const ReadOnlyArrayOf *array ); friend MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, ReadOnlyArrayOf *array ); protected: const T *m_data; size_t m_length; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const ReadOnlyArrayOf *array ) { Check_Object(stream); Check_Pointer(array); MemoryStreamIO::Write(stream, &array->m_length); if (array->m_length > 0) stream->WriteBytes(array->m_data, array->m_length * sizeof(T)); return *stream; } template MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, ReadOnlyArrayOf *array ) { Check_Object(stream); Check_Pointer(array); MemoryStreamIO::Read(stream, &array->m_length); if (array->m_length > 0) { array->m_data = Cast_Pointer(const T*,stream->GetPointer()); stream->AdvancePointer(array->m_length * sizeof(T)); } else array->m_data = NULL; return *stream; } //########################################################################## //######################### DynamicArrayOf ########################### //########################################################################## template class DynamicArrayOf: public ReadOnlyArrayOf { public: DynamicArrayOf() {} DynamicArrayOf(const DynamicArrayOf& array) {Check_Pointer(this); Check_Object(&array); CopyArray(array);} DynamicArrayOf(size_t length); DynamicArrayOf(const T &value, size_t length) {Check_Pointer(this); AssignValue(value, length);} DynamicArrayOf(const T *data, size_t length) {Check_Pointer(this); AssignData(data, length);} ~DynamicArrayOf() { if (m_data) { Check_Pointer(m_data); delete[] const_cast(m_data); } } void TestInstance() const {} DynamicArrayOf& operator=(const DynamicArrayOf& array) { if (this != &array) CopyArray(array); return *this; } T& operator[](size_t i) {Check_Pointer(m_data); Verify(i < m_length); return const_cast(m_data[i]);} const T& operator[](size_t i) const {Check_Pointer(m_data); Verify(i < m_length); return m_data[i];} void AssignValue(const T &value, size_t length); void AssignData(const T *data, size_t length); void SetLength(size_t length); T* GetData() {return const_cast(m_data);} const T* GetData() const {return m_data;} friend MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const DynamicArrayOf *array ); friend MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, DynamicArrayOf *array ); private: void SetStorageLength(size_t length); void CopyArray(const DynamicArrayOf&); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template DynamicArrayOf::DynamicArrayOf(size_t length_to_set) { SetStorageLength(length_to_set); Verify(m_length == length_to_set); #if defined(_ARMOR) if (length_to_set > 0) Check_Pointer(m_data); else Verify(!m_data); #endif } template void DynamicArrayOf::AssignValue(const T &value, size_t length_to_set) { SetStorageLength(length_to_set); // Do not memcopy, object semantics may be required for (int i = 0; i < m_length; i++) (const_cast(m_data))[i] = value; } template void DynamicArrayOf::AssignData(const T *data_to_copy, size_t length_to_set) { Check_Pointer(data_to_copy); SetStorageLength(length_to_set); // Do not memcopy, object semantics may be required for (int i = 0; i < m_length; i++) (const_cast(m_data))[i] = data_to_copy[i]; } template void DynamicArrayOf::SetLength(size_t length_to_set) { if (length_to_set != m_length) { if (length_to_set > 0) { T* new_data = new T[length_to_set]; Check_Pointer(new_data); if (m_data != NULL) { // Do not memcopy, object semantics may be required size_t i = Min(length_to_set, m_length); while (i--) new_data[i] = m_data[i]; Check_Pointer(m_data); delete[] const_cast(m_data); } m_data = new_data; } else { Check_Pointer(m_data); delete[] const_cast(m_data); m_data = NULL; } m_length = length_to_set; } } template void DynamicArrayOf::SetStorageLength(size_t length_to_set) { if (length_to_set != m_length) { if (length_to_set > 0) { if (m_data != NULL) { Check_Pointer(m_data); delete[] const_cast(m_data); } m_length = length_to_set; m_data = new T[m_length]; Check_Pointer(m_data); } else { Verify(length_to_set == 0); Check_Pointer(m_data); delete[] const_cast(m_data); m_data = NULL; } } } template void DynamicArrayOf::CopyArray(const DynamicArrayOf &array) { if (array.m_length > 0) { Check_Pointer(array.m_data); AssignData(&array.m_data[0], array.m_length); } else { Verify(array.m_length == 0); Verify(array.m_data == NULL); if (m_data != NULL) { Check_Pointer(m_data); delete[] const_cast(m_data); m_length = 0; } } } template MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const DynamicArrayOf *array ) { Check_Object(stream); Check_Pointer(array); size_t length = array->m_length; MemoryStreamIO::Write(stream, &length); if (length > 0) stream->WriteBytes(array->m_data, length * sizeof(T)); return *stream; } template MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, DynamicArrayOf *array ) { Check_Object(stream); Check_Pointer(array); size_t length; MemoryStreamIO::Read(stream, &length); array->SetLength(length); Verify(length == array->m_length); if (length > 0) stream->ReadBytes(const_cast(array->m_data), length * sizeof(T)); return *stream; } //########################################################################## //########################## StaticArrayOf ########################### //########################################################################## template class StaticArrayOf #if defined(_ARMOR) : public Stuff::Signature #endif { public: StaticArrayOf(); StaticArrayOf(const StaticArrayOf&); StaticArrayOf(const T &value); StaticArrayOf(T *data, size_t length); ~StaticArrayOf(); void TestInstance() const {} StaticArrayOf& operator=(const StaticArrayOf&); T& operator[](size_t i); const T& operator[](size_t i) const; void AssignValue(const T &value); void AssignData(const T *data, size_t length); size_t GetLength() const {return N;} size_t GetSize() const {return N * sizeof(T);} T* GetData() {return data;} const T* GetData() const {return data;} #if 0 bool Compare(const StaticArrayOf&); #endif friend MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const StaticArrayOf *array ); friend MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, StaticArrayOf *array ); private: T data[N]; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template inline StaticArrayOf::StaticArrayOf() { } template inline StaticArrayOf::StaticArrayOf(const StaticArrayOf &array) { AssignData(array.data, N); } template inline StaticArrayOf::StaticArrayOf(const T &value) { AssignValue(value); } template inline StaticArrayOf::StaticArrayOf(T *data_to_copy, size_t length) { AssignData(data_to_copy, length); } template inline StaticArrayOf::~StaticArrayOf() { } template StaticArrayOf& StaticArrayOf::operator=(const StaticArrayOf &array) { if (this != &array) { AssignData(&array.data[0], N); } return *this; } template inline T& StaticArrayOf::operator[](size_t i) { Verify(i < N); return data[i]; } template inline const T& StaticArrayOf::operator[](size_t i) const { Verify(i < N); return data[i]; } template void StaticArrayOf::AssignValue(const T &value) { // Do not memcopy, object semantics may be required for (int i = 0; i < N; i++) data[i] = value; } template void StaticArrayOf::AssignData(const T *data_to_copy, size_t length) { Check_Pointer(data_to_copy); Verify(length <= N); // Do not memcopy, object semantics may be required for (int i = 0; i < length; i++) data[i] = data_to_copy[i]; } #if 0 template bool StaticArrayOf::Compare(const StaticArrayOf &array) { if (N != array.GetLength()) return false; for (int i = 0; i < N; i++) { if (data[i] != array.data[i]) return false; } return true; } #endif template MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const StaticArrayOf *array ) { Check_Object(stream); Check_Pointer(array); return stream->WriteBytes(&array->data[0], N * sizeof(T)); } template MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, StaticArrayOf *array ) { Check_Object(stream); Check_Pointer(array); return stream->ReadBytes(&array->data[0], N * sizeof(T)); } }