From b0fee17d6e1a463dcd84568e5997663b69488998 Mon Sep 17 00:00:00 2001 From: Marcoen Hirschberg Date: Tue, 6 Dec 2005 13:27:15 +0000 Subject: waiting is over: initial unicode commit git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8169 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/fat.c | 165 +++++++------------------------------------------ 1 file changed, 24 insertions(+), 141 deletions(-) (limited to 'firmware/drivers/fat.c') diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index fd09bff0da..559d00b2b9 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -28,6 +28,7 @@ #include "system.h" #include "timefuncs.h" #include "kernel.h" +#include "rbunicode.h" #define BYTES2INT16(array,pos) \ (array[pos] | (array[pos+1] << 8 )) @@ -115,74 +116,6 @@ #define FAT_BAD_MARK 0x0ffffff7 #define FAT_EOF_MARK 0x0ffffff8 -/* filename charset conversion table */ -static const unsigned char unicode2iso8859_2[] = { - 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6, /* 0x0100 */ - 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x0108 */ - 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0110 */ - 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x0118 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0120 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0128 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0130 */ - 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xa5, 0xb5, 0x00, /* 0x0138 */ - 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x0140 */ - 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0148 */ - 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x0150 */ - 0xd8, 0xf8, 0xa6, 0xb6, 0x00, 0x00, 0xaa, 0xba, /* 0x0158 */ - 0xa9, 0xb9, 0xde, 0xfe, 0xab, 0xbb, 0x00, 0x00, /* 0x0160 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x0168 */ - 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0170 */ - 0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00, /* 0x0178 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0188 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0190 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0198 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01a0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01a8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01b0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01b8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01d0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01d8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01e0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01e8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01f0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01f8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0208 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0210 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0218 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0220 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0228 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0230 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0238 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0248 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0250 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0258 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0260 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0268 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0270 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0278 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0288 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0290 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0298 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02a0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02a8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02b0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02b8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0x02c0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02d0 */ - 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0x02d8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02e0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02e8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02f0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x02f8 */ -}; - struct fsinfo { unsigned long freecount; /* last known free cluster count */ unsigned long nextfree; /* first cluster to start looking for free @@ -1106,10 +1039,11 @@ static int write_long_name(struct fat_file* file, unsigned char* entry; unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR; unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR; - unsigned int i, j=0; unsigned char chksum = 0; - int nameidx=0, namelen = strlen(name); + unsigned int i, j=0; + unsigned int nameidx=0, namelen = utf8length(name); int rc; + unsigned short name_utf16[namelen + 1]; LDEBUGF("write_long_name(file:%lx, first:%d, num:%d, name:%s)\n", file->firstcluster, firstentry, numentries, name); @@ -1132,6 +1066,11 @@ static int write_long_name(struct fat_file* file, nameidx < (namelen - NAME_BYTES_PER_ENTRY); nameidx += NAME_BYTES_PER_ENTRY); + /* we need to convert the name first */ + /* since it is written in reverse order */ + for (i = 0; i <= namelen; i++) + name = utf8decode(name, &name_utf16[i]); + for (i=0; i < numentries; i++) { /* new sector? */ if ( idx >= DIR_ENTRIES_PER_SECTOR ) { @@ -1170,7 +1109,7 @@ static int write_long_name(struct fat_file* file, memset(entry, 0, DIR_ENTRY_SIZE); if ( i+1 < numentries ) { /* longname entry */ - int k, l = nameidx; + unsigned int k, l = nameidx; entry[FATLONG_ORDER] = numentries-i-1; if (i==0) { @@ -1178,22 +1117,22 @@ static int write_long_name(struct fat_file* file, entry[FATLONG_ORDER] |= 0x40; /* pad name with 0xffff */ - for (k=1; k<12; k++) entry[k] = 0xff; + for (k=1; k<11; k++) entry[k] = 0xff; for (k=14; k<26; k++) entry[k] = 0xff; for (k=28; k<32; k++) entry[k] = 0xff; }; /* set name */ for (k=0; k<5 && l <= namelen; k++) { - entry[k*2 + 1] = name[l++]; - entry[k*2 + 2] = 0; + entry[k*2 + 1] = (unsigned char)(name_utf16[l] & 0xff); + entry[k*2 + 2] = (unsigned char)(name_utf16[l++] >> 8); } for (k=0; k<6 && l <= namelen; k++) { - entry[k*2 + 14] = name[l++]; - entry[k*2 + 15] = 0; + entry[k*2 + 14] = (unsigned char)(name_utf16[l] & 0xff); + entry[k*2 + 15] = (unsigned char)(name_utf16[l++] >> 8); } for (k=0; k<2 && l <= namelen; k++) { - entry[k*2 + 28] = name[l++]; - entry[k*2 + 29] = 0; + entry[k*2 + 28] = (unsigned char)(name_utf16[l] & 0xff); + entry[k*2 + 29] = (unsigned char)(name_utf16[l++] >> 8); } entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME; @@ -1291,7 +1230,7 @@ static int add_dir_entry(struct fat_dir* dir, /* one dir entry needed for every 13 bytes of filename, plus one entry for the short name */ - entries_needed = (strlen(name) + (NAME_BYTES_PER_ENTRY-1)) + entries_needed = (utf8length(name) + (NAME_BYTES_PER_ENTRY-1)) / NAME_BYTES_PER_ENTRY + 1; } @@ -2226,58 +2165,6 @@ int fat_opendir(IF_MV2(int volume,) return 0; } -/* convert from unicode to a single-byte charset */ -static void unicode2iso(const unsigned char* unicode, unsigned char* iso, - int count) -{ - int i; - - for (i=0; iname; /* iterate backwards through the dir entries */ for (j=longs-1; j>=0; j--) { unsigned char* ptr = cached_buf; @@ -2370,16 +2258,11 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) index &= SECTOR_SIZE-1; } - /* names are stored in unicode, but we - only grab the low byte (iso8859-1). */ - unicode2iso(ptr + index + 1, entry->name + l, 5); - l+= 5; - unicode2iso(ptr + index + 14, entry->name + l, 6); - l+= 6; - unicode2iso(ptr + index + 28, entry->name + l, 2); - l+= 2; + utf8 = utf16LEdecode(ptr + index + 1, utf8, 5); + utf8 = utf16LEdecode(ptr + index + 14, utf8, 6); + utf8 = utf16LEdecode(ptr + index + 28, utf8, 2); } - entry->name[l]=0; + *utf8 = 0; } done = true; sectoridx = 0; -- cgit v1.2.3