d2b75d095d44b614acc060562a2c62730f14562b
[reactos.git] / rosapps / applications / devutils / txt2nls / nls.c
1 /*
2 * PROJECT: ReactOS TXT to NLS Converter
3 * LICENSE: GNU General Public License Version 2.0 or any later version
4 * FILE: devutils/txt2nls/nls.c
5 * COPYRIGHT: Copyright 2016 Dmitry Chapyshev <dmitry@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 #define _NLS_DEBUG_PRINT
11
12 #ifdef _NLS_DEBUG_PRINT
13
14 static void
15 nls_print_header(NLS_FILE_HEADER *header)
16 {
17 uint32_t i;
18
19 printf("HEADER:\n");
20 printf("CodePage: %u\n", header->CodePage);
21 printf("Character size: %u\n", header->MaximumCharacterSize);
22 printf("Default char: 0x%02X\n", header->DefaultChar);
23 printf("Default unicode char: 0x%04X\n", header->UniDefaultChar);
24 printf("Trans default char: 0x%02X\n", header->TransUniDefaultChar);
25 printf("Trans default unicode char: 0x%04X\n", header->TransUniDefaultChar);
26
27 for (i = 0; i < MAXIMUM_LEADBYTES; i++)
28 {
29 printf("LeadByte[%u] = 0x%02X\n", i, header->LeadByte[i]);
30 }
31
32 printf("\n");
33 }
34
35 static void
36 nls_print_mb_table(uint16_t *mb_table, uint16_t uni_default_char)
37 {
38 uint32_t ch;
39
40 printf("MBTABLE:\n");
41
42 for (ch = 0; ch <= 0xFF; ch++)
43 {
44 if (mb_table[ch] != uni_default_char)
45 {
46 printf("0x%02X 0x%04X\n", (unsigned int)ch, (unsigned int)mb_table[ch]);
47 }
48 }
49
50 printf("\n");
51 }
52
53 static void
54 nls_print_wc_table(uint16_t *wc_table, uint16_t default_char, int is_dbcs)
55 {
56 uint32_t ch;
57
58 printf("WCTABLE:\n");
59
60 for (ch = 0; ch <= 0xFFFF; ch++)
61 {
62 /* DBCS code page */
63 if (is_dbcs)
64 {
65 uint16_t *table = (uint16_t*)wc_table;
66
67 if (table[ch] != default_char)
68 printf("0x%04X 0x%04X\n", (unsigned int)ch, (unsigned int)table[ch]);
69 }
70 /* SBCS code page */
71 else
72 {
73 uint8_t *table = (uint8_t*)wc_table;
74
75 if (table[ch] != default_char)
76 printf("0x%04X 0x%02X\n", (unsigned int)ch, (unsigned int)table[ch]);
77 }
78 }
79
80 printf("\n");
81 }
82
83 static void
84 nls_print_glyph_table(uint16_t *glyph_table, uint16_t uni_default_char)
85 {
86 uint32_t ch;
87
88 printf("GLYPHTABLE:\n");
89
90 for (ch = 0; ch <= 0xFF; ch++)
91 {
92 if (glyph_table[ch] != uni_default_char)
93 {
94 printf("0x%02X 0x%04X\n", (unsigned int)ch, (unsigned int)glyph_table[ch]);
95 }
96 }
97
98 printf("\n");
99 }
100
101 #endif /* _NLS_DEBUG_PRINT */
102
103 int
104 nls_from_txt(const char *txt_file_path, const char *nls_file_path)
105 {
106 NLS_FILE_HEADER header;
107 FILE *file = NULL;
108 uint16_t *mb_table = NULL;
109 uint16_t *wc_table = NULL;
110 uint16_t *glyph_table = NULL;
111 uint16_t number_of_lb_ranges;
112 uint16_t size;
113 int is_dbcs;
114 int res = 0;
115
116 memset(&header, 0, sizeof(header));
117
118 if (!txt_get_header(txt_file_path, &header))
119 goto Cleanup;
120
121 is_dbcs = (header.MaximumCharacterSize == 2) ? 1 : 0;
122
123 mb_table = txt_get_mb_table(txt_file_path, header.UniDefaultChar);
124 if (!mb_table)
125 goto Cleanup;
126
127 wc_table = txt_get_wc_table(txt_file_path, header.DefaultChar, is_dbcs);
128 if (!wc_table)
129 goto Cleanup;
130
131 /* GLYPHTABLE optionally. We do not leave if it is absent */
132 glyph_table = txt_get_glyph_table(txt_file_path, header.UniDefaultChar);
133
134 #ifdef _NLS_DEBUG_PRINT
135 nls_print_header(&header);
136 nls_print_mb_table(mb_table, header.UniDefaultChar);
137 if (glyph_table)
138 nls_print_glyph_table(glyph_table, header.UniDefaultChar);
139 nls_print_wc_table(wc_table, header.DefaultChar, is_dbcs);
140 #endif /* _NLS_DEBUG_PRINT */
141
142 /* Create binary file with write access */
143 file = fopen(nls_file_path, "wb");
144 if (!file)
145 {
146 printf("Unable to create NLS file.\n");
147 goto Cleanup;
148 }
149
150 /* Write NLS file header */
151 if (fwrite(&header, 1, sizeof(header), file) != sizeof(header))
152 {
153 printf("Unable to write NLS file.\n");
154 goto Cleanup;
155 }
156
157 size = (256 * sizeof(uint16_t)) + /* Primary CP to Unicode table */
158 sizeof(uint16_t) + /* optional OEM glyph table size in words */
159 (glyph_table ? (256 * sizeof(uint16_t)) : 0) + /* OEM glyph table size in words * sizeof(uint16_t) */
160 sizeof(uint16_t) + /* Number of DBCS LeadByte ranges */
161 0 + /* offsets of lead byte sub tables */
162 0 + /* LeadByte sub tables */
163 sizeof(uint16_t); /* Unknown flag */
164
165 size /= sizeof(uint16_t);
166
167 if (fwrite(&size, 1, sizeof(size), file) != sizeof(size))
168 {
169 printf("Unable to write NLS file.\n");
170 goto Cleanup;
171 }
172
173 /* Write multibyte table */
174 if (fwrite(mb_table, 1, (256 * sizeof(uint16_t)), file) != (256 * sizeof(uint16_t)))
175 {
176 printf("Unable to write NLS file.\n");
177 goto Cleanup;
178 }
179
180 /* OEM glyph table size in words */
181 size = (glyph_table ? (256 * sizeof(uint16_t)) : 0);
182
183 if (fwrite(&size, 1, sizeof(size), file) != sizeof(size))
184 {
185 printf("Unable to write NLS file.\n");
186 goto Cleanup;
187 }
188
189 if (glyph_table)
190 {
191 /* Write OEM glyph table */
192 if (fwrite(glyph_table, 1, (256 * sizeof(uint16_t)), file) != (256 * sizeof(uint16_t)))
193 {
194 printf("Unable to write NLS file.\n");
195 goto Cleanup;
196 }
197 }
198
199 /* Number of DBCS LeadByte ranges */
200 number_of_lb_ranges = 0;
201 if (fwrite(&number_of_lb_ranges, 1, sizeof(number_of_lb_ranges), file) != sizeof(number_of_lb_ranges))
202 {
203 printf("Unable to write NLS file.\n");
204 goto Cleanup;
205 }
206
207 /* Unknown flag */
208 size = 0;
209 if (fwrite(&size, 1, sizeof(size), file) != sizeof(size))
210 {
211 printf("Unable to write NLS file.\n");
212 goto Cleanup;
213 }
214
215 /* Write wide char table */
216 if (fwrite(wc_table, 1, (65536 * header.MaximumCharacterSize), file) != (65536 * header.MaximumCharacterSize))
217 {
218 printf("Unable to write NLS file.\n");
219 goto Cleanup;
220 }
221
222 res = 1;
223
224 Cleanup:
225 if (file) fclose(file);
226 free(mb_table);
227 free(wc_table);
228 free(glyph_table);
229
230 return res;
231 }