| /* |
| ******************************************************************************* |
| * |
| * Copyright (C) 1998-1999, 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 */ |
| } |