#include "ldap-int.h"
static char UTF8len[64]
= {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6};
int
LDAP_CALL
ldap_utf8len (const char* s)
{
return ldap_utf8next((char*)s) - s;
}
char*
LDAP_CALL
ldap_utf8next (char* s)
{
register unsigned char* next = (unsigned char*)s;
switch (UTF8len [(*next >> 2) & 0x3F]) {
case 0:
case 6: if ((*++next & 0xC0) != 0x80) break;
case 5: if ((*++next & 0xC0) != 0x80) break;
case 4: if ((*++next & 0xC0) != 0x80) break;
case 3: if ((*++next & 0xC0) != 0x80) break;
case 2: if ((*++next & 0xC0) != 0x80) break;
case 1: ++next;
}
return (char*) next;
}
char*
LDAP_CALL
ldap_utf8prev (char* s)
{
register unsigned char* prev = (unsigned char*)s;
unsigned char* limit = prev - 6;
while (((*--prev & 0xC0) == 0x80) && (prev != limit)) {
;
}
return (char*) prev;
}
int
LDAP_CALL
ldap_utf8copy (char* dst, const char* src)
{
register const unsigned char* s = (const unsigned char*)src;
switch (UTF8len [(*s >> 2) & 0x3F]) {
case 0:
case 6: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 5: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 4: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 3: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 2: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 1: *dst = *s++;
}
return s - (const unsigned char*)src;
}
size_t
LDAP_CALL
ldap_utf8characters (const char* src)
{
register char* s = (char*)src;
size_t n;
for (n = 0; *s; LDAP_UTF8INC(s)) ++n;
return n;
}
unsigned long LDAP_CALL
ldap_utf8getcc( const char** src )
{
register unsigned long c;
register const unsigned char* s = (const unsigned char*)*src;
switch (UTF8len [(*s >> 2) & 0x3F]) {
case 0:
c = (*s++) & 0x3F; goto more5;
case 1: c = (*s++); break;
case 2: c = (*s++) & 0x1F; goto more1;
case 3: c = (*s++) & 0x0F; goto more2;
case 4: c = (*s++) & 0x07; goto more3;
case 5: c = (*s++) & 0x03; goto more4;
case 6: c = (*s++) & 0x01; goto more5;
more5: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more4: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more3: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more2: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more1: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
break;
}
*src = (const char*)s;
return c;
}
char*
LDAP_CALL
ldap_utf8strtok_r( char* sp, const char* brk, char** next)
{
const char *bp;
unsigned long sc, bc;
char *tok;
if (sp == NULL && (sp = *next) == NULL)
return NULL;
cont:
sc = LDAP_UTF8GETC(sp);
for (bp = brk; (bc = LDAP_UTF8GETCC(bp)) != 0;) {
if (sc == bc)
goto cont;
}
if (sc == 0) {
*next = NULL;
return NULL;
}
tok = LDAP_UTF8PREV(sp);
while (1) {
sc = LDAP_UTF8GETC(sp);
bp = brk;
do {
if ((bc = LDAP_UTF8GETCC(bp)) == sc) {
if (sc == 0) {
*next = NULL;
} else {
*next = sp;
*(LDAP_UTF8PREV(sp)) = 0;
}
return tok;
}
} while (bc != 0);
}
}
int
LDAP_CALL
ldap_utf8isalnum( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= 'A' && c <= 'Z') return 1;
if (c >= 'a' && c <= 'z') return 1;
if (c >= '0' && c <= '9') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isalpha( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= 'A' && c <= 'Z') return 1;
if (c >= 'a' && c <= 'z') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isdigit( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= '0' && c <= '9') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isxdigit( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= '0' && c <= '9') return 1;
if (c >= 'A' && c <= 'F') return 1;
if (c >= 'a' && c <= 'f') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isspace( char* s )
{
register unsigned char *c = (unsigned char*)s;
int len = ldap_utf8len(s);
if (len == 0) {
return 0;
} else if (len == 1) {
switch (*c) {
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x20:
return 1;
default:
return 0;
}
} else if (len == 2) {
if (*c == 0xc2) {
return *(c+1) == 0x80;
}
} else if (len == 3) {
if (*c == 0xE2) {
c++;
if (*c == 0x80) {
c++;
return (*c>=0x80 && *c<=0x8a);
}
} else if (*c == 0xE3) {
return (*(c+1)==0x80) && (*(c+2)==0x80);
} else if (*c==0xEF) {
return (*(c+1)==0xBB) && (*(c+2)==0xBF);
}
return 0;
}
return 0;
}