⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instream.pm

📁 外国人写的Perl搜索引擎程序
💻 PM
📖 第 1 页 / 共 2 页
字号:
package KinoSearch::Store::InStream;use base qw( KinoSearch::Util::CClass );use strict;use warnings;use KinoSearch::Util::ToolSet;sub close { CORE::close shift->get_fh }=for commentDupe the filehandle and create a new object around the dupe.  Seek the dupeto the same spot as the original.=cutsub clone_stream {    my $self = shift;    open( my $duped_fh, '<&=', $self->get_fh )        or confess("Couldn't dupe filehandle: $!");    my $evil_twin        = __PACKAGE__->new( $duped_fh, $self->get_offset, $self->length, );    $evil_twin->seek( $self->tell );    return $evil_twin;}1;__END____XS__MODULE = KinoSearch    PACKAGE = KinoSearch::Store::InStream=begin comment    my $instream = KinoSearch::Store::Instream->new(         $filehandle, $offset, $length     );Constructor.  Takes 1-3 arguments, and unlike most classes in the KinoSearchsuite, the arguments to the constructor are not labeled parameters.The second argument, an offset, defaults to 0 if not supplied.  Non-zerooffsets get factored in when calling seek and tell.The last argument, a length, is the length of the "file" in bytes.  Supplyingan explicit value is only essential for InStreams which are assigned to read aportion of a compound file -- otherwise, the length gets auto-calculatedcorrectly.=end comment=cutInStream*new(class, fh_sv, ...)    char   *class;    SV     *fh_sv;PREINIT:    double  offset = 0;    double  len    = -1;CODE:    if (items > 2) {        SV* offset_sv;        offset_sv = ST(2);        if (SvOK(offset_sv))            offset = SvNV(offset_sv);    }    if (items > 3) {        SV *len_sv;        len_sv = ST(3);        if (SvOK(len_sv))            len = SvNV(len_sv);    }    RETVAL = Kino_InStream_new(class, fh_sv, offset, len);OUTPUT: RETVAL=for commentSeek to target plus the object's start offset.=cutvoidseek(instream, target)    InStream *instream;    double    target;PPCODE:    instream->seek(instream, target);=for commentReturn the filehandle's position minus the offset.=cutdoubletell(instream)    InStream *instream;CODE:    RETVAL = instream->tell(instream);OUTPUT: RETVAL=for commentReturn the length of the "file" in bytes, factoring in the offset.=cutdoublelength(instream)    InStream *instream;CODE:    RETVAL = instream->len;OUTPUT: RETVAL=begin comment    @items = $instream->lu_read( TEMPLATE );Read the items specified by TEMPLATE from the InStream.=end comment=cutSV*_set_or_get(instream, ...)    InStream *instream;ALIAS:    set_len      = 1    get_len      = 2    set_offset   = 3    get_offset   = 4    set_fh       = 5    get_fh       = 6CODE:{    KINO_START_SET_OR_GET_SWITCH    case 1:  instream->len = SvNV( ST(1) );             /* fall through */    case 2:  RETVAL = newSVnv(instream->len);             break;        case 3:  instream->offset = SvNV( ST(1) );             /* fall through */    case 4:  RETVAL = newSVnv(instream->offset);             break;        case 5:  Kino_confess("Can't set_fh");             /* fall through */    case 6:  RETVAL = newSVsv(instream->fh_sv);             break;    KINO_END_SET_OR_GET_SWITCH}OUTPUT: RETVALvoidlu_read (instream, template_sv)    InStream *instream;    SV       *template_svPREINIT:    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 */    char      sym;          /* the current symbol in the template */    char      countsym;     /* used when calculating repeat counts */    IV        aIV;    SV       *aSV;    char      aChar;    char*     string;    STRLEN    len;PPCODE:{    /* prepare template string pointers */    template    = SvPV(template_sv, tpt_len);    tpt_end     = SvEND(template_sv);    repeat_count = 0;    while (1) {        if (repeat_count == 0) {            /* fast-forward past space characters */            while (*template == ' ' && template < tpt_end) {                template++;            }            /* break out of the loop if we've exhausted the template */            if (template == tpt_end) {                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, so process once */                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;            }        }        /* thwart potential infinite loop */        if (repeat_count < 1)            Kino_confess( "invalid repeat_count: %d", repeat_count);                switch(sym) {        case 'a': /* arbitrary binary data */            len = repeat_count;            repeat_count = 1;            aSV = newSV(len + 1);            SvCUR_set(aSV, len);            SvPOK_on(aSV);            string = SvPVX(aSV);            instream->read_bytes(instream, string, len);            break;        case 'b': /* signed byte */        case 'B': /* unsigned byte */            aChar = instream->read_byte(instream);            if (sym == 'b')                 aIV = aChar;            else                aIV = (unsigned char)aChar;            aSV = newSViv(aIV);            break;        case 'i': /* signed 32-bit integer */            aSV = newSViv( (I32)instream->read_int(instream) );            break;                    case 'I': /* unsigned 32-bit integer */            aSV = newSVuv( instream->read_int(instream) );            break;        case 'Q': /* unsigned "64-bit integer" */            aSV = newSVnv( instream->read_long(instream) );            break;        case 'T': /* string */            len = instream->read_vint(instream);            aSV = newSV(len + 1);            SvCUR_set(aSV, len);            SvPOK_on(aSV);            string = SvPVX(aSV);            instream->read_chars(instream, string, 0, len);            break;        case 'V': /* VInt */            aSV = newSVuv( instream->read_vint(instream) );            break;        case 'W': /* VLong */            aSV = newSVnv( instream->read_vlong(instream) );            break;        default:             aSV = NULL; /* suppress unused var compiler warning */            Kino_confess("Invalid type in template: '%c'", sym);        }        /* Put a scalar on the stack, use up one symbol or repeater */        XPUSHs( sv_2mortal(aSV) );        repeat_count -= 1;    }}voidDESTROY(instream)    InStream *instream;PPCODE:    Kino_InStream_destroy(instream);__H__#ifndef H_KINOSEARCH_STORE_INSTREAM#define H_KINOSEARCH_STORE_INSTREAM 1#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "KinoSearchUtilCarp.h"#include "KinoSearchUtilMathUtils.h"/* Detect whether we're on an ASCII or EBCDIC machine. */#if '0' == 240#define KINO_NUM_CHAR_OFFSET 240#else#define KINO_NUM_CHAR_OFFSET 48#endif#define KINO_IO_STREAM_BUF_SIZE 1024typedef struct instream {    PerlIO  *fh;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -