pike.git / src / builtin.cmod

version» Context lines:

pike.git/src/builtin.cmod:2969:    *! string result = b->get(); // also clears the buffer    *! @endcode    */   PIKECLASS Buffer   {    CVAR struct string_builder str;    CVAR int initial;       PIKEFUN int _size_object()    { -  if( THIS->str.s ) +     RETURN THIS->str.malloced; -  RETURN 0; +     }       void f_Buffer_get_copy( INT32 args );    void f_Buffer_get( INT32 args );    void f_Buffer_add( INT32 args );       /*! @decl void create(int initial_size)    *!    *! Initializes a new buffer.    *!    *! If no @[initial_size] is specified, 256 is used. If you    *! know approximately how big the buffer will be, you can optimize    *! the operation of @[add()] (slightly) by passing the size to this    *! function.    */    PIKEFUN void create( int|void size )    {    struct Buffer_struct *str = THIS; -  if( size ) -  str->initial = MAXIMUM( size->u.integer, 512 ); -  else -  str->initial = 256; +  init_string_builder_alloc(&str->str, +  str->initial = size ? MAXIMUM( size->u.integer, 512 ) : 256 , 0);    }       /*! @decl string _sprintf( int flag, mapping flags )    *! It is possible to @[sprintf] a String.Buffer object    *! as @tt{%s@} just as if it was a string.    */    PIKEFUN string _sprintf( int flag, mapping flags )    {    switch( flag )    {    case 'O':    {    struct pike_string *res;    struct Buffer_struct *str = THIS;    push_text( "Buffer(%d /* %d */)" ); -  if( str->str.s ) -  { +     push_int(str->str.s->len);    push_int(str->str.malloced); -  } -  else -  { -  push_int( 0 ); -  push_int( 0 ); -  } +     f_sprintf( 3 );    dmalloc_touch_svalue(Pike_sp-1);    res = Pike_sp[-1].u.string;    Pike_sp--;    RETURN res;    }       case 's':    {    pop_n_elems( args );
pike.git/src/builtin.cmod:3082:    pop_stack();    push_undefined();    }       /*! @decl int|Buffer `[](int index, int|void end_or_none)    */    PIKEFUN int|Buffer `[](int index, int|void end_or_none)    {    struct Buffer_struct *str = THIS;    struct pike_string *s = str->str.s; -  unsigned len = 0,shift = 0; -  void *p = NULL; +  unsigned len = s->len, shift = s->size_shift; +  void *p = s->str;    -  if (s) -  len = s->len, shift = s->size_shift, p = s->str; -  +     if (args==1) {    pop_n_elems(args);    if (index<0)    index += len;    if (index<0 || index>=len)    index_error("Buffer->`[]", Pike_sp, args, NULL, Pike_sp,    "Index %"PRINTPIKEINT"d is out of array range 0..%d,\n",    index, len-1);    p = (char*)p+(index<<shift);    push_int (!shift ? *(p_wchar0*)p
pike.git/src/builtin.cmod:3129:    push_object (res);    }    }       /*! @decl int `[]=(int index, int ch)    */    PIKEFUN int `[]=(int index, int ch)    {    struct Buffer_struct *str = THIS;    struct pike_string *s = str->str.s; -  unsigned len = 0,shift = 0; -  void *p = NULL; +  unsigned len = s->len, shift = s->size_shift; +  void *p = s->str;       pop_n_elems(args); -  if (s) -  len = s->len, shift = s->size_shift, p = s->str; +        if (index<0)    index += len;    if (index<0 || index>=len)    index_error("Buffer->`[]=", Pike_sp, args, NULL, Pike_sp,    "Index %"PRINTPIKEINT"d is out of array range 0..%d,\n",    index, len-1);    p = (char*)p+(index<<shift);    if (!shift)    *(p_wchar0*)p = ch;
pike.git/src/builtin.cmod:3161:       /*! @decl Buffer `+( string|Buffer what )    */    PIKEFUN object `+( string|Buffer what )    rawtype tFunc(tOr(tString, tObjIs_BUFFER), tObjIs_BUFFER);    {    struct Buffer_struct *str = THIS, *str2;    struct object *res = fast_clone_object( Buffer_program );    str2 = OBJ2_BUFFER( res );    str2->initial = str->initial; -  if( str->str.s ) +     init_string_builder_copy (&str2->str, &str->str);    if( (Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT) )    res->flags |= OBJECT_CLEAR_ON_EXIT;    apply( res, "add", 1 );    RETURN res;    }       /*! @decl Buffer `+=( string|Buffer what )    */    PIKEFUN object `+=( string|Buffer what )
pike.git/src/builtin.cmod:3184:    f_Buffer_add( 1 );    REF_RETURN Pike_fp->current_object;    }       /*! @decl Buffer `==( mixed other )    */    PIKEFUN int(0..1) `==( mixed other )    rawtype tFunc(tMixed, tInt01);    {    struct Buffer_struct *str = THIS; -  struct pike_string *s, *a; +  struct pike_string *a;       switch(TYPEOF(*other))    {    case PIKE_T_STRING:    a = other->u.string;    break;    case PIKE_T_OBJECT:    if (other->u.object->prog == Buffer_program) {    a = OBJ2_BUFFER(other->u.object)->str.s;    break;    }    default:    RETURN 0;    } -  RETURN !(s = str->str.s) ? !a->len : !my_quick_strcmp(s, a); +  RETURN !my_quick_strcmp(str->str.s, a);    }       /*! @decl int addat(int(0..) pos, string|Buffer ... data)    *!    *! Adds @[data] to the buffer, starting at position @[pos].    *! It overwrites existing content at that offset, never truncates the    *! buffer, possibly extends the buffer if the new content does not fit.    *!    *! @returns    *! Returns the size of the buffer.
pike.git/src/builtin.cmod:3242:    a = Pike_sp[j-args].u.string;    else if ((TYPEOF(Pike_sp[j-args]) != PIKE_T_OBJECT) ||    (Pike_sp[j-args].u.object->prog != Buffer_program))    SIMPLE_BAD_ARG_ERROR("addat", j+1, "string|String.Buffer");    else if(!(a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s))    continue;    sum += a->len;    shift |= a->size_shift;    }    -  if (!(s = str->str.s)) { -  if ((sum + pos) <= str->initial) -  sum = str->initial; -  else -  sum <<= 1, sum += pos; -  shift = shift & ~(shift >> 1); -  -  init_string_builder_alloc(&str->str, sum, shift); -  } else { +  s = str->str.s;    sum += pos;    shift |= str->str.known_shift;    shift = shift & ~(shift >> 1);    if (sum > s->len)    string_build_mkspace(&str->str, sum - s->len, shift);    else if (shift != str->str.known_shift)    string_build_mkspace(&str->str, 0, shift); -  } +     s = str->str.s;    /* We know it will be a string that really is this wide. */    str->str.known_shift = shift;       if (s->len < pos) // Clear the padding    MEMSET(s->str + (s->len << s->size_shift),    0, (pos - s->len) << s->size_shift);       for(j = 1; j<args; j++) {    struct pike_string *a;
pike.git/src/builtin.cmod:3299:    *! @returns    *! Returns the size of the buffer.    *!    *! @seealso    *! @[addat()]    */    PIKEFUN int add( string|Buffer ... arg1 )    rawtype tFuncV(tNone, tOr(tString, tObjIs_BUFFER), tIntPos);    {    struct Buffer_struct *str = THIS; -  push_int(str->str.s ? str->str.s->len : 0); +  push_int(str->str.s->len);    stack_revroll(++args);    f_Buffer_addat(args);    }       /*! @decl void putchar(int c)    *! Appends the character @[c] at the end of the string.    */    PIKEFUN void putchar(int c) {    struct Buffer_struct *str = THIS; -  if(!str->str.s) -  init_string_builder_alloc(&str->str, str->initial, 0); +     string_builder_putchar(&str->str, c);    }       /*! @decl int sprintf(strict_sprintf_format format, sprintf_args ... args)    *! Appends the output from @[sprintf] at the end of the string.    *! Returns the resulting size of the String.Buffer.    */    PIKEFUN int sprintf(mixed ... arguments)    rawtype tFuncV(tAttr("strict_sprintf_format", tOr(tStr, tObj)),    tAttr("sprintf_args", tMix), tStr);       {    // FIXME: Reset length on exception?    struct Buffer_struct *str = THIS; -  if(!str->str.s) -  init_string_builder_alloc(&str->str, str->initial, 0); +     low_f_sprintf(args, 0, &str->str);    RETURN str->str.s->len;    }       /*! @decl string get_copy()    *!    *! Get the data from the buffer. Significantly slower than @[get],    *! but does not clear the buffer.    *!    *! @seealso    *! @[get()]    */    PIKEFUN string get_copy()    {    struct pike_string *str = THIS->str.s;    ptrdiff_t len; -  if( str && (len = str->len) > 0 ) +  if((len = str->len) > 0 )    {    char *d = (char *)str->str;    switch( str->size_shift )    {    case 0:    str=make_shared_binary_string0((p_wchar0 *)d,len);    break;    case 1:    str=make_shared_binary_string1((p_wchar1 *)d,len);    break;    default:    str=make_shared_binary_string2((p_wchar2 *)d,len);    break;    }    if( Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT )    str->flags |= STRING_CLEAR_ON_EXIT;    RETURN str;    }    push_empty_string(); -  return; +     }       /*! @decl string get()    *!    *! Get the data from the buffer.    *!    *! @note    *! This will clear the data in the buffer    *!    *! @seealso    *! @[get_copy()], @[clear()]    */    PIKEFUN string get( )    {    struct Buffer_struct *str = THIS; -  pop_n_elems(args); -  if( str->str.s ) -  { +     struct pike_string *s = finish_string_builder( &str->str );    str->str.malloced = 0;    str->str.s = NULL;    if( Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT )    s->flags |= STRING_CLEAR_ON_EXIT;    push_string(s);    } -  else -  push_empty_string(); -  } +        /*! @decl Buffer|void cut(int index, int|void end_or_none,void|int discard)    *!    *! Cut and delete the range of data from the current buffer.    *! Returns a new buffer with the cut data, unless discard is true.    *!    *! @seealso    *! @[get()], @[get_copy()], @[clear()]    */    PIKEFUN Buffer|void cut(int index, int|void end_or_none,void|int discard)    {    struct Buffer_struct *str = THIS, *str2;    struct object *res;    struct pike_string *s = str->str.s; -  unsigned len = 0,shift = 0; -  void *p = NULL; +  unsigned len = s->len,shift = s->size_shift; +  void *p = s->str;    INT_TYPE end,vdiscard;    -  if (s) -  len = s->len, shift = s->size_shift, p = s->str; -  +     end = args==1 ? len-1 : end_or_none->u.integer;    vdiscard = args==3 ? discard->u.integer : 0;    pop_n_elems(args);       if (index < 0)    index = 0;    if (end >= len)    end = len-1;       p = (char*)p+(index<<shift);
pike.git/src/builtin.cmod:3462:    /*! @decl void clear()    *!    *! Empty the buffer, and don't care about the old content.    *!    *! @seealso    *! @[get()], @[cut()]    */    PIKEFUN void clear()    {    struct Buffer_struct *str = THIS; -  if (str->str.s) +     reset_string_builder(&str->str);    }       /*! @decl int _sizeof()    *!    *! Returns the size of the buffer.    */    PIKEFUN int _sizeof()    {    struct Buffer_struct *str = THIS; -  RETURN str->str.s ? str->str.s->len : 0; +  RETURN str->str.s->len;    }       INIT    {    struct Buffer_struct *str = THIS;    MEMSET( str, 0, sizeof( *str ) );    }       EXIT    gc_trivial;    {    struct Buffer_struct *str = THIS; -  if( str->str.s ) -  { +     if( Pike_fp->flags & OBJECT_CLEAR_ON_EXIT )    guaranteed_memset( str->str.s->str, 0, str->str.s->len );    free_string_builder( &str->str );    } -  } +        GC_RECURSE    { -  if (mc_count_bytes (Pike_fp->current_object) && THIS->str.s) +  if (mc_count_bytes (Pike_fp->current_object))    mc_counted_bytes += THIS->str.malloced;    }   }      /*! @endclass    */      /*! @class Replace    *!    *! This is a "compiled" version of the @[replace] function applied on