X-Git-Url: http://nitlanguage.org?ds=sidebyside diff --git a/lib/standard/string.nit b/lib/standard/string.nit index 88c4074..4892f95 100644 --- a/lib/standard/string.nit +++ b/lib/standard/string.nit @@ -350,12 +350,12 @@ abstract class Text # # assert " \n\thello \n\t".l_trim == "hello \n\t" # - # A whitespace is defined as any character which ascii value is less than or equal to 32 + # `Char::is_whitespace` determines what is a whitespace. fun l_trim: SELFTYPE do var iter = self.chars.iterator while iter.is_ok do - if iter.item.ascii > 32 then break + if not iter.item.is_whitespace then break iter.next end if iter.index == length then return self.empty @@ -366,12 +366,12 @@ abstract class Text # # assert " \n\thello \n\t".r_trim == " \n\thello" # - # A whitespace is defined as any character which ascii value is less than or equal to 32 + # `Char::is_whitespace` determines what is a whitespace. fun r_trim: SELFTYPE do var iter = self.chars.reverse_iterator while iter.is_ok do - if iter.item.ascii > 32 then break + if not iter.item.is_whitespace then break iter.next end if iter.index < 0 then return self.empty @@ -379,12 +379,29 @@ abstract class Text end # Trims trailing and preceding white spaces - # A whitespace is defined as any character which ascii value is less than or equal to 32 # # assert " Hello World ! ".trim == "Hello World !" # assert "\na\nb\tc\t".trim == "a\nb\tc" + # + # `Char::is_whitespace` determines what is a whitespace. fun trim: SELFTYPE do return (self.l_trim).r_trim + # Is the string non-empty but only made of whitespaces? + # + # assert " \n\t ".is_whitespace == true + # assert " hello ".is_whitespace == false + # assert "".is_whitespace == false + # + # `Char::is_whitespace` determines what is a whitespace. + fun is_whitespace: Bool + do + if is_empty then return false + for c in self.chars do + if not c.is_whitespace then return false + end + return true + end + # Returns `self` removed from its last line terminator (if any). # # assert "Hello\n".chomp == "Hello" @@ -1052,7 +1069,7 @@ class FlatString # Indes in _items of the last item of the string private var index_to: Int is noinit - redef var chars: SequenceRead[Char] = new FlatStringCharView(self) + redef var chars: SequenceRead[Char] = new FlatStringCharView(self) is lazy redef fun [](index) do @@ -1163,10 +1180,14 @@ class FlatString # String Specific Methods # ################################################## - private init with_infos(items: NativeString, len: Int, from: Int, to: Int) + # Low-level creation of a new string with given data. + # + # `items` will be used as is, without copy, to retrieve the characters of the string. + # Aliasing issues is the responsibility of the caller. + private init with_infos(items: NativeString, length: Int, from: Int, to: Int) do self.items = items - length = len + self.length = length index_from = from index_to = to end @@ -1522,7 +1543,7 @@ class FlatBuffer super FlatText super Buffer - redef var chars: Sequence[Char] = new FlatBufferCharView(self) + redef var chars: Sequence[Char] = new FlatBufferCharView(self) is lazy private var capacity: Int = 0 @@ -1610,6 +1631,20 @@ class FlatBuffer # Create a new empty string. init do end + # Low-level creation a new buffer with given data. + # + # `items` will be used as is, without copy, to store the characters of the buffer. + # Aliasing issues is the responsibility of the caller. + # + # If `items` is shared, `written` should be set to true after the creation + # so that a modification will do a copy-on-write. + private init with_infos(items: NativeString, capacity, length: Int) + do + self.items = items + self.length = length + self.capacity = capacity + end + # Create a new string copied from `s`. init from(s: Text) do @@ -1634,7 +1669,6 @@ class FlatBuffer init with_capacity(cap: Int) do assert cap >= 0 - # _items = new NativeString.calloc(cap) items = new NativeString(cap+1) capacity = cap length = 0 @@ -1678,11 +1712,10 @@ class FlatBuffer if from < 0 then from = 0 if count > length then count = length if from < count then - var r = new FlatBuffer.with_capacity(count - from) - while from < count do - r.chars.push(items[from]) - from += 1 - end + var len = count - from + var r_items = new NativeString(len) + items.copy_to(r_items, len, from, 0) + var r = new FlatBuffer.with_infos(r_items, len, len) return r else return new FlatBuffer @@ -1920,6 +1953,10 @@ redef class Int # assert 1.to_s == "1" # assert (-123).to_s == "-123" redef fun to_s do + # Fast case for common numbers + if self == 0 then return "0" + if self == 1 then return "1" + var nslen = int_to_s_len var ns = new NativeString(nslen + 1) ns[nslen] = '\0' @@ -2147,6 +2184,48 @@ redef class Array[E] end end +redef class NativeArray[E] + # Join all the elements using `to_s` + # + # REQUIRE: `self isa NativeArray[String]` + # REQUIRE: all elements are initialized + fun native_to_s: String + do + assert self isa NativeArray[String] + var l = length + var na = self + var i = 0 + var sl = 0 + var mypos = 0 + while i < l do + sl += na[i].length + i += 1 + mypos += 1 + end + var ns = new NativeString(sl + 1) + ns[sl] = '\0' + i = 0 + var off = 0 + while i < mypos do + var tmp = na[i] + var tpl = tmp.length + if tmp isa FlatString then + tmp.items.copy_to(ns, tpl, tmp.index_from, off) + off += tpl + else + for j in tmp.substrings do + var s = j.as(FlatString) + var slen = s.length + s.items.copy_to(ns, slen, s.index_from, off) + off += slen + end + end + i += 1 + end + return ns.to_s_with_length(sl) + end +end + redef class Map[K,V] # Concatenate couple of 'key value'. # key and value are separated by `couple_sep`.