Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/* SPDX-License-Identifier: GPL-2.0-or-later */
  2/*
  3 * Some of the source code in this file came from fs/cifs/cifs_unicode.c
  4 * and then via server/unicode.c
  5 * cifs_unicode:  Unicode kernel case support
  6 *
  7 * Function:
  8 *     Convert a unicode character to upper or lower case using
  9 *     compressed tables.
 10 *
 11 *   Copyright (c) International Business Machines  Corp., 2000,2009
 12 *
 13 *
 14 * Notes:
 15 *     These APIs are based on the C library functions.  The semantics
 16 *     should match the C functions but with expanded size operands.
 17 *
 18 *     The upper/lower functions are based on a table created by mkupr.
 19 *     This is a compressed table of upper and lower case conversion.
 20 *
 21 */
 22#ifndef _NLS_UCS2_UTILS_H
 23#define _NLS_UCS2_UTILS_H
 24
 25#include <asm/byteorder.h>
 26#include <linux/types.h>
 27#include <linux/nls.h>
 28#include <linux/unicode.h>
 29#include "nls_ucs2_data.h"
 30
 31/*
 32 * Windows maps these to the user defined 16 bit Unicode range since they are
 33 * reserved symbols (along with \ and /), otherwise illegal to store
 34 * in filenames in NTFS
 35 */
 36#define UNI_ASTERISK    ((__u16)('*' + 0xF000))
 37#define UNI_QUESTION    ((__u16)('?' + 0xF000))
 38#define UNI_COLON       ((__u16)(':' + 0xF000))
 39#define UNI_GRTRTHAN    ((__u16)('>' + 0xF000))
 40#define UNI_LESSTHAN    ((__u16)('<' + 0xF000))
 41#define UNI_PIPE        ((__u16)('|' + 0xF000))
 42#define UNI_SLASH       ((__u16)('\\' + 0xF000))
 43
 44/*
 45 * UniStrcat:  Concatenate the second string to the first
 46 *
 47 * Returns:
 48 *     Address of the first string
 49 */
 50static inline wchar_t *UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
 51{
 52	wchar_t *anchor = ucs1;	/* save a pointer to start of ucs1 */
 53
 54	while (*ucs1++)
 55	/*NULL*/;	/* To end of first string */
 56	ucs1--;			/* Return to the null */
 57	while ((*ucs1++ = *ucs2++))
 58	/*NULL*/;	/* copy string 2 over */
 59	return anchor;
 60}
 61
 62/*
 63 * UniStrchr:  Find a character in a string
 64 *
 65 * Returns:
 66 *     Address of first occurrence of character in string
 67 *     or NULL if the character is not in the string
 68 */
 69static inline wchar_t *UniStrchr(const wchar_t *ucs, wchar_t uc)
 70{
 71	while ((*ucs != uc) && *ucs)
 72		ucs++;
 73
 74	if (*ucs == uc)
 75		return (wchar_t *)ucs;
 76	return NULL;
 77}
 78
 79/*
 80 * UniStrcmp:  Compare two strings
 81 *
 82 * Returns:
 83 *     < 0:  First string is less than second
 84 *     = 0:  Strings are equal
 85 *     > 0:  First string is greater than second
 86 */
 87static inline int UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2)
 88{
 89	while ((*ucs1 == *ucs2) && *ucs1) {
 90		ucs1++;
 91		ucs2++;
 92	}
 93	return (int)*ucs1 - (int)*ucs2;
 94}
 95
 96/*
 97 * UniStrcpy:  Copy a string
 98 */
 99static inline wchar_t *UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
