Project

General

Profile

Download (5 KB) Statistics
| Branch: | Tag: | Revision:
1 5872753e laforge
/* AT91SAM7 USB string descriptor builder 
2
 * (C) 2006 by Harald Welte <laforge@gnumonks.org>
3
 *
4
 *  This program is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by 
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 */
18
19
/* Based on existing utf8_to_utf16le() function,
20
 * Copyright (C) 2003 David Brownell
21
 *
22
 * This program is free software; you can redistribute it and/or modify
23
 * it under the terms of the GNU Lesser General Public License as published
24
 * by the Free Software Foundation; either version 2.1 of the License, or
25
 * (at your option) any later version.
26
 */
27
28
#include <sys/types.h>
29 41423de5 laforge
#include <unistd.h>
30
#include <stdlib.h>
31 373c172a Harald Welte
#include <stdint.h>
32 5872753e laforge
#include <stdio.h>
33
#include <string.h>
34
35 373c172a Harald Welte
static int utf8_to_utf16le(const char *s, uint16_t *cp, unsigned len)
36 5872753e laforge
{
37
	int	count = 0;
38 373c172a Harald Welte
	uint8_t	c;
39
	uint16_t	uchar;
40 5872753e laforge
41
	/* this insists on correct encodings, though not minimal ones.
42
	 * BUT it currently rejects legit 4-byte UTF-8 code points,
43
	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
44
	 */
45 373c172a Harald Welte
	while (len != 0 && (c = (uint8_t) *s++) != 0) {
46 5872753e laforge
		if (c & 0x80) {
47
			// 2-byte sequence:
48
			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
49
			if ((c & 0xe0) == 0xc0) {
50
				uchar = (c & 0x1f) << 6;
51
52 373c172a Harald Welte
				c = (uint8_t) *s++;
53 5872753e laforge
				if ((c & 0xc0) != 0xc0)
54
					goto fail;
55
				c &= 0x3f;
56
				uchar |= c;
57
58
			// 3-byte sequence (most CJKV characters):
59
			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
60
			} else if ((c & 0xf0) == 0xe0) {
61
				uchar = (c & 0x0f) << 12;
62
63 373c172a Harald Welte
				c = (uint8_t) *s++;
64 5872753e laforge
				if ((c & 0xc0) != 0xc0)
65
					goto fail;
66
				c &= 0x3f;
67
				uchar |= c << 6;
68
69 373c172a Harald Welte
				c = (uint8_t) *s++;
70 5872753e laforge
				if ((c & 0xc0) != 0xc0)
71
					goto fail;
72
				c &= 0x3f;
73
				uchar |= c;
74
75
				/* no bogus surrogates */
76
				if (0xd800 <= uchar && uchar <= 0xdfff)
77
					goto fail;
78
79
			// 4-byte sequence (surrogate pairs, currently rare):
80
			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
81
			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
82
			// (uuuuu = wwww + 1)
83
			// FIXME accept the surrogate code points (only)
84
85
			} else
86
				goto fail;
87
		} else
88
			uchar = c;
89
90
		*cp++ = uchar;
91
		count++;
92
		len--;
93
	}
94
	return count;
95
fail:
96
	return -1;
97
}
98
99
#define COLUMNS		6
100 373c172a Harald Welte
static int print_array16(uint16_t *buf, int len)
101 5872753e laforge
{
102
	int i;
103
	for (i = 0; i < len; i++) {
104
		int mod = i % COLUMNS;
105
		char *suffix;
106
		char *prefix;
107
108
		switch (mod) {
109
		case 0:
110
			if (i == 0)
111
				prefix = "\t";
112
			else
113
				prefix= "\t\t\t";
114
			suffix = ", ";
115
			break;
116
		case COLUMNS-1:
117
			prefix = "";
118
			suffix = ",\n";
119
			break;
120
		default:
121
			prefix = "";
122
			suffix = ", ";
123
			break;
124
		}
125
			
126
		printf("%s0x%04x%s", prefix, buf[i], suffix);
127
	}
128
}
129
130
static void print_structhdr(int i, int size)
131
{
132
	printf( "static const struct {\n"
133
		"\tstruct usb_descriptor_header hdr;\n"
134 373c172a Harald Welte
		"\tuint16_t wData[];\n"
135 5872753e laforge
		"} __attribute__((packed)) string%d = {\n"
136
		"\t.hdr = {\n"
137 373c172a Harald Welte
		"\t\t.bLength = sizeof(struct usb_descriptor_header) + %u * sizeof(uint16_t),\n"
138 5872753e laforge
		"\t\t.bDescriptorType = USB_DT_STRING,\n"
139
		"\t},\n"
140
		"\t.wData = {", i, size);
141
}
142
static void print_structftr(void)
143
{
144
	printf("},\n};\n\n");
145
}
146
147
int main(int argc, char **argv)
148
{
149
	char asciibuf[512+1];
150 373c172a Harald Welte
	uint16_t utf16buf[1024+1];
151 5872753e laforge
	int len;
152
	int j, i = 1;
153
154
	printf("#ifndef _USB_STRINGS_H\n#define _USB_STRINGS_H\n\n");
155
	printf("/* THIS FILE IS AUTOGENERATED, DO NOT MODIFY MANUALLY */\n\n");
156
	printf("#include <usb_ch9.h>\n");
157
	printf("#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n\n");
158
159
	print_structhdr(0, 1);
160
	printf("0x0409 /* English */ ");
161
	print_structftr();
162
#if 0	
163
	printf("static const struct usb_string_descriptor string0 = {\n"
164 373c172a Harald Welte
	       "\t.bLength = sizeof(string0) + 1 * sizeof(uint16_t),\n"
165 5872753e laforge
	       "\t.bDescriptorType = USB_DT_STRING,\n"
166
	       "\t.wData[0] = 0x0409, /* English */\n"
167
	       "};\n\n");
168
#endif
169
170
	while (scanf("%512[^\n]\n", asciibuf) != EOF) {
171
		len = strlen(asciibuf);
172
		printf("/* String %u \"%s\" */\n", i, asciibuf);
173
174
		/* FIXME: check return value */
175
		utf8_to_utf16le(asciibuf, utf16buf, len);
176
177
		print_structhdr(i, len);
178
#if 0
179
		printf("static const struct usb_string_descriptor string%d = {\n"
180 373c172a Harald Welte
		       "\t.bLength = sizeof(string%d) + %d * sizeof(uint16_t),\n"
181 5872753e laforge
		       "\t.bDescriptorType = USB_DT_STRING,\n"
182
		       "\t.wData = {", i, i, len);
183
#endif
184
185
		print_array16(utf16buf, len);
186
187
		print_structftr();
188
#if 0
189
		printf("},\n};\n\n");
190
#endif
191
192
		i++;
193
	}
194
195
	printf("static const struct usb_descriptor_header *usb_strings[] = {\n");
196
	for (j = 0; j < i; j++) 
197
		printf("\t(struct usb_descriptor_header *) &string%d,\n", j);
198
	printf("};\n\n");
199
	printf("#endif /* _USB_STRINGS_H */\n");
200 41423de5 laforge
201
	exit(0);
202 5872753e laforge
}
Add picture from clipboard (Maximum size: 48.8 MB)