/*
 ***************************************************************************
 *   Copyright (C) 1998-2001, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ***************************************************************************
*
* File rbdata.cpp
*
* Modification History:
*
*   Date        Name        Description
*   06/11/99    stephen     Creation. (Moved here from resbund.cpp)
******************************************************************************
*/

#include "rbdata.h"

UClassID StringList::fgClassID = 0; // Value is irrelevant
UClassID String2dList::fgClassID = 0; // Value is irrelevant
UClassID TaggedList::fgClassID = 0; // Value is irrelevant

//----------------------------------------------------------------------------

StringList::StringList()
  : fCount(0), fStrings(0)
{}

StringList::StringList(UnicodeString *adopted, 
                       int32_t count) 
  : fCount(count), fStrings(adopted)
{}

StringList::~StringList() 
{ delete [] fStrings; }
  
const UnicodeString& 
StringList::operator[](int32_t i) const 
{ return fStrings[i]; }

UClassID 
StringList::getDynamicClassID() const 
{ return getStaticClassID(); }

UClassID 
StringList::getStaticClassID() 
{ return (UClassID)&fgClassID; }

//-----------------------------------------------------------------------------

String2dList::String2dList() 
  : fRowCount(0), fColCount(0), fStrings(0) 
{}
  
String2dList::String2dList(UnicodeString **adopted, 
                           int32_t rowCount, 
                           int32_t colCount) 
  : fRowCount(rowCount), fColCount(colCount), fStrings(adopted) 
{}

String2dList::~String2dList() 
{ 
  for(int32_t i = 0; i < fRowCount; ++i) {
    delete[] fStrings[i]; 
  }
  delete[] fStrings;
}
  
const UnicodeString& 
String2dList::getString(int32_t rowIndex, 
                        int32_t colIndex) 
{ return fStrings[rowIndex][colIndex]; }
  
UClassID 
String2dList::getDynamicClassID() const 
{ return getStaticClassID(); }

UClassID 
String2dList::getStaticClassID() 
{ return (UClassID)&fgClassID; }

//-----------------------------------------------------------------------------

TaggedList::TaggedList() {
    UErrorCode status = U_ZERO_ERROR;
    hash = new Hashtable(status);
    hash->setValueDeleter(uhash_deleteUnicodeString);
}
  
TaggedList::~TaggedList() {
    delete hash;
}

int32_t TaggedList::count() const {
    return hash->count();
}

void 
TaggedList::put(const UnicodeString& tag, 
                const UnicodeString& data) {
    UErrorCode status = U_ZERO_ERROR;
    hash->put(tag, new UnicodeString(data), status);
}

const UnicodeString* 
TaggedList::get(const UnicodeString& tag) const {
    return (const UnicodeString*) hash->get(tag);
}

UBool TaggedList::nextElement(const UnicodeString*& key,
                               const UnicodeString*& value,
                               int32_t& pos) const {
    const UHashElement *e = hash->nextElement(pos);
    if (e != NULL) {
        key   = (const UnicodeString*) e->key;
        value = (const UnicodeString*) e->value;
        return TRUE;
    } else {
        return FALSE;
    }
}

UClassID 
TaggedList::getDynamicClassID() const 
{ return getStaticClassID(); }

UClassID 
TaggedList::getStaticClassID() 
{ return (UClassID)&fgClassID; }
