blob: dea4c8b423fbf4745eb23462ade2cd4b092ba2aa [file] [log] [blame]
/*
*******************************************************************************
*
* Copyright (C) 1998-1999, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File list.c
*
* Modification History:
*
* Date Name Description
* 06/01/99 stephen Creation.
*******************************************************************************
*/
#include "list.h"
#include "cmemory.h"
#include "unicode/ustring.h"
/* Protos */
static void strlist_grow(struct SList *list, UErrorCode *status);
static void strlist2d_grow(struct SList *list, UErrorCode *status);
static void strlist2d_growRows(struct SList *list, UErrorCode *status);
static void taglist_grow(struct SList *list, UErrorCode *status);
/* String list */
struct SList*
strlist_open(UErrorCode *status)
{
struct SList *list;
if(U_FAILURE(*status)) return 0;
list = (struct SList*) uprv_malloc(sizeof(struct SList));
if(list == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return 0;
}
list->fType = eStringList;
list->u.fStringList.fData = 0;
list->u.fStringList.fCount = 0;
list->u.fStringList.fCapacity = 32;
strlist_grow(list, status);
return list;
}
void
strlist_close(struct SList *list,
UErrorCode *status)
{
int32_t i;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
/* deallocate each string */
for(i = 0; i < list->u.fStringList.fCount; ++i) {
uprv_free(list->u.fStringList.fData[i]);
}
uprv_free(list->u.fStringList.fData);
list->fType = eEmpty;
uprv_free(list);
}
void
strlist_add(struct SList *list,
const UChar *s,
UErrorCode *status)
{
int32_t index;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
index = list->u.fStringList.fCount;
if(list->u.fStringList.fCount == list->u.fStringList.fCapacity)
strlist_grow(list, status);
list->u.fStringList.fData[index] = (UChar*)
uprv_malloc(sizeof(UChar) * (u_strlen(s) + 1));
if(list->u.fStringList.fData[index] == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
u_strcpy(list->u.fStringList.fData[index], s);
++(list->u.fStringList.fCount);
}
static void
strlist_grow(struct SList *list,
UErrorCode *status)
{
int32_t i, j;
int32_t newCapacity;
UChar **newData;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
newCapacity = list->u.fStringList.fCapacity << 1;
/* allocate space for the array of strings */
newData = (UChar**) uprv_malloc(sizeof(UChar*) * newCapacity);
if(newData == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
/* allocate and copy each string */
for(i = 0; i < list->u.fStringList.fCount; ++i) {
newData[i] = (UChar*)
uprv_malloc(sizeof(UChar) * (u_strlen(list->u.fStringList.fData[i]) + 1));
if(newData[i] == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
for(j = 0; j < i; ++j)
uprv_free(newData[j]);
uprv_free(newData);
return;
}
u_strcpy(newData[i], list->u.fStringList.fData[i]);
}
uprv_free(list->u.fStringList.fData);
list->u.fStringList.fData = newData;
list->u.fStringList.fCapacity = newCapacity;
}
/* 2-d String list*/
struct SList*
strlist2d_open(UErrorCode *status)
{
struct SList *list;
if(U_FAILURE(*status)) return 0;
list = (struct SList*) uprv_malloc(sizeof(struct SList));
if(list == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return 0;
}
list->fType = eStringList2d;
list->u.fStringList2d.fData = 0;
list->u.fStringList2d.fCount = 0;
list->u.fStringList2d.fCapacity = 32;
list->u.fStringList2d.fRows = 0;
list->u.fStringList2d.fRowCount = 0;
list->u.fStringList2d.fRowCapacity = 32;
strlist2d_grow(list, status);
strlist2d_growRows(list, status);
if(U_SUCCESS(*status)) {
list->u.fStringList2d.fRows[0] = 0;
list->u.fStringList2d.fRowCount = 1;
}
return list;
}
void
strlist2d_close(struct SList *list,
UErrorCode *status)
{
int32_t i;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList2d) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
/* deallocate each string */
for(i = 0; i < list->u.fStringList2d.fCount; ++i) {
uprv_free(list->u.fStringList2d.fData[i]);
}
uprv_free(list->u.fStringList2d.fData);
uprv_free(list->u.fStringList2d.fRows);
list->fType = eEmpty;
uprv_free(list);
}
void
strlist2d_newRow(struct SList *list,
UErrorCode *status)
{
if(U_FAILURE(*status)) return;
if(list->fType != eStringList2d) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
if(list->u.fStringList2d.fRowCount == list->u.fStringList2d.fRowCapacity)
strlist2d_growRows(list, status);
if(U_FAILURE(*status)) return;
list->u.fStringList2d.fRows[(list->u.fStringList2d.fRowCount)++] =
list->u.fStringList2d.fCount;
}
void strlist2d_add(struct SList *list,
const UChar *s,
UErrorCode *status)
{
int32_t index;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList2d) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
index = list->u.fStringList2d.fCount;
if(list->u.fStringList2d.fCount == list->u.fStringList2d.fCapacity)
strlist2d_grow(list, status);
list->u.fStringList2d.fData[index] = (UChar*)
uprv_malloc(sizeof(UChar) * (u_strlen(s) + 1));
if(list->u.fStringList2d.fData[index] == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
u_strcpy(list->u.fStringList2d.fData[index], s);
++(list->u.fStringList2d.fCount);
}
static void
strlist2d_grow(struct SList *list,
UErrorCode *status)
{
int32_t i, j;
int32_t newCapacity;
UChar **newData;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList2d) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
newCapacity = list->u.fStringList2d.fCapacity << 1;
/* allocate space for the array of strings */
newData = (UChar**) uprv_malloc(sizeof(UChar*) * newCapacity);
if(newData == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
/* allocate and copy each string */
for(i = 0; i < list->u.fStringList2d.fCount; ++i) {
newData[i] = (UChar*)
uprv_malloc(sizeof(UChar) * (u_strlen(list->u.fStringList2d.fData[i]) + 1));
if(newData[i] == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
for(j = 0; j < i; ++j)
uprv_free(newData[j]);
uprv_free(newData);
return;
}
u_strcpy(newData[i], list->u.fStringList2d.fData[i]);
}
uprv_free(list->u.fStringList2d.fData);
list->u.fStringList2d.fData = newData;
list->u.fStringList2d.fCapacity = newCapacity;
}
static void
strlist2d_growRows(struct SList *list,
UErrorCode *status)
{
int32_t i;
int32_t newCapacity;
int32_t *newRows;
if(U_FAILURE(*status)) return;
if(list->fType != eStringList2d) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
newCapacity = list->u.fStringList2d.fRowCapacity << 1;
/* allocate space for the array of ints */
newRows = (int32_t*) uprv_malloc(sizeof(int32_t) * newCapacity);
if(newRows == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
}
/* copy each int */
for(i = 0; i < list->u.fStringList2d.fRowCount; ++i)
newRows[i] = list->u.fStringList2d.fRows[i];
/* clean up */
uprv_free(list->u.fStringList2d.fRows);
list->u.fStringList2d.fRows = newRows;
list->u.fStringList2d.fRowCapacity = newCapacity;
}
/* Tagged list */
struct SList*
taglist_open(UErrorCode *status)
{
struct SList *list;
if(U_FAILURE(*status)) return 0;
list = (struct SList*) uprv_malloc(sizeof(struct SList));
if(list == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return 0;
}
list->fType = eTaggedList;
list->u.fTaggedList.fData = 0;
list->u.fTaggedList.fCount = 0;
list->u.fTaggedList.fCapacity = 32;
taglist_grow(list, status);
return list;
}
void
taglist_close(struct SList *list,
UErrorCode *status)
{
if(U_FAILURE(*status)) return;
if(list->fType != eTaggedList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
uprv_free(list->u.fTaggedList.fData);
list->fType = eEmpty;
uprv_free(list);
}
static void
taglist_grow(struct SList *list,
UErrorCode *status)
{
int32_t i;
int32_t newCapacity;
struct SStringPair *newData;
if(U_FAILURE(*status)) return;
if(list->fType != eTaggedList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
newCapacity = list->u.fTaggedList.fCapacity << 1;
/* allocate space for the array of string pairs */
newData = (struct SStringPair*)
uprv_malloc(sizeof(struct SStringPair) * newCapacity);
if(newData == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
/* copy each string pair */
for(i = 0; i < list->u.fTaggedList.fCount; ++i) {
newData[i] = list->u.fTaggedList.fData[i];
}
uprv_free(list->u.fTaggedList.fData);
list->u.fTaggedList.fData = newData;
list->u.fTaggedList.fCapacity = newCapacity;
}
void
taglist_add(struct SList *list,
const UChar *tag,
const UChar *data,
UErrorCode *status)
{
int32_t index;
struct SStringPair pair;
if(U_FAILURE(*status)) return;
if(list->fType != eTaggedList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
pair.fKey = (UChar*) uprv_malloc(sizeof(UChar) * (u_strlen(tag) + 1));
if(pair.fKey == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
pair.fValue = (UChar*) uprv_malloc(sizeof(UChar) * (u_strlen(data) + 1));
if(pair.fValue == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
uprv_free(pair.fKey);
return;
}
u_strcpy(pair.fKey, tag);
u_strcpy(pair.fValue, data);
index = list->u.fTaggedList.fCount;
if(list->u.fTaggedList.fCount == list->u.fTaggedList.fCapacity)
taglist_grow(list, status);
list->u.fTaggedList.fData[index] = pair;
++(list->u.fTaggedList.fCount);
}
const UChar*
taglist_get(const struct SList *list,
const UChar *tag,
UErrorCode *status)
{
int32_t i;
if(U_FAILURE(*status)) return 0;
if(list->fType != eTaggedList) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
for(i = 0; i < list->u.fTaggedList.fCount; ++i) {
if(u_strcmp(list->u.fTaggedList.fData[i].fKey, tag) == 0)
return list->u.fTaggedList.fData[i].fValue;
}
return 0;
}