- Main Page
- Related Pages
- Data Structures
- Files
- Examples

- File List

# /home/v/Kate/WORK_TREES/kate-sorceress-backup/v/src/kate/src/kate_text.c

    00001 /* Copyright (C) 2008 Vincent Penquerc'h.
    00002    This file is part of the Kate codec library.
    00003    Written by Vincent Penquerc'h.
    00004
    00005    Use, distribution and reproduction of this library is governed
    00006    by a BSD style source license included with this source in the
    00007    file 'COPYING'. Please read these terms before distributing. */
    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 /* #define ENABLE_CODE_POINTS_ABOVE_0x10ffff */
    00019
    00020 inline int kate_is_valid_code_point(int c)
    00021 {
    00022   /* surrogate range is invalid */
    00023   if (c>=0xd800 && c<=0xdfff) return 0; /* UTF-16 surrogates */
    00024   if (c>=0xfffe && c<=0xffff) return 0; /* Markus Kuhn's UTF-8 test files says these are invalid */
    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     /* 1 byte */
    00060     c=*s;
    00061
    00062     *cp=c;
    00063     return 1;
    00064   }
    00065   else if (((*s)&0xe0)==0xc0) {
    00066     /* 2 bytes */
    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     /* 3 bytes */
    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     /* 4 bytes */
    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   /* 5 and 6 bytes are for unicode code points not yet assigned */
    00109   else if (((*s)&0xfc)==0xf8) {
    00110     /* 5 bytes */
    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     /* 6 bytes */
    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           /* we went over the limit, we probably read dummy data, discard */
    00300           break;
    00301         }
    00302         if (c=='<') {
    00303           in_tag++;
    00304           /* add a newline if we just removed a br */
    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       /* zero all bytes we removed */
    00321       for (n=0;n<*len0-(w-text);++n) w[n]=0;
    00322       /* adjust len0 to new size */
    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           /* we went over the limit, we probably read dummy data, discard */
    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