2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
Samba utility functions
Copyright ( C ) Andrew Tridgell 1992 - 2001
Copyright ( C ) Simo Sorce 2001
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-02 04:42:45 +03:00
# include "system/iconv.h"
2003-08-13 05:53:07 +04:00
2004-10-08 12:13:00 +04:00
/* these 2 tables define the unicode case handling. They are loaded
2003-08-13 05:53:07 +04:00
at startup either via mmap ( ) or read ( ) from the lib directory */
2004-10-08 12:13:00 +04:00
static void * upcase_table ;
static void * lowcase_table ;
2003-08-13 05:53:07 +04:00
/*******************************************************************
load the case handling tables
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-10-08 12:13:00 +04:00
static void load_case_tables ( void )
2003-08-13 05:53:07 +04:00
{
TALLOC_CTX * mem_ctx ;
mem_ctx = talloc_init ( " load_case_tables " ) ;
if ( ! mem_ctx ) {
smb_panic ( " No memory for case_tables " ) ;
}
upcase_table = map_file ( lib_path ( mem_ctx , " upcase.dat " ) , 0x20000 ) ;
lowcase_table = map_file ( lib_path ( mem_ctx , " lowcase.dat " ) , 0x20000 ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2004-10-09 11:11:21 +04:00
if ( upcase_table = = NULL ) {
2004-10-11 06:07:30 +04:00
upcase_table = ( void * ) - 1 ;
2003-08-13 05:53:07 +04:00
}
2004-10-09 11:11:21 +04:00
if ( lowcase_table = = NULL ) {
2004-10-11 06:07:30 +04:00
lowcase_table = ( void * ) - 1 ;
2003-08-13 05:53:07 +04:00
}
}
/*******************************************************************
2004-10-08 12:13:00 +04:00
Convert a codepoint_t to upper case .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-10-08 12:13:00 +04:00
codepoint_t toupper_w ( codepoint_t val )
2003-08-13 05:53:07 +04:00
{
2004-10-08 12:13:00 +04:00
if ( val < 128 ) {
return toupper ( val ) ;
}
2004-10-11 06:10:45 +04:00
if ( upcase_table = = ( void * ) - 1 ) {
return val ;
}
2004-10-08 12:13:00 +04:00
if ( upcase_table = = NULL ) {
load_case_tables ( ) ;
}
2004-10-11 06:10:45 +04:00
if ( val & 0xFFFF0000 ) {
2004-10-11 06:07:30 +04:00
return val ;
}
2004-10-08 12:13:00 +04:00
return SVAL ( upcase_table , val * 2 ) ;
2003-08-13 05:53:07 +04:00
}
/*******************************************************************
2004-10-08 12:13:00 +04:00
Convert a codepoint_t to lower case .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-10-08 12:13:00 +04:00
codepoint_t tolower_w ( codepoint_t val )
2003-08-13 05:53:07 +04:00
{
2004-10-08 12:13:00 +04:00
if ( val < 128 ) {
return tolower ( val ) ;
}
2004-10-11 06:10:45 +04:00
if ( lowcase_table = = ( void * ) - 1 ) {
return val ;
}
2004-10-08 12:13:00 +04:00
if ( lowcase_table = = NULL ) {
load_case_tables ( ) ;
}
2004-10-11 06:10:45 +04:00
if ( val & 0xFFFF0000 ) {
2004-10-11 06:07:30 +04:00
return val ;
}
2004-10-08 12:13:00 +04:00
return SVAL ( lowcase_table , val * 2 ) ;
2003-08-13 05:53:07 +04:00
}
/*******************************************************************
2004-10-08 12:13:00 +04:00
return the number of bytes occupied by a buffer in CH_UTF16 format
the result includes the null termination
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-10-08 12:13:00 +04:00
size_t utf16_len ( const void * buf )
2003-08-13 05:53:07 +04:00
{
size_t len ;
2004-10-08 12:13:00 +04:00
for ( len = 0 ; SVAL ( buf , len ) ; len + = 2 ) ;
2003-08-13 05:53:07 +04:00
2004-10-08 12:13:00 +04:00
return len + 2 ;
2003-08-13 05:53:07 +04:00
}
/*******************************************************************
2004-10-08 12:13:00 +04:00
return the number of bytes occupied by a buffer in CH_UTF16 format
the result includes the null termination
limited by ' n ' bytes
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-10-08 12:13:00 +04:00
size_t utf16_len_n ( const void * src , size_t n )
2003-08-13 05:53:07 +04:00
{
size_t len ;
2004-10-08 12:13:00 +04:00
for ( len = 0 ; ( len + 2 < n ) & & SVAL ( src , len ) ; len + = 2 ) ;
2003-08-13 05:53:07 +04:00
2004-10-08 12:13:00 +04:00
if ( len + 2 < = n ) {
len + = 2 ;
2003-08-13 05:53:07 +04:00
}
2004-10-08 12:13:00 +04:00
return len ;
2003-08-13 05:53:07 +04:00
}
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
size_t ucs2_align ( const void * base_ptr , const void * p , int flags )
{
if ( flags & ( STR_NOALIGN | STR_ASCII ) )
return 0 ;
return PTR_DIFF ( p , base_ptr ) & 1 ;
}
2004-10-08 12:13:00 +04:00
/*
compare two codepoints case insensitively
*/
int codepoint_cmpi ( codepoint_t c1 , codepoint_t c2 )
{
if ( c1 = = c2 | |
toupper_w ( c1 ) = = toupper_w ( c2 ) ) {
return 0 ;
}
return c1 - c2 ;
}