KinoSearch1
view release on metacpan or search on metacpan
lib/KinoSearch1/Store/OutStream.pm view on Meta::CPAN
package KinoSearch1::Store::OutStream;
use strict;
use warnings;
use KinoSearch1::Util::ToolSet;
use base qw( KinoSearch1::Util::CClass );
sub close {
my $self = shift;
$self->flush;
CORE::close $self->get_fh;
}
1;
__END__
__XS__
MODULE = KinoSearch1 PACKAGE = KinoSearch1::Store::OutStream
=for comment
Constructor - takes one arg: a filehandle.
=cut
OutStream*
new(class, fh_sv)
char *class;
SV *fh_sv;
CODE:
RETVAL = Kino1_OutStream_new(class, fh_sv);
OUTPUT: RETVAL
void
seek(outstream, target)
OutStream *outstream;
double target;
PPCODE:
outstream->seek(outstream, target);
double
tell(outstream)
OutStream *outstream;
CODE:
RETVAL = outstream->tell(outstream);
OUTPUT: RETVAL
double
length(outstream)
OutStream *outstream;
CODE:
RETVAL = Kino1_OutStream_length(outstream);
OUTPUT: RETVAL
void
flush(outstream);
OutStream *outstream;
PPCODE:
Kino1_OutStream_flush(outstream);
=for comment
Write the entire contents of an instream to an outstream.
=cut
void
absorb(outstream, instream)
OutStream *outstream;
InStream *instream;
PPCODE:
Kino1_OutStream_absorb(outstream, instream);
SV*
_set_or_get(outstream, ...)
OutStream *outstream;
ALIAS:
set_fh = 1
get_fh = 2
CODE:
{
KINO_START_SET_OR_GET_SWITCH
case 1: Kino1_confess("Can't set_fh");
/* fall through */
case 2: RETVAL = newSVsv(outstream->fh_sv);
break;
KINO_END_SET_OR_GET_SWITCH
}
OUTPUT: RETVAL
=begin comment
$outstream->lu_write( TEMPLATE, LIST );
Write the items in LIST to the OutStream using the serialization schemes
specified by TEMPLATE.
=end comment
=cut
void
lu_write (outstream, template_sv, ...)
OutStream *outstream;
SV *template_sv;
PREINIT:
STRLEN tpt_len; /* bytelength of template */
char *template; /* ptr to a spot in the template */
char *tpt_end; /* ptr to the end of the template */
int repeat_count; /* number of times to repeat sym */
int item_count; /* current place in @_ */
char sym; /* the current symbol in the template */
char countsym; /* used when calculating repeat counts */
I32 aI32;
U32 aU32;
double aDouble;
SV *aSV;
char *string;
STRLEN string_len;
PPCODE:
{
/* require an object, a template, and at least 1 item */
if (items < 2) {
Kino1_confess("lu_write error: too few arguments");
}
/* prepare the template and get pointers */
template = SvPV(template_sv, tpt_len);
tpt_end = template + tpt_len;
/* reject an empty template */
if (tpt_len == 0) {
Kino1_confess("lu_write error: TEMPLATE cannot be empty string");
}
/* init counters */
repeat_count = 0;
item_count = 2;
while (1) {
/* only process template if we're not in the midst of a repeat */
if (repeat_count == 0) {
/* fast-forward past space characters */
while (*template == ' ' && template < tpt_end) {
template++;
}
/* if we're done, return or throw error */
if (template == tpt_end || item_count == items) {
if (item_count != items) {
Kino1_confess(
"lu_write error: Too many ITEMS, not enough TEMPLATE");
}
else if (template != tpt_end) {
Kino1_confess(
"lu_write error: Too much TEMPLATE, not enough ITEMS");
}
else { /* success! */
break;
}
}
/* derive the current symbol and a possible digit repeat sym */
sym = *template++;
countsym = *template;
if (template == tpt_end) { /* sym is last char in template */
repeat_count = 1;
}
else if (countsym >= '0' && countsym <= '9') {
/* calculate numerical repeat count */
repeat_count = countsym - KINO_NUM_CHAR_OFFSET;
countsym = *(++template);
while ( template <= tpt_end
&& countsym >= '0'
&& countsym <= '9'
) {
repeat_count = (repeat_count * 10)
+ (countsym - KINO_NUM_CHAR_OFFSET);
countsym = *(++template);
lib/KinoSearch1/Store/OutStream.pm view on Meta::CPAN
Kino1_confess(
"lu_write error: repeat_count != string_len: %d %d",
repeat_count, string_len);
}
Kino1_OutStream_write_bytes(outstream, string, string_len);
/* trigger next sym */
repeat_count = 1;
break;
case 'b': /* signed byte */
case 'B': /* unsigned byte */
aI32 = SvIV( ST(item_count) );
Kino1_OutStream_write_byte(outstream, (char)(aI32 & 0xff));
break;
case 'i': /* signed 32-bit integer */
aI32 = SvIV( ST(item_count) );
Kino1_OutStream_write_int(outstream, (U32)aI32);
break;
case 'I': /* unsigned 32-bit integer */
aU32 = SvUV( ST(item_count) );
Kino1_OutStream_write_int(outstream, aU32);
break;
case 'Q': /* unsigned "64-bit" integer */
aDouble = SvNV( ST(item_count) );
Kino1_OutStream_write_long(outstream, aDouble);
break;
case 'V': /* VInt */
aU32 = SvUV( ST(item_count) );
Kino1_OutStream_write_vint(outstream, aU32);
break;
case 'W': /* VLong */
aDouble = SvNV( ST(item_count) );
Kino1_OutStream_write_vlong(outstream, aDouble);
break;
case 'T': /* string */
aSV = ST(item_count);
string = SvPV(aSV, string_len);
Kino1_OutStream_write_string(outstream, string, string_len);
break;
default:
Kino1_confess("Illegal character in template: %c", sym);
}
/* use up one repeat_count and one item from the stack */
repeat_count--;
item_count++;
}
}
void
DESTROY(outstream)
OutStream *outstream;
PPCODE:
Kino1_OutStream_destroy(outstream);
__H__
#ifndef H_KINOIO
#define H_KINOIO 1
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "KinoSearch1StoreInStream.h"
#include "KinoSearch1UtilCarp.h"
#include "KinoSearch1UtilMathUtils.h"
typedef struct outstream {
PerlIO *fh;
SV *fh_sv;
char *buf;
Off_t buf_start;
int buf_pos;
void (*seek) (struct outstream*, double);
double (*tell) (struct outstream*);
void (*write_byte) (struct outstream*, char);
void (*write_bytes) (struct outstream*, char*, STRLEN);
void (*write_int) (struct outstream*, U32);
void (*write_long) (struct outstream*, double);
void (*write_vint) (struct outstream*, U32);
void (*write_vlong) (struct outstream*, double);
void (*write_string)(struct outstream*, char*, STRLEN);
} OutStream;
OutStream* Kino1_OutStream_new (char*, SV*);
void Kino1_OutStream_seek (OutStream*, double);
double Kino1_OutStream_tell (OutStream*);
double Kino1_OutStream_length (OutStream*);
void Kino1_OutStream_flush (OutStream*);
void Kino1_OutStream_absorb (OutStream*, InStream*);
void Kino1_OutStream_write_byte (OutStream*, char);
void Kino1_OutStream_write_bytes (OutStream*, char*, STRLEN);
void Kino1_OutStream_write_int (OutStream*, U32);
void Kino1_OutStream_write_long (OutStream*, double);
void Kino1_OutStream_write_vint (OutStream*, U32);
int Kino1_OutStream_encode_vint (U32, char*);
void Kino1_OutStream_write_vlong (OutStream*, double);
void Kino1_OutStream_write_string (OutStream*, char*, STRLEN);
void Kino1_OutStream_destroy (OutStream*);
#endif /* include guard */
__C__
#include "KinoSearch1StoreOutStream.h"
OutStream*
Kino1_OutStream_new(char* class, SV* fh_sv) {
OutStream *outstream;
/* allocate */
( run in 0.487 second using v1.01-cache-2.11-cpan-5511b514fd6 )