#define ILLEGAL_CHAR_MARK '_' #define EXT_MARK '.' #define CRC_MARK '#' #define EXT_SIZE 5 /* Number of chars we need to store generated CRC to make filename unique */ #define CRC_LEN 5
static unicode_t get_utf16_char(const uint8_t *str_i, int str_i_max_len, int str_i_idx, int u_ch, unicode_t *ret)
{
unicode_t c; int start_idx = str_i_idx;
/* Expand OSTA compressed Unicode to Unicode */
c = str_i[str_i_idx++]; if (u_ch > 1)
c = (c << 8) | str_i[str_i_idx++]; if ((c & SURROGATE_MASK) == SURROGATE_PAIR) {
unicode_t next;
/* Trailing surrogate char */ if (str_i_idx >= str_i_max_len) {
c = UNICODE_MAX + 1; goto out;
}
/* Low surrogate must follow the high one... */ if (c & SURROGATE_LOW) {
c = UNICODE_MAX + 1; goto out;
}
WARN_ON_ONCE(u_ch != 2);
next = str_i[str_i_idx++] << 8;
next |= str_i[str_i_idx++]; if ((next & SURROGATE_MASK) != SURROGATE_PAIR ||
!(next & SURROGATE_LOW)) {
c = UNICODE_MAX + 1; goto out;
}
staticint udf_name_conv_char(uint8_t *str_o, int str_o_max_len, int *str_o_idx, const uint8_t *str_i, int str_i_max_len, int *str_i_idx, int u_ch, int *needsCRC, int (*conv_f)(wchar_t, unsignedchar *, int), int translate)
{
unicode_t c; int illChar = 0; int len, gotch = 0;
while (!gotch && *str_i_idx < str_i_max_len) { if (*str_o_idx >= str_o_max_len) {
*needsCRC = 1; return gotch;
}
len = get_utf16_char(str_i, str_i_max_len, *str_i_idx, u_ch,
&c); /* These chars cannot be converted. Replace them. */ if (c == 0 || c > UNICODE_MAX || (conv_f && c > MAX_WCHAR_T) ||
(translate && c == '/')) {
illChar = 1; if (!translate)
gotch = 1;
} elseif (illChar) break; else
gotch = 1;
*str_i_idx += len;
} if (illChar) {
*needsCRC = 1;
c = ILLEGAL_CHAR_MARK;
gotch = 1;
} if (gotch) { if (conv_f) {
len = conv_f(c, &str_o[*str_o_idx],
str_o_max_len - *str_o_idx);
} else {
len = utf32_to_utf8(c, &str_o[*str_o_idx],
str_o_max_len - *str_o_idx); if (len < 0)
len = -ENAMETOOLONG;
} /* Valid character? */ if (len >= 0)
*str_o_idx += len; elseif (len == -ENAMETOOLONG) {
*needsCRC = 1;
gotch = 0;
} else {
str_o[(*str_o_idx)++] = ILLEGAL_CHAR_MARK;
*needsCRC = 1;
}
} return gotch;
}
staticint udf_name_from_CS0(struct super_block *sb,
uint8_t *str_o, int str_max_len, const uint8_t *ocu, int ocu_len, int translate)
{
uint32_t c;
uint8_t cmp_id; int idx, len; int u_ch; int needsCRC = 0; int ext_i_len, ext_max_len; int str_o_len = 0; /* Length of resulting output */ int ext_o_len = 0; /* Extension output length */ int ext_crc_len = 0; /* Extension output length if used with CRC */ int i_ext = -1; /* Extension position in input buffer */ int o_crc = 0; /* Rightmost possible output pos for CRC+ext */ unsignedshort valueCRC;
uint8_t ext[EXT_SIZE * NLS_MAX_CHARSET_SIZE + 1];
uint8_t crc[CRC_LEN]; int (*conv_f)(wchar_t, unsignedchar *, int);
if (str_max_len <= 0) return0;
if (ocu_len == 0) {
memset(str_o, 0, str_max_len); return0;
}
if (UDF_SB(sb)->s_nls_map)
conv_f = UDF_SB(sb)->s_nls_map->uni2char; else
conv_f = NULL;
staticint udf_name_to_CS0(struct super_block *sb,
uint8_t *ocu, int ocu_max_len, const uint8_t *str_i, int str_len)
{ int i, len; unsignedint max_val; int u_len, u_ch;
unicode_t uni_char; int (*conv_f)(constunsignedchar *, int, wchar_t *);
if (ocu_max_len <= 0) return0;
if (UDF_SB(sb)->s_nls_map)
conv_f = UDF_SB(sb)->s_nls_map->char2uni; else
conv_f = NULL;
try_again:
u_len = 1; for (i = 0; i < str_len; i += len) { /* Name didn't fit? */ if (u_len + u_ch > ocu_max_len) return0; if (conv_f) { wchar_t wchar;
len = conv_f(&str_i[i], str_len - i, &wchar); if (len > 0)
uni_char = wchar;
} else {
len = utf8_to_utf32(&str_i[i], str_len - i,
&uni_char);
} /* Invalid character, deal with it */ if (len <= 0 || uni_char > UNICODE_MAX) {
len = 1;
uni_char = '?';
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.