📄 outstream.pm
字号:
package KinoSearch::Store::OutStream;use strict;use warnings;use KinoSearch::Util::ToolSet;use base qw( KinoSearch::Util::CClass );sub close { my $self = shift; $self->flush; CORE::close $self->get_fh;}1;__END____XS__MODULE = KinoSearch PACKAGE = KinoSearch::Store::OutStream=for commentConstructor - takes one arg: a filehandle.=cutOutStream*new(class, fh_sv) char *class; SV *fh_sv;CODE: RETVAL = Kino_OutStream_new(class, fh_sv);OUTPUT: RETVALvoidseek(outstream, target) OutStream *outstream; double target;PPCODE: outstream->seek(outstream, target);doubletell(outstream) OutStream *outstream;CODE: RETVAL = outstream->tell(outstream);OUTPUT: RETVALdoublelength(outstream) OutStream *outstream;CODE: RETVAL = Kino_OutStream_length(outstream);OUTPUT: RETVALvoidflush(outstream); OutStream *outstream;PPCODE: Kino_OutStream_flush(outstream);=for commentWrite the entire contents of an instream to an outstream.=cutvoidabsorb(outstream, instream) OutStream *outstream; InStream *instream;PPCODE: Kino_OutStream_absorb(outstream, instream);SV*_set_or_get(outstream, ...) OutStream *outstream;ALIAS: set_fh = 1 get_fh = 2CODE:{ KINO_START_SET_OR_GET_SWITCH case 1: Kino_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 schemesspecified by TEMPLATE.=end comment=cutvoidlu_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) { Kino_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) { Kino_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) { Kino_confess( "lu_write error: Too many ITEMS, not enough TEMPLATE"); } else if (template != tpt_end) { Kino_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); } } else { /* no numeric repeat count, so process sym only once */ repeat_count = 1; } } switch(sym) { case 'a': /* arbitrary binary data */ aSV = ST(item_count); if (!SvOK(aSV)) { Kino_confess("Internal error: undef at lu_write 'a'"); } string = SvPV(aSV, string_len); if (repeat_count != string_len) { Kino_confess( "lu_write error: repeat_count != string_len: %d %d", repeat_count, string_len); } Kino_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) ); Kino_OutStream_write_byte(outstream, (char)(aI32 & 0xff)); break; case 'i': /* signed 32-bit integer */ aI32 = SvIV( ST(item_count) ); Kino_OutStream_write_int(outstream, (U32)aI32); break; case 'I': /* unsigned 32-bit integer */ aU32 = SvUV( ST(item_count) ); Kino_OutStream_write_int(outstream, aU32); break; case 'Q': /* unsigned "64-bit" integer */ aDouble = SvNV( ST(item_count) ); Kino_OutStream_write_long(outstream, aDouble); break; case 'V': /* VInt */ aU32 = SvUV( ST(item_count) ); Kino_OutStream_write_vint(outstream, aU32); break; case 'W': /* VLong */ aDouble = SvNV( ST(item_count) ); Kino_OutStream_write_vlong(outstream, aDouble); break; case 'T': /* string */ aSV = ST(item_count); string = SvPV(aSV, string_len); Kino_OutStream_write_string(outstream, string, string_len); break; default: Kino_confess("Illegal character in template: %c", sym); } /* use up one repeat_count and one item from the stack */ repeat_count--; item_count++; }}voidDESTROY(outstream) OutStream *outstream;PPCODE: Kino_OutStream_destroy(outstream);__H__#ifndef H_KINOIO#define H_KINOIO 1#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "KinoSearchStoreInStream.h"#include "KinoSearchUtilCarp.h"#include "KinoSearchUtilMathUtils.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* Kino_OutStream_new (char*, SV*);void Kino_OutStream_seek (OutStream*, double);double Kino_OutStream_tell (OutStream*);double Kino_OutStream_length (OutStream*);void Kino_OutStream_flush (OutStream*);void Kino_OutStream_absorb (OutStream*, InStream*);void Kino_OutStream_write_byte (OutStream*, char);void Kino_OutStream_write_bytes (OutStream*, char*, STRLEN);void Kino_OutStream_write_int (OutStream*, U32);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -