/[public]/psiconv/trunk/lib/psiconv/unicode.c
ViewVC logotype

Diff of /psiconv/trunk/lib/psiconv/unicode.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 184 Revision 231
1/* 1/*
2 unicode.c - Part of psiconv, a PSION 5 file formats converter 2 unicode.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 2003 Frodo Looijaard <frodol@dds.nl> 3 Copyright (c) 2003-2004 Frodo Looijaard <frodol@dds.nl>
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version. 8 (at your option) any later version.
20#include "config.h" 20#include "config.h"
21#include "compat.h" 21#include "compat.h"
22#include "error.h" 22#include "error.h"
23 23
24#include "unicode.h" 24#include "unicode.h"
25#include "parse_routines.h"
26#include "generate_routines.h"
25 27
26#include <string.h> 28#include <string.h>
27 29
28#ifdef DMALLOC 30#ifdef DMALLOC
29#include <dmalloc.h> 31#include <dmalloc.h>
84 } 86 }
85 return 0; 87 return 0;
86} 88}
87 89
88 90
89psiconv_ucs2 psiconv_unicode_from_char(const psiconv_config config, 91psiconv_ucs2 psiconv_unicode_read_char(const psiconv_config config,
90 psiconv_u8 input) 92 psiconv_buffer buf,
93 int lev,psiconv_u32 off,
94 int *length,int *status)
91{ 95{
96 psiconv_u8 char1,char2,char3;
97 psiconv_ucs2 result=0;
98 int res;
99 int len=0;
100
101 char1 = psiconv_read_u8(config,buf,lev,off+len,&res);
102 if (res)
103 goto ERROR;
104 len ++;
105
106 if (config->unicode) {
107 if (char1 >= 0xf0) {
108 res = PSICONV_E_PARSE;
109 goto ERROR;
110 } else if (char1 < 0x80)
111 result = char1;
112 else {
113 char2 = psiconv_read_u8(config,buf,lev,off+len,&res);
114 len ++;
115 if ((char2 & 0xc0) != 0x80) {
116 res = PSICONV_E_PARSE;
117 goto ERROR;
118 }
119 if (char1 < 0xe0)
120 result = ((char1 & 0x1f) << 6) | (char2 & 0x3f);
121 else {
122 char3 = psiconv_read_u8(config,buf,lev,off+len,&res);
123 len ++;
124 if ((char3 & 0xc0) != 0x80) {
125 res = PSICONV_E_PARSE;
126 goto ERROR;
127 }
128 result = ((char1 & 0x0f) << 12) | ((char2 & 0x3f) << 6) |
129 (char3 & 0x3f);
130 }
131 }
132 } else
92 return config->unicode_table[input]?config->unicode_table[input]: 133 result = config->unicode_table[char1]?config->unicode_table[char1]:
93 config->unknown_unicode_char; 134 config->unknown_unicode_char;
135ERROR:
136 if (length)
137 *length = len;
138 if (status)
139 *status = res;
140 return result;
94} 141}
95 142
96/* This is quite inefficient at the moment; the obvious ways of making it 143int psiconv_unicode_write_char(const psiconv_config config,
97 faster consume quite a bit of memory, though */ 144 psiconv_buffer buf,
98psiconv_u8 psiconv_unicode_to_char(psiconv_config config,psiconv_ucs2 input) 145 int lev, psiconv_ucs2 value)
99{ 146{
100 int i; 147 int i;
148 int res=0;
149
150 if (config->unicode) {
151 if (value < 0x80) {
152 if ((res = psiconv_write_u8(config,buf,lev,value)))
153 goto ERROR;
154 } else if (value < 0x800) {
155 if ((res = psiconv_write_u8(config,buf,lev,0xc0 | (value >> 6))))
156 goto ERROR;
157 if ((res = psiconv_write_u8(config,buf,lev,0x80 | (value & 0x3f))))
158 goto ERROR;
159 } else {
160 if ((res = psiconv_write_u8(config,buf,lev,0xe0 | (value >> 12))))
161 goto ERROR;
162 if ((res = psiconv_write_u8(config,buf,lev,0x80 | ((value >> 6) & 0x3f))))
163 goto ERROR;
164 if ((res = psiconv_write_u8(config,buf,lev,0x80 | (value & 0x3f))))
165 goto ERROR;
166 }
167 } else {
101 for (i = 0; i < 256; i++) 168 for (i = 0; i < 256; i++)
102 if (config->unicode_table[i] == input) 169 if (config->unicode_table[i] == value)
103 break; 170 break;
104 return (i == 256?config->unknown_epoc_char:i); 171 if ((res = psiconv_write_u8(config,buf,lev,
105} 172 i == 256?config->unknown_epoc_char:i)))
106 173 goto ERROR;
107int psiconv_unicode_from_chars(const psiconv_config config, 174 }
108 const psiconv_u8 *input, 175ERROR:
109 psiconv_ucs2 **output) 176 return res;
110{
111 int i;
112 if (!output)
113 return PSICONV_E_NOMEM;
114 if (!(*output = malloc(sizeof(**output) * (1 + strlen(input)))))
115 return PSICONV_E_NOMEM;
116 for (i = 0; i < strlen(input); i++)
117 (*output)[i] = psiconv_unicode_from_char(config,input[i]);
118 (*output)[i] = 0x0000;
119 return PSICONV_E_OK;
120}
121
122int psiconv_unicode_to_chars(const psiconv_config config,
123 const psiconv_ucs2 *input,
124 psiconv_u8 **output)
125{
126 int i;
127 if (!output)
128 return -PSICONV_E_NOMEM;
129 if (!(*output = malloc(sizeof(**output) *
130 (1 + psiconv_unicode_strlen(input)))))
131 return -PSICONV_E_NOMEM;
132 for (i = 0; i < psiconv_unicode_strlen(input); i++)
133 (*output)[i] = psiconv_unicode_to_char(config,input[i]);
134 (*output)[i] = 0x00;
135 return -PSICONV_E_OK;
136} 177}
137 178
138int psiconv_unicode_strlen(const psiconv_ucs2 *input) 179int psiconv_unicode_strlen(const psiconv_ucs2 *input)
139{ 180{
140 int i = 0; 181 int i = 0;
144} 185}
145 186
146psiconv_ucs2 *psiconv_unicode_strdup(const psiconv_ucs2 *input) 187psiconv_ucs2 *psiconv_unicode_strdup(const psiconv_ucs2 *input)
147{ 188{
148 psiconv_ucs2 *output; 189 psiconv_ucs2 *output;
149 int i = 0; 190 int i = 0;
150 191
151 if (!(output = malloc(sizeof(*output) * 192 if (!(output = malloc(sizeof(*output) *
152 (1 + psiconv_unicode_strlen(input))))) 193 (1 + psiconv_unicode_strlen(input)))))
153 return NULL; 194 return NULL;
154 while ((output[i] = input[i])) 195 while ((output[i] = input[i]))
172 return 1; 213 return 1;
173 else 214 else
174 return 0; 215 return 0;
175} 216}
176 217
218
219psiconv_ucs2 *psiconv_unicode_empty_string(void)
220{
221 psiconv_ucs2 *result;
222 result = malloc(sizeof(psiconv_ucs2));
223 if (result)
224 result[0] = 0;
225 return result;
226}
227
228
229psiconv_ucs2 *psiconv_unicode_from_list(psiconv_list input)
230{
231 psiconv_ucs2 *result;
232 int i;
233 psiconv_ucs2 *character;
234
235 if (!(result = malloc(sizeof(psiconv_ucs2) * (psiconv_list_length(input)+1))))
236 goto ERROR1;
237 for (i = 0; i < psiconv_list_length(input); i++) {
238 if (!(character = psiconv_list_get(input,i)))
239 goto ERROR2;
240 result[i] = *character;
241 }
242 result[i] = 0;
243 return result;
244
245ERROR2:
246 free(result);
247ERROR1:
248 return NULL;
249}
250
251
252psiconv_ucs2 *psiconv_unicode_strstr(const psiconv_ucs2 *haystack,
253 const psiconv_ucs2 *needle)
254{
255 int i,j,haystack_len,needle_len;
256 haystack_len = psiconv_unicode_strlen(haystack);
257 needle_len = psiconv_unicode_strlen(needle);
258
259
260
261 for (i = 0; i < haystack_len - needle_len + 1; i++) {
262 for (j = 0; j < needle_len; j++)
263 if (haystack[i+j] != needle[j])
264 break;
265 if (j == needle_len)
266 return (psiconv_ucs2 *) haystack+i;
267 }
268 return NULL;
269}

Legend:
Removed from v.184  
changed lines
  Added in v.231

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26