Subversion Repositories HelenOS

Rev

Rev 4196 | Rev 4199 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4196 Rev 4198
Line 42... Line 42...
42
#include <arch.h>
42
#include <arch.h>
43
#include <console/kconsole.h>
43
#include <console/kconsole.h>
44
 
44
 
45
char invalch = '?';
45
char invalch = '?';
46
 
46
 
47
/** Byte mask consisting of bits 0 - (@n - 1) */
47
/** Byte mask consisting of lowest @n bits (out of eight). */
48
#define LO_MASK_8(n) ((uint8_t)((1 << (n)) - 1))
48
#define LO_MASK_8(n) ((uint8_t)((1 << (n)) - 1))
49
 
49
 
-
 
50
/** Byte mask consisting of lowest @n bits (out of 32). */
-
 
51
#define LO_MASK_32(n) ((uint32_t)((1 << (n)) - 1))
-
 
52
 
-
 
53
/** Byte mask consisting of highest @n bits (out of eight). */
-
 
54
#define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))
-
 
55
 
50
/** Number of data bits in a UTF-8 continuation byte. */
56
/** Number of data bits in a UTF-8 continuation byte. */
51
#define CONT_BITS 6
57
#define CONT_BITS 6
52
 
58
 
53
/** Decode a single UTF-8 character from a NULL-terminated string.
59
/** Decode a single UTF-8 character from a NULL-terminated string.
54
 *
60
 *
Line 142... Line 148...
142
 *         Unicode code point.
148
 *         Unicode code point.
143
 *
149
 *
144
 */
150
 */
145
bool utf8_encode(const wchar_t ch, char *str, index_t *index, index_t limit)
151
bool utf8_encode(const wchar_t ch, char *str, index_t *index, index_t limit)
146
{
152
{
-
 
153
    uint32_t cc;        /* Unsigned version of ch. */
-
 
154
 
-
 
155
    int cbytes;     /* Number of continuation bytes. */
-
 
156
    int b0_bits;        /* Number of data bits in first byte. */
-
 
157
    int i;
-
 
158
 
147
    if (*index > limit)
159
    if (*index > limit)
148
        return false;
160
        return false;
149
   
161
 
150
    if ((ch >= 0) && (ch <= 127)) {
-
 
151
        /* Plain ASCII (code points 0 .. 127) */
-
 
152
        str[*index] = ch & 0x7f;
162
    if (ch < 0)
153
        return true;
163
        return false;
154
    }
164
 
-
 
165
    /* Bit operations should only be done on unsigned numbers. */
-
 
166
    cc = (uint32_t) ch;
155
   
167
 
156
    if ((ch >= 128) && (ch <= 2047)) {
168
    /* Determine how many continuation bytes are needed. */
157
        /* Code points 128 .. 2047 */
169
    if ((cc & ~LO_MASK_32(7)) == 0) {
158
        if (*index + 1 > limit)
170
        b0_bits = 7;
159
            return false;
171
        cbytes = 0;
160
       
-
 
161
        str[*index] = 0xc0 | ((ch >> 6) & 0x1f);
172
    } else if ((cc & ~LO_MASK_32(11)) == 0) {
162
        (*index)++;
173
        b0_bits = 5;
163
        str[*index] = 0x80 | (ch & 0x3f);
-
 
164
        return true;
174
        cbytes = 1;
165
    }
-
 
166
   
-
 
167
    if ((ch >= 2048) && (ch <= 65535)) {
175
    } else if ((cc & ~LO_MASK_32(16)) == 0) {
168
        /* Code points 2048 .. 65535 */
-
 
169
        if (*index + 2 > limit)
176
        b0_bits = 4;
170
            return false;
177
        cbytes = 2;
171
       
-
 
172
        str[*index] = 0xe0 | ((ch >> 12) & 0x0f);
178
    } else if ((cc & ~LO_MASK_32(21)) == 0) {
173
        (*index)++;
179
        b0_bits = 3;
174
        str[*index] = 0x80 | ((ch >> 6) & 0x3f);
180
        cbytes = 3;
175
        (*index)++;
181
    } else {
176
        str[*index] = 0x80 | (ch & 0x3f);
182
        /* Codes longer than 21 bits are not supported. */
177
        return true;
183
        return false;
178
    }
184
    }
179
   
185
 
180
    if ((ch >= 65536) && (ch <= 1114111)) {
-
 
181
        /* Code points 65536 .. 1114111 */
186
    /* Check for available space in buffer. */
182
        if (*index + 3 > limit)
187
    if (*index + cbytes > limit)
183
            return false;
188
        return false;
184
       
189
 
185
        str[*index] = 0xf0 | ((ch >> 18) & 0x07);
-
 
186
        (*index)++;
-
 
187
        str[*index] = 0x80 | ((ch >> 12) & 0x3f);
190
    /* Encode continuation bytes. */
188
        (*index)++;
-
 
189
        str[*index] = 0x80 | ((ch >> 6) & 0x3f);
191
    for (i = cbytes; i > 0; --i) {
190
        (*index)++;
-
 
191
        str[*index] = 0x80 | (ch & 0x3f);
192
        str[*index + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
192
        return true;
193
        cc = cc >> CONT_BITS;
193
    }
194
    }
-
 
195
 
-
 
196
    /* Encode first byte. */
-
 
197
    str[*index] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
-
 
198
 
-
 
199
    /* Advance index. */
-
 
200
    *index += cbytes;
194
   
201
   
195
    return false;
202
    return true;
196
}
203
}
197
 
204
 
198
/** Get bytes used by UTF-8 characters.
205
/** Get bytes used by UTF-8 characters.
199
 *
206
 *
200
 * Get the number of bytes (count of plain characters) which
207
 * Get the number of bytes (count of plain characters) which