2 *******************************************************************************
4 * Copyright (C) 1999-2010, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: unewdata.c
10 * tab size: 8 (not used)
13 * created on: 1999oct25
14 * created by: Markus W. Scherer
18 #include "unicode/utypes.h"
19 #include "unicode/putil.h"
20 #include "unicode/ustring.h"
24 #include "unicode/udata.h"
27 struct UNewDataMemory
{
30 uint8_t magic1
, magic2
;
33 U_CAPI UNewDataMemory
* U_EXPORT2
34 udata_create(const char *dir
, const char *type
, const char *name
,
35 const UDataInfo
*pInfo
,
37 UErrorCode
*pErrorCode
) {
38 UNewDataMemory
*pData
;
39 uint16_t headerSize
, commentLength
;
44 if(pErrorCode
==NULL
|| U_FAILURE(*pErrorCode
)) {
46 } else if(name
==NULL
|| *name
==0 || pInfo
==NULL
) {
47 *pErrorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
51 /* allocate the data structure */
52 pData
=(UNewDataMemory
*)uprv_malloc(sizeof(UNewDataMemory
));
54 *pErrorCode
=U_MEMORY_ALLOCATION_ERROR
;
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 */
62 length
+= strlen(dir
);
64 /* Add 1 if dir doesn't end with path sep */
65 if (dir
[strlen(dir
) - 1]!= U_FILE_SEP_CHAR
) {
69 length
+= strlen(name
); /* Add the filename length */
71 if(type
!= NULL
&& *type
!=0) { /* Add directory length if given */
72 length
+= strlen(type
);
76 /* LDH buffer Length error check */
77 if(length
> (sizeof(filename
) - 1))
79 *pErrorCode
= U_BUFFER_OVERFLOW_ERROR
;
84 /* open the output file */
85 if(dir
!=NULL
&& *dir
!=0) { /* if dir has a value, we prepend it to the filename */
86 char *p
=filename
+strlen(dir
);
87 uprv_strcpy(filename
, dir
);
88 if (*(p
-1)!=U_FILE_SEP_CHAR
) {
92 } else { /* otherwise, we'll output to the current dir */
95 uprv_strcat(filename
, name
);
96 if(type
!=NULL
&& *type
!=0) {
97 uprv_strcat(filename
, ".");
98 uprv_strcat(filename
, type
);
100 pData
->file
=T_FileStream_open(filename
, "wb");
101 if(pData
->file
==NULL
) {
103 *pErrorCode
=U_FILE_ACCESS_ERROR
;
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
;
116 /* write the size of the header, take padding into account */
117 pData
->headerSize
=(uint16_t)((headerSize
+15)&~0xf);
120 T_FileStream_write(pData
->file
, &pData
->headerSize
, 4);
122 /* write the information data */
123 T_FileStream_write(pData
->file
, pInfo
, pInfo
->size
);
125 /* write the comment */
126 if(commentLength
>0) {
127 T_FileStream_write(pData
->file
, comment
, commentLength
);
130 /* write padding bytes to align the data section to 16 bytes */
133 headerSize
=(uint16_t)(16-headerSize
);
134 uprv_memset(bytes
, 0, headerSize
);
135 T_FileStream_write(pData
->file
, bytes
, headerSize
);
141 U_CAPI
uint32_t U_EXPORT2
142 udata_finish(UNewDataMemory
*pData
, UErrorCode
*pErrorCode
) {
143 uint32_t fileLength
=0;
145 if(pErrorCode
==NULL
|| U_FAILURE(*pErrorCode
)) {
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
;
156 fileLength
-=pData
->headerSize
;
158 T_FileStream_close(pData
->file
);
166 /* dummy UDataInfo cf. udata.h */
167 static const UDataInfo dummyDataInfo
= {
176 { 0, 0, 0, 0 }, /* dummy dataFormat */
177 { 0, 0, 0, 0 }, /* dummy formatVersion */
178 { 0, 0, 0, 0 } /* dummy dataVersion */
181 U_CAPI
void U_EXPORT2
182 udata_createDummy(const char *dir
, const char *type
, const char *name
, UErrorCode
*pErrorCode
) {
183 if(U_SUCCESS(*pErrorCode
)) {
184 udata_finish(udata_create(dir
, type
, name
, &dummyDataInfo
, NULL
, pErrorCode
), pErrorCode
);
185 if(U_FAILURE(*pErrorCode
)) {
186 fprintf(stderr
, "error %s writing dummy data file %s" U_FILE_SEP_STRING
"%s.%s\n",
187 u_errorName(*pErrorCode
), dir
, name
, type
);
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);
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);
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);
214 U_CAPI
void U_EXPORT2
215 udata_writeBlock(UNewDataMemory
*pData
, const void *s
, int32_t length
) {
216 if(pData
!=NULL
&& pData
->file
!=NULL
) {
218 T_FileStream_write(pData
->file
, s
, length
);
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
231 if(pData
!=NULL
&& pData
->file
!=NULL
) {
233 T_FileStream_write(pData
->file
, padding
, 16);
237 T_FileStream_write(pData
->file
, padding
, length
);
242 U_CAPI
void U_EXPORT2
243 udata_writeString(UNewDataMemory
*pData
, const char *s
, int32_t length
) {
244 if(pData
!=NULL
&& pData
->file
!=NULL
) {
246 length
=(int32_t)uprv_strlen(s
);
249 T_FileStream_write(pData
->file
, s
, length
);
254 U_CAPI
void U_EXPORT2
255 udata_writeUString(UNewDataMemory
*pData
, const UChar
*s
, int32_t length
) {
256 if(pData
!=NULL
&& pData
->file
!=NULL
) {
261 T_FileStream_write(pData
->file
, s
, length
*sizeof(UChar
));
267 * Hey, Emacs, please set the following:
270 * indent-tabs-mode: nil