2fd1566cac3f0951969026f0ccc943f1f8eb1349
[chise/concord.git] / read.c
1 /* Copyright (C) 2013 MORIOKA Tomohiko
2    This file is part of the CONCORD Library.
3
4    The CONCORD Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The CONCORD Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the CONCORD Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <stdlib.h>
20 #include "cos-read.h"
21
22 int
23 cos_read_utf8 (unsigned char *str, size_t len, size_t start, size_t* endp)
24 {
25   size_t i = start;
26
27   if ( len >= i + 1 )
28     {
29       unsigned char c = str[i++];
30       int counter;
31       int cid;
32
33       if ( c < 0xC0 )
34         {
35           cid = c;
36           counter = 0;
37         }
38       else if ( c < 0xE0 )
39         {
40           cid = c & 0x1f;
41           counter = 1;
42         }
43       else if ( c < 0xF0 )
44         {
45           cid = c & 0x0f;
46           counter = 2;
47         }
48       else if ( c < 0xF8 )
49         {
50           cid = c & 0x07;
51           counter = 3;
52         }
53       else if ( c < 0xFC )
54         {
55           cid = c & 0x03;
56           counter = 4;
57         }
58       else
59         {
60           cid = c & 0x01;
61           counter = 5;
62         }
63
64       if (counter + i <= len)
65         {
66           int j;
67
68           for (j = 0; j < counter; j++)
69             cid = (cid << 6) | (str[i++] & 0x3F);
70           *endp = i;
71           return cid;
72         }
73     }
74   return -1;
75 }
76
77 int
78 cos_read_char (unsigned char *str, size_t len, size_t start, size_t* endp)
79 {
80   size_t i = start;
81
82   if ( (len >= start + 2) && (str[i++] == '?') )
83     {
84       if ( (len >= start + 3) && (str[i] == '\\') )
85         {
86           i++;
87           return cos_read_utf8 (str, len, i, endp);
88         }
89       else
90         return cos_read_utf8 (str, len, i, endp);
91     }
92
93   return -1;
94 }
95
96 COS_String
97 cos_read_string (unsigned char *str, size_t len, size_t start, size_t* endp)
98 {
99   size_t i = start;
100   int c;
101
102   if ( (len >= start + 2) && (str[i++] == '"') )
103     {
104       while ( ( i < len )
105               && ( (c = cos_read_utf8 (str, len, i, &i)) >= 0 )
106               )
107         {
108           if ( c == '"' )
109             {
110               return cos_make_string ((char*)&str[1], i - 2);
111             }
112           else if ( c == '\\' )
113             {
114               i++;
115               if ( cos_read_utf8 (str, len, i, &i) < 0 )
116                 return NULL;
117             }
118         }
119     }
120   return NULL;
121 }