summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2007-02-13 21:51:18 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2007-02-13 21:51:18 +0000
commit9b9539c8d3349975127ff725c313d3b888f89ab6 (patch)
treea9688e8c7210abe09af38dfd60eafb88aba9b40f
parent24c8da0b56c5961d948bf85d2a1b25dffd6f9c00 (diff)
downloadrockbox-9b9539c8d3349975127ff725c313d3b888f89ab6.tar.gz
rockbox-9b9539c8d3349975127ff725c313d3b888f89ab6.zip
Make database endianess independent.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12297 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/tagcache.c124
-rw-r--r--apps/tagcache.h1
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/common/structec.c179
-rw-r--r--firmware/export/structec.h31
-rw-r--r--tools/Makefile3
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 */
164static const char *tagfile_entry_ec = "ss";
165static const char *index_entry_ec = "llllllllllllllll"; /* (1 + TAG_COUNT) * l */
166static const char *tagcache_header_ec = "lll";
167static const char *master_header_ec = "llll";
168
162static long current_serial; 169static 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
53common/strncpy.c 53common/strncpy.c
54common/strrchr.c 54common/strrchr.c
55common/strtok.c 55common/strtok.c
56common/structec.c
56common/timefuncs.c 57common/timefuncs.c
57common/unicode.c 58common/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 */
46void 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 */
105size_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 */
132ssize_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 */
152ssize_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
26void structec_convert(void *structure, const char *ecinst,
27 long count, bool enable);
28ssize_t ecread(int fd, void *buf, size_t scount, const char *ecinst, bool ec);
29ssize_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
41database: database.c ../apps/tagcache.c ../apps/metadata.c \ 41database: 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 $@