blob: a4d8cd707c3d2159753b096dee0e9f809db6494e [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1996-1999, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
//===============================================================================
//
// File tables.cpp
//
// Contains:
// EntryPair - Represents a contracting-character string
// PointerToPatternEntry - a smart pointer to a PatternEntry
//
// VectorOfInt - Dynamic array classes, in lieu of templates
// VectorOfPointer
// VectorOfPToExpandTable
// VectorOfPToContractElement
// VectorOfPointersToPatternEntry
//
// All of these classes are fairly small and self-explanatory, so they don't
// contain too many internal comments.
//
// Created by: Helena Shih
//
// Modification History:
//
// Date Name Description
// 2/5/97 aliu Added streamIn and streamOut methods to EntryPair,
// VectorOfInt, VectorOfPToExpandTable, VectorOfPToContractElement,
// VectorOfPToContractTable. These are used by TableCollation
// streamIn and streamOut methods.
// 2/11/97 aliu Moved declarations out of for loop initializer.
// 3/5/97 aliu Made VectorOfPointersToPatternEntry::at() inline.
// 6/18/97 helena Added VectorOfPointer for MergeCollation.
// 6/23/97 helena Added comments to make code more readable. Since
// this is converted from a templatized version, the comment
// is only added to one class.
// 8/04/98 erm Added EntryPair::fwd.
//===============================================================================
#ifndef _TABLES
#include "tables.h"
#endif
#ifndef _PTNENTRY
#include "ptnentry.h"
#endif
#ifndef _FILESTRM
#include "filestrm.h"
#endif
#ifndef _UNISTRM
#include "unistrm.h"
#endif
//=======================================================================================
// METHODS ON EntryPair
//=======================================================================================
void EntryPair::streamOut(FileStream* os) const
{
if (!T_FileStream_error(os))
{
UnicodeString tempForStreaming(nameChars, nameLen);
UnicodeStringStreamer::streamOut(&tempForStreaming, os);
T_FileStream_write(os, &value, sizeof(value));
T_FileStream_write(os, &fwd, sizeof(fwd));
}
}
void EntryPair::streamIn(FileStream* is)
{
if(storage != NULL) {
delete storage;
storage = NULL;
}
storage = new UnicodeString();
if (!T_FileStream_error(is))
{
UnicodeStringStreamer::streamIn(storage, is);
T_FileStream_read(is, &value, sizeof(value));
T_FileStream_read(is, &fwd, sizeof(fwd));
}
nameChars = storage->getUChars();
nameLen = storage->size();
}
void EntryPair::streamOut(UMemoryStream* os) const
{
if (!uprv_mstrm_error(os))
{
UnicodeString stringForStream(nameChars, nameLen);
UnicodeStringStreamer::streamOut(&stringForStream, os);
uprv_mstrm_write(os, (uint8_t *)&value, sizeof(value));
uprv_mstrm_write(os, (uint8_t *)&fwd, sizeof(fwd));
}
}
void EntryPair::streamIn(UMemoryStream* is)
{
if(storage != NULL) {
delete storage;
storage = NULL;
}
storage = new UnicodeString();
if (!uprv_mstrm_error(is))
{
UnicodeStringStreamer::streamIn(storage, is);
uprv_mstrm_read(is, &value, sizeof(value));
uprv_mstrm_read(is, &fwd, sizeof(fwd));
}
nameChars = storage->getUChars();
nameLen = storage->size();
}
//=======================================================================================
// METHODS ON VectorOfInt
//=======================================================================================
VectorOfInt::VectorOfInt(int32_t initialSize)
: fSize(0),
fCapacity(0),
fElements(0),
fBogus(FALSE)
{
if (initialSize != 0) {
resize(initialSize);
if (fBogus) return;
}
}
// Copy constructor
VectorOfInt::VectorOfInt(const VectorOfInt& that)
: fSize(that.fSize),
fCapacity(that.fCapacity),
fElements(0),
fBogus(FALSE)
{
fElements = new int32_t[fCapacity];
if (!fElements) {
fBogus = TRUE;
return;
}
int32_t* to = fElements;
int32_t* from = that.fElements;
int32_t* end = &(fElements[fCapacity]);
while (to < end)
*to++ = *from++;
}
VectorOfInt::~VectorOfInt()
{
delete [] fElements;
}
// assignment operator
const VectorOfInt&
VectorOfInt::operator=(const VectorOfInt& that)
{
if (this != &that) {
// resize if necessary
if (fCapacity < that.fSize) {
delete [] fElements;
fElements = 0;
fElements = new int32_t[that.fCapacity];
if (!fElements) {
fBogus = TRUE;
return *this;
}
fCapacity = that.fCapacity;
}
int32_t* to = fElements;
int32_t* from = that.fElements;
int32_t* cutover = &(fElements[that.fCapacity]);
int32_t* end = &(fElements[fCapacity]);
while (to < cutover)
*to++ = *from++;
while (to < end)
*to++ = 0;
fSize = that.fSize;
}
return *this;
}
UBool
VectorOfInt::isBogus() const
{
return fBogus;
}
UBool
VectorOfInt::operator==(const VectorOfInt& that)
{
if (this == &that) return TRUE;
if (fSize != that.fSize) return FALSE;
for (int32_t i = 0; i < fSize; i++) {
if (fElements[i] != that.fElements[i])
return FALSE;
}
return TRUE;
}
UBool
VectorOfInt::operator!=(const VectorOfInt& that)
{
return !(*this == that);
}
// replace the element at the index
void
VectorOfInt::atPut( int32_t index,
const int32_t& value)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return;
}
else
fSize = index + 1;
}
fElements[index] = value;
}
// insert the element at the index, shift down the following elements
void
VectorOfInt::atInsert( int32_t index,
const int32_t& value)
{
if (fSize + 1 >= fCapacity) {
resize(fSize + 1);
if (fBogus) return;
} else {
fSize++;
}
int32_t i;
for (i = fSize - 2 ; i >= index; i--)
{
fElements[i+1] = fElements[i];
}
fElements[index] = value;
}
void
VectorOfInt::setSize(int32_t newSize) {
if (newSize < 0) {
newSize = 0;
}
if (newSize > fCapacity) {
resize(newSize);
// Although resize zeros out elements past fCapacity, the API
// doc specifies that we zero out elements past fSize.
for (int32_t i=fSize; i<newSize; ++i) {
fElements[i] = 0;
}
}
fSize = newSize;
}
// Resize the element array. Create a new array and copy the elements over
// then discard the old array.
void
VectorOfInt::resize(int32_t newSize)
{
int32_t newCapacity;
newCapacity = newSize / GROWTH_RATE;
if (newCapacity < 10)
newCapacity = 10;
newCapacity += newSize;
int32_t* newArray = 0;
newArray = new int32_t[newCapacity];
if (!newArray) {
fBogus = TRUE;
return;
}
int32_t* iter = newArray;
int32_t* cutover = &(newArray[fCapacity]);
int32_t* end = &(newArray[newCapacity]);
int32_t* from = fElements;
while (iter < cutover)
*iter++ = *from++;
while (iter < end)
*iter++ = 0;
delete [] fElements;
fElements = newArray;
fSize = newSize;
fCapacity = newCapacity;
}
// Do not detect the out of bounds error, try to do the right thing
// by resizing the array.
int32_t&
VectorOfInt::operator[](int32_t index)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return fElements[0]; // HSYS : Is this correct?
}
else
fSize = index + 1;
}
return fElements[index];
}
void
VectorOfInt::streamOut(FileStream* os) const
{
if (!T_FileStream_error(os))
{
T_FileStream_write(os, &fSize, sizeof(fSize));
T_FileStream_write(os, fElements, sizeof(*fElements) * fSize);
}
}
void
VectorOfInt::streamIn(FileStream* is)
{
if (!T_FileStream_error(is))
{
int32_t newSize;
T_FileStream_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
T_FileStream_read(is, fElements, sizeof(*fElements) * newSize);
}
}
void
VectorOfInt::streamOut(UMemoryStream* os) const
{
if (!uprv_mstrm_error(os))
{
uprv_mstrm_write(os, (uint8_t *)&fSize, sizeof(fSize));
uprv_mstrm_write(os, (uint8_t *)fElements, sizeof(*fElements) * fSize);
}
}
void
VectorOfInt::streamIn(UMemoryStream* is)
{
if (!uprv_mstrm_error(is))
{
int32_t newSize;
uprv_mstrm_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
uprv_mstrm_read(is, fElements, sizeof(*fElements) * newSize);
}
}
//=======================================================================================
// METHODS ON VectorOfPointer
//=======================================================================================
VectorOfPointer::VectorOfPointer(int32_t initialSize)
: fSize(0),
fCapacity(0),
fElements(0),
fBogus(FALSE)
{
if (initialSize != 0) {
resize(initialSize);
if (fBogus) return;
}
}
VectorOfPointer::VectorOfPointer(const VectorOfPointer& that)
: fSize(that.fSize),
fCapacity(that.fCapacity),
fElements(0),
fBogus(FALSE)
{
fElements = new void*[fCapacity];
if (!fElements) {
fBogus = TRUE;
return;
}
void** to = fElements;
void** from = that.fElements;
void** end = &(fElements[fCapacity]);
while (to < end)
*to++ = *from++;
}
VectorOfPointer::~VectorOfPointer()
{
delete [] fElements;
}
const VectorOfPointer&
VectorOfPointer::operator=(const VectorOfPointer& that)
{
if (this != &that) {
if (fCapacity < that.fSize) {
delete [] fElements;
fElements = 0;
fElements = new void*[that.fCapacity];
if (!fElements) {
fBogus = TRUE;
return *this;
}
fCapacity = that.fCapacity;
}
void** to = fElements;
void** from = that.fElements;
void** cutover = &(fElements[that.fCapacity]);
void** end = &(fElements[fCapacity]);
while (to < cutover)
*to++ = *from++;
while (to < end)
*to++ = 0;
fSize = that.fSize;
}
return *this;
}
UBool
VectorOfPointer::isBogus() const
{
return fBogus;
}
UBool
VectorOfPointer::operator==(const VectorOfPointer& that)
{
if (this == &that) return TRUE;
if (fSize != that.fSize) return FALSE;
for (int32_t i = 0; i < fSize; i++) {
if (fElements[i] != that.fElements[i])
return FALSE;
}
return TRUE;
}
UBool
VectorOfPointer::operator!=(const VectorOfPointer& that)
{
return !(*this == that);
}
void
VectorOfPointer::atPut( int32_t index,
const void*& value)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return;
}
else
fSize = index + 1;
}
fElements[index] = (void*)value;
}
void
VectorOfPointer::atInsert( int32_t index,
const void*& value)
{
if (fSize + 1 >= fCapacity) {
resize(fSize + 1);
if (fBogus) return;
} else {
fSize++;
}
int32_t i;
for (i = fSize - 2 ; i >= index; i--)
{
fElements[i+1] = fElements[i];
}
fElements[index] = (void*)value;
}
void
VectorOfPointer::resize(int32_t newSize)
{
int32_t newCapacity;
newCapacity = newSize / GROWTH_RATE;
if (newCapacity < 10)
newCapacity = 10;
newCapacity += newSize;
void** newArray = 0;
newArray = new void*[newCapacity];
if (!newArray) {
fBogus = TRUE;
return;
}
void** iter = newArray;
void** cutover = &(newArray[fCapacity]);
void** end = &(newArray[newCapacity]);
void** from = fElements;
while (iter < cutover)
*iter++ = *from++;
while (iter < end)
*iter++ = 0;
delete [] fElements;
fElements = newArray;
fSize = newSize;
fCapacity = newCapacity;
}
void*&
VectorOfPointer::operator[](int32_t index)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return fElements[0]; // HSYS : Is this correct?
}
else
fSize = index + 1;
}
return fElements[index];
}
//=======================================================================================
// METHODS ON VectorOfPToExpandTable
//=======================================================================================
VectorOfPToExpandTable::VectorOfPToExpandTable(int32_t initialSize)
: fSize(0),
fCapacity(0),
fElements(0),
fBogus(FALSE)
{
if (initialSize != 0) {
resize(initialSize);
if (fBogus) return;
}
}
VectorOfPToExpandTable::VectorOfPToExpandTable(const VectorOfPToExpandTable& that)
: fSize(that.fSize),
fCapacity(that.fCapacity),
fElements(0),
fBogus(FALSE)
{
fElements = new VectorOfInt*[fCapacity];
if (!fElements) {
fBogus = TRUE;
return;
}
VectorOfInt** to = fElements;
VectorOfInt** from = that.fElements;
VectorOfInt** end = &(fElements[fCapacity]);
while (to < end) {
if (*from == 0)
*to++ = *from++;
else
// We actually DUPLICATE the items pointed to by "that"
*to = new VectorOfInt(*(*from++));
if ((*to)->isBogus()) {
delete [] fElements;
fElements = 0;
return;
}
to++;
}
}
VectorOfPToExpandTable::~VectorOfPToExpandTable()
{
VectorOfInt** iter = fElements;
VectorOfInt** end = &(fElements[fSize]);
while (iter < end)
delete *iter++;
delete [] fElements;
}
UBool
VectorOfPToExpandTable::isBogus() const
{
return fBogus;
}
const VectorOfPToExpandTable&
VectorOfPToExpandTable::operator=(const VectorOfPToExpandTable& that)
{
if (this != &that) {
if (fCapacity < that.fSize) {
delete [] fElements;
fElements = 0;
fElements = new VectorOfInt*[that.fCapacity];
if (!fElements) {
fBogus = TRUE;
return *this;
}
fCapacity = that.fCapacity;
}
VectorOfInt** to = fElements;
VectorOfInt** from = that.fElements;
VectorOfInt** cutover = &(fElements[that.fCapacity]);
VectorOfInt** end = &(fElements[fCapacity]);
while (to < cutover) {
delete *to;
if (*from == 0)
*to++ = *from++;
else {
*to = new VectorOfInt(*(*from++));
if ((*to)->isBogus()) {
delete [] fElements;
fElements = 0;
return *this;
}
to++;
}
}
while (to < end) {
delete *to;
*to++ = 0;
}
fSize = that.fSize;
}
return *this;
}
PToExpandTable
VectorOfPToExpandTable::operator[](int32_t index)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return fElements[0]; // Always return the first element
}
else
fSize = index + 1;
}
return fElements[index];
}
void
VectorOfPToExpandTable::atPut( int32_t index,
VectorOfInt* value)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return;
}
else
fSize = index + 1;
}
delete fElements[index];
fElements[index] = value;
}
VectorOfInt*
VectorOfPToExpandTable::orphanAt(int32_t index)
{
if (index > fSize)
return 0;
else {
VectorOfInt* returnVal = fElements[index];
fElements[index] = 0;
return returnVal;
}
}
void
VectorOfPToExpandTable::resize(int32_t newSize)
{
int32_t newCapacity;
newCapacity = newSize / GROWTH_RATE;
if (newCapacity < 10)
newCapacity = 10;
newCapacity += newSize;
VectorOfInt** newArray = 0;
newArray = new VectorOfInt*[newCapacity];
if (!newArray) {
fBogus = TRUE;
return;
}
VectorOfInt** iter = newArray;
VectorOfInt** cutover = &(newArray[fCapacity]);
VectorOfInt** end = &(newArray[newCapacity]);
VectorOfInt** from = fElements;
while (iter < cutover)
*iter++ = *from++;
while (iter < end)
*iter++ = 0;
delete [] fElements;
fElements = newArray;
fSize = newSize;
fCapacity = newCapacity;
}
void
VectorOfPToExpandTable::streamOut(FileStream* os) const
{
if (!T_FileStream_error(os))
{
T_FileStream_write(os, &fSize, sizeof(fSize));
int32_t i;
for (i=0; i<fSize; ++i)
{
char isNull = (fElements[i] == 0);
T_FileStream_write(os, &isNull, sizeof(isNull));
if (!isNull) fElements[i]->streamOut(os);
}
}
}
void
VectorOfPToExpandTable::streamIn(FileStream* is)
{
if (!T_FileStream_error(is))
{
int32_t newSize;
T_FileStream_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
int32_t i;
for (i=0; i<newSize; ++i)
{
char isNull;
T_FileStream_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete fElements[i];
fElements[i] = 0;
}
else
{
if (fElements[i] == 0) fElements[i] = new VectorOfInt;
fElements[i]->streamIn(is);
if (fElements[i]->isBogus()) {
fBogus = TRUE;
return;
}
}
}
}
}
void
VectorOfPToExpandTable::streamOut(UMemoryStream* os) const
{
if (!uprv_mstrm_error(os))
{
uprv_mstrm_write(os, (uint8_t *)&fSize, sizeof(fSize));
int32_t i;
for (i=0; i<fSize; ++i)
{
char isNull = (fElements[i] == 0);
uprv_mstrm_write(os, (uint8_t *)&isNull, sizeof(isNull));
if (!isNull) fElements[i]->streamOut(os);
}
}
}
void
VectorOfPToExpandTable::streamIn(UMemoryStream* is)
{
if (!uprv_mstrm_error(is))
{
int32_t newSize;
uprv_mstrm_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
int32_t i;
for (i=0; i<newSize; ++i)
{
char isNull;
uprv_mstrm_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete fElements[i];
fElements[i] = 0;
}
else
{
if (fElements[i] == 0) fElements[i] = new VectorOfInt;
fElements[i]->streamIn(is);
if (fElements[i]->isBogus()) {
fBogus = TRUE;
return;
}
}
}
}
}
//=======================================================================================
// METHODS ON VectorOfPToContractElement
//=======================================================================================
VectorOfPToContractElement::VectorOfPToContractElement(int32_t initialSize)
: fSize(0),
fCapacity(0),
fElements(0),
fBogus(FALSE)
{
if (initialSize != 0) {
resize(initialSize);
if (fBogus) return;
}
}
VectorOfPToContractElement::VectorOfPToContractElement(const VectorOfPToContractElement& that)
: fSize(that.fSize),
fCapacity(that.fCapacity),
fElements(0),
fBogus(FALSE)
{
fElements = new EntryPair*[fCapacity];
if (!fElements) {
fBogus = TRUE;
return;
}
EntryPair** to = fElements;
EntryPair** from = that.fElements;
EntryPair** end = &(fElements[fCapacity]);
while (to < end) {
if (*from == 0)
*to++ = *from++;
else
// We actually DUPLICATE the items pointed to by "that"
*to++ = new EntryPair(*(*from++));
}
}
VectorOfPToContractElement::~VectorOfPToContractElement()
{
EntryPair** iter = fElements;
EntryPair** end = &(fElements[fSize]);
while (iter < end)
delete *iter++;
delete [] fElements;
}
UBool
VectorOfPToContractElement::isBogus() const
{
return fBogus;
}
const VectorOfPToContractElement&
VectorOfPToContractElement::operator=(const VectorOfPToContractElement& that)
{
if (this != &that) {
if (fCapacity < that.fSize) {
delete [] fElements;
fElements = 0;
fElements = new EntryPair*[that.fCapacity];
if (!fElements) {
fBogus = TRUE;
return *this;
}
fCapacity = that.fCapacity;
}
EntryPair** to = fElements;
EntryPair** from = that.fElements;
EntryPair** cutover = &(fElements[that.fCapacity]);
EntryPair** end = &(fElements[fCapacity]);
while (to < cutover) {
delete *to;
if (*from == 0)
*to++ = *from++;
else
*to++ = new EntryPair(*(*from++));
}
while (to < end) {
delete *to;
*to++ = 0;
}
fSize = that.fSize;
}
return *this;
}
PToContractElement
VectorOfPToContractElement::operator[](int32_t index)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return fElements[0];
}
else
fSize = index + 1;
}
return fElements[index];
}
void
VectorOfPToContractElement::atPut( int32_t index,
EntryPair* value)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return;
}
else
fSize = index + 1;
}
delete fElements[index];
fElements[index] = value;
}
void
VectorOfPToContractElement::atInsert( int32_t index,
EntryPair* value)
{
if (fSize + 1 >= fCapacity) {
resize(fSize + 1);
if (fBogus) return;
} else {
fSize++;
}
int32_t i;
for (i = fSize - 2 ; i >= index; i--)
{
fElements[i+1] = fElements[i];
}
fElements[index] = value;
}
EntryPair*
VectorOfPToContractElement::orphanAt(int32_t index)
{
if (index > fSize)
return 0;
else {
EntryPair* returnVal = fElements[index];
fElements[index] = 0;
return returnVal;
}
}
void
VectorOfPToContractElement::resize(int32_t newSize)
{
int32_t newCapacity;
newCapacity = newSize / GROWTH_RATE;
if (newCapacity < 10)
newCapacity = 10;
newCapacity += newSize;
EntryPair** newArray = 0;
newArray = new EntryPair*[newCapacity];
if (!newArray) {
fBogus = TRUE;
return;
}
EntryPair** iter = newArray;
EntryPair** cutover = &(newArray[fCapacity]);
EntryPair** end = &(newArray[newCapacity]);
EntryPair** from = fElements;
while (iter < cutover)
*iter++ = *from++;
while (iter < end)
*iter++ = 0;
delete [] fElements;
fElements = newArray;
fSize = newSize;
fCapacity = newCapacity;
}
void
VectorOfPToContractElement::streamOut(FileStream* os) const
{
if (!T_FileStream_error(os))
{
T_FileStream_write(os, &fSize, sizeof(fSize));
int32_t i;
for (i=0; i<fSize; ++i)
{
char isNull = (fElements[i] == 0);
T_FileStream_write(os, &isNull, sizeof(isNull));
if (!isNull) fElements[i]->streamOut(os);
}
}
}
void
VectorOfPToContractElement::streamIn(FileStream* is)
{
if (!T_FileStream_error(is))
{
int32_t newSize;
T_FileStream_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
int32_t i;
for (i=0; i<newSize; ++i)
{
char isNull;
T_FileStream_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete fElements[i];
fElements[i] = 0;
}
else
{
if (fElements[i] == 0) fElements[i] = new EntryPair;
fElements[i]->streamIn(is);
}
}
}
}
void
VectorOfPToContractElement::streamOut(UMemoryStream* os) const
{
if (!uprv_mstrm_error(os))
{
uprv_mstrm_write(os, (uint8_t *)&fSize, sizeof(fSize));
int32_t i;
for (i=0; i<fSize; ++i)
{
char isNull = (fElements[i] == 0);
uprv_mstrm_write(os, (uint8_t *)&isNull, sizeof(isNull));
if (!isNull) fElements[i]->streamOut(os);
}
}
}
void
VectorOfPToContractElement::streamIn(UMemoryStream* is)
{
if (!uprv_mstrm_error(is))
{
int32_t newSize;
uprv_mstrm_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
int32_t i;
for (i=0; i<newSize; ++i)
{
char isNull;
uprv_mstrm_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete fElements[i];
fElements[i] = 0;
}
else
{
if (fElements[i] == 0) fElements[i] = new EntryPair;
fElements[i]->streamIn(is);
}
}
}
}
//=======================================================================================
// METHODS ON VectorOfPToContractTable
//=======================================================================================
VectorOfPToContractTable::VectorOfPToContractTable(int32_t initialSize)
: fSize(0),
fCapacity(0),
fElements(0),
fBogus(FALSE)
{
if (initialSize != 0) {
resize(initialSize);
if (fBogus) return;
}
}
VectorOfPToContractTable::VectorOfPToContractTable(const VectorOfPToContractTable& that)
: fSize(that.fSize),
fCapacity(that.fCapacity),
fElements(0),
fBogus(FALSE)
{
fElements = new VectorOfPToContractElement*[fCapacity];
if (!fElements) {
fBogus = TRUE;
return;
}
VectorOfPToContractElement** to = fElements;
VectorOfPToContractElement** from = that.fElements;
VectorOfPToContractElement** end = &(fElements[fCapacity]);
while (to < end) {
if (*from == 0)
*to++ = *from++;
else {
// We actually DUPLICATE the items pointed to by "that"
*to = new VectorOfPToContractElement(*(*from++));
if ((*to)->isBogus()) {
delete [] fElements;
fElements = 0;
return;
}
to++;
}
}
}
VectorOfPToContractTable::~VectorOfPToContractTable()
{
VectorOfPToContractElement** iter = fElements;
VectorOfPToContractElement** end = &(fElements[fSize]);
while (iter < end)
delete *iter++;
delete [] fElements;
}
UBool
VectorOfPToContractTable::isBogus() const
{
return fBogus;
}
const VectorOfPToContractTable&
VectorOfPToContractTable::operator=(const VectorOfPToContractTable& that)
{
if (this != &that) {
if (fCapacity < that.fSize) {
delete [] fElements;
fElements = 0;
fElements = new VectorOfPToContractElement*[that.fCapacity];
if (!fElements) {
fBogus = TRUE;
return *this;
}
fCapacity = that.fCapacity;
}
VectorOfPToContractElement** to = fElements;
VectorOfPToContractElement** from = that.fElements;
VectorOfPToContractElement** cutover = &(fElements[that.fCapacity]);
VectorOfPToContractElement** end = &(fElements[fCapacity]);
while (to < cutover) {
delete *to;
if (*from == 0)
*to++ = *from++;
else {
*to = new VectorOfPToContractElement(*(*from++));
if ((*to)->isBogus()) {
delete [] fElements;
fElements = 0;
return *this;
}
to++;
}
}
while (to < end) {
delete *to;
*to++ = 0;
}
fSize = that.fSize;
}
return *this;
}
void
VectorOfPToContractTable::atPut( int32_t index,
VectorOfPToContractElement* value)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return;
}
else
fSize = index + 1;
}
delete fElements[index];
fElements[index] = value;
}
PToContractTable
VectorOfPToContractTable::operator[](int32_t index)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return fElements[0];
}
else
fSize = index + 1;
}
return fElements[index];
}
VectorOfPToContractElement*
VectorOfPToContractTable::orphanAt(int32_t index)
{
if (index > fSize)
return 0;
else {
VectorOfPToContractElement* returnVal = fElements[index];
fElements[index] = 0;
return returnVal;
}
}
void
VectorOfPToContractTable::resize(int32_t newSize)
{
int32_t newCapacity;
newCapacity = newSize / GROWTH_RATE;
if (newCapacity < 10)
newCapacity = 10;
newCapacity += newSize;
VectorOfPToContractElement** newArray = 0;
newArray = new VectorOfPToContractElement*[newCapacity];
if (!newArray) {
fBogus = TRUE;
return;
}
VectorOfPToContractElement** iter = newArray;
VectorOfPToContractElement** cutover = &(newArray[fCapacity]);
VectorOfPToContractElement** end = &(newArray[newCapacity]);
VectorOfPToContractElement** from = fElements;
while (iter < cutover)
*iter++ = *from++;
while (iter < end)
*iter++ = 0;
delete [] fElements;
fElements = newArray;
fSize = newSize;
fCapacity = newCapacity;
}
void
VectorOfPToContractTable::streamOut(FileStream* os) const
{
if (!T_FileStream_error(os))
{
T_FileStream_write(os, &fSize, sizeof(fSize));
int32_t i;
for (i=0; i<fSize; ++i)
{
char isNull = (fElements[i] == 0);
T_FileStream_write(os, &isNull, sizeof(isNull));
if (!isNull) fElements[i]->streamOut(os);
}
}
}
void
VectorOfPToContractTable::streamIn(FileStream* is)
{
if (!T_FileStream_error(is))
{
int32_t newSize;
T_FileStream_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
int32_t i;
for (i=0; i<newSize; ++i)
{
char isNull;
T_FileStream_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete fElements[i];
fElements[i] = 0;
}
else
{
if (fElements[i] == 0) fElements[i] = new VectorOfPToContractElement;
fElements[i]->streamIn(is);
}
}
}
}
void
VectorOfPToContractTable::streamOut(UMemoryStream* os) const
{
if (!uprv_mstrm_error(os))
{
uprv_mstrm_write(os, (uint8_t *)&fSize, sizeof(fSize));
int32_t i;
for (i=0; i<fSize; ++i)
{
char isNull = (fElements[i] == 0);
uprv_mstrm_write(os, (uint8_t *)&isNull, sizeof(isNull));
if (!isNull) fElements[i]->streamOut(os);
}
}
}
void
VectorOfPToContractTable::streamIn(UMemoryStream* is)
{
if (!uprv_mstrm_error(is))
{
int32_t newSize;
uprv_mstrm_read(is, &newSize, sizeof(newSize));
resize(newSize);
if (fBogus) return;
int32_t i;
for (i=0; i<newSize; ++i)
{
char isNull;
uprv_mstrm_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete fElements[i];
fElements[i] = 0;
}
else
{
if (fElements[i] == 0) fElements[i] = new VectorOfPToContractElement;
fElements[i]->streamIn(is);
}
}
}
}
//=======================================================================================
// METHODS ON PointerToPatternEntry
//=======================================================================================
PointerToPatternEntry::PointerToPatternEntry(PatternEntry*& value)
: fValue(value)
{
}
PointerToPatternEntry::PointerToPatternEntry(const PointerToPatternEntry& that)
: fValue(that.fValue)
{
}
PointerToPatternEntry::~PointerToPatternEntry()
{
}
const PointerToPatternEntry&
PointerToPatternEntry::operator=(PatternEntry* newValue)
{
delete fValue;
fValue = newValue;
return *this;
}
const PointerToPatternEntry&
PointerToPatternEntry::operator=(const PointerToPatternEntry& pointerToNewValue)
{
delete fValue;
fValue = (PatternEntry*)(pointerToNewValue);
return *this;
}
PointerToPatternEntry::operator PatternEntry*() const
{
return fValue;
}
//=======================================================================================
// METHODS ON VectorOfPointersToPatternEntry
//=======================================================================================
VectorOfPointersToPatternEntry::VectorOfPointersToPatternEntry(int32_t initialSize)
: fSize(0),
fCapacity(0),
fElements(0),
fBogus(FALSE)
{
if (initialSize != 0) {
resize(initialSize);
if (fBogus) return;
}
}
VectorOfPointersToPatternEntry::VectorOfPointersToPatternEntry(const VectorOfPointersToPatternEntry& that)
: fSize(that.fSize),
fCapacity(that.fCapacity),
fElements(0),
fBogus(FALSE)
{
fElements = new PatternEntry*[fCapacity];
if (!fElements) {
fBogus = TRUE;
return;
}
PatternEntry** to = fElements;
PatternEntry** from = that.fElements;
PatternEntry** end = &(fElements[fCapacity]);
while (to < end) {
if (*from == 0)
*to++ = *from++;
else
// We actually DUPLICATE the items pointed to by "that"
*to++ = new PatternEntry(*(*from++));
}
}
VectorOfPointersToPatternEntry::~VectorOfPointersToPatternEntry()
{
PatternEntry** iter = fElements;
PatternEntry** end = &(fElements[fSize]);
while (iter < end)
delete *iter++;
delete [] fElements;
}
UBool
VectorOfPointersToPatternEntry::isBogus() const
{
return fBogus;
}
const VectorOfPointersToPatternEntry&
VectorOfPointersToPatternEntry::operator=(const VectorOfPointersToPatternEntry& that)
{
if (this != &that) {
if (fCapacity < that.fSize) {
delete [] fElements;
fElements = 0;
fElements = new PatternEntry*[that.fCapacity];
if (!fElements) {
fBogus = TRUE;
return *this;
}
fCapacity = that.fCapacity;
}
PatternEntry** to = fElements;
PatternEntry** from = that.fElements;
PatternEntry** cutover = &(fElements[that.fCapacity]);
PatternEntry** end = &(fElements[fCapacity]);
while (to < cutover) {
delete *to;
if (*from == 0)
*to++ = *from++;
else
*to++ = new PatternEntry(*(*from++));
}
while (to < end) {
delete *to;
*to++ = 0;
}
fSize = that.fSize;
}
return *this;
}
PatternEntry*
VectorOfPointersToPatternEntry::operator[](int32_t index) const
{
return (index < fCapacity) ? fElements[index] : 0;
}
PointerToPatternEntry
VectorOfPointersToPatternEntry::operator[](int32_t index)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return fElements[0];
}
else
fSize = index + 1;
}
return fElements[index];
}
void
VectorOfPointersToPatternEntry::atPut( int32_t index,
PatternEntry* value)
{
if (index >= fSize) {
if (index >= fCapacity) {
resize(index + 1);
if (fBogus) return;
}
else
fSize = index + 1;
}
delete fElements[index];
fElements[index] = value;
}
void
VectorOfPointersToPatternEntry::atInsert( int32_t index,
PatternEntry* value)
{
if (fSize + 1 >= fCapacity) {
resize(fSize + 1);
if (fBogus) return;
} else {
fSize++;
}
int32_t i;
for (i = fSize - 2 ; i >= index; i--)
{
fElements[i+1] = fElements[i];
}
fElements[index] = value;
}
PatternEntry*
VectorOfPointersToPatternEntry::orphanAt(int32_t index)
{
if (index > fSize)
return 0;
else {
PatternEntry* returnVal = fElements[index];
fElements[index] = 0;
return returnVal;
}
}
void
VectorOfPointersToPatternEntry::clear()
{
int32_t i;
for (i = 0; i < fSize; i += 1)
{
delete fElements[i];
fElements[i] = NULL;
}
fSize = 0;
}
int32_t
VectorOfPointersToPatternEntry::size() const
{
return fSize;
}
int32_t
VectorOfPointersToPatternEntry::indexOf(const PatternEntry* value) const
{
int32_t i;
if (value == NULL)
{
for (i = 0; i < fSize; i += 1)
{
if (fElements[i] == NULL)
{
return i;
}
}
}
else
{
for (i = 0; i < fSize; i += 1)
{
if (fElements[i] != NULL && value->equals(*fElements[i]))
{
return i;
}
}
}
return -1;
}
int32_t
VectorOfPointersToPatternEntry::lastIndexOf(const PatternEntry* value) const
{
int32_t i;
if (value == NULL)
{
for (i = fSize - 1; i >= 0; i -= 1)
{
if (fElements[i] == NULL)
{
return i;
}
}
}
else
{
for (i = fSize - 1; i >= 0; i -= 1)
{
if (fElements[i] != NULL && value->equals(*fElements[i]))
{
return i;
}
}
}
return -1;
}
void
VectorOfPointersToPatternEntry::resize(int32_t newSize)
{
int32_t newCapacity;
newCapacity = newSize / GROWTH_RATE;
if (newCapacity < 10)
newCapacity = 10;
newCapacity += newSize;
PatternEntry** newArray = 0;
newArray = new PatternEntry*[newCapacity];
if (!newArray) {
fBogus = TRUE;
return;
}
PatternEntry** iter = newArray;
PatternEntry** cutover = &(newArray[fCapacity]);
PatternEntry** end = &(newArray[newCapacity]);
PatternEntry** from = fElements;
while (iter < cutover)
*iter++ = *from++;
while (iter < end)
*iter++ = 0;
delete [] fElements;
fElements = newArray;
fSize = newSize;
fCapacity = newCapacity;
}