From: Lucas Bajolet Date: Tue, 31 Mar 2015 20:31:07 +0000 (-0400) Subject: lib/standard/string: Added faster cstring method on flatstring. X-Git-Tag: v0.7.4~46^2 X-Git-Url: http://nitlanguage.org lib/standard/string: Added faster cstring method on flatstring. Signed-off-by: Lucas Bajolet --- diff --git a/lib/standard/string.nit b/lib/standard/string.nit index e974d91..409b4ed 100644 --- a/lib/standard/string.nit +++ b/lib/standard/string.nit @@ -864,6 +864,23 @@ abstract class FlatText # Real items, used as cache for to_cstring is called private var real_items: nullable NativeString = null + # Returns a char* starting at position `index_from` + # + # WARNING: If you choose to use this service, be careful of the following. + # + # Strings and NativeString are *ideally* always allocated through a Garbage Collector. + # Since the GC tracks the use of the pointer for the beginning of the char*, it may be + # deallocated at any moment, rendering the pointer returned by this function invalid. + # Any access to freed memory may very likely cause undefined behaviour or a crash. + # (Failure to do so will most certainly result in long and painful debugging hours) + # + # The only safe use of this pointer is if it is ephemeral (e.g. read in a C function + # then immediately return). + # + # As always, do not modify the content of the String in C code, if this is what you want + # copy locally the char* as Nit Strings are immutable. + private fun fast_cstring: NativeString is abstract + redef var length: Int = 0 redef fun output @@ -1119,6 +1136,8 @@ class FlatString return native.to_s_with_length(self.length) end + redef fun fast_cstring do return items.fast_cstring(index_from) + redef fun substring(from, count) do assert count >= 0 @@ -1567,6 +1586,8 @@ class FlatBuffer private var capacity: Int = 0 + redef fun fast_cstring do return items.fast_cstring(0) + redef fun substrings do return new FlatSubstringsIter(self) # Re-copies the `NativeString` into a new one and sets it as the new `Buffer` @@ -2289,6 +2310,12 @@ extern class NativeString `{ char* `} # Creates a new NativeString with a capacity of `length` new(length: Int) is intern + # Returns a char* starting at `index`. + # + # WARNING: Unsafe for extern code, use only for temporary + # pointer manipulation purposes (e.g. write to file or such) + fun fast_cstring(index: Int): NativeString is intern + # Get char at `index`. fun [](index: Int): Char is intern diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 43fd172..1a551d6 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -2204,6 +2204,9 @@ redef class AMethPropdef else if pname == "atoi" then v.ret(v.new_expr("atoi({arguments[0]});", ret.as(not null))) return true + else if pname == "fast_cstring" then + v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) + return true else if pname == "new" then v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null))) return true diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index aba779a..8818874 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -1016,6 +1016,9 @@ redef class AMethPropdef return v.int_instance(res) else if pname == "atof" then return v.float_instance(recvval.to_f) + else if pname == "fast_cstring" then + var ns = recvval.to_cstring.to_s.substring_from(args[1].to_i) + return v.native_string_instance(ns) end else if cname == "String" then var cs = v.send(v.force_get_primitive_method("to_cstring", args.first.mtype), [args.first])