Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc3 357 lines 8.1 kB view raw
1/* 2 * cifs_unicode: Unicode kernel case support 3 * 4 * Function: 5 * Convert a unicode character to upper or lower case using 6 * compressed tables. 7 * 8 * Copyright (c) International Business Machines Corp., 2000,2007 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 18 * the GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * 24 * 25 * Notes: 26 * These APIs are based on the C library functions. The semantics 27 * should match the C functions but with expanded size operands. 28 * 29 * The upper/lower functions are based on a table created by mkupr. 30 * This is a compressed table of upper and lower case conversion. 31 * 32 */ 33 34#include <asm/byteorder.h> 35#include <linux/types.h> 36#include <linux/nls.h> 37 38#define UNIUPR_NOLOWER /* Example to not expand lower case tables */ 39 40/* Just define what we want from uniupr.h. We don't want to define the tables 41 * in each source file. 42 */ 43#ifndef UNICASERANGE_DEFINED 44struct UniCaseRange { 45 wchar_t start; 46 wchar_t end; 47 signed char *table; 48}; 49#endif /* UNICASERANGE_DEFINED */ 50 51#ifndef UNIUPR_NOUPPER 52extern signed char CifsUniUpperTable[512]; 53extern const struct UniCaseRange CifsUniUpperRange[]; 54#endif /* UNIUPR_NOUPPER */ 55 56#ifndef UNIUPR_NOLOWER 57extern signed char UniLowerTable[512]; 58extern struct UniCaseRange UniLowerRange[]; 59#endif /* UNIUPR_NOLOWER */ 60 61#ifdef __KERNEL__ 62int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *); 63int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); 64#endif 65 66/* 67 * UniStrcat: Concatenate the second string to the first 68 * 69 * Returns: 70 * Address of the first string 71 */ 72static inline wchar_t * 73UniStrcat(wchar_t *ucs1, const wchar_t *ucs2) 74{ 75 wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */ 76 77 while (*ucs1++) ; /* To end of first string */ 78 ucs1--; /* Return to the null */ 79 while ((*ucs1++ = *ucs2++)) ; /* copy string 2 over */ 80 return anchor; 81} 82 83/* 84 * UniStrchr: Find a character in a string 85 * 86 * Returns: 87 * Address of first occurrence of character in string 88 * or NULL if the character is not in the string 89 */ 90static inline wchar_t * 91UniStrchr(const wchar_t *ucs, wchar_t uc) 92{ 93 while ((*ucs != uc) && *ucs) 94 ucs++; 95 96 if (*ucs == uc) 97 return (wchar_t *) ucs; 98 return NULL; 99} 100 101/* 102 * UniStrcmp: Compare two strings 103 * 104 * Returns: 105 * < 0: First string is less than second 106 * = 0: Strings are equal 107 * > 0: First string is greater than second 108 */ 109static inline int 110UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2) 111{ 112 while ((*ucs1 == *ucs2) && *ucs1) { 113 ucs1++; 114 ucs2++; 115 } 116 return (int) *ucs1 - (int) *ucs2; 117} 118 119/* 120 * UniStrcpy: Copy a string 121 */ 122static inline wchar_t * 123UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2) 124{ 125 wchar_t *anchor = ucs1; /* save the start of result string */ 126 127 while ((*ucs1++ = *ucs2++)) ; 128 return anchor; 129} 130 131/* 132 * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes) 133 */ 134static inline size_t 135UniStrlen(const wchar_t *ucs1) 136{ 137 int i = 0; 138 139 while (*ucs1++) 140 i++; 141 return i; 142} 143 144/* 145 * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a 146 * string (length limited) 147 */ 148static inline size_t 149UniStrnlen(const wchar_t *ucs1, int maxlen) 150{ 151 int i = 0; 152 153 while (*ucs1++) { 154 i++; 155 if (i >= maxlen) 156 break; 157 } 158 return i; 159} 160 161/* 162 * UniStrncat: Concatenate length limited string 163 */ 164static inline wchar_t * 165UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n) 166{ 167 wchar_t *anchor = ucs1; /* save pointer to string 1 */ 168 169 while (*ucs1++) ; 170 ucs1--; /* point to null terminator of s1 */ 171 while (n-- && (*ucs1 = *ucs2)) { /* copy s2 after s1 */ 172 ucs1++; 173 ucs2++; 174 } 175 *ucs1 = 0; /* Null terminate the result */ 176 return (anchor); 177} 178 179/* 180 * UniStrncmp: Compare length limited string 181 */ 182static inline int 183UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n) 184{ 185 if (!n) 186 return 0; /* Null strings are equal */ 187 while ((*ucs1 == *ucs2) && *ucs1 && --n) { 188 ucs1++; 189 ucs2++; 190 } 191 return (int) *ucs1 - (int) *ucs2; 192} 193 194/* 195 * UniStrncmp_le: Compare length limited string - native to little-endian 196 */ 197static inline int 198UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n) 199{ 200 if (!n) 201 return 0; /* Null strings are equal */ 202 while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) { 203 ucs1++; 204 ucs2++; 205 } 206 return (int) *ucs1 - (int) __le16_to_cpu(*ucs2); 207} 208 209/* 210 * UniStrncpy: Copy length limited string with pad 211 */ 212static inline wchar_t * 213UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n) 214{ 215 wchar_t *anchor = ucs1; 216 217 while (n-- && *ucs2) /* Copy the strings */ 218 *ucs1++ = *ucs2++; 219 220 n++; 221 while (n--) /* Pad with nulls */ 222 *ucs1++ = 0; 223 return anchor; 224} 225 226/* 227 * UniStrncpy_le: Copy length limited string with pad to little-endian 228 */ 229static inline wchar_t * 230UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n) 231{ 232 wchar_t *anchor = ucs1; 233 234 while (n-- && *ucs2) /* Copy the strings */ 235 *ucs1++ = __le16_to_cpu(*ucs2++); 236 237 n++; 238 while (n--) /* Pad with nulls */ 239 *ucs1++ = 0; 240 return anchor; 241} 242 243/* 244 * UniStrstr: Find a string in a string 245 * 246 * Returns: 247 * Address of first match found 248 * NULL if no matching string is found 249 */ 250static inline wchar_t * 251UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2) 252{ 253 const wchar_t *anchor1 = ucs1; 254 const wchar_t *anchor2 = ucs2; 255 256 while (*ucs1) { 257 if (*ucs1 == *ucs2) { 258 /* Partial match found */ 259 ucs1++; 260 ucs2++; 261 } else { 262 if (!*ucs2) /* Match found */ 263 return (wchar_t *) anchor1; 264 ucs1 = ++anchor1; /* No match */ 265 ucs2 = anchor2; 266 } 267 } 268 269 if (!*ucs2) /* Both end together */ 270 return (wchar_t *) anchor1; /* Match found */ 271 return NULL; /* No match */ 272} 273 274#ifndef UNIUPR_NOUPPER 275/* 276 * UniToupper: Convert a unicode character to upper case 277 */ 278static inline wchar_t 279UniToupper(register wchar_t uc) 280{ 281 register const struct UniCaseRange *rp; 282 283 if (uc < sizeof(CifsUniUpperTable)) { 284 /* Latin characters */ 285 return uc + CifsUniUpperTable[uc]; /* Use base tables */ 286 } else { 287 rp = CifsUniUpperRange; /* Use range tables */ 288 while (rp->start) { 289 if (uc < rp->start) /* Before start of range */ 290 return uc; /* Uppercase = input */ 291 if (uc <= rp->end) /* In range */ 292 return uc + rp->table[uc - rp->start]; 293 rp++; /* Try next range */ 294 } 295 } 296 return uc; /* Past last range */ 297} 298 299/* 300 * UniStrupr: Upper case a unicode string 301 */ 302static inline wchar_t * 303UniStrupr(register wchar_t *upin) 304{ 305 register wchar_t *up; 306 307 up = upin; 308 while (*up) { /* For all characters */ 309 *up = UniToupper(*up); 310 up++; 311 } 312 return upin; /* Return input pointer */ 313} 314#endif /* UNIUPR_NOUPPER */ 315 316#ifndef UNIUPR_NOLOWER 317/* 318 * UniTolower: Convert a unicode character to lower case 319 */ 320static inline wchar_t 321UniTolower(wchar_t uc) 322{ 323 register struct UniCaseRange *rp; 324 325 if (uc < sizeof(UniLowerTable)) { 326 /* Latin characters */ 327 return uc + UniLowerTable[uc]; /* Use base tables */ 328 } else { 329 rp = UniLowerRange; /* Use range tables */ 330 while (rp->start) { 331 if (uc < rp->start) /* Before start of range */ 332 return uc; /* Uppercase = input */ 333 if (uc <= rp->end) /* In range */ 334 return uc + rp->table[uc - rp->start]; 335 rp++; /* Try next range */ 336 } 337 } 338 return uc; /* Past last range */ 339} 340 341/* 342 * UniStrlwr: Lower case a unicode string 343 */ 344static inline wchar_t * 345UniStrlwr(register wchar_t *upin) 346{ 347 register wchar_t *up; 348 349 up = upin; 350 while (*up) { /* For all characters */ 351 *up = UniTolower(*up); 352 up++; 353 } 354 return upin; /* Return input pointer */ 355} 356 357#endif