Merge branch 'master' into polymorphic_extern_classes
[nit.git] / lib / string_experimentations / utf8.nit
index dc177ca..14f8550 100644 (file)
@@ -16,6 +16,7 @@
 module utf8
 
 intrude import standard::string
+intrude import standard::file
 
 in "C Header" `{
 
@@ -98,6 +99,40 @@ extern class UnicodeChar `{ UTF8Char* `}
                }
        `}
 
+       # Returns an upper-case version of self
+       #
+       # NOTE : Works only on ASCII chars
+       # TODO : Support unicode for to_upper
+       fun to_upper: UnicodeChar import UnicodeChar.code_point `{
+               int cp = UnicodeChar_code_point(recv);
+               if(cp < 97 || cp > 122){ return recv; }
+               char* ns = malloc(2);
+               ns[1] = '\0';
+               char c = recv->ns[recv->pos];
+               ns[0] = c - 32;
+               UTF8Char* ret = malloc(sizeof(UTF8Char));
+               ret->ns = ns;
+               ret->pos = 0;
+               return ret;
+       `}
+
+       # Returns an lower-case version of self
+       #
+       # NOTE : Works only on ASCII chars
+       # TODO : Support unicode for to_upper
+       fun to_lower: UnicodeChar import UnicodeChar.code_point `{
+               int cp = UnicodeChar_code_point(recv);
+               if(cp < 65 || cp > 90){ return recv; }
+               char* ns = malloc(2);
+               ns[1] = '\0';
+               char c = recv->ns[recv->pos];
+               ns[0] = c + 32;
+               UTF8Char* ret = malloc(sizeof(UTF8Char));
+               ret->ns = ns;
+               ret->pos = 0;
+               return ret;
+       `}
+
        redef fun ==(o)
        do
                if o isa Char then
@@ -110,6 +145,23 @@ extern class UnicodeChar `{ UTF8Char* `}
                return false
        end
 
+       redef fun output import UnicodeChar.code_point `{
+               switch(UnicodeChar_len(recv)){
+                       case 1:
+                               printf("%c", recv->ns[recv->pos]);
+                               break;
+                       case 2:
+                               printf("%c%c", recv->ns[recv->pos], recv->ns[recv->pos + 1]);
+                               break;
+                       case 3:
+                               printf("%c%c%c", recv->ns[recv->pos], recv->ns[recv->pos + 1], recv->ns[recv->pos + 2]);
+                               break;
+                       case 4:
+                               printf("%c%c%c%c", recv->ns[recv->pos], recv->ns[recv->pos + 1], recv->ns[recv->pos + 2], recv->ns[recv->pos + 3]);
+                               break;
+               }
+       `}
+
        redef fun to_s import NativeString.to_s_with_length `{
                int len = utf8___UnicodeChar_len___impl(recv);
                char* r = malloc(len + 1);
@@ -246,6 +298,60 @@ redef class FlatString
 
        end
 
+       redef fun to_upper
+       do
+               var outstr = calloc_string(self.bytelen + 1)
+
+               var out_index = 0
+               var index = self.index
+               var ipos = 0
+               var max = length
+               var items = self.items
+
+               while ipos < max do
+                       var u = index[ipos].to_upper
+                       u.ns.copy_to(outstr, u.len, u.pos, out_index)
+                       out_index += u.len
+                       ipos += 1
+               end
+
+               outstr[self.bytelen] = '\0'
+
+               return outstr.to_s_with_length(self.bytelen)
+       end
+
+       redef fun to_lower
+       do
+               var outstr = calloc_string(self.bytelen + 1)
+
+               var out_index = 0
+               var index = self.index
+               var ipos = 0
+               var max = length
+               var items = self.items
+
+               while ipos < max do
+                       var u = index[ipos].to_lower
+                       u.ns.copy_to(outstr, u.len, u.pos, out_index)
+                       out_index += u.len
+                       ipos += 1
+               end
+
+               outstr[self.bytelen] = '\0'
+
+               return outstr.to_s_with_length(self.bytelen)
+       end
+
+       redef fun output
+       do
+               var i = self.index_from
+               var imax = self.index_to
+               while i <= imax do
+                       index[i].output
+                       i += 1
+               end
+       end
+
 end
 
 redef class NativeString
@@ -291,3 +397,17 @@ redef class NativeString
                return new FlatString.with_infos_index(new_self, real_len.item, 0, real_len.item - 1, x, length)
        end
 end
+
+redef class OFStream
+       redef fun write(s)
+       do
+               assert is_writable
+               if s isa FlatText then
+                       if s isa FlatString then
+                               write_native(s.to_cstring, s.bytelen)
+                       else
+                               write_native(s.to_cstring, s.length)
+                       end
+               else for i in s.substrings do write_native(i.to_cstring, i.length)
+       end
+end