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