1  /* SPDX-License-Identifier: GPL-2.0-or-later */
2  /*
3   *   Copyright (C) International Business Machines Corp., 2000-2002
4   *   Portions Copyright (C) Christoph Hellwig, 2001-2002
5   */
6  #ifndef _H_JFS_UNICODE
7  #define _H_JFS_UNICODE
8  
9  #include <linux/slab.h>
10  #include <asm/byteorder.h>
11  #include "jfs_types.h"
12  
13  typedef struct {
14  	wchar_t start;
15  	wchar_t end;
16  	signed char *table;
17  } UNICASERANGE;
18  
19  extern signed char UniUpperTable[512];
20  extern UNICASERANGE UniUpperRange[];
21  extern int get_UCSname(struct component_name *, struct dentry *);
22  extern int jfs_strfromUCS_le(char *, const __le16 *, int, struct nls_table *);
23  
24  #define free_UCSname(COMP) kfree((COMP)->name)
25  
26  /*
27   * UniStrcpy:  Copy a string
28   */
UniStrcpy(wchar_t * ucs1,const wchar_t * ucs2)29  static inline wchar_t *UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2)
30  {
31  	wchar_t *anchor = ucs1;	/* save the start of result string */
32  
33  	while ((*ucs1++ = *ucs2++));
34  	return anchor;
35  }
36  
37  
38  
39  /*
40   * UniStrncpy:  Copy length limited string with pad
41   */
UniStrncpy_le(__le16 * ucs1,const __le16 * ucs2,size_t n)42  static inline __le16 *UniStrncpy_le(__le16 * ucs1, const __le16 * ucs2,
43  				  size_t n)
44  {
45  	__le16 *anchor = ucs1;
46  
47  	while (n-- && *ucs2)	/* Copy the strings */
48  		*ucs1++ = *ucs2++;
49  
50  	n++;
51  	while (n--)		/* Pad with nulls */
52  		*ucs1++ = 0;
53  	return anchor;
54  }
55  
56  /*
57   * UniStrncmp_le:  Compare length limited string - native to little-endian
58   */
UniStrncmp_le(const wchar_t * ucs1,const __le16 * ucs2,size_t n)59  static inline int UniStrncmp_le(const wchar_t * ucs1, const __le16 * ucs2,
60  				size_t n)
61  {
62  	if (!n)
63  		return 0;	/* Null strings are equal */
64  	while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) {
65  		ucs1++;
66  		ucs2++;
67  	}
68  	return (int) *ucs1 - (int) __le16_to_cpu(*ucs2);
69  }
70  
71  /*
72   * UniStrncpy_to_le:  Copy length limited string with pad to little-endian
73   */
UniStrncpy_to_le(__le16 * ucs1,const wchar_t * ucs2,size_t n)74  static inline __le16 *UniStrncpy_to_le(__le16 * ucs1, const wchar_t * ucs2,
75  				       size_t n)
76  {
77  	__le16 *anchor = ucs1;
78  
79  	while (n-- && *ucs2)	/* Copy the strings */
80  		*ucs1++ = cpu_to_le16(*ucs2++);
81  
82  	n++;
83  	while (n--)		/* Pad with nulls */
84  		*ucs1++ = 0;
85  	return anchor;
86  }
87  
88  /*
89   * UniStrncpy_from_le:  Copy length limited string with pad from little-endian
90   */
UniStrncpy_from_le(wchar_t * ucs1,const __le16 * ucs2,size_t n)91  static inline wchar_t *UniStrncpy_from_le(wchar_t * ucs1, const __le16 * ucs2,
92  					  size_t n)
93  {
94  	wchar_t *anchor = ucs1;
95  
96  	while (n-- && *ucs2)	/* Copy the strings */
97  		*ucs1++ = __le16_to_cpu(*ucs2++);
98  
99  	n++;
100  	while (n--)		/* Pad with nulls */
101  		*ucs1++ = 0;
102  	return anchor;
103  }
104  
105  /*
106   * UniToupper:  Convert a unicode character to upper case
107   */
UniToupper(wchar_t uc)108  static inline wchar_t UniToupper(wchar_t uc)
109  {
110  	UNICASERANGE *rp;
111  
112  	if (uc < sizeof(UniUpperTable)) {	/* Latin characters */
113  		return uc + UniUpperTable[uc];	/* Use base tables */
114  	} else {
115  		rp = UniUpperRange;	/* Use range tables */
116  		while (rp->start) {
117  			if (uc < rp->start)	/* Before start of range */
118  				return uc;	/* Uppercase = input */
119  			if (uc <= rp->end)	/* In range */
120  				return uc + rp->table[uc - rp->start];
121  			rp++;	/* Try next range */
122  		}
123  	}
124  	return uc;		/* Past last range */
125  }
126  
127  
128  /*
129   * UniStrupr:  Upper case a unicode string
130   */
UniStrupr(wchar_t * upin)131  static inline wchar_t *UniStrupr(wchar_t * upin)
132  {
133  	wchar_t *up;
134  
135  	up = upin;
136  	while (*up) {		/* For all characters */
137  		*up = UniToupper(*up);
138  		up++;
139  	}
140  	return upin;		/* Return input pointer */
141  }
142  
143  #endif				/* !_H_JFS_UNICODE */
144