]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/toolutil/unewdata.c
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / tools / toolutil / unewdata.c
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