unewdata.c revision c69afcec261fc345fda8daf46f0ea6b4351dc777
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 26struct UNewDataMemory { 27 FileStream *file; 28 uint16_t headerSize; 29 uint8_t magic1, magic2; 30}; 31 32U_CAPI UNewDataMemory * U_EXPORT2 33udata_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 140U_CAPI uint32_t U_EXPORT2 141udata_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 165U_CAPI void U_EXPORT2 166udata_write8(UNewDataMemory *pData, uint8_t byte) { 167 if(pData!=NULL && pData->file!=NULL) { 168 T_FileStream_write(pData->file, &byte, 1); 169 } 170} 171 172U_CAPI void U_EXPORT2 173udata_write16(UNewDataMemory *pData, uint16_t word) { 174 if(pData!=NULL && pData->file!=NULL) { 175 T_FileStream_write(pData->file, &word, 2); 176 } 177} 178 179U_CAPI void U_EXPORT2 180udata_write32(UNewDataMemory *pData, uint32_t wyde) { 181 if(pData!=NULL && pData->file!=NULL) { 182 T_FileStream_write(pData->file, &wyde, 4); 183 } 184} 185 186U_CAPI void U_EXPORT2 187udata_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 195U_CAPI void U_EXPORT2 196udata_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 214U_CAPI void U_EXPORT2 215udata_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 226U_CAPI void U_EXPORT2 227udata_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