scuffed-code/icu4c/source/tools/rbdump/parse.c

294 lines
5.7 KiB
C

/*
*******************************************************************************
*
* 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 "parse.h"
#include "cmemory.h"
#include "cstring.h"
#include "filestrm.h"
#include "unicode/ustring.h"
#include "uprint.h"
/* Protos */
static UChar* read_ustring(FileStream *rb, UErrorCode *status);
static void read_strlist(FileStream *rb, UErrorCode *status);
static void read_strlist2d(FileStream *rb, UErrorCode *status);
static void read_taglist(FileStream *rb, UErrorCode *status);
/* Special values */
static const int32_t sBOM = 0x021C;
#define STRINGLIST 1
#define STRINGLIST2D 2
#define TAGGEDLIST 3
static const int32_t sSTRINGLIST = 1;
static const int32_t sSTRINGLIST2D = 2;
static const int32_t sTAGGEDLIST = 3;
static const int32_t sEOF = -1;
/* Read a UChar array */
static UChar*
read_ustring(FileStream *rb,
UErrorCode *status)
{
int32_t len;
UChar *s;
if(U_FAILURE(*status)) return 0;
/* Read the string's length */
T_FileStream_read(rb, &len, sizeof(len));
/* Allocate space for the string */
s = (UChar*) uprv_malloc(sizeof(UChar) * (len + 1));
if(s == 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return 0;
}
/* Read the string's data */
T_FileStream_read(rb, s, sizeof(UChar) * len);
/* Add the null terminator */
s[len] = 0x0000;
return s;
}
/* Read a string list */
static void
read_strlist(FileStream *rb,
UErrorCode *status)
{
int32_t i, count;
UChar *name;
UChar *s;
if(U_FAILURE(*status)) return;
/* Read the name of this string list */
name = read_ustring(rb, status);
/* Read the number of items in this string list */
T_FileStream_read(rb, &count, sizeof(count));
printf(" ");
uprint(name, stdout, status);
fputc('\n', stdout);
/* Successively read strings in the list */
for(i = 0; i < count; ++i) {
s = read_ustring(rb, status);
/* handle error */
if(U_FAILURE(*status) || s == 0) {
goto finish;
}
printf(" ");
uprint(s, stdout, status);
fputc('\n', stdout);
uprv_free(s);
}
finish:
/* clean up */
uprv_free(name);
}
/* Read a 2-d string list */
static void
read_strlist2d(FileStream *rb,
UErrorCode *status)
{
int32_t i, j;
int32_t rows, itemcount;
UChar *name;
UChar *s;
if(U_FAILURE(*status)) return;
/* Read the name of this 2-d string list */
name = read_ustring(rb, status);
/* Read the number of rows in this 2-d string list */
T_FileStream_read(rb, &rows, sizeof(rows));
printf(" ");
uprint(name, stdout, status);
fputc('\n', stdout);
/* Read each row */
for(i = 0; i < rows; ++i) {
/* Read the number of items in this row */
T_FileStream_read(rb, &itemcount, sizeof(itemcount));
printf(" ");
/* Read each item */
for(j = 0; j < itemcount; ++j) {
s = read_ustring(rb, status);
/* handle error */
if(U_FAILURE(*status) || s == 0) {
goto finish;
}
uprint(s, stdout, status);
if(j != itemcount - 1)
fputc(',', stdout);
uprv_free(s);
}
puts("");
}
finish:
/* clean up */
uprv_free(name);
}
/* Read a tagged list */
static void
read_taglist(FileStream *rb,
UErrorCode *status)
{
int32_t i, count;
UChar *name;
UChar *tag, *value;
if(U_FAILURE(*status)) return;
/* Read the name of this tagged list */
name = read_ustring(rb, status);
/* Read the number of items in this tagged list */
T_FileStream_read(rb, &count, sizeof(count));
printf(" ");
uprint(name, stdout, status);
fputc('\n', stdout);
/* Successively read strings in the list */
for(i = 0; i < count; ++i) {
tag = read_ustring(rb, status);
value = read_ustring(rb, status);
/* handle error */
if(U_FAILURE(*status) || tag == 0 || value == 0) {
goto finish;
}
printf(" ");
uprint(tag, stdout, status);
printf(": ");
uprint(value, stdout, status);
fputc('\n', stdout);
uprv_free(tag);
uprv_free(value);
}
finish:
/* clean up */
uprv_free(name);
}
/* Parse a compiled rb file */
void
parse(FileStream *f,
UErrorCode *status)
{
int32_t bom;
int32_t itemtype;
UChar *localename;
if(U_FAILURE(*status)) return;
/* Read the byte order mark from the file */
T_FileStream_read(f, &bom, sizeof(bom));
/* Verify the byte ordering matches */
if(bom != sBOM) {
*status = U_INVALID_FORMAT_ERROR;
goto finish;
}
/* Read the locale name from the file */
localename = read_ustring(f, status);
uprint(localename, stdout, status);
fputc('\n', stdout);
if(U_FAILURE(*status)) {
goto finish;
}
/* Successively read each list item */
for(;;) {
/* Read the next item type */
T_FileStream_read(f, &itemtype, sizeof(itemtype));
/* If we're at EOF, break */
if(itemtype == sEOF) {
goto finish;
}
/* Parse each item */
switch(itemtype) {
case STRINGLIST:
read_strlist(f, status);
if(U_FAILURE(*status)) {
goto finish;
}
break;
case STRINGLIST2D:
read_strlist2d(f, status);
if(U_FAILURE(*status)) {
goto finish;
}
break;
case TAGGEDLIST:
read_taglist(f, status);
if(U_FAILURE(*status)) {
goto finish;
}
break;
}
}
/* Check if any errors occurred during reading */
if(T_FileStream_error(f) != 0) {
*status = U_FILE_ACCESS_ERROR;
}
finish:
/* clean up */
uprv_free(localename);
}