1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/tools/toolutil/unewdata.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,274 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* 1.7 +* Copyright (C) 1999-2010, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************* 1.11 +* file name: unewdata.c 1.12 +* encoding: US-ASCII 1.13 +* tab size: 8 (not used) 1.14 +* indentation:4 1.15 +* 1.16 +* created on: 1999oct25 1.17 +* created by: Markus W. Scherer 1.18 +*/ 1.19 + 1.20 +#include <stdio.h> 1.21 +#include "unicode/utypes.h" 1.22 +#include "unicode/putil.h" 1.23 +#include "unicode/ustring.h" 1.24 +#include "cmemory.h" 1.25 +#include "cstring.h" 1.26 +#include "filestrm.h" 1.27 +#include "unicode/udata.h" 1.28 +#include "unewdata.h" 1.29 + 1.30 +struct UNewDataMemory { 1.31 + FileStream *file; 1.32 + uint16_t headerSize; 1.33 + uint8_t magic1, magic2; 1.34 +}; 1.35 + 1.36 +U_CAPI UNewDataMemory * U_EXPORT2 1.37 +udata_create(const char *dir, const char *type, const char *name, 1.38 + const UDataInfo *pInfo, 1.39 + const char *comment, 1.40 + UErrorCode *pErrorCode) { 1.41 + UNewDataMemory *pData; 1.42 + uint16_t headerSize, commentLength; 1.43 + char filename[512]; 1.44 + uint8_t bytes[16]; 1.45 + int length; 1.46 + 1.47 + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1.48 + return NULL; 1.49 + } else if(name==NULL || *name==0 || pInfo==NULL) { 1.50 + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1.51 + return NULL; 1.52 + } 1.53 + 1.54 + /* allocate the data structure */ 1.55 + pData=(UNewDataMemory *)uprv_malloc(sizeof(UNewDataMemory)); 1.56 + if(pData==NULL) { 1.57 + *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1.58 + return NULL; 1.59 + } 1.60 + 1.61 + /* Check that the full path won't be too long */ 1.62 + length = 0; /* Start with nothing */ 1.63 + if(dir != NULL && *dir !=0) /* Add directory length if one was given */ 1.64 + { 1.65 + length += strlen(dir); 1.66 + 1.67 + /* Add 1 if dir doesn't end with path sep */ 1.68 + if (dir[strlen(dir) - 1]!= U_FILE_SEP_CHAR) { 1.69 + length++; 1.70 + } 1.71 + } 1.72 + length += strlen(name); /* Add the filename length */ 1.73 + 1.74 + if(type != NULL && *type !=0) { /* Add directory length if given */ 1.75 + length += strlen(type); 1.76 + } 1.77 + 1.78 + 1.79 + /* LDH buffer Length error check */ 1.80 + if(length > (sizeof(filename) - 1)) 1.81 + { 1.82 + *pErrorCode = U_BUFFER_OVERFLOW_ERROR; 1.83 + uprv_free(pData); 1.84 + return NULL; 1.85 + } 1.86 + 1.87 + /* open the output file */ 1.88 + if(dir!=NULL && *dir!=0) { /* if dir has a value, we prepend it to the filename */ 1.89 + char *p=filename+strlen(dir); 1.90 + uprv_strcpy(filename, dir); 1.91 + if (*(p-1)!=U_FILE_SEP_CHAR) { 1.92 + *p++=U_FILE_SEP_CHAR; 1.93 + *p=0; 1.94 + } 1.95 + } else { /* otherwise, we'll output to the current dir */ 1.96 + filename[0]=0; 1.97 + } 1.98 + uprv_strcat(filename, name); 1.99 + if(type!=NULL && *type!=0) { 1.100 + uprv_strcat(filename, "."); 1.101 + uprv_strcat(filename, type); 1.102 + } 1.103 + pData->file=T_FileStream_open(filename, "wb"); 1.104 + if(pData->file==NULL) { 1.105 + uprv_free(pData); 1.106 + *pErrorCode=U_FILE_ACCESS_ERROR; 1.107 + return NULL; 1.108 + } 1.109 + 1.110 + /* write the header information */ 1.111 + headerSize=(uint16_t)(pInfo->size+4); 1.112 + if(comment!=NULL && *comment!=0) { 1.113 + commentLength=(uint16_t)(uprv_strlen(comment)+1); 1.114 + headerSize+=commentLength; 1.115 + } else { 1.116 + commentLength=0; 1.117 + } 1.118 + 1.119 + /* write the size of the header, take padding into account */ 1.120 + pData->headerSize=(uint16_t)((headerSize+15)&~0xf); 1.121 + pData->magic1=0xda; 1.122 + pData->magic2=0x27; 1.123 + T_FileStream_write(pData->file, &pData->headerSize, 4); 1.124 + 1.125 + /* write the information data */ 1.126 + T_FileStream_write(pData->file, pInfo, pInfo->size); 1.127 + 1.128 + /* write the comment */ 1.129 + if(commentLength>0) { 1.130 + T_FileStream_write(pData->file, comment, commentLength); 1.131 + } 1.132 + 1.133 + /* write padding bytes to align the data section to 16 bytes */ 1.134 + headerSize&=0xf; 1.135 + if(headerSize!=0) { 1.136 + headerSize=(uint16_t)(16-headerSize); 1.137 + uprv_memset(bytes, 0, headerSize); 1.138 + T_FileStream_write(pData->file, bytes, headerSize); 1.139 + } 1.140 + 1.141 + return pData; 1.142 +} 1.143 + 1.144 +U_CAPI uint32_t U_EXPORT2 1.145 +udata_finish(UNewDataMemory *pData, UErrorCode *pErrorCode) { 1.146 + uint32_t fileLength=0; 1.147 + 1.148 + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1.149 + return 0; 1.150 + } 1.151 + 1.152 + if(pData!=NULL) { 1.153 + if(pData->file!=NULL) { 1.154 + /* fflush(pData->file);*/ 1.155 + fileLength=T_FileStream_size(pData->file); 1.156 + if(T_FileStream_error(pData->file)) { 1.157 + *pErrorCode=U_FILE_ACCESS_ERROR; 1.158 + } else { 1.159 + fileLength-=pData->headerSize; 1.160 + } 1.161 + T_FileStream_close(pData->file); 1.162 + } 1.163 + uprv_free(pData); 1.164 + } 1.165 + 1.166 + return fileLength; 1.167 +} 1.168 + 1.169 +/* dummy UDataInfo cf. udata.h */ 1.170 +static const UDataInfo dummyDataInfo = { 1.171 + sizeof(UDataInfo), 1.172 + 0, 1.173 + 1.174 + U_IS_BIG_ENDIAN, 1.175 + U_CHARSET_FAMILY, 1.176 + U_SIZEOF_UCHAR, 1.177 + 0, 1.178 + 1.179 + { 0, 0, 0, 0 }, /* dummy dataFormat */ 1.180 + { 0, 0, 0, 0 }, /* dummy formatVersion */ 1.181 + { 0, 0, 0, 0 } /* dummy dataVersion */ 1.182 +}; 1.183 + 1.184 +U_CAPI void U_EXPORT2 1.185 +udata_createDummy(const char *dir, const char *type, const char *name, UErrorCode *pErrorCode) { 1.186 + if(U_SUCCESS(*pErrorCode)) { 1.187 + udata_finish(udata_create(dir, type, name, &dummyDataInfo, NULL, pErrorCode), pErrorCode); 1.188 + if(U_FAILURE(*pErrorCode)) { 1.189 + fprintf(stderr, "error %s writing dummy data file %s" U_FILE_SEP_STRING "%s.%s\n", 1.190 + u_errorName(*pErrorCode), dir, name, type); 1.191 + exit(*pErrorCode); 1.192 + } 1.193 + } 1.194 +} 1.195 + 1.196 +U_CAPI void U_EXPORT2 1.197 +udata_write8(UNewDataMemory *pData, uint8_t byte) { 1.198 + if(pData!=NULL && pData->file!=NULL) { 1.199 + T_FileStream_write(pData->file, &byte, 1); 1.200 + } 1.201 +} 1.202 + 1.203 +U_CAPI void U_EXPORT2 1.204 +udata_write16(UNewDataMemory *pData, uint16_t word) { 1.205 + if(pData!=NULL && pData->file!=NULL) { 1.206 + T_FileStream_write(pData->file, &word, 2); 1.207 + } 1.208 +} 1.209 + 1.210 +U_CAPI void U_EXPORT2 1.211 +udata_write32(UNewDataMemory *pData, uint32_t wyde) { 1.212 + if(pData!=NULL && pData->file!=NULL) { 1.213 + T_FileStream_write(pData->file, &wyde, 4); 1.214 + } 1.215 +} 1.216 + 1.217 +U_CAPI void U_EXPORT2 1.218 +udata_writeBlock(UNewDataMemory *pData, const void *s, int32_t length) { 1.219 + if(pData!=NULL && pData->file!=NULL) { 1.220 + if(length>0) { 1.221 + T_FileStream_write(pData->file, s, length); 1.222 + } 1.223 + } 1.224 +} 1.225 + 1.226 +U_CAPI void U_EXPORT2 1.227 +udata_writePadding(UNewDataMemory *pData, int32_t length) { 1.228 + static const uint8_t padding[16]={ 1.229 + 0xaa, 0xaa, 0xaa, 0xaa, 1.230 + 0xaa, 0xaa, 0xaa, 0xaa, 1.231 + 0xaa, 0xaa, 0xaa, 0xaa, 1.232 + 0xaa, 0xaa, 0xaa, 0xaa 1.233 + }; 1.234 + if(pData!=NULL && pData->file!=NULL) { 1.235 + while(length>=16) { 1.236 + T_FileStream_write(pData->file, padding, 16); 1.237 + length-=16; 1.238 + } 1.239 + if(length>0) { 1.240 + T_FileStream_write(pData->file, padding, length); 1.241 + } 1.242 + } 1.243 +} 1.244 + 1.245 +U_CAPI void U_EXPORT2 1.246 +udata_writeString(UNewDataMemory *pData, const char *s, int32_t length) { 1.247 + if(pData!=NULL && pData->file!=NULL) { 1.248 + if(length==-1) { 1.249 + length=(int32_t)uprv_strlen(s); 1.250 + } 1.251 + if(length>0) { 1.252 + T_FileStream_write(pData->file, s, length); 1.253 + } 1.254 + } 1.255 +} 1.256 + 1.257 +U_CAPI void U_EXPORT2 1.258 +udata_writeUString(UNewDataMemory *pData, const UChar *s, int32_t length) { 1.259 + if(pData!=NULL && pData->file!=NULL) { 1.260 + if(length==-1) { 1.261 + length=u_strlen(s); 1.262 + } 1.263 + if(length>0) { 1.264 + T_FileStream_write(pData->file, s, length*sizeof(UChar)); 1.265 + } 1.266 + } 1.267 +} 1.268 + 1.269 +/* 1.270 + * Hey, Emacs, please set the following: 1.271 + * 1.272 + * Local Variables: 1.273 + * indent-tabs-mode: nil 1.274 + * End: 1.275 + * 1.276 + */ 1.277 +