pike.git
/
src
/
modules
/
_Roxen
/
roxen.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/modules/_Roxen/roxen.c:37:
#define THP ((struct header_buf *)Pike_fp->current_object->storage) struct header_buf { char headers[8192]; char *pnt; ptrdiff_t left; };
-
#define THB ((struct buffer_str *)Pike_fp->current_object->storage)
-
struct buffer_str
-
{
-
unsigned int len, size, initial;
-
unsigned char *data;
-
int shift;
-
};
-
-
#define INITIAL_BUF_LEN 4096
-
-
/*! @class Buffer A buffer, used for building strings. It's
-
*! conceptually similar to a string, but you can only @[add]
-
*! strings to it, and you can only @[get] the value from it once.
-
*!
-
*! There is a reason for those seemingly rather odd limitations,
-
*! it makes it possible to do some optimizations that really speed
-
*! things up.
-
*!
-
*! You do not need to use this class unless you add very many
-
*! strings together, or very large strings.
-
*!
-
*! For the fastest possible operation, write your code like this:
-
*!
-
*! @example{
-
*! String.Buffer b = String.Buffer( );
-
*!
-
*! function add = b->add;
-
*!
-
*! .. call add several times in code ...
-
*!
-
*! string result = b->get(); // also clears the buffer
-
*! @}
-
*/
-
-
static void f_buf_create( INT32 args )
-
/*! @method void create(int|void initial_size) Initializes a new
-
*! buffer. If no @[initial_size] is specified, 4096 is used. If you
-
*! know aproximately how big the buffer will be, you can optimize
-
*! the operation of add (slightly) by passing the size to this
-
*! function.
-
*/
-
{
-
struct buffer_str *str = THB;
-
if( args && Pike_sp[-1].type == PIKE_T_INT )
-
str->initial = Pike_sp[-1].u.integer;
-
else
-
str->initial = INITIAL_BUF_LEN;
-
}
-
-
static void f_buf_nullfun( INT32 args )
-
{
-
pop_n_elems( args );
-
push_int( 0 );
-
}
-
-
static void f_buf_add( INT32 args )
-
/*! @method void add(string data)
-
*! Adds @[data] to the buffer
-
*/
-
{
-
struct buffer_str *str = THB;
-
struct pike_string *a;
-
unsigned int l;
-
-
if( args != 1 || Pike_sp[-args].type != PIKE_T_STRING )
-
Pike_error("Illegal argument\n");
-
-
a = Pike_sp[-args].u.string;
-
-
if(!(l = (unsigned)a->len) )
-
return;
-
-
-
if( !str->size )
-
{
-
str->shift = a->size_shift;
-
str->size = str->initial + sizeof( struct pike_string );
-
str->data = xalloc( str->size );
-
str->len = sizeof( struct pike_string );
-
}
-
else if( str->shift < a->size_shift )
-
{
-
static void f_buf_get( INT32 args );
-
/* This will not win the "most optimal code of the year"
-
award, but it works. */
-
f_buf_get( 0 );
-
f_add( 2 );
-
f_buf_add( 1 );
-
return;
-
}
-
-
l<<=str->shift;
-
-
while( str->size < ((unsigned)l+str->len) )
-
{
-
str->size *= 2;
-
str->data = realloc( str->data, str->size );
-
if(!str->data )
-
{
-
int sz = str->size;
-
str->len = 0;
-
str->size = 0;
-
Pike_error( "Malloc %d failed!\n", sz );
-
}
-
}
-
#ifdef DEBUG
-
if( str->shift < a->size_shift )
-
fatal("Impossible!\n");
-
#endif
-
/* str->shift is always greater than or equal to a->size_shift here. */
-
-
if( a->size_shift == str->shift )
-
MEMCPY( (str->data+str->len), a->str, l );
-
else
-
if( a->size_shift )
-
convert_1_to_2((p_wchar2 *)(str->data+str->len),
-
(p_wchar1 *)a->str, a->len);
-
else
-
if( str->shift & 1 )
-
convert_0_to_1((p_wchar1 *)(str->data+str->len),
-
(p_wchar0 *)a->str, a->len);
-
else
-
convert_0_to_2((p_wchar2 *)(str->data+str->len),
-
(p_wchar0 *)a->str, a->len);
-
-
str->len += l;
-
pop_stack();
-
push_int( str->len );
-
}
-
-
-
static void f_buf_get( INT32 args )
-
/*! @method string get( )
-
*! Get the data from the buffer.
-
*! @note This will clear the data in the buffer
-
*/
-
{
-
struct buffer_str *str = THB;
-
int len = str->len-sizeof(struct pike_string);
-
if( len <= 0 )
-
{
-
push_text("");
-
return;
-
}
-
-
if( str->len < 64 )
-
{
-
char *d = str->data+sizeof(struct pike_string);
-
switch( str->shift )
-
{
-
case 0:
-
push_string(make_shared_binary_string(d,len));
-
break;
-
case 1:
-
push_string(make_shared_binary_string1((short*)d,len>>1));
-
break;
-
case 2:
-
push_string(make_shared_binary_string2((int*)d,len>>2));
-
break;
-
}
-
xfree( str->data );
-
}
-
else
-
{
-
str->data = realloc( str->data, str->len+(1<<str->shift) );
-
{
-
struct pike_string *s = (struct pike_string *)str->data;
-
s->len = len>>str->shift;
-
s->size_shift = str->shift;
-
push_string( low_end_shared_string( s ) );
-
}
-
}
-
str->data = 0;
-
str->size = 0;
-
str->len = 0;
-
str->shift = 0;
-
}
-
-
-
static void f_buf_init()
-
{
-
struct buffer_str *str = THB;
-
str->data = 0;
-
str->size = 0;
-
str->len = 0;
-
str->shift = 0;
-
}
-
-
static void f_buf_free()
-
{
-
struct buffer_str *str = THB;
-
if( str->data ) xfree( str->data );
-
}
-
-
+
static void f_hp_feed( INT32 args ) { struct pike_string *str = Pike_sp[-1].u.string; int tot_slash_n=0, slash_n = 0, spc = 0, cnt, num; char *pp,*ep; struct svalue *tmp; struct mapping *headers; ptrdiff_t os=0, i, j, l; unsigned char *in;
pike.git/src/modules/_Roxen/roxen.c:465:
"function(mapping(string:string|array(string)):string)", 0 ); pike_add_function("http_decode_string", f_http_decode_string, "function(string:string)", 0 ); start_new_program(); ADD_STORAGE( struct header_buf ); pike_add_function( "feed", f_hp_feed, "function(string:array(string|mapping))",0 ); pike_add_function( "create", f_hp_create, "function(void:void)", 0 ); end_class( "HeaderParser", 0 );
-
-
-
start_new_program();
-
ADD_STORAGE( struct buffer_str );
-
pike_add_function( "add", f_buf_add, "function(string:int)",0 );
-
pike_add_function( "nullfun", f_buf_nullfun, "function(string:int)",0 );
-
pike_add_function( "get", f_buf_get, "function(void:string)", 0 );
-
pike_add_function( "create", f_buf_create, "function(int|void:void)", 0 );
-
set_init_callback( f_buf_init );
-
set_exit_callback( f_buf_free );
-
end_class( "Buffer", 0 );
+
} void pike_module_exit() { }