end
redef class CString
- # Get a `String` from the data at `self` copied into Nit memory
- #
- # Require: `self` is a null-terminated string.
- fun to_s_with_copy: String is abstract
-
- # Get a `String` from `length` bytes at `self`
- #
- # The result may point to the data at `self` or
- # it may make a copy in Nit controlled memory.
- # This method should only be used when `self` was allocated by the Nit GC,
- # or when manually controlling the deallocation of `self`.
- fun to_s_with_length(length: Int): String is abstract
- # Get a `String` from the raw `length` bytes at `self`
+ # Get a `String` from the data at `self` (with unsafe options)
#
- # The default value of `length` is the number of bytes before
- # the first null character.
+ # The default behavior is the safest and equivalent to `to_s`.
#
- # The created `String` points to the data at `self`.
- # This method should be used when `self` was allocated by the Nit GC,
- # or when manually controlling the deallocation of `self`.
+ # Options:
#
- # /!\: This service does not clean the items for compliance with UTF-8,
- # use only when the data has already been verified as valid UTF-8.
- fun to_s_unsafe(length: nullable Int): String is abstract
-
- # Get a `String` from the raw `byte_length` bytes at `self` with `unilen` Unicode characters
+ # * Set `byte_length` to the number of bytes to use as data.
+ # Otherwise, this method searches for a terminating null byte.
#
- # The created `String` points to the data at `self`.
- # This method should be used when `self` was allocated by the Nit GC,
- # or when manually controlling the deallocation of `self`.
+ # * Set `char_length` to the number of Unicode character in the string.
+ # Otherwise, the data is read to count the characters.
+ # Ignored if `clean == true`.
#
- # /!\: This service does not clean the items for compliance with UTF-8,
- # use only when the data has already been verified as valid UTF-8.
+ # * If `copy == true`, the default, copies the data at `self` in the
+ # Nit GC allocated memory. Otherwise, the return may still point to
+ # the data at `self`.
#
- # SEE: `abstract_text::Text` for more info on the difference
- # between `Text::byte_length` and `Text::length`.
- fun to_s_full(byte_length, unilen: Int): String is abstract
+ # * If `clean == true`, the default, the string is cleaned of invalid UTF-8
+ # characters. If cleaning is necessary, the data is copied into Nit GC
+ # managed memory, whether or not `copy == true`.
+ # Don't clean only when the data has already been verified as valid UTF-8,
+ # other library services rely on UTF-8 compliant characters.
+ fun to_s_unsafe(byte_length, char_length: nullable Int, copy, clean: nullable Bool): String is abstract
# Copies the content of `src` to `self`
#
- # NOTE: `self` must be large enough to withold `self.byte_length` bytes
+ # NOTE: `self` must be large enough to contain `self.byte_length` bytes
fun fill_from(src: Text) do src.copy_to_native(self, src.byte_length, 0, 0)
end
end
redef class CString
- redef fun to_s
- do
- return to_s_with_length(cstring_length)
- end
- redef fun to_s_with_length(length)
- do
- assert length >= 0
- return clean_utf8(length)
- end
+ # Get a `String` from the data at `self` copied into Nit memory
+ #
+ # Require: `self` is a null-terminated string.
+ redef fun to_s do return to_s_unsafe
- redef fun to_s_full(byte_length, unilen) do
- return new FlatString.full(self, byte_length, 0, unilen)
- end
+ # Get a `String` from `byte_length` bytes at `self` copied into Nit memory
+ #
+ # The string is cleaned.
+ fun to_s_with_length(byte_length: Int): String do return to_s_unsafe(byte_length)
- redef fun to_s_unsafe(len) do
- if len == null then len = cstring_length
- return new FlatString.with_infos(self, len, 0)
- end
+ redef fun to_s_unsafe(byte_length, char_length, copy, clean)
+ do
+ byte_length = byte_length or else cstring_length
+ clean = clean or else true
+ copy = copy or else true
+
+ # Clean?
+ var str = null
+ if clean then
+ str = clean_utf8(byte_length)
+ char_length = str.length
+ else
+ char_length = char_length or else utf8_length(0, byte_length)
+ end
- redef fun to_s_with_copy do return to_s_with_copy_and_length(cstring_length)
+ # Copy? (if not already copied by `clean_utf8`)
+ if copy and (str == null or str.items == self) then
+ var new_cstr = new CString(byte_length + 1)
+ copy_to(new_cstr, byte_length, 0, 0)
+ new_cstr[byte_length] = 0u8
+ str = new FlatString.full(new_cstr, byte_length, 0, char_length)
+ end
+
+ if str == null then
+ str = new FlatString.full(self, byte_length, 0, char_length)
+ end
- # Get a `String` from `length` bytes at `self` copied into Nit memory
- fun to_s_with_copy_and_length(length: Int): String
- do
- var r = clean_utf8(length)
- if r.items != self then return r
- var new_self = new CString(length + 1)
- copy_to(new_self, length, 0, 0)
- var str = new FlatString.with_infos(new_self, length, 0)
- new_self[length] = 0u8
return str
end