r15292: fix the IDL_* variable names
[bbaumbach/samba-autobuild/.git] / source4 / lib / util / util_unistr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-2001
5    Copyright (C) Simo Sorce 2001
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "system/iconv.h"
24
25 /**
26  * @file
27  * @brief Unicode string manipulation
28  */
29
30 /* these 2 tables define the unicode case handling.  They are loaded
31    at startup either via mmap() or read() from the lib directory */
32 static void *upcase_table;
33 static void *lowcase_table;
34
35
36 /*******************************************************************
37 load the case handling tables
38 ********************************************************************/
39 static void load_case_tables(void)
40 {
41         TALLOC_CTX *mem_ctx;
42
43         mem_ctx = talloc_init("load_case_tables");
44         if (!mem_ctx) {
45                 smb_panic("No memory for case_tables");
46         }
47         upcase_table = map_file(data_path(mem_ctx, "upcase.dat"), 0x20000);
48         lowcase_table = map_file(data_path(mem_ctx, "lowcase.dat"), 0x20000);
49         talloc_free(mem_ctx);
50         if (upcase_table == NULL) {
51                 /* try also under codepages for testing purposes */
52                 upcase_table = map_file("codepages/upcase.dat", 0x20000);
53                 if (upcase_table == NULL) {
54                         upcase_table = (void *)-1;
55                 }
56         }
57         if (lowcase_table == NULL) {
58                 /* try also under codepages for testing purposes */
59                 lowcase_table = map_file("codepages/lowcase.dat", 0x20000);
60                 if (lowcase_table == NULL) {
61                         lowcase_table = (void *)-1;
62                 }
63         }
64 }
65
66 /**
67  Convert a codepoint_t to upper case.
68 **/
69 codepoint_t toupper_w(codepoint_t val)
70 {
71         if (val < 128) {
72                 return toupper(val);
73         }
74         if (upcase_table == NULL) {
75                 load_case_tables();
76         }
77         if (upcase_table == (void *)-1) {
78                 return val;
79         }
80         if (val & 0xFFFF0000) {
81                 return val;
82         }
83         return SVAL(upcase_table, val*2);
84 }
85
86 /**
87  Convert a codepoint_t to lower case.
88 **/
89 codepoint_t tolower_w(codepoint_t val)
90 {
91         if (val < 128) {
92                 return tolower(val);
93         }
94         if (lowcase_table == NULL) {
95                 load_case_tables();
96         }
97         if (lowcase_table == (void *)-1) {
98                 return val;
99         }
100         if (val & 0xFFFF0000) {
101                 return val;
102         }
103         return SVAL(lowcase_table, val*2);
104 }
105
106 /**
107 return the number of bytes occupied by a buffer in CH_UTF16 format
108 the result includes the null termination
109 **/
110 size_t utf16_len(const void *buf)
111 {
112         size_t len;
113
114         for (len = 0; SVAL(buf,len); len += 2) ;
115
116         return len + 2;
117 }
118
119 /**
120 return the number of bytes occupied by a buffer in CH_UTF16 format
121 the result includes the null termination
122 limited by 'n' bytes
123 **/
124 size_t utf16_len_n(const void *src, size_t n)
125 {
126         size_t len;
127
128         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
129
130         if (len+2 <= n) {
131                 len += 2;
132         }
133
134         return len;
135 }
136
137
138 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
139 {
140         if (flags & (STR_NOALIGN|STR_ASCII))
141                 return 0;
142         return PTR_DIFF(p, base_ptr) & 1;
143 }
144
145 /**
146   compare two codepoints case insensitively
147 */
148 int codepoint_cmpi(codepoint_t c1, codepoint_t c2)
149 {
150         if (c1 == c2 ||
151             toupper_w(c1) == toupper_w(c2)) {
152                 return 0;
153         }
154         return c1 - c2;
155 }