aboutsummaryrefslogtreecommitdiff
path: root/src/libutf/decodeprev.c
blob: 27dced6b0c47d32b07e1aaafa1313fb3706970d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "internal.h"

#define ACCEPT 0
#define REJECT 12

static uint8 decode[] = {
    /*
     * the first part of the table maps bytes to character classes that
     * to reduce the size of the transition table and create bitmasks.
     */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
         8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
        10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
    /*
     * The second part is a transition table that maps a combination
     * of a state of the automaton and a character class to a state.
     */
    //   0  1  2  3  4  5  6  7  8  9 10 11
         0,24,12,12,12,12,12,24,12,24,12,12,
         0,24,12,12,12,12,12,24,12,24,12,12,
        12,36, 0,12,12,12,12,48,12,36,12,12,
        12,60,12, 0, 0,12,12,72,12,72,12,12,
        12,60,12, 0,12,12,12,72,12,72, 0,12,
        12,12,12,12,12, 0, 0,12,12,12,12,12,
        12,12,12,12,12,12,12,12,12,12,12, 0
};

int
utf8ยทdecodeprev(byte *s, rune *r)
{
    int   n;
    rune  v;
    uint8 b, t, d, x=ACCEPT;

    v=0, n=0, d=0;
nextbyte:
    b = ((uint8 *)s)[-n++];
    t = decode[b];
    x = decode[256+x+t];

    if(x > REJECT && n < UTFmax){
        v = v | ((b & TMask) << d);
        d += 6;
        goto nextbyte;
    }

    if(x != ACCEPT)
        *r = RuneErr;
    else{
        v |= (((0xFFu >> t) & b) << d);
        *r = v;
    }

    return n;
}