00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define KATE_INTERNAL
00011 #include "kate_internal.h"
00012
00013 #ifdef HAVE_STRING_H
00014 #include <string.h>
00015 #endif
00016 #include "kate/kate.h"
00017
00018
00019
00020 inline int kate_is_valid_code_point(int c)
00021 {
00022
00023 if (c>=0xd800 && c<=0xdfff) return 0;
00024 if (c>=0xfffe && c<=0xffff) return 0;
00025
00026 #ifdef ENABLE_CODE_POINTS_ABOVE_0x10ffff
00027 return c>=0 && c<=0x7fffffff;
00028 #else
00029 return c>=0 && c<=0x10ffff;
00030 #endif
00031 }
00032
00033 static inline int get_bytes_for_code_point(int c) __attribute__((const));
00034 static inline int get_bytes_for_code_point(int c)
00035 {
00036 if (!kate_is_valid_code_point(c)) return -1;
00037 if (c<=0x7f) return 1;
00038 if (c<=0x7ff) return 2;
00039 if (c<=0xffff) return 3;
00040 #ifdef ENABLE_CODE_POINTS_ABOVE_0x10ffff
00041 if (c<=0x001fffff) return 4;
00042 if (c<=0x03ffffff) return 5;
00043 if (c<=0x7fffffff) return 6;
00044 #else
00045 if (c<=0x10ffff) return 4;
00046 #endif
00047 return -1;
00048 }
00049
00050 static int kate_text_utf8_read(const char *s,int *cp)
00051 {
00052 int c;
00053
00054 if (!s) return KATE_E_INVALID_PARAMETER;
00055
00056 c=0;
00057
00058 if (((*s)&0x80)==0) {
00059
00060 c=*s;
00061
00062 *cp=c;
00063 return 1;
00064 }
00065 else if (((*s)&0xe0)==0xc0) {
00066
00067 c|=(((*s)&0x1f)<<6);
00068 s++;
00069 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00070 c|=((*s)&0x3f);
00071 if (c<=0x7f) return KATE_E_TEXT;
00072
00073 *cp=c;
00074 return 2;
00075 }
00076 else if (((*s)&0xf0)==0xe0) {
00077
00078 c|=(((*s)&0xf)<<12);
00079 s++;
00080 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00081 c|=(((*s)&0x3f)<<6);
00082 s++;
00083 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00084 c|=(((*s)&0x3f));
00085 if (c<=0x7ff) return KATE_E_TEXT;
00086
00087 *cp=c;
00088 return 3;
00089 }
00090 else if (((*s)&0xf8)==0xf0) {
00091
00092 c|=(((*s)&0x7)<<18);
00093 s++;
00094 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00095 c|=(((*s)&0x3f)<<12);
00096 s++;
00097 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00098 c|=(((*s)&0x3f)<<6);
00099 s++;
00100 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00101 c|=(((*s)&0x3f));
00102 if (c<=0xffff) return KATE_E_TEXT;
00103
00104 *cp=c;
00105 return 4;
00106 }
00107 #ifdef ENABLE_CODE_POINTS_ABOVE_0x10ffff
00108
00109 else if (((*s)&0xfc)==0xf8) {
00110
00111 c|=(((*s)&0x3)<<24);
00112 s++;
00113 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00114 c|=(((*s)&0x3f)<<18);
00115 s++;
00116 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00117 c|=(((*s)&0x3f)<<12);
00118 s++;
00119 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00120 c|=(((*s)&0x3f)<<6);
00121 s++;
00122 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00123 c|=(((*s)&0x3f));
00124 if (c<=0x001fffff) return KATE_E_TEXT;
00125
00126 *cp=c;
00127 return 5;
00128 }
00129 else if (((*s)&0xfe)==0xfc) {
00130
00131 c|=(((*s)&0x1)<<30);
00132 s++;
00133 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00134 c|=(((*s)&0x3f)<<24);
00135 s++;
00136 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00137 c|=(((*s)&0x3f)<<18);
00138 s++;
00139 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00140 c|=(((*s)&0x3f)<<12);
00141 s++;
00142 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00143 c|=(((*s)&0x3f)<<6);
00144 s++;
00145 if (((*s)&0xc0)!=0x80) return KATE_E_TEXT;
00146 c|=(((*s)&0x3f));
00147 if (c<=0x03ffffff) return KATE_E_TEXT;
00148
00149 *cp=c;
00150 return 6;
00151 }
00152 #endif
00153
00154 return KATE_E_TEXT;
00155 }
00156
00157 static int kate_text_utf8_write(char *s,int cp)
00158 {
00159 int bytes;
00160
00161 if (!s) return KATE_E_INVALID_PARAMETER;
00162 if (!kate_is_valid_code_point(cp)) return KATE_E_INVALID_PARAMETER;
00163
00164 bytes=get_bytes_for_code_point(cp);
00165 if (bytes<=0) return KATE_E_INVALID_PARAMETER;
00166
00167 switch (bytes) {
00168 case 1:
00169 *s++=cp;
00170 break;
00171 case 2:
00172 *s++=0xc0 | (cp>>6);
00173 *s++=0x80 | (cp&0x3f);
00174 break;
00175 case 3:
00176 *s++=0xe0 | (cp>>12);
00177 *s++=0x80 | ((cp>>6)&0x3f);
00178 *s++=0x80 | (cp&0x3f);
00179 break;
00180 case 4:
00181 *s++=0xf0 | (cp>>18);
00182 *s++=0x80 | ((cp>>12)&0x3f);
00183 *s++=0x80 | ((cp>>6)&0x3f);
00184 *s++=0x80 | (cp&0x3f);
00185 break;
00186 #ifdef ENABLE_CODE_POINTS_ABOVE_0x10ffff
00187 case 5:
00188 *s++=0xf8 | (cp>>24);
00189 *s++=0x80 | ((cp>>18)&0x3f);
00190 *s++=0x80 | ((cp>>12)&0x3f);
00191 *s++=0x80 | ((cp>>6)&0x3f);
00192 *s++=0x80 | (cp&0x3f);
00193 break;
00194 case 6:
00195 *s++=0xfc | (cp>>30);
00196 *s++=0x80 | ((cp>>24)&0x3f);
00197 *s++=0x80 | ((cp>>18)&0x3f);
00198 *s++=0x80 | ((cp>>12)&0x3f);
00199 *s++=0x80 | ((cp>>6)&0x3f);
00200 *s++=0x80 | (cp&0x3f);
00201 break;
00202 #endif
00203 default:
00204 return KATE_E_INVALID_PARAMETER;
00205 }
00206 return bytes;
00207 }
00208
00218 int kate_text_get_character(kate_text_encoding text_encoding,const char ** const text,size_t *len0)
00219 {
00220 const char *new_text;
00221 int c,ret;
00222 size_t bytes;
00223
00224 if (!text || !len0) return KATE_E_INVALID_PARAMETER;
00225
00226 switch (text_encoding) {
00227 case kate_utf8:
00228 new_text=*text;
00229 ret=kate_text_utf8_read(new_text,&c);
00230 if (ret<0) return ret;
00231 bytes=ret;
00232 if (bytes>*len0) return KATE_E_TEXT;
00233 *len0-=bytes;
00234 *text+=bytes;
00235 return c;
00236 default:
00237 return KATE_E_INVALID_PARAMETER;
00238 }
00239 }
00240
00251 int kate_text_set_character(kate_text_encoding text_encoding,int c,char ** const text,size_t *len0)
00252 {
00253 char tmp[8]={0};
00254 size_t bytes;
00255 int ret;
00256
00257 if (!text || !len0) return KATE_E_INVALID_PARAMETER;
00258
00259 switch (text_encoding) {
00260 case kate_utf8:
00261 ret=kate_text_utf8_write(tmp,c);
00262 if (ret<0) return ret;
00263 bytes=ret;
00264 if (bytes>*len0) return KATE_E_TEXT;
00265 memcpy(*text,tmp,bytes);
00266 *text+=bytes;
00267 *len0-=bytes;
00268 return bytes;
00269 default:
00270 return KATE_E_INVALID_PARAMETER;
00271 }
00272 }
00273
00283 int kate_text_remove_markup(kate_text_encoding text_encoding,char *text,size_t *len0)
00284 {
00285 char *r=text,*w=text;
00286 int in_tag=0;
00287 size_t n;
00288
00289 if (!text || !len0) return KATE_E_INVALID_PARAMETER;
00290
00291 switch (text_encoding) {
00292 case kate_utf8:
00293 while (*r && (size_t)(r-text)<*len0) {
00294 int ret,c;
00295 ret=kate_text_utf8_read(r,&c);
00296 if (ret<0) return ret;
00297 r+=ret;
00298 if (r>text+*len0) {
00299
00300 break;
00301 }
00302 if (c=='<') {
00303 in_tag++;
00304
00305 if (*len0>=3 && !strncmp(r,"br>",3)) {
00306 ret=kate_text_utf8_write(w,'\n');
00307 if (ret<0) return ret;
00308 w+=ret;
00309 }
00310 }
00311 if (!in_tag) {
00312 ret=kate_text_utf8_write(w,c);
00313 if (ret<0) return ret;
00314 w+=ret;
00315 }
00316 if (c=='>') {
00317 in_tag--;
00318 }
00319 }
00320
00321 for (n=0;n<*len0-(w-text);++n) w[n]=0;
00322
00323 *len0=w-text;
00324 break;
00325 default:
00326 return KATE_E_INVALID_PARAMETER;
00327 }
00328
00329 return 0;
00330 }
00331
00341 int kate_text_validate(kate_text_encoding text_encoding,const char *text,size_t len0)
00342 {
00343 if (!text) return KATE_E_INVALID_PARAMETER;
00344
00345 switch (text_encoding) {
00346 case kate_utf8:
00347 while (len0>0) {
00348 int ret,c;
00349 ret=kate_text_utf8_read(text,&c);
00350 if (ret<0) return ret;
00351 if (!kate_is_valid_code_point(c)) return KATE_E_TEXT;
00352 if ((size_t)ret>len0) {
00353
00354 return KATE_E_TEXT;
00355 }
00356 text+=ret;
00357 len0-=ret;
00358 }
00359 break;
00360 default:
00361 return KATE_E_INVALID_PARAMETER;
00362 }
00363
00364 return 0;
00365 }
00366