diff options
-rw-r--r-- | apps/tagcache.c | 124 | ||||
-rw-r--r-- | apps/tagcache.h | 1 | ||||
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/common/structec.c | 179 | ||||
-rw-r--r-- | firmware/export/structec.h | 31 | ||||
-rw-r--r-- | tools/Makefile | 3 |
6 files changed, 288 insertions, 51 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index 57bde77cf9..6ef0755809 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include "misc.h" | 69 | #include "misc.h" |
70 | #include "settings.h" | 70 | #include "settings.h" |
71 | #include "dircache.h" | 71 | #include "dircache.h" |
72 | #include "structec.h" | ||
72 | #ifndef __PCTOOL__ | 73 | #ifndef __PCTOOL__ |
73 | #include "atoi.h" | 74 | #include "atoi.h" |
74 | #include "splash.h" | 75 | #include "splash.h" |
@@ -159,6 +160,12 @@ struct master_header { | |||
159 | long serial; /* Increasing counting number */ | 160 | long serial; /* Increasing counting number */ |
160 | }; | 161 | }; |
161 | 162 | ||
163 | /* For the endianess correction */ | ||
164 | static const char *tagfile_entry_ec = "ss"; | ||
165 | static const char *index_entry_ec = "llllllllllllllll"; /* (1 + TAG_COUNT) * l */ | ||
166 | static const char *tagcache_header_ec = "lll"; | ||
167 | static const char *master_header_ec = "llll"; | ||
168 | |||
162 | static long current_serial; | 169 | static long current_serial; |
163 | 170 | ||
164 | #ifdef HAVE_TC_RAMCACHE | 171 | #ifdef HAVE_TC_RAMCACHE |
@@ -296,7 +303,7 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) | |||
296 | } | 303 | } |
297 | 304 | ||
298 | /* Check the header. */ | 305 | /* Check the header. */ |
299 | rc = read(fd, hdr, sizeof(struct tagcache_header)); | 306 | rc = ecread(fd, hdr, 1, tagcache_header_ec, tc_stat.econ); |
300 | if (hdr->magic != TAGCACHE_MAGIC || rc != sizeof(struct tagcache_header)) | 307 | if (hdr->magic != TAGCACHE_MAGIC || rc != sizeof(struct tagcache_header)) |
301 | { | 308 | { |
302 | logf("header error"); | 309 | logf("header error"); |
@@ -399,8 +406,8 @@ static long find_entry_disk(const char *filename) | |||
399 | pos_history[i+1] = pos_history[i]; | 406 | pos_history[i+1] = pos_history[i]; |
400 | pos_history[0] = pos; | 407 | pos_history[0] = pos; |
401 | 408 | ||
402 | if (read(fd, &tfe, sizeof(struct tagfile_entry)) != | 409 | if (ecread(fd, &tfe, 1, tagfile_entry_ec, tc_stat.econ) |
403 | sizeof(struct tagfile_entry)) | 410 | != sizeof(struct tagfile_entry)) |
404 | { | 411 | { |
405 | break ; | 412 | break ; |
406 | } | 413 | } |
@@ -512,8 +519,8 @@ static bool get_index(int masterfd, int idxid, | |||
512 | 519 | ||
513 | lseek(masterfd, idxid * sizeof(struct index_entry) | 520 | lseek(masterfd, idxid * sizeof(struct index_entry) |
514 | + sizeof(struct master_header), SEEK_SET); | 521 | + sizeof(struct master_header), SEEK_SET); |
515 | if (read(masterfd, idx, sizeof(struct index_entry)) != | 522 | if (ecread(masterfd, idx, 1, index_entry_ec, tc_stat.econ) |
516 | sizeof(struct index_entry)) | 523 | != sizeof(struct index_entry)) |
517 | { | 524 | { |
518 | logf("read error #3"); | 525 | logf("read error #3"); |
519 | return false; | 526 | return false; |
@@ -543,8 +550,8 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
543 | 550 | ||
544 | lseek(masterfd, idxid * sizeof(struct index_entry) | 551 | lseek(masterfd, idxid * sizeof(struct index_entry) |
545 | + sizeof(struct master_header), SEEK_SET); | 552 | + sizeof(struct master_header), SEEK_SET); |
546 | if (write(masterfd, idx, sizeof(struct index_entry)) != | 553 | if (ecwrite(masterfd, idx, 1, index_entry_ec, tc_stat.econ) |
547 | sizeof(struct index_entry)) | 554 | != sizeof(struct index_entry)) |
548 | { | 555 | { |
549 | logf("write error #3"); | 556 | logf("write error #3"); |
550 | logf("idxid: %d", idxid); | 557 | logf("idxid: %d", idxid); |
@@ -619,8 +626,8 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, | |||
619 | return false; | 626 | return false; |
620 | 627 | ||
621 | lseek(tcs->idxfd[tag], seek, SEEK_SET); | 628 | lseek(tcs->idxfd[tag], seek, SEEK_SET); |
622 | if (read(tcs->idxfd[tag], &tfe, sizeof(struct tagfile_entry)) != | 629 | if (ecread(tcs->idxfd[tag], &tfe, 1, tagfile_entry_ec, tc_stat.econ) |
623 | sizeof(struct tagfile_entry)) | 630 | != sizeof(struct tagfile_entry)) |
624 | { | 631 | { |
625 | logf("read error #5"); | 632 | logf("read error #5"); |
626 | return false; | 633 | return false; |
@@ -831,7 +838,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
831 | { | 838 | { |
832 | int fd = tcs->idxfd[clause[i]->tag]; | 839 | int fd = tcs->idxfd[clause[i]->tag]; |
833 | lseek(fd, seek, SEEK_SET); | 840 | lseek(fd, seek, SEEK_SET); |
834 | read(fd, &tfe, sizeof(struct tagfile_entry)); | 841 | ecread(fd, &tfe, 1, tagfile_entry_ec, tc_stat.econ); |
835 | if (tfe.tag_length >= (int)sizeof(str)) | 842 | if (tfe.tag_length >= (int)sizeof(str)) |
836 | { | 843 | { |
837 | logf("Too long tag read!"); | 844 | logf("Too long tag read!"); |
@@ -952,8 +959,8 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
952 | lseek(tcs->masterfd, tcs->seek_pos * sizeof(struct index_entry) + | 959 | lseek(tcs->masterfd, tcs->seek_pos * sizeof(struct index_entry) + |
953 | sizeof(struct master_header), SEEK_SET); | 960 | sizeof(struct master_header), SEEK_SET); |
954 | 961 | ||
955 | while (read(tcs->masterfd, &entry, sizeof(struct index_entry)) == | 962 | while (ecread(tcs->masterfd, &entry, 1, index_entry_ec, tc_stat.econ) |
956 | sizeof(struct index_entry)) | 963 | == sizeof(struct index_entry)) |
957 | { | 964 | { |
958 | /* Check if entry has been deleted. */ | 965 | /* Check if entry has been deleted. */ |
959 | if (entry.flag & FLAG_DELETED) | 966 | if (entry.flag & FLAG_DELETED) |
@@ -1001,6 +1008,7 @@ static void remove_files(void) | |||
1001 | 1008 | ||
1002 | tc_stat.ready = false; | 1009 | tc_stat.ready = false; |
1003 | tc_stat.ramcache = false; | 1010 | tc_stat.ramcache = false; |
1011 | tc_stat.econ = false; | ||
1004 | remove(TAGCACHE_FILE_MASTER); | 1012 | remove(TAGCACHE_FILE_MASTER); |
1005 | for (i = 0; i < TAG_COUNT; i++) | 1013 | for (i = 0; i < TAG_COUNT; i++) |
1006 | { | 1014 | { |
@@ -1026,8 +1034,20 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
1026 | return fd; | 1034 | return fd; |
1027 | } | 1035 | } |
1028 | 1036 | ||
1037 | tc_stat.econ = false; | ||
1038 | |||
1029 | /* Check the header. */ | 1039 | /* Check the header. */ |
1030 | rc = read(fd, hdr, sizeof(struct master_header)); | 1040 | rc = read(fd, hdr, sizeof(struct master_header)); |
1041 | if (hdr->tch.magic == TAGCACHE_MAGIC && rc == sizeof(struct master_header)) | ||
1042 | { | ||
1043 | /* Success. */ | ||
1044 | return fd; | ||
1045 | } | ||
1046 | |||
1047 | /* Trying to read again, this time with endianess correction enabled. */ | ||
1048 | lseek(fd, 0, SEEK_SET); | ||
1049 | |||
1050 | rc = ecread(fd, hdr, 1, master_header_ec, true); | ||
1031 | if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) | 1051 | if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) |
1032 | { | 1052 | { |
1033 | logf("header error"); | 1053 | logf("header error"); |
@@ -1035,6 +1055,8 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
1035 | close(fd); | 1055 | close(fd); |
1036 | return -2; | 1056 | return -2; |
1037 | } | 1057 | } |
1058 | |||
1059 | tc_stat.econ = true; | ||
1038 | 1060 | ||
1039 | return fd; | 1061 | return fd; |
1040 | } | 1062 | } |
@@ -1260,8 +1282,8 @@ static bool get_next(struct tagcache_search *tcs) | |||
1260 | return false; | 1282 | return false; |
1261 | 1283 | ||
1262 | tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR); | 1284 | tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR); |
1263 | if (read(tcs->idxfd[tcs->type], &entry, sizeof(struct tagfile_entry)) != | 1285 | if (ecread(tcs->idxfd[tcs->type], &entry, 1, |
1264 | sizeof(struct tagfile_entry)) | 1286 | tagfile_entry_ec, tc_stat.econ) != sizeof(struct tagfile_entry)) |
1265 | { | 1287 | { |
1266 | /* End of data. */ | 1288 | /* End of data. */ |
1267 | tcs->valid = false; | 1289 | tcs->valid = false; |
@@ -1739,7 +1761,7 @@ static int tempbuf_sort(int fd) | |||
1739 | } | 1761 | } |
1740 | #endif | 1762 | #endif |
1741 | 1763 | ||
1742 | if (write(fd, &fe, sizeof(struct tagfile_entry)) != | 1764 | if (ecwrite(fd, &fe, 1, tagfile_entry_ec, tc_stat.econ) != |
1743 | sizeof(struct tagfile_entry)) | 1765 | sizeof(struct tagfile_entry)) |
1744 | { | 1766 | { |
1745 | logf("tempbuf_sort: write error #1"); | 1767 | logf("tempbuf_sort: write error #1"); |
@@ -1833,8 +1855,8 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
1833 | { | 1855 | { |
1834 | int loc = lseek(masterfd, 0, SEEK_CUR); | 1856 | int loc = lseek(masterfd, 0, SEEK_CUR); |
1835 | 1857 | ||
1836 | if (read(masterfd, &idx, sizeof(struct index_entry)) != | 1858 | if (ecread(masterfd, &idx, 1, index_entry_ec, tc_stat.econ) |
1837 | sizeof(struct index_entry)) | 1859 | != sizeof(struct index_entry)) |
1838 | { | 1860 | { |
1839 | logf("read fail #2"); | 1861 | logf("read fail #2"); |
1840 | close(masterfd); | 1862 | close(masterfd); |
@@ -1852,8 +1874,8 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
1852 | 1874 | ||
1853 | /* Write back the updated index. */ | 1875 | /* Write back the updated index. */ |
1854 | lseek(masterfd, loc, SEEK_SET); | 1876 | lseek(masterfd, loc, SEEK_SET); |
1855 | if (write(masterfd, &idx, sizeof(struct index_entry)) != | 1877 | if (ecwrite(masterfd, &idx, 1, index_entry_ec, tc_stat.econ) |
1856 | sizeof(struct index_entry)) | 1878 | != sizeof(struct index_entry)) |
1857 | { | 1879 | { |
1858 | logf("write fail"); | 1880 | logf("write fail"); |
1859 | close(masterfd); | 1881 | close(masterfd); |
@@ -1977,7 +1999,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
1977 | int loc = lseek(fd, 0, SEEK_CUR); | 1999 | int loc = lseek(fd, 0, SEEK_CUR); |
1978 | bool ret; | 2000 | bool ret; |
1979 | 2001 | ||
1980 | if (read(fd, &entry, sizeof(struct tagfile_entry)) | 2002 | if (ecread(fd, &entry, 1, tagfile_entry_ec, tc_stat.econ) |
1981 | != sizeof(struct tagfile_entry)) | 2003 | != sizeof(struct tagfile_entry)) |
1982 | { | 2004 | { |
1983 | logf("read error #7"); | 2005 | logf("read error #7"); |
@@ -2041,8 +2063,8 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2041 | tch.entry_count = 0; | 2063 | tch.entry_count = 0; |
2042 | tch.datasize = 0; | 2064 | tch.datasize = 0; |
2043 | 2065 | ||
2044 | if (write(fd, &tch, sizeof(struct tagcache_header)) != | 2066 | if (ecwrite(fd, &tch, 1, tagcache_header_ec, tc_stat.econ) |
2045 | sizeof(struct tagcache_header)) | 2067 | != sizeof(struct tagcache_header)) |
2046 | { | 2068 | { |
2047 | logf("header write failed"); | 2069 | logf("header write failed"); |
2048 | close(fd); | 2070 | close(fd); |
@@ -2071,7 +2093,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2071 | tcmh.tch = *h; | 2093 | tcmh.tch = *h; |
2072 | tcmh.tch.entry_count = 0; | 2094 | tcmh.tch.entry_count = 0; |
2073 | tcmh.tch.datasize = 0; | 2095 | tcmh.tch.datasize = 0; |
2074 | write(masterfd, &tcmh, sizeof(struct master_header)); | 2096 | ecwrite(masterfd, &tcmh, 1, master_header_ec, tc_stat.econ); |
2075 | init = true; | 2097 | init = true; |
2076 | masterfd_pos = lseek(masterfd, 0, SEEK_CUR); | 2098 | masterfd_pos = lseek(masterfd, 0, SEEK_CUR); |
2077 | current_serial = 0; | 2099 | current_serial = 0; |
@@ -2084,7 +2106,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2084 | */ | 2106 | */ |
2085 | init = false; | 2107 | init = false; |
2086 | 2108 | ||
2087 | if (read(masterfd, &tcmh, sizeof(struct master_header)) != | 2109 | if (ecread(masterfd, &tcmh, 1, master_header_ec, tc_stat.econ) != |
2088 | sizeof(struct master_header) || tcmh.tch.magic != TAGCACHE_MAGIC) | 2110 | sizeof(struct master_header) || tcmh.tch.magic != TAGCACHE_MAGIC) |
2089 | { | 2111 | { |
2090 | logf("header error"); | 2112 | logf("header error"); |
@@ -2125,7 +2147,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2125 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != | 2147 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != |
2126 | sizeof(struct temp_file_entry)) | 2148 | sizeof(struct temp_file_entry)) |
2127 | { | 2149 | { |
2128 | logf("read fail #1"); | 2150 | logf("read fail #3"); |
2129 | error = true; | 2151 | error = true; |
2130 | goto error_exit; | 2152 | goto error_exit; |
2131 | } | 2153 | } |
@@ -2142,7 +2164,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2142 | if (read(tmpfd, buf, entry.tag_length[index_type]) != | 2164 | if (read(tmpfd, buf, entry.tag_length[index_type]) != |
2143 | entry.tag_length[index_type]) | 2165 | entry.tag_length[index_type]) |
2144 | { | 2166 | { |
2145 | logf("read fail #3"); | 2167 | logf("read fail #4"); |
2146 | error = true; | 2168 | error = true; |
2147 | goto error_exit; | 2169 | goto error_exit; |
2148 | } | 2170 | } |
@@ -2184,10 +2206,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2184 | 2206 | ||
2185 | idxbuf_pos = MIN(tcmh.tch.entry_count - i, IDX_BUF_DEPTH); | 2207 | idxbuf_pos = MIN(tcmh.tch.entry_count - i, IDX_BUF_DEPTH); |
2186 | 2208 | ||
2187 | if (read(masterfd, idxbuf, sizeof(struct index_entry)*idxbuf_pos) != | 2209 | if (ecread(masterfd, idxbuf, idxbuf_pos, index_entry_ec, tc_stat.econ) |
2188 | (int)sizeof(struct index_entry)*idxbuf_pos) | 2210 | != (int)sizeof(struct index_entry)*idxbuf_pos) |
2189 | { | 2211 | { |
2190 | logf("read fail #2"); | 2212 | logf("read fail #5"); |
2191 | error = true; | 2213 | error = true; |
2192 | goto error_exit ; | 2214 | goto error_exit ; |
2193 | } | 2215 | } |
@@ -2217,7 +2239,8 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2217 | } | 2239 | } |
2218 | 2240 | ||
2219 | /* Write back the updated index. */ | 2241 | /* Write back the updated index. */ |
2220 | if (write(masterfd, idxbuf, sizeof(struct index_entry)*idxbuf_pos) != | 2242 | if (ecwrite(masterfd, idxbuf, idxbuf_pos, |
2243 | index_entry_ec, tc_stat.econ) != | ||
2221 | (int)sizeof(struct index_entry)*idxbuf_pos) | 2244 | (int)sizeof(struct index_entry)*idxbuf_pos) |
2222 | { | 2245 | { |
2223 | logf("write fail"); | 2246 | logf("write fail"); |
@@ -2249,10 +2272,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2249 | { | 2272 | { |
2250 | int loc = lseek(masterfd, 0, SEEK_CUR); | 2273 | int loc = lseek(masterfd, 0, SEEK_CUR); |
2251 | 2274 | ||
2252 | if (read(masterfd, idxbuf, sizeof(struct index_entry)*idxbuf_pos) != | 2275 | if (ecread(masterfd, idxbuf, idxbuf_pos, index_entry_ec, tc_stat.econ) |
2253 | (int)sizeof(struct index_entry)*idxbuf_pos) | 2276 | != (int)sizeof(struct index_entry)*idxbuf_pos) |
2254 | { | 2277 | { |
2255 | logf("read fail #2"); | 2278 | logf("read fail #6"); |
2256 | error = true; | 2279 | error = true; |
2257 | break ; | 2280 | break ; |
2258 | } | 2281 | } |
@@ -2270,7 +2293,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2270 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != | 2293 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != |
2271 | sizeof(struct temp_file_entry)) | 2294 | sizeof(struct temp_file_entry)) |
2272 | { | 2295 | { |
2273 | logf("read fail #1"); | 2296 | logf("read fail #7"); |
2274 | error = true; | 2297 | error = true; |
2275 | break ; | 2298 | break ; |
2276 | } | 2299 | } |
@@ -2289,7 +2312,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2289 | if (read(tmpfd, buf, entry.tag_length[index_type]) != | 2312 | if (read(tmpfd, buf, entry.tag_length[index_type]) != |
2290 | entry.tag_length[index_type]) | 2313 | entry.tag_length[index_type]) |
2291 | { | 2314 | { |
2292 | logf("read fail #3"); | 2315 | logf("read fail #8"); |
2293 | logf("offset=0x%02x", entry.tag_offset[index_type]); | 2316 | logf("offset=0x%02x", entry.tag_offset[index_type]); |
2294 | logf("length=0x%02x", entry.tag_length[index_type]); | 2317 | logf("length=0x%02x", entry.tag_length[index_type]); |
2295 | error = true; | 2318 | error = true; |
@@ -2300,7 +2323,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2300 | idxbuf[j].tag_seek[index_type] = lseek(fd, 0, SEEK_CUR); | 2323 | idxbuf[j].tag_seek[index_type] = lseek(fd, 0, SEEK_CUR); |
2301 | fe.tag_length = entry.tag_length[index_type]; | 2324 | fe.tag_length = entry.tag_length[index_type]; |
2302 | fe.idx_id = tcmh.tch.entry_count + i + j; | 2325 | fe.idx_id = tcmh.tch.entry_count + i + j; |
2303 | write(fd, &fe, sizeof(struct tagfile_entry)); | 2326 | ecwrite(fd, &fe, 1, tagfile_entry_ec, tc_stat.econ); |
2304 | write(fd, buf, fe.tag_length); | 2327 | write(fd, buf, fe.tag_length); |
2305 | tempbufidx++; | 2328 | tempbufidx++; |
2306 | 2329 | ||
@@ -2322,7 +2345,8 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2322 | } | 2345 | } |
2323 | 2346 | ||
2324 | /* Write index. */ | 2347 | /* Write index. */ |
2325 | if (write(masterfd, idxbuf, sizeof(struct index_entry)*idxbuf_pos) != | 2348 | if (ecwrite(masterfd, idxbuf, idxbuf_pos, |
2349 | index_entry_ec, tc_stat.econ) != | ||
2326 | (int)sizeof(struct index_entry)*idxbuf_pos) | 2350 | (int)sizeof(struct index_entry)*idxbuf_pos) |
2327 | { | 2351 | { |
2328 | logf("tagcache: write fail #4"); | 2352 | logf("tagcache: write fail #4"); |
@@ -2339,7 +2363,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2339 | tch.entry_count = tempbufidx; | 2363 | tch.entry_count = tempbufidx; |
2340 | tch.datasize = lseek(fd, 0, SEEK_END) - sizeof(struct tagcache_header); | 2364 | tch.datasize = lseek(fd, 0, SEEK_END) - sizeof(struct tagcache_header); |
2341 | lseek(fd, 0, SEEK_SET); | 2365 | lseek(fd, 0, SEEK_SET); |
2342 | write(fd, &tch, sizeof(struct tagcache_header)); | 2366 | ecwrite(fd, &tch, 1, tagcache_header_ec, tc_stat.econ); |
2343 | 2367 | ||
2344 | if (index_type != tag_filename) | 2368 | if (index_type != tag_filename) |
2345 | h->datasize += tch.datasize; | 2369 | h->datasize += tch.datasize; |
@@ -2495,7 +2519,7 @@ static bool commit(void) | |||
2495 | + tch.datasize; | 2519 | + tch.datasize; |
2496 | 2520 | ||
2497 | lseek(masterfd, 0, SEEK_SET); | 2521 | lseek(masterfd, 0, SEEK_SET); |
2498 | write(masterfd, &tcmh, sizeof(struct master_header)); | 2522 | ecwrite(masterfd, &tcmh, 1, master_header_ec, tc_stat.econ); |
2499 | close(masterfd); | 2523 | close(masterfd); |
2500 | 2524 | ||
2501 | logf("tagcache committed"); | 2525 | logf("tagcache committed"); |
@@ -2570,7 +2594,7 @@ static bool update_current_serial(long serial) | |||
2570 | 2594 | ||
2571 | /* Write it back */ | 2595 | /* Write it back */ |
2572 | lseek(fd, 0, SEEK_SET); | 2596 | lseek(fd, 0, SEEK_SET); |
2573 | write(fd, &myhdr, sizeof(struct master_header)); | 2597 | ecwrite(fd, &myhdr, 1, master_header_ec, tc_stat.econ); |
2574 | close(fd); | 2598 | close(fd); |
2575 | 2599 | ||
2576 | return true; | 2600 | return true; |
@@ -2872,14 +2896,14 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
2872 | else | 2896 | else |
2873 | { | 2897 | { |
2874 | lseek(tcs->masterfd, 0, SEEK_SET); | 2898 | lseek(tcs->masterfd, 0, SEEK_SET); |
2875 | read(tcs->masterfd, &myhdr, sizeof(struct master_header)); | 2899 | ecread(tcs->masterfd, &myhdr, 1, master_header_ec, tc_stat.econ); |
2876 | } | 2900 | } |
2877 | 2901 | ||
2878 | write(clfd, "## Changelog version 1\n", 23); | 2902 | write(clfd, "## Changelog version 1\n", 23); |
2879 | 2903 | ||
2880 | for (i = 0; i < myhdr.tch.entry_count; i++) | 2904 | for (i = 0; i < myhdr.tch.entry_count; i++) |
2881 | { | 2905 | { |
2882 | if (read(tcs->masterfd, &idx, sizeof(struct index_entry)) | 2906 | if (ecread(tcs->masterfd, &idx, 1, index_entry_ec, tc_stat.econ) |
2883 | != sizeof(struct index_entry)) | 2907 | != sizeof(struct index_entry)) |
2884 | { | 2908 | { |
2885 | logf("read error #9"); | 2909 | logf("read error #9"); |
@@ -2943,7 +2967,7 @@ static bool delete_entry(long idx_id) | |||
2943 | return false; | 2967 | return false; |
2944 | 2968 | ||
2945 | lseek(fd, idx_id * sizeof(struct index_entry), SEEK_CUR); | 2969 | lseek(fd, idx_id * sizeof(struct index_entry), SEEK_CUR); |
2946 | if (read(fd, &myidx, sizeof(struct index_entry)) | 2970 | if (ecread(fd, &myidx, 1, index_entry_ec, tc_stat.econ) |
2947 | != sizeof(struct index_entry)) | 2971 | != sizeof(struct index_entry)) |
2948 | { | 2972 | { |
2949 | logf("delete_entry(): read error"); | 2973 | logf("delete_entry(): read error"); |
@@ -2953,7 +2977,7 @@ static bool delete_entry(long idx_id) | |||
2953 | 2977 | ||
2954 | myidx.flag |= FLAG_DELETED; | 2978 | myidx.flag |= FLAG_DELETED; |
2955 | lseek(fd, -sizeof(struct index_entry), SEEK_CUR); | 2979 | lseek(fd, -sizeof(struct index_entry), SEEK_CUR); |
2956 | if (write(fd, &myidx, sizeof(struct index_entry)) | 2980 | if (ecwrite(fd, &myidx, 1, index_entry_ec, tc_stat.econ) |
2957 | != sizeof(struct index_entry)) | 2981 | != sizeof(struct index_entry)) |
2958 | { | 2982 | { |
2959 | logf("delete_entry(): write_error"); | 2983 | logf("delete_entry(): write_error"); |
@@ -2968,7 +2992,7 @@ static bool delete_entry(long idx_id) | |||
2968 | lseek(fd, sizeof(struct master_header), SEEK_SET); | 2992 | lseek(fd, sizeof(struct master_header), SEEK_SET); |
2969 | for (i = 0; i < myhdr.tch.entry_count; i++) | 2993 | for (i = 0; i < myhdr.tch.entry_count; i++) |
2970 | { | 2994 | { |
2971 | if (read(fd, &idx, sizeof(struct index_entry)) | 2995 | if (ecread(fd, &idx, 1, index_entry_ec, tc_stat.econ) |
2972 | != sizeof(struct index_entry)) | 2996 | != sizeof(struct index_entry)) |
2973 | { | 2997 | { |
2974 | logf("delete_entry(): read error #2"); | 2998 | logf("delete_entry(): read error #2"); |
@@ -3190,7 +3214,7 @@ static bool load_tagcache(void) | |||
3190 | return false; | 3214 | return false; |
3191 | } | 3215 | } |
3192 | 3216 | ||
3193 | if (read(fd, &hdr->h, sizeof(struct master_header)) | 3217 | if (ecread(fd, &hdr->h, 1, master_header_ec, tc_stat.econ) |
3194 | != sizeof(struct master_header) | 3218 | != sizeof(struct master_header) |
3195 | || hdr->h.tch.magic != TAGCACHE_MAGIC) | 3219 | || hdr->h.tch.magic != TAGCACHE_MAGIC) |
3196 | { | 3220 | { |
@@ -3203,7 +3227,7 @@ static bool load_tagcache(void) | |||
3203 | /* Load the master index table. */ | 3227 | /* Load the master index table. */ |
3204 | for (i = 0; i < hdr->h.tch.entry_count; i++) | 3228 | for (i = 0; i < hdr->h.tch.entry_count; i++) |
3205 | { | 3229 | { |
3206 | rc = read(fd, idx, sizeof(struct index_entry)); | 3230 | rc = ecread(fd, idx, 1, index_entry_ec, tc_stat.econ); |
3207 | if (rc != sizeof(struct index_entry)) | 3231 | if (rc != sizeof(struct index_entry)) |
3208 | { | 3232 | { |
3209 | logf("read error #10"); | 3233 | logf("read error #10"); |
@@ -3262,7 +3286,7 @@ static bool load_tagcache(void) | |||
3262 | 3286 | ||
3263 | fe = (struct tagfile_entry *)p; | 3287 | fe = (struct tagfile_entry *)p; |
3264 | pos = lseek(fd, 0, SEEK_CUR); | 3288 | pos = lseek(fd, 0, SEEK_CUR); |
3265 | rc = read(fd, fe, sizeof(struct tagfile_entry)); | 3289 | rc = ecread(fd, fe, 1, tagfile_entry_ec, tc_stat.econ); |
3266 | if (rc != sizeof(struct tagfile_entry)) | 3290 | if (rc != sizeof(struct tagfile_entry)) |
3267 | { | 3291 | { |
3268 | /* End of lookup table. */ | 3292 | /* End of lookup table. */ |
@@ -3413,7 +3437,7 @@ static bool check_deleted_files(void) | |||
3413 | } | 3437 | } |
3414 | 3438 | ||
3415 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); | 3439 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); |
3416 | while (read(fd, &tfe, sizeof(struct tagfile_entry)) | 3440 | while (ecread(fd, &tfe, 1, tagfile_entry_ec, tc_stat.econ) |
3417 | == sizeof(struct tagfile_entry) | 3441 | == sizeof(struct tagfile_entry) |
3418 | #ifndef __PCTOOL__ | 3442 | #ifndef __PCTOOL__ |
3419 | && !check_event_queue() | 3443 | && !check_event_queue() |
@@ -3443,7 +3467,7 @@ static bool check_deleted_files(void) | |||
3443 | if (testfd < 0) | 3467 | if (testfd < 0) |
3444 | { | 3468 | { |
3445 | logf("Entry no longer valid."); | 3469 | logf("Entry no longer valid."); |
3446 | logf("-> %s", buf); | 3470 | logf("-> %s / %d", buf, tfe.tag_length); |
3447 | delete_entry(tfe.idx_id); | 3471 | delete_entry(tfe.idx_id); |
3448 | } | 3472 | } |
3449 | close(testfd); | 3473 | close(testfd); |
diff --git a/apps/tagcache.h b/apps/tagcache.h index 503da8c1eb..5140aa1989 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h | |||
@@ -88,6 +88,7 @@ struct tagcache_stat { | |||
88 | bool ready; /* Is tagcache ready to be used? */ | 88 | bool ready; /* Is tagcache ready to be used? */ |
89 | bool ramcache; /* Is tagcache loaded in ram? */ | 89 | bool ramcache; /* Is tagcache loaded in ram? */ |
90 | bool commit_delayed; /* Has commit been delayed until next reboot? */ | 90 | bool commit_delayed; /* Has commit been delayed until next reboot? */ |
91 | bool econ; /* Is endianess correction enabled? */ | ||
91 | int commit_step; /* Commit progress */ | 92 | int commit_step; /* Commit progress */ |
92 | int ramcache_allocated; /* Has ram been allocated for ramcache? */ | 93 | int ramcache_allocated; /* Has ram been allocated for ramcache? */ |
93 | int ramcache_used; /* How much ram has been really used */ | 94 | int ramcache_used; /* How much ram has been really used */ |
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 | |||
diff --git a/tools/Makefile b/tools/Makefile index e477f7fc43..d957f75327 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -41,7 +41,8 @@ ipod_fw: ipod_fw.c | |||
41 | database: database.c ../apps/tagcache.c ../apps/metadata.c \ | 41 | database: database.c ../apps/tagcache.c ../apps/metadata.c \ |
42 | ../firmware/id3.c ../firmware/common/unicode.c \ | 42 | ../firmware/id3.c ../firmware/common/unicode.c \ |
43 | ../firmware/common/crc32.c ../uisimulator/common/io.c \ | 43 | ../firmware/common/crc32.c ../uisimulator/common/io.c \ |
44 | ../firmware/mp3data.c ../firmware/logf.c ../firmware/replaygain.c | 44 | ../firmware/mp3data.c ../firmware/logf.c ../firmware/replaygain.c \ |
45 | ../firmware/common/structec.c | ||
45 | $(SILENT)$(CC) -g -I../firmware/export -iquote ../firmware/include \ | 46 | $(SILENT)$(CC) -g -I../firmware/export -iquote ../firmware/include \ |
46 | -D__PCTOOL__ -DHAVE_TAGCACHE -DROCKBOX_HAS_LOGF -DSIMULATOR \ | 47 | -D__PCTOOL__ -DHAVE_TAGCACHE -DROCKBOX_HAS_LOGF -DSIMULATOR \ |
47 | -DCONFIG_CODEC=1 -ldl -I../apps $+ -o $@ | 48 | -DCONFIG_CODEC=1 -ldl -I../apps $+ -o $@ |