360f38dc1e
X-SVN-Rev: 4245
231 lines
5.6 KiB
C
231 lines
5.6 KiB
C
/*
|
|
*******************************************************************************
|
|
*
|
|
* Copyright (C) 1998-2000, International Business Machines
|
|
* Corporation and others. All Rights Reserved.
|
|
*
|
|
*******************************************************************************
|
|
*
|
|
* File write.c
|
|
*
|
|
* Modification History:
|
|
*
|
|
* Date Name Description
|
|
* 06/01/99 stephen Creation.
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "write.h"
|
|
#include "cmemory.h"
|
|
#include "cstring.h"
|
|
#include "filestrm.h"
|
|
#include "unicode/ustring.h"
|
|
#include "error.h"
|
|
#include "list.h"
|
|
|
|
|
|
/* Protos */
|
|
static void write_ustring(FileStream *rb, const UChar *data);
|
|
static void write_string(FileStream *rb, const char *data);
|
|
static void write_strlist(FileStream *rb, const char *name,
|
|
const struct SStringList *list);
|
|
static void write_strlist2d(FileStream *rb, const char *name,
|
|
const struct SStringList2d *list);
|
|
static void write_taglist(FileStream *rb, const char *name,
|
|
const struct STaggedList *list);
|
|
|
|
/* Special values */
|
|
static const int32_t sBOM = 0x021C;
|
|
|
|
static const int32_t sEOF = -1;
|
|
|
|
static const int32_t sSTRINGLIST = 1;
|
|
static const int32_t sSTRINGLIST2D = 2;
|
|
static const int32_t sTAGGEDLIST = 3;
|
|
|
|
static const UChar gCollationElementsTag [] = {
|
|
/* "CollationElements" */
|
|
0x0043, 0x006f, 0x006c, 0x006c, 0x0061, 0x0074, 0x0069, 0x006f, 0x006e,
|
|
0x0045, 0x006c, 0x0065, 0x006d, 0x0065, 0x006e, 0x0074, 0x0073, 0x0000
|
|
};
|
|
|
|
/* Write a null-terminated UChar array */
|
|
static void
|
|
write_ustring(FileStream *rb,
|
|
const UChar *data)
|
|
{
|
|
int32_t len;
|
|
|
|
len = u_strlen(data);
|
|
|
|
/* Write the string's length */
|
|
T_FileStream_write(rb, &len, sizeof(len));
|
|
|
|
/* Write the string's data */
|
|
T_FileStream_write(rb, data, sizeof(UChar) * len);
|
|
}
|
|
|
|
static void
|
|
write_string(FileStream *rb,
|
|
const char *data) {
|
|
int32_t len;
|
|
|
|
len = uprv_strlen(data);
|
|
T_FileStream_write(rb, &len, sizeof(len));
|
|
|
|
T_FileStream_write(rb, data, sizeof(char) * len);
|
|
}
|
|
|
|
/* Write a string list */
|
|
static void
|
|
write_strlist(FileStream *rb,
|
|
const char *name,
|
|
const struct SStringList *list)
|
|
{
|
|
int32_t i;
|
|
|
|
/* Write out the value indicating this is a string list */
|
|
T_FileStream_write(rb, &sSTRINGLIST, sizeof(sSTRINGLIST));
|
|
|
|
/* Write the name of this string list */
|
|
write_string(rb, name);
|
|
|
|
/* Write the item count */
|
|
T_FileStream_write(rb, &list->fCount, sizeof(list->fCount));
|
|
|
|
/* Write each string in the list */
|
|
for(i = 0; i < list->fCount; ++i) {
|
|
write_ustring(rb, list->fData[i]);
|
|
}
|
|
}
|
|
|
|
/* Write a 2-d string list */
|
|
static void
|
|
write_strlist2d(FileStream *rb,
|
|
const char *name,
|
|
const struct SStringList2d *list)
|
|
{
|
|
int32_t i, j;
|
|
int32_t itemcount;
|
|
|
|
/* Write out the value indicating this is a 2-d string list */
|
|
T_FileStream_write(rb, &sSTRINGLIST2D, sizeof(sSTRINGLIST2D));
|
|
|
|
/* Write the name of this 2-d string list */
|
|
write_string(rb, name);
|
|
|
|
/* Write the row count */
|
|
T_FileStream_write(rb, &list->fRowCount, sizeof(list->fRowCount));
|
|
|
|
/* Write out each row */
|
|
for(i = 0; i < list->fRowCount; ++i) {
|
|
itemcount = (i == list->fRowCount - 1 ? list->fCount: list->fRows[i+1])
|
|
- list->fRows[i];
|
|
|
|
/* Write out the count of strings in this row */
|
|
T_FileStream_write(rb, &itemcount, sizeof(itemcount));
|
|
|
|
/* Write out each string in the row */
|
|
for(j = 0; j < itemcount; ++j) {
|
|
write_ustring(rb, list->fData[list->fRows[i] + j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Write a tagged list */
|
|
static void
|
|
write_taglist(FileStream *rb,
|
|
const char *name,
|
|
const struct STaggedList *list)
|
|
{
|
|
// int32_t i;
|
|
struct SStringPair *current;
|
|
|
|
/* Write out the value indicating this is a tagged list */
|
|
T_FileStream_write(rb, &sTAGGEDLIST, sizeof(sTAGGEDLIST));
|
|
|
|
/* Write the name of this tagged list */
|
|
write_string(rb, name);
|
|
|
|
/* Write the item count */
|
|
T_FileStream_write(rb, &list->fCount, sizeof(list->fCount));
|
|
|
|
/* Write out each key/value pair */
|
|
current = list->fFirst;
|
|
while(current != NULL) {
|
|
write_string(rb, current->fKey);
|
|
write_ustring(rb, current->fValue);
|
|
current = current->fNext;
|
|
}
|
|
|
|
|
|
// for(i = 0; i < list->fCount; ++i) {
|
|
// write_ustring(rb, list->fData[i].fKey);
|
|
// write_ustring(rb, list->fData[i].fValue);
|
|
// }
|
|
}
|
|
|
|
/* Write a parsed SRBItemList to a file */
|
|
void
|
|
rb_write(FileStream *f,
|
|
struct SRBItemList *data,
|
|
UErrorCode *status)
|
|
{
|
|
// int32_t i;
|
|
struct SRBItem *item;
|
|
|
|
if(U_FAILURE(*status)) return;
|
|
|
|
/* Write the byte order mark to the file */
|
|
T_FileStream_write(f, &sBOM, sizeof(sBOM));
|
|
|
|
/* Write the locale name to the file */
|
|
write_ustring(f, data->fLocale);
|
|
|
|
item = data->fFirst;
|
|
|
|
/* Successively write each list item */
|
|
// for(i = 0; i < data->fCount; ++i) {
|
|
while(item != NULL) {
|
|
|
|
// item = data->fData[i];
|
|
|
|
switch(item->fData->fType) {
|
|
case eStringList:
|
|
/*if(u_strcmp(item->fTag, gCollationElementsTag) == 0)
|
|
puts("got CollationElements");*/
|
|
write_strlist(f, item->fTag, &item->fData->u.fStringList);
|
|
break;
|
|
|
|
case eStringList2d:
|
|
write_strlist2d(f, item->fTag, &item->fData->u.fStringList2d);
|
|
break;
|
|
|
|
case eTaggedList:
|
|
write_taglist(f, item->fTag, &item->fData->u.fTaggedList);
|
|
break;
|
|
|
|
case eEmpty:
|
|
*status = U_INTERNAL_PROGRAM_ERROR;
|
|
setErrorText("Unexpected empty item found");
|
|
goto finish;
|
|
/*break;*/
|
|
}
|
|
item = item->fNext;
|
|
}
|
|
|
|
/* Indicate the end of the data */
|
|
T_FileStream_write(f, &sEOF, sizeof(sEOF));
|
|
|
|
/* Check if any errors occurred during writing */
|
|
if(T_FileStream_error(f) != 0) {
|
|
*status = U_FILE_ACCESS_ERROR;
|
|
}
|
|
|
|
finish:
|
|
;
|
|
|
|
/* clean up */
|
|
}
|