pike.git/
src/
builtin.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2014-08-26
2014-08-26 09:02:32 by Stephen R. van den Berg <srb@cuci.nl>
96881abbe8200a2aac372e320f3c4ec91d03d870 (
130
lines) (+
129
/-
1
)
[
Show
|
Annotate
]
Branch:
8.0
Add new member functions
[]
and cut().
3081:
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;
+
unsigned len = 0,shift;
+
void *p;
+
+
if (s = str->str.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
+
: shift==1 ? *(p_wchar1*)p
+
: *(p_wchar2*)p);
+
} else {
+
INT_TYPE end = end_or_none->u.integer;
+
struct object *res;
+
struct Buffer_struct *str2;
+
+
pop_n_elems(args);
+
res = fast_clone_object( Buffer_program );
+
str2 = OBJ2_BUFFER( res );
+
if (index < 0)
+
index = 0;
+
if (end >= len)
+
end = len-1;
+
str2->initial = end -= index-1;
+
init_string_builder_alloc (&str2->str, end, shift);
+
memcpy (str2->str.s->str, (char*)p+(index<<shift), end<<shift);
+
str2->str.s->len = end;
+
if( (Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT) )
+
res->flags |= OBJECT_CLEAR_ON_EXIT;
+
push_object (res);
+
}
+
}
+
+
/*! @decl int `[]=(int index, int ch)
+
*/
+
PIKEFUN int `[]=(int index, int ch)
+
{
+
struct Buffer_struct *str = THIS;
+
struct pike_string *s;
+
unsigned len = 0,shift;
+
void *p;
+
+
pop_n_elems(args);
+
if (s = str->str.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;
+
else if(shift==1)
+
*(p_wchar1*)p = ch;
+
else
+
*(p_wchar2*)p = ch;
+
push_int(ch);
+
}
+
/*! @decl String.Buffer `+( string|String.Buffer what ) */ PIKEFUN object `+( string|Buffer what )
3312:
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;
+
unsigned len = 0,shift;
+
void *p;
+
INT_TYPE end,vdiscard;
+
+
if (s = str->str.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);
+
end -= index-1;
+
if (!vdiscard)
+
{
+
res = fast_clone_object( Buffer_program );
+
str2 = OBJ2_BUFFER( res );
+
init_string_builder_alloc(&str2->str, str2->initial = end, shift);
+
memcpy(str2->str.s->str, p, shift = end<<shift);
+
str2->str.s->len = end;
+
}
+
memmove(p, (char*)p+shift, shift);
+
s->len -= end;
+
+
if(!vdiscard)
+
{
+
if( (Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT) )
+
res->flags |= OBJECT_CLEAR_ON_EXIT;
+
push_object(res);
+
}
+
else
+
push_undefined();
+
}
+
/*! @decl void clear() *! *! Empty the buffer, and don't care about the old content.
3320:
*! This function was not available in Pike 7.8 and earlier. *! *! @seealso
-
*! @[get()]
+
*! @[get()]
, @[cut()]
*/ PIKEFUN void clear() {