/* if character not one of seven in special remap set */
len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); if (len <= 0) goto surrogate_pair;
return len;
surrogate_pair: /* convert SURROGATE_PAIR and IVS */ if (strcmp(cp->charset, "utf8")) goto unknown;
len = utf16s_to_utf8s(from, 3, UTF16_LITTLE_ENDIAN, target, 6); if (len <= 0) goto unknown; return len;
unknown:
*target = '?';
len = 1; return len;
}
/* *cifs_from_utf16-convertutf16lestringtolocalcharset *@to-destinationbuffer *@from-sourcebuffer *@tolen-destinationbuffersize(inbytes) *@fromlen-sourcebuffersize(inbytes) *@codepage-codepagetowhichcharactersshouldbeconverted *@mapchar-shouldcharactersberemappedaccordingtothemapcharsoption? * *Convertalittle-endianutf16lestring(assentbytheserver)toastring *intheprovidedcodepage.Thetolenandfromlenparametersaretoensure *thatthecodedoesn'twalkoffoftheendofthebuffer(whichisalways *adangerifthealignmentofthesourcebufferisoff).Thedestination *stringisalwaysproperlynullterminatedandfitsinthedestination *buffer.Returnsthelengthofthedestinationstringinbytes(including *nullterminator). * *NotethatsomewindowsversionsactuallysendmultiwordUTF-16characters *insteadofstraightUTF16-2.Thelinuxnlsroutineshoweveraren'tableto *dealwiththosecharactersproperly.Intheeventthatwegetsomeof *thosecharacters,theywon'tbetranslatedproperly.
*/ int
cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, conststruct nls_table *codepage, int map_type)
{ int i, charlen, safelen; int outlen = 0; int nullsize = nls_nullsize(codepage); int fromwords = fromlen / 2; char tmp[NLS_MAX_CHARSET_SIZE];
__u16 ftmp[3]; /* ftmp[3] = 3array x 2bytes = 6bytes UTF-16 */
/* put converted char into 'to' buffer */
charlen = cifs_mapchar(&to[outlen], ftmp, codepage, map_type);
outlen += charlen;
/* charlen (=bytes of UTF-8 for 1 character) *4bytesUTF-8(surrogatepair)ischarlen=4 *(4bytesUTF-16code) *7-8bytesUTF-8(IVS)ischarlen=3+4or4+4
* (2 UTF-8 pairs divided to 2 UTF-16 pairs) */ if (charlen == 4)
i++; elseif (charlen >= 5) /* 5-6bytes UTF-8 */
i += 2;
}
/* properly null-terminate string */ for (i = 0; i < nullsize; i++)
to[outlen++] = 0;
return outlen;
}
/* *NAME:cifs_strtoUTF16() * *FUNCTION:Convertcharacterstringtounicodestring *
*/ int
cifs_strtoUTF16(__le16 *to, constchar *from, int len, conststruct nls_table *codepage)
{ int charlen; int i; wchar_t wchar_to; /* needed to quiet sparse */
/* special case for utf8 to handle no plane0 chars */ if (!strcmp(codepage->charset, "utf8")) { /* *convertutf8->utf16,weassumewehaveenoughspace *ascallershouldhaveassumedconversiondoesnotoverflow *indestinationlenislengthinwchar_tunits(16bits)
*/
i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN,
(wchar_t *) to, len);
/* if success terminate and exit */ if (i >= 0) goto success; /* *iffailsfallbacktoUCSencodingasthis *functionshouldnotreturnnegativevalues *currentlycanfailonlyifsourcecontains *invalidencodedcharacters
*/
}
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &wchar_to); if (charlen < 1) {
cifs_dbg(VFS, "strtoUTF16: char2uni of 0x%x returned %d\n",
*from, charlen); /* A question mark */
wchar_to = 0x003f;
charlen = 1;
}
put_unaligned_le16(wchar_to, &to[i]);
}
/* *Convert16bitUnicodepathnametowireformatfromstringincurrentcode *page.Conversionmayinvolveremappingupthesixcharactersthatare *onlylegalinPOSIX-likeOS(iftheyarepresentinthestring).Path *namesarelittleendian16bitUnicodeonthewire
*/ int
cifsConvertToUTF16(__le16 *target, constchar *source, int srclen, conststruct nls_table *cp, int map_chars)
{ int i, charlen; int j = 0; char src_char;
__le16 dst_char; wchar_t tmp; wchar_t *wchar_to; /* UTF-16 */ int ret;
unicode_t u;
if (map_chars == NO_MAP_UNI_RSVD) return cifs_strtoUTF16(target, source, PATH_MAX, cp);
wchar_to = kzalloc(6, GFP_KERNEL);
for (i = 0; i < srclen; j++) {
src_char = source[i];
charlen = 1;
/* check if end of string */ if (src_char == 0) goto ctoUTF16_out;
/* see if we must remap this char */ if (map_chars == SFU_MAP_UNI_RSVD)
dst_char = convert_to_sfu_char(src_char); elseif (map_chars == SFM_MAP_UNI_RSVD) { bool end_of_string;
staticint
cifs_local_to_utf16_bytes(constchar *from, int len, conststruct nls_table *codepage)
{ int charlen; int i; wchar_t wchar_to;
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &wchar_to); /* Failed conversion defaults to a question mark */ if (charlen < 1)
charlen = 1;
} return2 * i; /* UTF16 characters are two bytes */
}
/* *cifs_strndup_to_utf16-copyastringtowireformatfromthelocalcodepage *@src-sourcestring *@maxlen-don'twalkpastthismanybytesinthesourcestring *@utf16_len-thelengthoftheallocatedstringinbytes(includingnull) *@cp-sourcecodepage *@remap-mapspecialchars * *TakeastringconvertitfromthelocalcodepagetoUTF16and *putitinanewbuffer.ReturnsapointertothenewstringorNULLon *error.
*/
__le16 *
cifs_strndup_to_utf16(constchar *src, constint maxlen, int *utf16_len, conststruct nls_table *cp, int remap)
{ int len;
__le16 *dst;
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.