GSCharacter.h
/* GSCharacter.h
Copyright (C) 2014 Free Software Foundation, Inc.
Written by: Stefan Bidigaray
Date: November, 2014
This file is part of the GNUstep CoreBase Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __GSCHARACTER_H__
#define __GSCHARACTER_H__ 1
#include <CoreFoundation/CFBase.h>
CF_INLINE Boolean
GSCharacterIsASCII (const UTF32Char c)
{
return c < 128;
}
CF_INLINE Boolean
GSCharacterIsWhitespace (const UTF32Char c)
{
return (0x0009 <= c && c <= 0x000D) || (c == 0x0020) || (c == 0x0085)
|| (c == 0x00A0) || (c == 0x1680) || (0x2000 <= c && c <= 0x200A)
|| (c == 0x2028) || (c == 0x2029) || (c == 0x202F) || (c == 0x205F)
|| (c == 0x3000);
}
CF_INLINE Boolean
GSCharacterIsInSupplementaryPlane (const UTF32Char c)
{
return c > 0xFFFF;
}
CF_INLINE Boolean
GSCharacterIsSurrogate (const UTF32Char c)
{
return (c & 0xFFFFF800) == 0xD800;
}
CF_INLINE Boolean
GSCharacterIsLeadSurrogate (const UTF32Char c)
{
return (c & 0xFFFFFC00) == 0xD800;
}
CF_INLINE Boolean
GSCharacterIsTrailSurrogate (const UTF32Char c)
{
return (c & 0xFFFFFC00) == 0xDC00;
}
#define kGSUTF8CharacterMaximumLength 4
CF_INLINE CFIndex
GSUTF8CharacterTrailBytesCount (const UTF8Char c)
{
return (c < 0xF5) ? (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0) : 0;
}
CF_INLINE Boolean
GSUTF8CharacterIsTrailing (const UTF8Char c)
{
return (c & 0xC0) == 0x80;
}
CF_INLINE CFIndex
GSUTF8CharacterLength (const UTF32Char c)
{
return (c <= 0x10FFFF) ? 1 + (c >= 0x80) + (c >= 0x800) + (c >= 0x10000) : 0;
}
CF_INLINE CFIndex
GSUTF8CharacterAppendByteOrderMark (UTF8Char * d, const UTF8Char * limit)
{
if ((limit - d) > 3)
{
d[0] = 0xEF;
d[1] = 0xBB;
d[2] = 0xBF;
}
return 3;
}
CF_INLINE Boolean
GSUTF8CharacterSkipByteOrderMark (const UTF8Char ** s, const UTF8Char * limit)
{
const UTF8Char *p;
p = *s;
if ((limit - p) > 3)
{
if (*p++ == 0xEF && *p++ == 0xBB && *p++ == 0xBF)
{
*s = p;
return true;
}
}
return false;
}
CF_INLINE CFIndex
GSUTF8CharacterAppend (UTF8Char * d, const UTF8Char * limit, UTF32Char c)
{
static const UTF8Char utf8LeadHeader[4] = { 0x00, 0xC0, 0xE0, 0xF0 };
CFIndex l;
if (GSCharacterIsSurrogate (c))
return 0;
l = GSUTF8CharacterLength (c);
if (l && limit - d > l)
{
switch (l)
{
case 4:
d[3] = (c & 0x3F) | 0x80;
c >>= 6;
case 3:
d[2] = (c & 0x3F) | 0x80;
c >>= 6;
case 2:
d[1] = (c & 0x3F) | 0x80;
c >>= 6;
case 1:
d[0] = c | utf8LeadHeader[l - 1];
}
}
return l;
}
CF_INLINE CFIndex
GSUTF8CharacterGet (const UTF8Char * s, const UTF8Char * limit, UTF32Char *c)
{
static const UTF32Char utf8LeadMask[4] = { 0x0, 0x1F, 0x0F, 0x07 };
const UTF8Char *start;
UTF32Char ch;
start = s;
ch = *s++;
if (ch > 0x7F)
{
CFIndex trail;
trail = GSUTF8CharacterTrailBytesCount (ch);
if (limit - s < trail)
trail = 0; /* Force an error */
ch &= utf8LeadMask[trail];
switch (trail)
{
case 3:
if (!GSUTF8CharacterIsTrailing (*s))
{
s = start;
break;
}
ch = (ch << 6) | (*s++ & 0x3F);
case 2:
if (!GSUTF8CharacterIsTrailing (*s))
{
s = start;
break;
}
ch = (ch << 6) | (*s++ & 0x3F);
case 1:
if (!GSUTF8CharacterIsTrailing (*s))
{
s = start;
break;
}
ch = (ch << 6) | (*s++ & 0x3F);
break;
case 0:
s = start;
break;
}
}
*c = ch;
return s - start;
}
#define kGSUTF16CharacterMaximumLength 2
#define kGSUTF16CharacterByteOrderMark 0xFEFF
#define kGSUTF16CharacterSwappedByteOrderMark 0xFFFE
CF_INLINE CFIndex
GSUTF16CharacterAppend (UTF16Char * d, const UTF16Char * limit, UTF32Char c)
{
if (c <= 0xFFFF)
{
if ((limit - d) > 1)
*d = c;
return 1;
}
else if (c <= 0x10FFFF)
{
if ((limit - d) > 2)
{
d[0] = (c >> 10) + 0xD7C0;
d[1] = (c & 0x3FF) + 0xDC00;
}
return 2;
}
return 0;
}
CF_INLINE CFIndex
GSUTF16CharacterGet (const UTF16Char * s, const UTF16Char * limit, UTF32Char *c)
{
const UTF16Char *start;
UTF32Char ch;
start = s;
ch = *s++;
if (GSCharacterIsSurrogate (ch))
{
if (GSCharacterIsLeadSurrogate (ch) && s < limit
&& GSCharacterIsTrailSurrogate (*s))
ch = (ch << 10) + (*s++) - ((0xD7C0 << 10) + 0xDC00);
else
--s;
}
*c = ch;
return s - start;
}
#define kGSUTF32CharacterByteOrderMark 0x0000FEFF
#define kGSUTF32CharacterSwappedByteOrderMark 0xFFFE0000
#endif /* __GSCHARACTER_H__ */
CFIndex
signed long CFIndex
Definition CFBase.h:165
GSUTF8CharacterIsTrailing
Boolean GSUTF8CharacterIsTrailing(const UTF8Char c)
Determines if the specified UTF-8 code unit is a trailing code unit.
Definition GSCharacter.h:128
GSUTF8CharacterGet
CFIndex GSUTF8CharacterGet(const UTF8Char *s, const UTF8Char *limit, UTF32Char *c)
Get a Unicode code unit from a UTF-8 string buffer.
Definition GSCharacter.h:241
GSUTF16CharacterGet
CFIndex GSUTF16CharacterGet(const UTF16Char *s, const UTF16Char *limit, UTF32Char *c)
Get a Unicode code point from a UTF-16 string buffer.
Definition GSCharacter.h:352
GSCharacterIsTrailSurrogate
Boolean GSCharacterIsTrailSurrogate(const UTF32Char c)
Determine if character is a trailing surrogate code point.
Definition GSCharacter.h:97
GSCharacterIsInSupplementaryPlane
Boolean GSCharacterIsInSupplementaryPlane(const UTF32Char c)
Determine if character is in one of the supplementary planes.
Definition GSCharacter.h:67
GSUTF8CharacterAppendByteOrderMark
CFIndex GSUTF8CharacterAppendByteOrderMark(UTF8Char *d, const UTF8Char *limit)
Append the UTF-8 Byte Order Mark to the string buffer.
Definition GSCharacter.h:151
GSCharacterIsWhitespace
Boolean GSCharacterIsWhitespace(const UTF32Char c)
Determine if a character is a whitespace character.
Definition GSCharacter.h:53
GSCharacterIsASCII
Boolean GSCharacterIsASCII(const UTF32Char c)
Determine if a character is an ASCII character (less than 128).
Definition GSCharacter.h:43
GSCharacterIsLeadSurrogate
Boolean GSCharacterIsLeadSurrogate(const UTF32Char c)
Determine if character is a leading surrogate code point.
Definition GSCharacter.h:87
GSCharacterIsSurrogate
Boolean GSCharacterIsSurrogate(const UTF32Char c)
Determine true if character is a surrogate code point.
Definition GSCharacter.h:77
GSUTF8CharacterTrailBytesCount
CFIndex GSUTF8CharacterTrailBytesCount(const UTF8Char c)
Determine the number of trailing bytes for a UTF-8 character based on the leading code unit.
Definition GSCharacter.h:118
GSUTF8CharacterLength
CFIndex GSUTF8CharacterLength(const UTF32Char c)
Determine the number of UTF-8 code units required to represent the specified Unicode code point.
Definition GSCharacter.h:139
GSUTF16CharacterAppend
CFIndex GSUTF16CharacterAppend(UTF16Char *d, const UTF16Char *limit, UTF32Char c)
Append a character to a UTF-16 string buffer.
Definition GSCharacter.h:318
GSUTF8CharacterAppend
CFIndex GSUTF8CharacterAppend(UTF8Char *d, const UTF8Char *limit, UTF32Char c)
Append a character to a UTF-8 string buffer.
Definition GSCharacter.h:198
GSUTF8CharacterSkipByteOrderMark
Boolean GSUTF8CharacterSkipByteOrderMark(const UTF8Char **s, const UTF8Char *limit)
Determine if a UTF-8 string buffer has a Byte Order Mark.
Definition GSCharacter.h:172