Project

General

Profile

Download (4.89 KB) Statistics
| Branch: | Tag: | Revision:
1
/* 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
#include <unistd.h>
30
#include <stdlib.h>
31
#include <stdio.h>
32
#include <string.h>
33

    
34
static int utf8_to_utf16le(const char *s, u_int16_t *cp, unsigned len)
35
{
36
	int	count = 0;
37
	u_int8_t	c;
38
	u_int16_t	uchar;
39

    
40
	/* this insists on correct encodings, though not minimal ones.
41
	 * BUT it currently rejects legit 4-byte UTF-8 code points,
42
	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
43
	 */
44
	while (len != 0 && (c = (u_int8_t) *s++) != 0) {
45
		if (c & 0x80) {
46
			// 2-byte sequence:
47
			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
48
			if ((c & 0xe0) == 0xc0) {
49
				uchar = (c & 0x1f) << 6;
50

    
51
				c = (u_int8_t) *s++;
52
				if ((c & 0xc0) != 0xc0)
53
					goto fail;
54
				c &= 0x3f;
55
				uchar |= c;
56

    
57
			// 3-byte sequence (most CJKV characters):
58
			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
59
			} else if ((c & 0xf0) == 0xe0) {
60
				uchar = (c & 0x0f) << 12;
61

    
62
				c = (u_int8_t) *s++;
63
				if ((c & 0xc0) != 0xc0)
64
					goto fail;
65
				c &= 0x3f;
66
				uchar |= c << 6;
67

    
68
				c = (u_int8_t) *s++;
69
				if ((c & 0xc0) != 0xc0)
70
					goto fail;
71
				c &= 0x3f;
72
				uchar |= c;
73

    
74
				/* no bogus surrogates */
75
				if (0xd800 <= uchar && uchar <= 0xdfff)
76
					goto fail;
77

    
78
			// 4-byte sequence (surrogate pairs, currently rare):
79
			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
80
			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
81
			// (uuuuu = wwww + 1)
82
			// FIXME accept the surrogate code points (only)
83

    
84
			} else
85
				goto fail;
86
		} else
87
			uchar = c;
88

    
89
		*cp++ = uchar;
90
		count++;
91
		len--;
92
	}
93
	return count;
94
fail:
95
	return -1;
96
}
97

    
98
#define COLUMNS		6
99
static int print_array16(u_int16_t *buf, int len)
100
{
101
	int i;
102
	for (i = 0; i < len; i++) {
103
		int mod = i % COLUMNS;
104
		char *suffix;
105
		char *prefix;
106

    
107
		switch (mod) {
108
		case 0:
109
			if (i == 0)
110
				prefix = "\t";
111
			else
112
				prefix= "\t\t\t";
113
			suffix = ", ";
114
			break;
115
		case COLUMNS-1:
116
			prefix = "";
117
			suffix = ",\n";
118
			break;
119
		default:
120
			prefix = "";
121
			suffix = ", ";
122
			break;
123
		}
124

    
125
		printf("%s0x%04x%s", prefix, buf[i], suffix);
126
	}
127
}
128

    
129
static void print_structhdr(int i, int size)
130
{
131
	printf( "static const struct {\n"
132
		"\tstruct usb_descriptor_header hdr;\n"
133
		"\tuint16_t wData[];\n"
134
		"} __attribute__((packed)) string%d = {\n"
135
		"\t.hdr = {\n"
136
		"\t\t.bLength = USBStringDescriptor_LENGTH(%u),\n"
137
		"\t\t.bDescriptorType = USBGenericDescriptor_STRING,\n"
138
		"\t},\n"
139
		"\t.wData = {", i, size);
140
}
141
static void print_structftr(void)
142
{
143
	printf("},\n};\n\n");
144
}
145

    
146
int main(int argc, char **argv)
147
{
148
	char asciibuf[512+1];
149
	u_int16_t utf16buf[1024+1];
150
	int len;
151
	int j, i = 1;
152

    
153
	printf("#ifndef _USB_STRINGS_H\n#define _USB_STRINGS_H\n\n");
154
	printf("/* THIS FILE IS AUTOGENERATED, DO NOT MODIFY MANUALLY */\n\n");
155

    
156
	printf("#include <stdint.h>\n");
157
	printf("#include <usb/common/core/USBGenericDescriptor.h>\n");
158

    
159
	printf("#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n\n");
160

    
161
	printf("/* All standard descriptors have these 2 fields at the beginning */\n\n");
162
	printf("struct usb_descriptor_header {\n"
163
		"\tuint8_t bLength;\n"
164
		"\tuint8_t bDescriptorType;\n"
165
		"} __attribute__ ((packed));\n\n");
166

    
167
	print_structhdr(0, 1);
168
	printf("0x0409 /* English */ ");
169
	print_structftr();
170

    
171
	while (scanf("%512[^\n]\n", asciibuf) != EOF) {
172
		len = strlen(asciibuf);
173
		printf("/* String %u \"%s\" */\n", i, asciibuf);
174

    
175
		/* FIXME: check return value */
176
		utf8_to_utf16le(asciibuf, utf16buf, len);
177

    
178
		print_structhdr(i, len);
179

    
180
		print_array16(utf16buf, len);
181

    
182
		print_structftr();
183

    
184
		i++;
185
	}
186

    
187
#if 0
188
	printf("static const unsigned char *usb_strings[] = {\n");
189
	for (j = 0; j < i; j++) 
190
		printf("\t(const unsigned char *) &string%d,\n", j);
191
	printf("};\n\n");
192
#else
193
	printf("#define USB_STRINGS_GENERATED\t\t\t\t\\\n");
194
	for (j = 0; j < i; j++) 
195
		printf("\t(const unsigned char *) &string%d,\t\t\\\n", j);
196
	printf("\n");
197
#endif
198

    
199
	printf("#endif /* _USB_STRINGS_H */\n");
200

    
201
	exit(0);
202
}
    (1-1/1)
    Add picture from clipboard (Maximum size: 48.8 MB)