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 )