Home | History | Annotate | Download | only in toolutil
      1 /*
      2 *******************************************************************************
      3 *
      4 *   Copyright (C) 1999,2008, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 *******************************************************************************
      8 *   file name:  unewdata.c
      9 *   encoding:   US-ASCII
     10 *   tab size:   8 (not used)
     11 *   indentation:4
     12 *
     13 *   created on: 1999oct25
     14 *   created by: Markus W. Scherer
     15 */
     16 
     17 #include "unicode/utypes.h"
     18 #include "unicode/putil.h"
     19 #include "unicode/ustring.h"
     20 #include "cmemory.h"
     21 #include "cstring.h"
     22 #include "filestrm.h"
     23 #include "unicode/udata.h"
     24 #include "unewdata.h"
     25 
     26 struct UNewDataMemory {
     27     FileStream *file;
     28     uint16_t headerSize;
     29     uint8_t magic1, magic2;
     30 };
     31 
     32 U_CAPI UNewDataMemory * U_EXPORT2
     33 udata_create(const char *dir, const char *type, const char *name,
     34              const UDataInfo *pInfo,
     35              const char *comment,
     36              UErrorCode *pErrorCode) {
     37     UNewDataMemory *pData;
     38     uint16_t headerSize, commentLength;
     39     char filename[512];
     40     uint8_t bytes[16];
     41     int length;
     42 
     43     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
     44         return NULL;
     45     } else if(name==NULL || *name==0 || pInfo==NULL) {
     46         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
     47         return NULL;
     48     }
     49 
     50     /* allocate the data structure */
     51     pData=(UNewDataMemory *)uprv_malloc(sizeof(UNewDataMemory));
     52     if(pData==NULL) {
     53         *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
     54         return NULL;
     55     }
     56 
     57     /* Check that the full path won't be too long */
     58     length = 0;					/* Start with nothing */
     59     if(dir != NULL  && *dir !=0)	/* Add directory length if one was given */
     60     {
     61     	length += strlen(dir);
     62 
     63     	/* Add 1 if dir doesn't end with path sep */
     64         if (dir[strlen(dir) - 1]!= U_FILE_SEP_CHAR) {
     65             length++;
     66         }
     67 	}
     68     length += strlen(name);		/* Add the filename length */
     69 
     70     if(type != NULL  && *type !=0) { /* Add directory length if  given */
     71         length += strlen(type);
     72     }
     73 
     74 
     75      /* LDH buffer Length error check */
     76     if(length  > (sizeof(filename) - 1))
     77     {
     78    	    *pErrorCode = U_BUFFER_OVERFLOW_ERROR;
     79    	    uprv_free(pData);
     80 	    return NULL;
     81     }
     82 
     83     /* open the output file */
     84     if(dir!=NULL && *dir!=0) { /* if dir has a value, we prepend it to the filename */
     85         char *p=filename+strlen(dir);
     86         uprv_strcpy(filename, dir);
     87         if (*(p-1)!=U_FILE_SEP_CHAR) {
     88             *p++=U_FILE_SEP_CHAR;
     89             *p=0;
     90         }
     91     } else { /* otherwise, we'll output to the current dir */
     92         filename[0]=0;
     93     }
     94     uprv_strcat(filename, name);
     95     if(type!=NULL && *type!=0) {
     96         uprv_strcat(filename, ".");
     97         uprv_strcat(filename, type);
     98     }
     99     pData->file=T_FileStream_open(filename, "wb");
    100     if(pData->file==NULL) {
    101         uprv_free(pData);
    102         *pErrorCode=U_FILE_ACCESS_ERROR;
    103         return NULL;
    104     }
    105 
    106     /* write the header information */
    107     headerSize=(uint16_t)(pInfo->size+4);
    108     if(comment!=NULL && *comment!=0) {
    109         commentLength=(uint16_t)(uprv_strlen(comment)+1);
    110         headerSize+=commentLength;
    111     } else {
    112         commentLength=0;
    113     }
    114 
    115     /* write the size of the header, take padding into account */
    116     pData->headerSize=(uint16_t)((headerSize+15)&~0xf);
    117     pData->magic1=0xda;
    118     pData->magic2=0x27;
    119     T_FileStream_write(pData->file, &pData->headerSize, 4);
    120 
    121     /* write the information data */
    122     T_FileStream_write(pData->file, pInfo, pInfo->size);
    123 
    124     /* write the comment */
    125     if(commentLength>0) {
    126         T_FileStream_write(pData->file, comment, commentLength);
    127     }
    128 
    129     /* write padding bytes to align the data section to 16 bytes */
    130     headerSize&=0xf;
    131     if(headerSize!=0) {
    132         headerSize=(uint16_t)(16-headerSize);
    133         uprv_memset(bytes, 0, headerSize);
    134         T_FileStream_write(pData->file, bytes, headerSize);
    135     }
    136 
    137     return pData;
    138 }
    139 
    140 U_CAPI uint32_t U_EXPORT2
    141 udata_finish(UNewDataMemory *pData, UErrorCode *pErrorCode) {
    142     uint32_t fileLength=0;
    143 
    144     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
    145         return 0;
    146     }
    147 
    148     if(pData!=NULL) {
    149         if(pData->file!=NULL) {
    150             /* fflush(pData->file);*/
    151             fileLength=T_FileStream_size(pData->file);
    152             if(T_FileStream_error(pData->file)) {
    153                 *pErrorCode=U_FILE_ACCESS_ERROR;
    154             } else {
    155                 fileLength-=pData->headerSize;
    156             }
    157             T_FileStream_close(pData->file);
    158         }
    159         uprv_free(pData);
    160     }
    161 
    162     return fileLength;
    163 }
    164 
    165 U_CAPI void U_EXPORT2
    166 udata_write8(UNewDataMemory *pData, uint8_t byte) {
    167     if(pData!=NULL && pData->file!=NULL) {
    168         T_FileStream_write(pData->file, &byte, 1);
    169     }
    170 }
    171 
    172 U_CAPI void U_EXPORT2
    173 udata_write16(UNewDataMemory *pData, uint16_t word) {
    174     if(pData!=NULL && pData->file!=NULL) {
    175         T_FileStream_write(pData->file, &word, 2);
    176     }
    177 }
    178 
    179 U_CAPI void U_EXPORT2
    180 udata_write32(UNewDataMemory *pData, uint32_t wyde) {
    181     if(pData!=NULL && pData->file!=NULL) {
    182         T_FileStream_write(pData->file, &wyde, 4);
    183     }
    184 }
    185 
    186 U_CAPI void U_EXPORT2
    187 udata_writeBlock(UNewDataMemory *pData, const void *s, int32_t length) {
    188     if(pData!=NULL && pData->file!=NULL) {
    189         if(length>0) {
    190             T_FileStream_write(pData->file, s, length);
    191         }
    192     }
    193 }
    194 
    195 U_CAPI void U_EXPORT2
    196 udata_writePadding(UNewDataMemory *pData, int32_t length) {
    197     static const uint8_t padding[16]={
    198         0xaa, 0xaa, 0xaa, 0xaa,
    199         0xaa, 0xaa, 0xaa, 0xaa,
    200         0xaa, 0xaa, 0xaa, 0xaa,
    201         0xaa, 0xaa, 0xaa, 0xaa
    202     };
    203     if(pData!=NULL && pData->file!=NULL) {
    204         while(length>=16) {
    205             T_FileStream_write(pData->file, padding, 16);
    206             length-=16;
    207         }
    208         if(length>0) {
    209             T_FileStream_write(pData->file, padding, length);
    210         }
    211     }
    212 }
    213 
    214 U_CAPI void U_EXPORT2
    215 udata_writeString(UNewDataMemory *pData, const char *s, int32_t length) {
    216     if(pData!=NULL && pData->file!=NULL) {
    217         if(length==-1) {
    218             length=(int32_t)uprv_strlen(s);
    219         }
    220         if(length>0) {
    221             T_FileStream_write(pData->file, s, length);
    222         }
    223     }
    224 }
    225 
    226 U_CAPI void U_EXPORT2
    227 udata_writeUString(UNewDataMemory *pData, const UChar *s, int32_t length) {
    228     if(pData!=NULL && pData->file!=NULL) {
    229         if(length==-1) {
    230             length=u_strlen(s);
    231         }
    232         if(length>0) {
    233             T_FileStream_write(pData->file, s, length*sizeof(UChar));
    234         }
    235     }
    236 }
    237 
    238 /*
    239  * Hey, Emacs, please set the following:
    240  *
    241  * Local Variables:
    242  * indent-tabs-mode: nil
    243  * End:
    244  *
    245  */
    246 
    247