r4466: rather than defining "STANDALONE" for building tdb, ldb and talloc
[samba.git] / source4 / lib / 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 /* these 2 tables define the unicode case handling.  They are loaded
26    at startup either via mmap() or read() from the lib directory */
27 static void *upcase_table;
28 static void *lowcase_table;
29
30
31 /*******************************************************************
32 load the case handling tables
33 ********************************************************************/
34 static void load_case_tables(void)
35 {
36         TALLOC_CTX *mem_ctx;
37
38         mem_ctx = talloc_init("load_case_tables");
39         if (!mem_ctx) {
40                 smb_panic("No memory for case_tables");
41         }
42         upcase_table = map_file(lib_path(mem_ctx, "upcase.dat"), 0x20000);
43         lowcase_table = map_file(lib_path(mem_ctx, "lowcase.dat"), 0x20000);
44         talloc_destroy(mem_ctx);
45         if (upcase_table == NULL) {
46                 upcase_table = (void *)-1;
47         }
48         if (lowcase_table == NULL) {
49                 lowcase_table = (void *)-1;
50         }
51 }
52
53 /*******************************************************************
54  Convert a codepoint_t to upper case.
55 ********************************************************************/
56 codepoint_t toupper_w(codepoint_t val)
57 {
58         if (val < 128) {
59                 return toupper(val);
60         }
61         if (upcase_table == (void *)-1) {
62                 return val;
63         }
64         if (upcase_table == NULL) {
65                 load_case_tables();
66         }
67         if (val & 0xFFFF0000) {
68                 return val;
69         }
70         return SVAL(upcase_table, val*2);
71 }
72
73 /*******************************************************************
74  Convert a codepoint_t to lower case.
75 ********************************************************************/
76 codepoint_t tolower_w(codepoint_t val)
77 {
78         if (val < 128) {
79                 return tolower(val);
80         }
81         if (lowcase_table == (void *)-1) {
82                 return val;
83         }
84         if (lowcase_table == NULL) {
85                 load_case_tables();
86         }
87         if (val & 0xFFFF0000) {
88                 return val;
89         }
90         return SVAL(lowcase_table, val*2);
91 }
92
93 /*******************************************************************
94 return the number of bytes occupied by a buffer in CH_UTF16 format
95 the result includes the null termination
96 ********************************************************************/
97 size_t utf16_len(const void *buf)
98 {
99         size_t len;
100
101         for (len = 0; SVAL(buf,len); len += 2) ;
102
103         return len + 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 limited by 'n' bytes
110 ********************************************************************/
111 size_t utf16_len_n(const void *src, size_t n)
112 {
113         size_t len;
114
115         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
116
117         if (len+2 <= n) {
118                 len += 2;
119         }
120
121         return len;
122 }
123
124
125 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
126 {
127         if (flags & (STR_NOALIGN|STR_ASCII))
128                 return 0;
129         return PTR_DIFF(p, base_ptr) & 1;
130 }
131
132 /*
133   compare two codepoints case insensitively
134 */
135 int codepoint_cmpi(codepoint_t c1, codepoint_t c2)
136 {
137         if (c1 == c2 ||
138             toupper_w(c1) == toupper_w(c2)) {
139                 return 0;
140         }
141         return c1 - c2;
142 }