1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 by Miika Pekkarinen
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 #define MAX_STRUCT_SIZE 128
32 * Convert the struct endianess with the instructions provided.
41 * structec_convert(instance_of_test, "lss", sizeof(struct test), true);
43 * Structures to be converted must be properly padded.
45 * @param structure Pointer to the struct being converted.
46 * @param ecinst Instructions how to do the endianess conversion.
47 * @param count Number of structures to write
48 * @param enable Conversion is not made unless this is true.
50 void structec_convert(void *structure
, const char *ecinst
,
51 long count
, bool enable
)
53 const char *ecinst_ring
= ecinst
;
54 char *buf
= (char *)structure
;
73 uint16_t *data
= (uint16_t *)buf
;
74 *data
= swap16(*data
);
82 uint32_t *data
= (uint32_t *)buf
;
83 *data
= swap32(*data
);
88 /* Skip N bytes, idea taken from metadata.c */
91 if (isdigit(*ecinst_ring
))
92 buf
+= (*ecinst_ring
- '0');
99 if (*ecinst_ring
== '\0')
101 ecinst_ring
= ecinst
;
108 * Determines the size of a struct in bytes by using endianess correction
111 * @param ecinst endianess correction string.
112 * @return length of the struct in bytes.
114 static size_t structec_size(const char *ecinst
)
122 case 'c': size
+= 1; break;
123 case 's': size
+= 2; break;
124 case 'l': size
+= 4; break;
126 if (isdigit(*ecinst
))
127 size
+= (*ecinst
- '0');
129 } while (*(++ecinst
) != '\0');
135 * Reads endianess corrected structure members from the given file.
137 * @param fd file descriptor of the file being read.
138 * @param buf endianess corrected data is placed here.
139 * @param scount the number of struct members to read.
140 * @param ecinst endianess correction string.
141 * @param ec if true, endianess correction is enabled.
143 ssize_t
ecread(int fd
, void *buf
, size_t scount
, const char *ecinst
, bool ec
)
146 size_t member_size
= structec_size(ecinst
);
148 ret
= read(fd
, buf
, scount
* member_size
);
149 structec_convert(buf
, ecinst
, scount
, ec
);
155 * Writes endianess corrected structure members to the given file.
157 * @param fd file descriptor of the file being written to.
158 * @param buf endianess corrected data is read here.
159 * @param scount the number of struct members to write.
160 * @param ecinst endianess correction string.
161 * @param ec if true, endianess correction is enabled.
163 ssize_t
ecwrite(int fd
, const void *buf
, size_t scount
,
164 const char *ecinst
, bool ec
)
166 char tmp
[MAX_STRUCT_SIZE
];
167 size_t member_size
= structec_size(ecinst
);
171 const char *p
= (const char *)buf
;
172 int maxamount
= (int)(MAX_STRUCT_SIZE
/ member_size
);
175 for (i
= 0; i
< (long)scount
; i
+= maxamount
)
177 long amount
= MIN((int)scount
-i
, maxamount
);
179 memcpy(tmp
, p
, member_size
* amount
);
180 structec_convert(tmp
, ecinst
, amount
, true);
181 write(fd
, tmp
, amount
* member_size
);
182 p
+= member_size
* amount
;
185 return scount
* member_size
;
188 return write(fd
, buf
, scount
* member_size
);