Subversion Repositories HelenOS

Rev

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

Rev 4212 Rev 4223
Line 107... Line 107...
107
#include <arch/asm.h>
107
#include <arch/asm.h>
108
#include <arch.h>
108
#include <arch.h>
109
#include <errno.h>
109
#include <errno.h>
110
#include <align.h>
110
#include <align.h>
111
 
111
 
112
char invalch = '?';
-
 
113
 
-
 
114
/** Byte mask consisting of lowest @n bits (out of 8) */
112
/** Byte mask consisting of lowest @n bits (out of 8) */
115
#define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
113
#define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
116
 
114
 
117
/** Byte mask consisting of lowest @n bits (out of 32) */
115
/** Byte mask consisting of lowest @n bits (out of 32) */
118
#define LO_MASK_32(n)  ((uint32_t) ((1 << (n)) - 1))
116
#define LO_MASK_32(n)  ((uint32_t) ((1 << (n)) - 1))
Line 132... Line 130...
132
 *
130
 *
133
 * @param str    String (not necessarily NULL-terminated).
131
 * @param str    String (not necessarily NULL-terminated).
134
 * @param offset Byte offset in string where to start decoding.
132
 * @param offset Byte offset in string where to start decoding.
135
 * @param size   Size of the string (in bytes).
133
 * @param size   Size of the string (in bytes).
136
 *
134
 *
137
 * @return Value of decoded character, invalch on decoding error or
135
 * @return Value of decoded character, U_SPECIAL on decoding error or
138
 *         NULL if attempt to decode beyond @a size.
136
 *         NULL if attempt to decode beyond @a size.
139
 *
137
 *
140
 */
138
 */
141
wchar_t str_decode(const char *str, size_t *offset, size_t size)
139
wchar_t str_decode(const char *str, size_t *offset, size_t size)
142
{
140
{
Line 167... Line 165...
167
        /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
165
        /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
168
        b0_bits = 3;
166
        b0_bits = 3;
169
        cbytes = 3;
167
        cbytes = 3;
170
    } else {
168
    } else {
171
        /* 10xxxxxx -- unexpected continuation byte */
169
        /* 10xxxxxx -- unexpected continuation byte */
172
        return invalch;
170
        return U_SPECIAL;
173
    }
171
    }
174
   
172
   
175
    if (*offset + cbytes > size)
173
    if (*offset + cbytes > size)
176
        return invalch;
174
        return U_SPECIAL;
177
   
175
   
178
    wchar_t ch = b0 & LO_MASK_8(b0_bits);
176
    wchar_t ch = b0 & LO_MASK_8(b0_bits);
179
   
177
   
180
    /* Decode continuation bytes */
178
    /* Decode continuation bytes */
181
    while (cbytes > 0) {
179
    while (cbytes > 0) {
182
        uint8_t b = (uint8_t) str[(*offset)++];
180
        uint8_t b = (uint8_t) str[(*offset)++];
183
       
181
       
184
        /* Must be 10xxxxxx */
182
        /* Must be 10xxxxxx */
185
        if ((b & 0xc0) != 0x80)
183
        if ((b & 0xc0) != 0x80)
186
            return invalch;
184
            return U_SPECIAL;
187
       
185
       
188
        /* Shift data bits to ch */
186
        /* Shift data bits to ch */
189
        ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
187
        ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
190
        cbytes--;
188
        cbytes--;
191
    }
189
    }