360f38dc1e
X-SVN-Rev: 4245
505 lines
11 KiB
C
505 lines
11 KiB
C
/*
|
|
*******************************************************************************
|
|
*
|
|
* Copyright (C) 1998-2000, 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 "cstring.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.fFirst = NULL;
|
|
list->u.fTaggedList.fCount = 0;
|
|
/*list->u.fTaggedList.fCapacity = 32;*/
|
|
|
|
/*taglist_grow(list, status);*/
|
|
|
|
return list;
|
|
}
|
|
|
|
void
|
|
taglist_close(struct SList *list,
|
|
UErrorCode *status)
|
|
{
|
|
struct SStringPair *current;
|
|
struct SStringPair *prev;
|
|
if(U_FAILURE(*status)) return;
|
|
|
|
if(list->fType != eTaggedList) {
|
|
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
|
return;
|
|
}
|
|
|
|
current = list->u.fTaggedList.fFirst;
|
|
|
|
while(current != NULL) {
|
|
prev = current;
|
|
current = current->fNext;
|
|
uprv_free(prev);
|
|
}
|
|
|
|
|
|
/*uprv_free(list->u.fTaggedList.fData);*/
|
|
|
|
list->fType = eEmpty;
|
|
uprv_free(list);
|
|
}
|
|
|
|
|
|
void
|
|
taglist_add(struct SList *list,
|
|
const UChar *tag,
|
|
const UChar *data,
|
|
UErrorCode *status)
|
|
{
|
|
/*int32_t index;*/
|
|
struct SStringPair *pair = NULL;
|
|
struct SStringPair *current = NULL;
|
|
struct SStringPair *prev = NULL;
|
|
|
|
if(U_FAILURE(*status)) return;
|
|
|
|
if(list->fType != eTaggedList) {
|
|
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
|
return;
|
|
}
|
|
|
|
pair = (struct SStringPair *) uprv_malloc(sizeof(struct SStringPair));
|
|
if(pair->fKey == 0) {
|
|
*status = U_MEMORY_ALLOCATION_ERROR;
|
|
return;
|
|
}
|
|
|
|
|
|
pair->fKey = (char*) uprv_malloc(sizeof(char) * (u_strlen(tag) + 1));
|
|
if(pair->fKey == 0) {
|
|
*status = U_MEMORY_ALLOCATION_ERROR;
|
|
uprv_free(pair);
|
|
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);
|
|
uprv_free(pair);
|
|
return;
|
|
}
|
|
|
|
++(list->u.fTaggedList.fCount);
|
|
|
|
/*u_strcpy(pair.fKey, tag);*/
|
|
u_UCharsToChars(tag, pair->fKey, u_strlen(tag)+1);
|
|
u_strcpy(pair->fValue, data);
|
|
|
|
/* is list still empty? */
|
|
if(list->u.fTaggedList.fFirst == NULL) {
|
|
list->u.fTaggedList.fFirst = pair;
|
|
pair->fNext = NULL;
|
|
return;
|
|
} else {
|
|
current = list->u.fTaggedList.fFirst;
|
|
}
|
|
|
|
while(current != NULL) {
|
|
if(uprv_strcmp(current->fKey, pair->fKey)<0) {
|
|
prev = current;
|
|
current = current->fNext;
|
|
} else { /*we're either in front of list, or in middle*/
|
|
if(prev == NULL) { /*front of the list*/
|
|
list->u.fTaggedList.fFirst = pair;
|
|
} else { /*middle of the list*/
|
|
prev->fNext = pair;
|
|
}
|
|
pair->fNext = current;
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* end of list */
|
|
prev->fNext = pair;
|
|
pair->fNext = NULL;
|
|
|
|
/*index = list->u.fTaggedList.fCount;*/
|
|
|
|
/*if(list->u.fTaggedList.fCount == list->u.fTaggedList.fCapacity)*/
|
|
/*taglist_grow(list, status);*/
|
|
|
|
/*list->u.fTaggedList.fData[index] = pair;*/
|
|
}
|
|
|
|
const UChar*
|
|
taglist_get(const struct SList *list,
|
|
const char *tag,
|
|
UErrorCode *status)
|
|
{
|
|
/*int32_t i;*/
|
|
struct SStringPair *current;
|
|
|
|
if(U_FAILURE(*status)) return 0;
|
|
|
|
if(list->fType != eTaggedList) {
|
|
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
|
return 0;
|
|
}
|
|
|
|
/* is list still empty? */
|
|
if(list->u.fTaggedList.fFirst == NULL) {
|
|
return NULL;
|
|
} else {
|
|
current = list->u.fTaggedList.fFirst;
|
|
}
|
|
|
|
while(current != NULL) {
|
|
if(uprv_strcmp(current->fKey, tag)!=0) {
|
|
current = current->fNext;
|
|
} else { /*we're either in front of list, or in middle*/
|
|
return current->fValue;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|