diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/common/structec.c | 179 | ||||
-rw-r--r-- | firmware/export/structec.h | 31 |
3 files changed, 211 insertions, 0 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 15e8cf0603..d4447c22cc 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -53,6 +53,7 @@ common/strncmp.c | |||
53 | common/strncpy.c | 53 | common/strncpy.c |
54 | common/strrchr.c | 54 | common/strrchr.c |
55 | common/strtok.c | 55 | common/strtok.c |
56 | common/structec.c | ||
56 | common/timefuncs.c | 57 | common/timefuncs.c |
57 | common/unicode.c | 58 | common/unicode.c |
58 | 59 | ||
diff --git a/firmware/common/structec.c b/firmware/common/structec.c new file mode 100644 index 0000000000..ec7e1409fd --- /dev/null +++ b/firmware/common/structec.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Miika Pekkarinen | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include <string.h> | ||
21 | #include "structec.h" | ||
22 | #include "system.h" | ||
23 | #include "file.h" | ||
24 | |||
25 | #define MAX_STRUCT_SIZE 128 | ||
26 | |||
27 | /** | ||
28 | * Convert the struct endianess with the instructions provided. | ||
29 | * | ||
30 | * For example: | ||
31 | * struct test { | ||
32 | * long par1; | ||
33 | * short par2; | ||
34 | * short par3; | ||
35 | * }; | ||
36 | * | ||
37 | * structec_convert(instance_of_test, "lss", sizeof(struct test), true); | ||
38 | * | ||
39 | * Structures to be converted must be properly padded. | ||
40 | * | ||
41 | * @param structure Pointer to the struct being converted. | ||
42 | * @param ecinst Instructions how to do the endianess conversion. | ||
43 | * @param count Number of structures to write | ||
44 | * @param enable Conversion is not made unless this is true. | ||
45 | */ | ||
46 | void structec_convert(void *structure, const char *ecinst, | ||
47 | long count, bool enable) | ||
48 | { | ||
49 | const char *ecinst_ring = ecinst; | ||
50 | char *buf = (char *)structure; | ||
51 | |||
52 | if (!enable) | ||
53 | return; | ||
54 | |||
55 | while (count > 0) | ||
56 | { | ||
57 | switch (*ecinst_ring) | ||
58 | { | ||
59 | /* Swap nothing. */ | ||
60 | case 'c': | ||
61 | { | ||
62 | buf++; | ||
63 | break; | ||
64 | } | ||
65 | |||
66 | /* Swap 2 bytes. */ | ||
67 | case 's': | ||
68 | { | ||
69 | unsigned short *data = (unsigned short *)buf; | ||
70 | *data = SWAP_16(*data); | ||
71 | buf += 2; | ||
72 | break; | ||
73 | } | ||
74 | |||
75 | /* Swap 4 bytes. */ | ||
76 | case 'l': | ||
77 | { | ||
78 | unsigned long *data = (unsigned long *)buf; | ||
79 | *data = SWAP_32(*data); | ||
80 | buf += 4; | ||
81 | break; | ||
82 | } | ||
83 | |||
84 | /* This should be never reached. */ | ||
85 | default: | ||
86 | break; | ||
87 | } | ||
88 | |||
89 | ecinst_ring++; | ||
90 | if (*ecinst_ring == '\0') | ||
91 | { | ||
92 | ecinst_ring = ecinst; | ||
93 | count--; | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * Determines the size of a struct in bytes by using endianess correction | ||
100 | * string format. | ||
101 | * | ||
102 | * @param ecinst endianess correction string. | ||
103 | * @return length of the struct in bytes. | ||
104 | */ | ||
105 | size_t structec_size(const char *ecinst) | ||
106 | { | ||
107 | size_t size = 0; | ||
108 | |||
109 | do | ||
110 | { | ||
111 | switch (*ecinst) | ||
112 | { | ||
113 | case 'c': size += 1; break; | ||
114 | case 's': size += 2; break; | ||
115 | case 'l': size += 4; break; | ||
116 | default: break; | ||
117 | } | ||
118 | } while (*(++ecinst) != '\0'); | ||
119 | |||
120 | return size; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * Reads endianess corrected structure members from the given file. | ||
125 | * | ||
126 | * @param fd file descriptor of the file being read. | ||
127 | * @param buf endianess corrected data is placed here. | ||
128 | * @param scount the number of struct members to read. | ||
129 | * @param ecinst endianess correction string. | ||
130 | * @param ec if true, endianess correction is enabled. | ||
131 | */ | ||
132 | ssize_t ecread(int fd, void *buf, size_t scount, const char *ecinst, bool ec) | ||
133 | { | ||
134 | ssize_t ret; | ||
135 | size_t member_size = structec_size(ecinst); | ||
136 | |||
137 | ret = read(fd, buf, scount * member_size); | ||
138 | structec_convert(buf, ecinst, scount, ec); | ||
139 | |||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Writes endianess corrected structure members to the given file. | ||
145 | * | ||
146 | * @param fd file descriptor of the file being written to. | ||
147 | * @param buf endianess corrected data is read here. | ||
148 | * @param scount the number of struct members to write. | ||
149 | * @param ecinst endianess correction string. | ||
150 | * @param ec if true, endianess correction is enabled. | ||
151 | */ | ||
152 | ssize_t ecwrite(int fd, const void *buf, size_t scount, | ||
153 | const char *ecinst, bool ec) | ||
154 | { | ||
155 | char tmp[MAX_STRUCT_SIZE]; | ||
156 | size_t member_size = structec_size(ecinst); | ||
157 | |||
158 | if (ec) | ||
159 | { | ||
160 | const char *p = (const char *)buf; | ||
161 | int maxamount = (int)(MAX_STRUCT_SIZE / member_size); | ||
162 | int i; | ||
163 | |||
164 | for (i = 0; i < (long)scount; i += maxamount) | ||
165 | { | ||
166 | long amount = MIN((int)scount-i, maxamount); | ||
167 | |||
168 | memcpy(tmp, p, member_size * amount); | ||
169 | structec_convert(tmp, ecinst, amount, true); | ||
170 | write(fd, tmp, amount * member_size); | ||
171 | p += member_size * amount; | ||
172 | } | ||
173 | |||
174 | return scount * member_size; | ||
175 | } | ||
176 | |||
177 | return write(fd, buf, scount * member_size); | ||
178 | } | ||
179 | |||
diff --git a/firmware/export/structec.h b/firmware/export/structec.h new file mode 100644 index 0000000000..de406f9f99 --- /dev/null +++ b/firmware/export/structec.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Miika Pekkarinen | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _STRUCTEC_H | ||
21 | #define _STRUCTEC_H | ||
22 | |||
23 | #include <sys/types.h> | ||
24 | #include <stdbool.h> | ||
25 | |||
26 | void structec_convert(void *structure, const char *ecinst, | ||
27 | long count, bool enable); | ||
28 | ssize_t ecread(int fd, void *buf, size_t scount, const char *ecinst, bool ec); | ||
29 | ssize_t ecwrite(int fd, const void *buf, size_t scount, const char *ecinst, bool ec); | ||
30 | #endif | ||
31 | |||