Update FatFs to R0.13a

This commit is contained in:
d0k3 2018-03-14 23:21:54 +01:00
parent 07e419f514
commit 6a0391bb86
7 changed files with 988 additions and 591 deletions

View File

@ -300,3 +300,15 @@ R0.13 (May 21, 2017)
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c) Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c) Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
R0.13a (October 14, 2017)
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)

View File

@ -1,4 +1,4 @@
FatFs Module Source Files R0.13 FatFs Module Source Files R0.13a
FILES FILES

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------/ /*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.13 / / FatFs - Generic FAT Filesystem module R0.13a /
/-----------------------------------------------------------------------------/ /-----------------------------------------------------------------------------/
/ /
/ Copyright (C) 2017, ChaN, all right reserved. / Copyright (C) 2017, ChaN, all right reserved.
@ -20,7 +20,7 @@
#ifndef FF_DEFINED #ifndef FF_DEFINED
#define FF_DEFINED 87030 /* Revision ID */ #define FF_DEFINED 89352 /* Revision ID */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -49,20 +49,25 @@ extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
/* Type of path name strings on FatFs API */ /* Type of path name strings on FatFs API */
#if FF_LFN_UNICODE && FF_USE_LFN /* Unicode (UTF-16) string */
#ifndef _INC_TCHAR #ifndef _INC_TCHAR
#define _INC_TCHAR
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
typedef WCHAR TCHAR; typedef WCHAR TCHAR;
#define _T(x) L ## x #define _T(x) L ## x
#define _TEXT(x) L ## x #define _TEXT(x) L ## x
#define _INC_TCHAR #elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
#endif typedef char TCHAR;
#else /* ANSI/OEM string */ #define _T(x) u8 ## x
#ifndef _INC_TCHAR #define _TEXT(x) u8 ## x
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 2)
#error Wrong FF_LFN_UNICODE setting
#else /* ANSI/OEM code in SBCS/DBCS */
typedef char TCHAR; typedef char TCHAR;
#define _T(x) x #define _T(x) x
#define _TEXT(x) x #define _TEXT(x) x
#define _INC_TCHAR
#endif #endif
#endif #endif
@ -70,9 +75,6 @@ typedef char TCHAR;
/* Type of file size variables */ /* Type of file size variables */
#if FF_FS_EXFAT #if FF_FS_EXFAT
#if !FF_USE_LFN
#error LFN must be enabled when enable exFAT
#endif
typedef QWORD FSIZE_t; typedef QWORD FSIZE_t;
#else #else
typedef DWORD FSIZE_t; typedef DWORD FSIZE_t;
@ -200,10 +202,10 @@ typedef struct {
WORD ftime; /* Modified time */ WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */ BYTE fattrib; /* File attribute */
#if FF_USE_LFN #if FF_USE_LFN
TCHAR altname[13]; /* Altenative file name */ TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
TCHAR fname[FF_MAX_LFN + 1]; /* Primary file name */ TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else #else
TCHAR fname[13]; /* File name */ TCHAR fname[12 + 1]; /* File name */
#endif #endif
} FILINFO; } FILINFO;
@ -299,10 +301,10 @@ DWORD get_fattime (void);
#endif #endif
/* LFN support functions */ /* LFN support functions */
#if FF_USE_LFN /* Code conversion (defined in unicode.c) */ #if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem (WCHAR uni, WORD cp); /* Unicode to OEM code conversion */ WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
WCHAR ff_wtoupper (WCHAR uni); /* Unicode upper-case conversion */ DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
#endif #endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */ #if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */ void* ff_memalloc (UINT msize); /* Allocate memory block */

View File