100{
101	wchar_t *anchor = ucs1;	/* save the start of result string */
102
103	while ((*ucs1++ = *ucs2++))
104	/*NULL*/;
105	return anchor;
106}
107
108/*
109 * UniStrlen:  Return the length of a string (in 16 bit Unicode chars not bytes)
110 */
111static inline size_t UniStrlen(const wchar_t *ucs1)
112{
113	int i = 0;
114
115	while (*ucs1++)
116		i++;
117	return i;
118}
119
120/*
121 * UniStrnlen:  Return the length (in 16 bit Unicode chars not bytes) of a
122 *		string (length limited)
123 */
124static inline size_t UniStrnlen(const wchar_t *ucs1, int maxlen)
125{
126	int i = 0;
127
128	while (*ucs1++) {
129		i++;
130		if (i >= maxlen)
131			break;
132	}
133	return i;
134}
135
136/*
137 * UniStrncat:  Concatenate length limited string
138 */
139static inline wchar_t *UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
140{
141	wchar_t *anchor = ucs1;	/* save pointer to string 1 */
142
143	while (*ucs1++)
144	/*NULL*/;
145	ucs1--;			/* point to null terminator of s1 */
146	while (n-- && (*ucs1 = *ucs2)) {	/* copy s2 after s1 */
147		ucs1++;
148		ucs2++;
149	}
150	*ucs1 = 0;		/* Null terminate the result */
151	return anchor;
152}
153
154/*
155 * UniStrncmp:  Compare length limited string
156 */
157static inline int UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
158{
159	if (!n)
160		return 0;	/* Null strings are equal */
161	while ((*ucs1 == *ucs2) && *ucs1 && --n) {
162		ucs1++;
163		ucs2++;
164	}
165	return (int)*ucs1 - (int)*ucs2;
166}
167
168/*
169 * UniStrncmp_le:  Compare length limited string - native to little-endian
170 */
171static inline int
172UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
173{
174	if (!n)
175		return 0;	/* Null strings are equal */
176	while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) {
177		ucs1++;
178		ucs2++;
179	}
180	return (int)*ucs1 - (int)__le16_to_cpu(*ucs2);
181}
182
183/*
184 * UniStrncpy:  Copy length limited string with pad
185 */
186static inline wchar_t *UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
187{
188	wchar_t *anchor = ucs1;
189
190	while (n-- && *ucs2)	/* Copy the strings */
191		*ucs1++ = *ucs2++;
192
193	n++;
194	while (n--)		/* Pad with nulls */
195		*ucs1++ = 0;
196	return anchor;
197}
198
199/*
200 * UniStrncpy_le:  Copy length limited string with pad to little-endian
201 */
202static inline wchar_t *UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
203{
204	wchar_t *anchor = ucs1;
205
206	while (n-- && *ucs2)	/* Copy the strings */
207		*ucs1++ = __le16_to_cpu(*ucs2++);
208
209	n++;
210	while (n--)		/* Pad with nulls */
211		*ucs1++ = 0;
212	return anchor;
213}
214
215/*
216 * UniStrstr:  Find a string in a string
217 *
218 * Returns:
219 *     Address of first match found
220 *     NULL if no matching string is found
221 */
222static inline wchar_t *UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
223{
224	const wchar_t *anchor1 = ucs1;
225	const wchar_t *anchor2 = ucs2;
226
227	while (*ucs1) {
228		if (*ucs1 == *ucs2) {
229			/* Partial match found */
230			ucs1++;
231			ucs2++;
232		} else {
233			if (!*ucs2)	/* Match found */
234				return (wchar_t *)anchor1;
235			ucs1 = ++anchor1;	/* No match */
236			ucs2 = anchor2;
237		}
238	}
239
240	if (!*ucs2)		/* Both end together */
241		return (wchar_t *)anchor1;	/* Match found */
242	return NULL;		/* No match */
243}
244
245#ifndef UNIUPR_NOUPPER
246/*
247 * UniToupper:  Convert a unicode character to upper case
248 */
249static inline wchar_t UniToupper(register wchar_t uc)
250{
251	register const struct UniCaseRange *rp;
252
253	if (uc < sizeof(NlsUniUpperTable)) {
254		/* Latin characters */
255		return uc + NlsUniUpperTable[uc];	/* Use base tables */
256	}
257
258	rp = NlsUniUpperRange;	/* Use range tables */
259	while (rp->start) {
260		if (uc < rp->start)	/* Before start of range */
261			return uc;	/* Uppercase = input */
262		if (uc <= rp->end)	/* In range */
263			return uc + rp->table[uc - rp->start];
264		rp++;	/* Try next range */
265	}
266	return uc;		/* Past last range */
267}
268
269/*
270 * UniStrupr:  Upper case a unicode string
271 */
272static inline __le16 *UniStrupr(register __le16 *upin)
273{
274	register __le16 *up;
275
276	up = upin;
277	while (*up) {		/* For all characters */
278		*up = cpu_to_le16(UniToupper(le16_to_cpu(*up)));
279		up++;
280	}
281	return upin;		/* Return input pointer */
282}
283#endif				/* UNIUPR_NOUPPER */
284
285#endif /* _NLS_UCS2_UTILS_H */