def get_nonmovingbuffer(data): """ Either returns a non-moving copy or performs neccessary pointer arithmetic to return a pointer to the characters of a string if the string is already nonmovable or could be pinned. Must be followed by a free_nonmovingbuffer call. First bool returned indicates if 'data' was pinned. Second bool returned indicates if we did a raw alloc because pinning failed. Both bools should never be true at the same time. """ lldata = llstrtype(data) count = len(data) pinned = False if rgc.can_move(data): if rgc.pin(data): pinned = True else: buf = lltype.malloc(TYPEP.TO, count, flavor='raw') copy_string_to_raw(lldata, buf, 0, count) return buf, pinned, True # ^^^ raw malloc used to get a nonmovable copy # # following code is executed if: # - rgc.can_move(data) and rgc.pin(data) both returned true # - rgc.can_move(data) returned false data_start = cast_ptr_to_adr(lldata) + \ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0) return cast(TYPEP, data_start), pinned, False
def str2charp(s, track_allocation=True): """ str -> char* """ if track_allocation: array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw', track_allocation=True) else: array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw', track_allocation=False) i = len(s) ll_s = llstrtype(s) copy_string_to_raw(ll_s, array, 0, i) array[i] = lastchar return array
def free_nonmovingbuffer(data, buf): """ Either free a non-moving buffer or keep the original storage alive. """ # We cannot rely on rgc.can_move(data) here, because its result # might have changed since get_nonmovingbuffer(). Instead we check # if 'buf' points inside 'data'. This is only possible if we # followed the 2nd case in get_nonmovingbuffer(); in the first case, # 'buf' points to its own raw-malloced memory. data = llstrtype(data) data_start = cast_ptr_to_adr(data) + \ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0) followed_2nd_path = (buf == cast(TYPEP, data_start)) keepalive_until_here(data) if not followed_2nd_path: lltype.free(buf, flavor='raw')
def get_nonmovingbuffer(data): """ Either returns a non-moving copy or performs neccessary pointer arithmetic to return a pointer to the characters of a string if the string is already nonmovable. Must be followed by a free_nonmovingbuffer call. """ lldata = llstrtype(data) if rgc.can_move(data): count = len(data) buf = lltype.malloc(TYPEP.TO, count, flavor='raw') copy_string_to_raw(lldata, buf, 0, count) return buf else: data_start = cast_ptr_to_adr(lldata) + \ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0) return cast(TYPEP, data_start)
def get_nonmovingbuffer(data): """ Either returns a non-moving copy or performs neccessary pointer arithmetic to return a pointer to the characters of a string if the string is already nonmovable or could be pinned. Must be followed by a free_nonmovingbuffer call. Also returns a char: * \4: no pinning, returned pointer is inside 'data' which is nonmovable * \5: 'data' was pinned, returned pointer is inside * \6: pinning failed, returned pointer is raw malloced For strings (not unicodes), the len()th character of the resulting raw buffer is available, but not initialized. Use get_nonmovingbuffer_final_null() instead of get_nonmovingbuffer() to get a regular null-terminated "char *". """ lldata = llstrtype(data) count = len(data) if we_are_translated_to_c() and not rgc.can_move(data): flag = '\x04' else: if we_are_translated_to_c() and rgc.pin(data): flag = '\x05' else: buf = lltype.malloc(TYPEP.TO, count + (TYPEP is CCHARP), flavor='raw') copy_string_to_raw(lldata, buf, 0, count) return buf, '\x06' # ^^^ raw malloc used to get a nonmovable copy # # following code is executed after we're translated to C, if: # - rgc.can_move(data) and rgc.pin(data) both returned true # - rgc.can_move(data) returned false data_start = cast_ptr_to_adr(lldata) + \ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0) return cast(TYPEP, data_start), flag
def str2chararray(s, array, maxsize): length = min(len(s), maxsize) ll_s = llstrtype(s) copy_string_to_raw(ll_s, array, 0, length) return length
def str2rawmem(s, array, start, length): ll_s = llstrtype(s) copy_string_to_raw(ll_s, array, start, length)