OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * |
| 4 * Copyright (C) 1999-2010, 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 <stdio.h> |
| 18 #include "unicode/utypes.h" |
| 19 #include "unicode/putil.h" |
| 20 #include "unicode/ustring.h" |
| 21 #include "cmemory.h" |
| 22 #include "cstring.h" |
| 23 #include "filestrm.h" |
| 24 #include "unicode/udata.h" |
| 25 #include "unewdata.h" |
| 26 |
| 27 struct UNewDataMemory { |
| 28 FileStream *file; |
| 29 uint16_t headerSize; |
| 30 uint8_t magic1, magic2; |
| 31 }; |
| 32 |
| 33 U_CAPI UNewDataMemory * U_EXPORT2 |
| 34 udata_create(const char *dir, const char *type, const char *name, |
| 35 const UDataInfo *pInfo, |
| 36 const char *comment, |
| 37 UErrorCode *pErrorCode) { |
| 38 UNewDataMemory *pData; |
| 39 uint16_t headerSize, commentLength; |
| 40 char filename[512]; |
| 41 uint8_t bytes[16]; |
| 42 int length; |
| 43 |
| 44 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { |
| 45 return NULL; |
| 46 } else if(name==NULL || *name==0 || pInfo==NULL) { |
| 47 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
| 48 return NULL; |
| 49 } |
| 50 |
| 51 /* allocate the data structure */ |
| 52 pData=(UNewDataMemory *)uprv_malloc(sizeof(UNewDataMemory)); |
| 53 if(pData==NULL) { |
| 54 *pErrorCode=U_MEMORY_ALLOCATION_ERROR; |
| 55 return NULL; |
| 56 } |
| 57 |
| 58 /* Check that the full path won't be too long */ |
| 59 length = 0; /* Start with nothing */ |
| 60 if(dir != NULL && *dir !=0) /* Add directory length if one was given
*/ |
| 61 { |
| 62 length += strlen(dir); |
| 63 |
| 64 /* Add 1 if dir doesn't end with path sep */ |
| 65 if (dir[strlen(dir) - 1]!= U_FILE_SEP_CHAR) { |
| 66 length++; |
| 67 } |
| 68 } |
| 69 length += strlen(name); /* Add the filename length */ |
| 70 |
| 71 if(type != NULL && *type !=0) { /* Add directory length if given */ |
| 72 length += strlen(type); |
| 73 } |
| 74 |
| 75 |
| 76 /* LDH buffer Length error check */ |
| 77 if(length > (sizeof(filename) - 1)) |
| 78 { |
| 79 *pErrorCode = U_BUFFER_OVERFLOW_ERROR; |
| 80 uprv_free(pData); |
| 81 return NULL; |
| 82 } |
| 83 |
| 84 /* open the output file */ |
| 85 if(dir!=NULL && *dir!=0) { /* if dir has a value, we prepend it to the filen
ame */ |
| 86 char *p=filename+strlen(dir); |
| 87 uprv_strcpy(filename, dir); |
| 88 if (*(p-1)!=U_FILE_SEP_CHAR) { |
| 89 *p++=U_FILE_SEP_CHAR; |
| 90 *p=0; |
| 91 } |
| 92 } else { /* otherwise, we'll output to the current dir */ |
| 93 filename[0]=0; |
| 94 } |
| 95 uprv_strcat(filename, name); |
| 96 if(type!=NULL && *type!=0) { |
| 97 uprv_strcat(filename, "."); |
| 98 uprv_strcat(filename, type); |
| 99 } |
| 100 pData->file=T_FileStream_open(filename, "wb"); |
| 101 if(pData->file==NULL) { |
| 102 uprv_free(pData); |
| 103 *pErrorCode=U_FILE_ACCESS_ERROR; |
| 104 return NULL; |
| 105 } |
| 106 |
| 107 /* write the header information */ |
| 108 headerSize=(uint16_t)(pInfo->size+4); |
| 109 if(comment!=NULL && *comment!=0) { |
| 110 commentLength=(uint16_t)(uprv_strlen(comment)+1); |
| 111 headerSize+=commentLength; |
| 112 } else { |
| 113 commentLength=0; |
| 114 } |
| 115 |
| 116 /* write the size of the header, take padding into account */ |
| 117 pData->headerSize=(uint16_t)((headerSize+15)&~0xf); |
| 118 pData->magic1=0xda; |
| 119 pData->magic2=0x27; |
| 120 T_FileStream_write(pData->file, &pData->headerSize, 4); |
| 121 |
| 122 /* write the information data */ |
| 123 T_FileStream_write(pData->file, pInfo, pInfo->size); |
| 124 |
| 125 /* write the comment */ |
| 126 if(commentLength>0) { |
| 127 T_FileStream_write(pData->file, comment, commentLength); |
| 128 } |
| 129 |
| 130 /* write padding bytes to align the data section to 16 bytes */ |
| 131 headerSize&=0xf; |
| 132 if(headerSize!=0) { |
| 133 headerSize=(uint16_t)(16-headerSize); |
| 134 uprv_memset(bytes, 0, headerSize); |
| 135 T_FileStream_write(pData->file, bytes, headerSize); |
| 136 } |
| 137 |
| 138 return pData; |
| 139 } |
| 140 |
| 141 U_CAPI uint32_t U_EXPORT2 |
| 142 udata_finish(UNewDataMemory *pData, UErrorCode *pErrorCode) { |
| 143 uint32_t fileLength=0; |
| 144 |
| 145 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { |
| 146 return 0; |
| 147 } |
| 148 |
| 149 if(pData!=NULL) { |
| 150 if(pData->file!=NULL) { |
| 151 /* fflush(pData->file);*/ |
| 152 fileLength=T_FileStream_size(pData->file); |
| 153 if(T_FileStream_error(pData->file)) { |
| 154 *pErrorCode=U_FILE_ACCESS_ERROR; |
| 155 } else { |
| 156 fileLength-=pData->headerSize; |
| 157 } |
| 158 T_FileStream_close(pData->file); |
| 159 } |
| 160 uprv_free(pData); |
| 161 } |
| 162 |
| 163 return fileLength; |
| 164 } |
| 165 |
| 166 /* dummy UDataInfo cf. udata.h */ |
| 167 static const UDataInfo dummyDataInfo = { |
| 168 sizeof(UDataInfo), |
| 169 0, |
| 170 |
| 171 U_IS_BIG_ENDIAN, |
| 172 U_CHARSET_FAMILY, |
| 173 U_SIZEOF_UCHAR, |
| 174 0, |
| 175 |
| 176 { 0, 0, 0, 0 }, /* dummy dataFormat */ |
| 177 { 0, 0, 0, 0 }, /* dummy formatVersion */ |
| 178 { 0, 0, 0, 0 } /* dummy dataVersion */ |
| 179 }; |
| 180 |
| 181 U_CAPI void U_EXPORT2 |
| 182 udata_createDummy(const char *dir, const char *type, const char *name, UErrorCod
e *pErrorCode) { |
| 183 if(U_SUCCESS(*pErrorCode)) { |
| 184 udata_finish(udata_create(dir, type, name, &dummyDataInfo, NULL, pErrorC
ode), pErrorCode); |
| 185 if(U_FAILURE(*pErrorCode)) { |
| 186 fprintf(stderr, "error %s writing dummy data file %s" U_FILE_SEP_STR
ING "%s.%s\n", |
| 187 u_errorName(*pErrorCode), dir, name, type); |
| 188 exit(*pErrorCode); |
| 189 } |
| 190 } |
| 191 } |
| 192 |
| 193 U_CAPI void U_EXPORT2 |
| 194 udata_write8(UNewDataMemory *pData, uint8_t byte) { |
| 195 if(pData!=NULL && pData->file!=NULL) { |
| 196 T_FileStream_write(pData->file, &byte, 1); |
| 197 } |
| 198 } |
| 199 |
| 200 U_CAPI void U_EXPORT2 |
| 201 udata_write16(UNewDataMemory *pData, uint16_t word) { |
| 202 if(pData!=NULL && pData->file!=NULL) { |
| 203 T_FileStream_write(pData->file, &word, 2); |
| 204 } |
| 205 } |
| 206 |
| 207 U_CAPI void U_EXPORT2 |
| 208 udata_write32(UNewDataMemory *pData, uint32_t wyde) { |
| 209 if(pData!=NULL && pData->file!=NULL) { |
| 210 T_FileStream_write(pData->file, &wyde, 4); |
| 211 } |
| 212 } |
| 213 |
| 214 U_CAPI void U_EXPORT2 |
| 215 udata_writeBlock(UNewDataMemory *pData, const void *s, int32_t length) { |
| 216 if(pData!=NULL && pData->file!=NULL) { |
| 217 if(length>0) { |
| 218 T_FileStream_write(pData->file, s, length); |
| 219 } |
| 220 } |
| 221 } |
| 222 |
| 223 U_CAPI void U_EXPORT2 |
| 224 udata_writePadding(UNewDataMemory *pData, int32_t length) { |
| 225 static const uint8_t padding[16]={ |
| 226 0xaa, 0xaa, 0xaa, 0xaa, |
| 227 0xaa, 0xaa, 0xaa, 0xaa, |
| 228 0xaa, 0xaa, 0xaa, 0xaa, |
| 229 0xaa, 0xaa, 0xaa, 0xaa |
| 230 }; |
| 231 if(pData!=NULL && pData->file!=NULL) { |
| 232 while(length>=16) { |
| 233 T_FileStream_write(pData->file, padding, 16); |
| 234 length-=16; |
| 235 } |
| 236 if(length>0) { |
| 237 T_FileStream_write(pData->file, padding, length); |
| 238 } |
| 239 } |
| 240 } |
| 241 |
| 242 U_CAPI void U_EXPORT2 |
| 243 udata_writeString(UNewDataMemory *pData, const char *s, int32_t length) { |
| 244 if(pData!=NULL && pData->file!=NULL) { |
| 245 if(length==-1) { |
| 246 length=(int32_t)uprv_strlen(s); |
| 247 } |
| 248 if(length>0) { |
| 249 T_FileStream_write(pData->file, s, length); |
| 250 } |
| 251 } |
| 252 } |
| 253 |
| 254 U_CAPI void U_EXPORT2 |
| 255 udata_writeUString(UNewDataMemory *pData, const UChar *s, int32_t length) { |
| 256 if(pData!=NULL && pData->file!=NULL) { |
| 257 if(length==-1) { |
| 258 length=u_strlen(s); |
| 259 } |
| 260 if(length>0) { |
| 261 T_FileStream_write(pData->file, s, length*sizeof(UChar)); |
| 262 } |
| 263 } |
| 264 } |
| 265 |
| 266 /* |
| 267 * Hey, Emacs, please set the following: |
| 268 * |
| 269 * Local Variables: |
| 270 * indent-tabs-mode: nil |
| 271 * End: |
| 272 * |
| 273 */ |
| 274 |
OLD | NEW |