@ -2,7 +2,7 @@
/ FatFs - Configuration file / FatFs - Configuration file
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define FFCONF_DEF 87030 /* Revision ID */ #define FFCONF_DEF 89352 /* Revision ID */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Function Configurations / Function Configurations
@ -18,7 +18,7 @@
#define FF_FS_MINIMIZE 0 #define FF_FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions. /* This option defines minimization level to remove some basic API functions.
/ /
/ 0: All basic functions are enabled. / 0: Basic functions are fully enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed. / are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
@ -106,32 +106,46 @@
/ 2: Enable LFN with dynamic working buffer on the STACK. / 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP. / 3: Enable LFN with dynamic working buffer on the HEAP.
/ /
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added / To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
/ to the project. The working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and / requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional 608 bytes at exFAT enabled. FF_MAX_LFN can be in range from 12 to 255. / additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ It should be set 255 to support full featured LFN operations. / The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
/ specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap / When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and / memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */ / ff_memfree() in ffsystem.c, need to be added to the project. */
#define FF_LFN_UNICODE 0 #define FF_LFN_UNICODE 0
/* This option switches character encoding on the API, 0:ANSI/OEM or 1:UTF-16, /* This option switches the character encoding on the API when LFN is enabled.
/ when LFN is enabled. Also behavior of string I/O functions will be affected by /
/ this option. When LFN is not enabled, this option has no effect. / 0: ANSI/OEM in current CP (TCHAR = char)
*/ / 1: Unicode in UTF-16 (TCHAR = WCHAR)
/ 2: Unicode in UTF-8 (TCHAR = char)
/
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255
#define FF_SFN_BUF 12
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_STRF_ENCODE 0 #define FF_STRF_ENCODE 0
/* When FF_LFN_UNICODE = 1 with LFN enabled, string I/O functions, f_gets(), /* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it. / f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be / This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions. / read/written via those functions.
/ /
/ 0: ANSI/OEM / 0: ANSI/OEM in current CP
/ 1: UTF-16LE / 1: Unicode in UTF-16LE
/ 2: UTF-16BE / 2: Unicode in UTF-16BE
/ 3: UTF-8 / 3: Unicode in UTF-8
*/ */
@ -217,9 +231,9 @@
#define FF_FS_NORTC 0 #define FF_FS_NORTC 0
#define FF_NORTC_MON 5 #define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1 #define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2017 #define FF_NORTC_YEAR 2018
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have /* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp / the timestamp function. All objects modified by FatFs will have a fixed timestamp

View File

@ -1,5 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */ /* Sample Code of OS Dependent Functions for FatFs */
/* (C)ChaN, 2017 */ /* (C)ChaN, 2017 */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -27,7 +27,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on no
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
void ff_memfree ( void ff_memfree (
void* mblock /* Pointer to the memory block to free */ void* mblock /* Pointer to the memory block to free (nothing to do for null) */
) )
{ {
free(mblock); /* Free the memory block with POSIX API */ free(mblock); /* Free the memory block with POSIX API */

View File

@ -1,5 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13+ */ /* Unicode handling functions for FatFs R0.13a */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the / /* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode / / FatFs is configured for LFN with DBCS. If the system has any Unicode /
@ -25,7 +25,11 @@
#include "ff.h" #include "ff.h"
#if FF_USE_LFN #if FF_USE_LFN /* This module is blanked when non-LFN configuration */
#if FF_DEFINED != 89352 /* Revision ID */
#error Wrong include file (ff.h).
#endif
#define MERGE2(a, b) a ## b #define MERGE2(a, b) a ## b
#define CVTBL(tbl, cp) MERGE2(tbl, cp) #define CVTBL(tbl, cp) MERGE2(tbl, cp)
@ -15245,7 +15249,7 @@ const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900 #if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WCHAR uni, /* Unicode character to be converted */ DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )
{ {
@ -15253,15 +15257,16 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE); const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
if (uni < 0x80) { /* ASCII char */ if (uni < 0x80) { /* ASCII? */
c = uni; c = (WCHAR)uni;
} else { /* Non-ASCII char */ } else { /* Non-ASCII */
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */ if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it a valid code? */
for (c = 0; c < 0x80 && uni != p[c]; c++) ; for (c = 0; c < 0x80 && uni != p[c]; c++) ;
c = (c + 0x80) & 0xFF; c = (c + 0x80) & 0xFF;
} }
} }
return c; return c;
} }
@ -15274,7 +15279,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE); const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
if (oem < 0x80) { /* ASCII char */ if (oem < 0x80) { /* ASCII? */
c = oem; c = oem;
} else { /* Extended char */ } else { /* Extended char */
@ -15282,6 +15287,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
if (oem < 0x100) c = p[oem - 0x80]; if (oem < 0x100) c = p[oem - 0x80];
} }
} }
return c; return c;
} }
@ -15294,37 +15300,41 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
/* DBCS fixed code page */ /* DBCS fixed code page */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE >= 900 #if FF_CODE_PAGE >= 900
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WCHAR uni, /* Unicode character to be converted */ DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )
{ {
const WCHAR *p; const WCHAR *p;
WCHAR c = 0; WCHAR c = 0, uc;
UINT i, n, li, hi; UINT i, n, li, hi;
if (uni < 0x80) { /* ASCII char */ if (uni < 0x80) { /* ASCII? */
c = uni; c = (WCHAR)uni;
} else { /* Non-ASCII char */ } else { /* Non-ASCII */
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */ if (uni < 0x10000) { /* Is it in BMP? */
p = CVTBL(uni2oem, FF_CODE_PAGE); if (cp == FF_CODE_PAGE) { /* Is it a valid code? */
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1; uc = (WCHAR)uni;
li = 0; p = CVTBL(uni2oem, FF_CODE_PAGE);
for (n = 16; n; n--) { hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
i = li + (hi - li) / 2; li = 0;
if (uni == p[i * 2]) break; for (n = 16; n; n--) {
if (uni > p[i * 2]) { i = li + (hi - li) / 2;
li = i; if (uc == p[i * 2]) break;
} else { if (uc > p[i * 2]) {
hi = i; li = i;
} else {
hi = i;
}
} }
if (n != 0) c = p[i * 2 + 1];
} }
if (n != 0) c = p[i * 2 + 1];
} }
} }
return c; return c;
} }
@ -15339,7 +15349,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
UINT i, n, li, hi; UINT i, n, li, hi;
if (oem < 0x80) { /* ASCII char */ if (oem < 0x80) { /* ASCII? */
c = oem; c = oem;
} else { /* Extended char */ } else { /* Extended char */
@ -15359,6 +15369,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
if (n != 0) c = p[i * 2 + 1]; if (n != 0) c = p[i * 2 + 1];
} }
} }
return c; return c;
} }
#endif #endif
@ -15376,55 +15387,59 @@ static const WCHAR *const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WCHAR uni, /* Unicode character to be converted */ DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )
{ {
const WCHAR *p; const WCHAR *p;
WCHAR c = 0; WCHAR c = 0, uc;
UINT i, n, li, hi; UINT i, n, li, hi;
if (uni < 0x80) { /* ASCII char */ if (uni < 0x80) { /* ASCII? */
c = uni; c = (WCHAR)uni;
} else { /* Non-ASCII char */ } else { /* Non-ASCII */
p = 0; if (uni < 0x10000) { /* Is it in BMP? */
if (cp < 900) { /* SBCS */ uc = (WCHAR)uni;
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */ p = 0;
p = cp_table[i]; if (cp < 900) { /* SBCS */
if (p) { /* Is it a valid CP ? */ for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
for (c = 0; c < 0x80 && uni != p[c]; c++) ; /* Find OEM code in the table */ p = cp_table[i];
c = (c + 0x80) & 0xFF; if (p) { /* Is it a valid CP ? */
} for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
} else { /* DBCS */ c = (c + 0x80) & 0xFF;
switch (cp) { }
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break; } else { /* DBCS */
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break; switch (cp) {
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break; case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break; case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
} case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
if (p) { /* Is it a valid code page? */ case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
li = 0; }
for (n = 16; n; n--) { /* Find OEM code */ if (p) { /* Is it a valid code page? */
i = li + (hi - li) / 2; li = 0;
if (uni == p[i * 2]) break; for (n = 16; n; n--) { /* Find OEM code */
if (uni > p[i * 2]) { i = li + (hi - li) / 2;
li = i; if (uc == p[i * 2]) break;
} else { if (uc > p[i * 2]) {
hi = i; li = i;
} } else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
} }
if (n != 0) c = p[i * 2 + 1];
} }
} }
} }
return c; return c;
} }
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted */ WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )
{ {
@ -15433,7 +15448,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
UINT i, n, li, hi; UINT i, n, li, hi;
if (oem < 0x80) { /* ASCII char */ if (oem < 0x80) { /* ASCII? */
c = oem; c = oem;
} else { /* Extended char */ } else { /* Extended char */
@ -15466,6 +15481,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
} }
} }
} }
return c; return c;
} }
#endif #endif
@ -15476,12 +15492,12 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
/* Unicode up-case conversion */ /* Unicode up-case conversion */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
WCHAR ff_wtoupper ( /* Returns up-converted character */ DWORD ff_wtoupper ( /* Returns up-converted code point */
WCHAR uni /* Unicode character to be upper converted (BMP only) */ DWORD uni /* Unicode code point to be up-converted */
) )
{ {
/* Compressed upper conversion table */ /* Compressed upper conversion table */
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */ static const WORD cvt1[] = { /* U+0000 - U+0FFF */
/* Basic Latin */ /* Basic Latin */
0x0061,0x031A, 0x0061,0x031A,
/* Latin-1 Supplement */ /* Latin-1 Supplement */
@ -15505,7 +15521,7 @@ WCHAR ff_wtoupper ( /* Returns up-converted character */
0x0000 0x0000
}; };
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */ static const WORD cvt2[] = { /* U+1000 - U+FFFF */
/* Phonetic Extensions */ /* Phonetic Extensions */
0x1D7D,0x0001,0x2C63, 0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */ /* Latin Extended Additional */
@ -15533,30 +15549,34 @@ WCHAR ff_wtoupper ( /* Returns up-converted character */
0x0000 0x0000
}; };
const WCHAR *p; const WORD *p;
WCHAR bc, nc, cmd; WORD uc, bc, nc, cmd;
p = uni < 0x1000 ? cvt1 : cvt2; if (uni < 0x10000) { /* Is it in BMP? */
for (;;) { uc = (WORD)uni;
bc = *p++; /* Get block base */ p = uc < 0x1000 ? cvt1 : cvt2;
if (!bc || uni < bc) break; for (;;) {
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */ bc = *p++; /* Get block base */
if (uni < bc + nc) { /* In the block? */ if (!bc || uc < bc) break;
switch (cmd) { nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
case 0: uni = p[uni - bc]; break; /* Table conversion */ if (uc < bc + nc) { /* In the block? */
case 1: uni -= (uni - bc) & 1; break; /* Case pairs */ switch (cmd) {
case 2: uni -= 16; break; /* Shift -16 */ case 0: uc = p[uc - bc]; break; /* Table conversion */
case 3: uni -= 32; break; /* Shift -32 */ case 1: uc -= (uc - bc) & 1; break; /* Case pairs */
case 4: uni -= 48; break; /* Shift -48 */ case 2: uc -= 16; break; /* Shift -16 */
case 5: uni -= 26; break; /* Shift -26 */ case 3: uc -= 32; break; /* Shift -32 */
case 6: uni += 8; break; /* Shift +8 */ case 4: uc -= 48; break; /* Shift -48 */
case 7: uni -= 80; break; /* Shift -80 */ case 5: uc -= 26; break; /* Shift -26 */
case 8: uni -= 0x1C60; break; /* Shift -0x1C60 */ case 6: uc += 8; break; /* Shift +8 */
case 7: uc -= 80; break; /* Shift -80 */
case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
} }
break; if (!cmd) p += nc;
} }
if (!cmd) p += nc; uni = uc;
} }
return uni; return uni;