Mail-Box-Parser-C

 view release on metacpan or  search on metacpan

C.xs  view on Meta::CPAN

    int       boxnr;

  CODE:
    box       = new_mailbox(name);
    box->file = fh;

    boxnr     = take_box_slot(box);

    /*fprintf(stderr, "Open with filehande is done.\n");*/
    RETVAL    = boxnr;

  OUTPUT:
    RETVAL


#
# close_file
#

void
MBPC_close_file(int boxnr)

  PREINIT:
    Mailbox   * box;
    Separator * sep;

  CODE:
    box  = get_box(boxnr);
    if(box==NULL) return;

    free_box_slot(boxnr);

    if(box->file != NULL)
    {   fclose(box->file);
        box->file = NULL;
    }

    sep = box->separators;
    while(sep!=NULL)
    {   Separator * next = sep->next;
        Safefree(sep->line);
        Safefree(sep);
        sep = next;
    }

    Safefree(box->filename);
    Safefree(box);


#
# push_separator
#

void
MBPC_push_separator(int boxnr, char *line_start)

  PREINIT:
    Mailbox *box;
    Separator  *sep;

  PPCODE:
    box  = get_box(boxnr);
    if(box==NULL) return;

    /*fprintf(stderr, "separator %s\n", line_start);*/
    New(0, sep, 1, Separator);
    sep->length     = strlen(line_start);

    /*fprintf(stderr, "separator %ld\n", (long)sep->length+1);*/
    New(0, sep->line, sep->length+1, char);
    strcpy(sep->line, line_start);

    sep->next       = box->separators;
    box->separators = sep;

    if(strncmp(sep->line, "From ", sep->length)==0)
        box->strip_gt++;


#
# pop_separator
#

SV *
MBPC_pop_separator(int boxnr)

  PREINIT:
    Mailbox   *box;
    Separator *old;

  CODE:
    box  = get_box(boxnr);
    if(box==NULL) XSRETURN_UNDEF;

    old = box->separators;
    if(old==NULL) XSRETURN_UNDEF;

    if(strncmp(old->line, "From ", old->length)==0)
        box->strip_gt--;

    /*fprintf(stderr, "pop sep %s\n", old->line);*/
    box->separators = old->next;
    RETVAL = newSVpv(old->line, old->length);

    Safefree(old->line);
    Safefree(old);

  OUTPUT:
    RETVAL


#
# get_position
#

long
MBPC_get_position(int boxnr)

  PREINIT:
    Mailbox *box;

  CODE:
    box  = get_box(boxnr);
    if(box==NULL) RETVAL = 0;
    else          RETVAL = file_position(box);

  OUTPUT:
    RETVAL

#
# set_position
#

int
MBPC_set_position(int boxnr, long where)

  PREINIT:
    Mailbox *box;

  CODE:
    box  = get_box(boxnr);

    if(box==NULL) RETVAL = 0;
    else          RETVAL = goto_position(box, where)==0;

  OUTPUT:
    RETVAL

#
# read_header
# Returns (begin, end, list-of-fields)
# Where
#     begin and end represent file-locations before resp after the header
#     each field is a ref to an array with a name/content pair, representing
#          one line.
#

void
MBPC_read_header(int boxnr)

  PREINIT:
    Mailbox * box;
    SV      * name;
    SV      * content;
    SV      * end;

  PPCODE:
    box = get_box(boxnr);
    if(box==NULL || box->file==NULL) return;

    XPUSHs(sv_2mortal(newSViv((IV)file_position(box))));
    XPUSHs(end = sv_newmortal());

    while(read_header_line(box, &name, &content))
    {   AV * field = newAV();
        av_push(field, name);     /* av_push does not increase refcount */
        av_push(field, content);
        XPUSHs(sv_2mortal(newRV_noinc((SV *)field)));
    }
 
    /*fprintf(stderr, "Header has been read\n");*/
    sv_setiv(end, (IV)file_position(box));

#
# in_dosmode
#

int
MBPC_in_dosmode(int boxnr)

  PREINIT:
    Mailbox *box;

  CODE:
    box   = get_box(boxnr);
    if(box==NULL)
        XSRETURN_UNDEF;

    RETVAL = box->dosmode;

  OUTPUT:
    RETVAL


#
# read_separator
# Return a line with the last defined separator.  Empty lines before this
# are permitted, but no other lines.
#

void
MBPC_read_separator(int boxnr)

  PREINIT:
    Mailbox   *box;
    Separator *sep;
    char      *line;

  PPCODE:
    box  = get_box(boxnr);
    if(box==NULL)
        XSRETURN_EMPTY;

    sep  = box->separators;    /* Never success when there is no sep */
    if(sep==NULL)
        XSRETURN_EMPTY;

    line = get_one_line(box);  /* Get first real line. */
    while(line!=NULL && line[0]=='\n' && line[1]==EOL)
        line = get_one_line(box);

    if(line==NULL)             /* EOF reached. */
        XSRETURN_EMPTY;

    if(strncmp(sep->line, line, sep->length)!=0)
    {   box->keep_line = 1;
        return;
    }

    EXTEND(SP, 2);
    PUSHs(sv_2mortal(newSViv(box->line_start)));
    PUSHs(sv_2mortal(newSVpv(line, strlen(line))));


#
# body_as_string
# Read the whole body into one scalar, and return it.
# When lines need a post-processing, we read line-by-line.  Otherwise
# we can read the block as a whole.
#

void
MBPC_body_as_string(int boxnr, int expect_chars, int expect_lines)

  PREINIT:
    Mailbox *box;
    SV      *result;
    char   **lines;
    int      nr_lines = 0;
    int      nr_chars = 0;
    int      line_nr;
    long     begin;

  PPCODE:
    box  = get_box(boxnr);
    if(box==NULL)
        XSRETURN_EMPTY;

    begin = file_position(box);

    if(!box->dosmode && !box->strip_gt && expect_chars >=0)
    {
        long  end = begin + expect_chars;

        if(is_good_end(box, end))
        {   EXTEND(SP, 3);
            PUSHs(sv_2mortal(newSViv(begin)));
            PUSHs(sv_2mortal(newSViv(file_position(box))));
            PUSHs(sv_2mortal(take_scalar(box, begin, end)));
            XSRETURN(3);
        }
    }

    lines = read_stripped_lines(box, expect_chars, expect_lines,
        &nr_chars, &nr_lines);

    if(lines==NULL)
        XSRETURN_EMPTY;

    /* Join the strings. */
    result = newSVpv("",0);
    SvGROW(result, (unsigned int)nr_chars);

    for(line_nr=0; line_nr<nr_lines; line_nr++)
    {   sv_catpv(result, lines[line_nr]);
        Safefree(lines[line_nr]);
    }

    skip_empty_lines(box);
    Safefree(lines);

    EXTEND(SP, 3);
    PUSHs(sv_2mortal(newSViv(begin)));
    PUSHs(sv_2mortal(newSViv(file_position(box))));
    PUSHs(sv_2mortal(result));


#
# body_as_list
# Read the whole body into a list of scalars.
#

void
MBPC_body_as_list(int boxnr, int expect_chars, int expect_lines)

  PREINIT:
    Mailbox *box;
    char   **lines;
    int      nr_lines = 0;
    int      nr_chars = 0;
    int      line_nr;
    long     begin;
    AV     * results;

  PPCODE:
    box   = get_box(boxnr);
    if(box==NULL)
        XSRETURN_EMPTY;

    begin = file_position(box);
    lines = read_stripped_lines(box, expect_chars, expect_lines,
        &nr_chars, &nr_lines);

    if(lines==NULL) return;

    XPUSHs(sv_2mortal(newSViv(begin)));
    XPUSHs(sv_2mortal(newSViv(file_position(box))));

    /* Allocating the lines for real. */

    results = (AV *)sv_2mortal((SV *)newAV());
    av_extend(results, nr_lines);

    for(line_nr=0; line_nr<nr_lines; line_nr++)
    {   char *line = lines[line_nr];
        av_push(results, newSVpv(line, 0));
        Safefree(line);
    }

    XPUSHs(sv_2mortal(newRV((SV *)results)));

    skip_empty_lines(box);
    Safefree(lines);


#
# body_as_file
# Read the whole body into a file.
#

void
MBPC_body_as_file(int boxnr, FILE *out, int expect_chars, int expect_lines)

  PREINIT:
    Mailbox *box;
    char   **lines;
    int      nr_lines=0;
    int      nr_chars=0;
    int      line_nr;
    long     begin;

  PPCODE:
    box    = get_box(boxnr);
    if(box==NULL)
        XSRETURN_EMPTY;

    begin = file_position(box);
    lines = read_stripped_lines(box, expect_chars, expect_lines,
        &nr_chars, &nr_lines);

    if(lines==NULL)
        XSRETURN_EMPTY;

    EXTEND(SP, 3);
    PUSHs(sv_2mortal(newSViv((IV)begin)));
    PUSHs(sv_2mortal(newSViv((IV)file_position(box))));
    PUSHs(sv_2mortal(newSViv((IV)nr_lines)));

    /* write the lines to file. */

    for(line_nr=0; line_nr<nr_lines; line_nr++)
    {   fprintf(out, "%s", lines[line_nr]);
        Safefree(lines[line_nr]);
    }

    skip_empty_lines(box);
    Safefree(lines);


#
# body_delayed
# Skip the whole body, only counting chars and lines.
#

void
MBPC_body_delayed(int boxnr, int expect_chars, int expect_lines)

  PREINIT:
    Mailbox *box;
    int      nr_lines = 0;
    int      nr_chars = 0;
    long     begin;

  PPCODE:
    box   = get_box(boxnr);
    if(box==NULL)
        XSRETURN_EMPTY;

    begin = file_position(box);

    if(expect_chars >=0)
    {
        long  end    = begin + expect_chars;
        if(is_good_end(box, end))
        {   /*  Accept new end  */
            goto_position(box, end);

            EXTEND(SP, 4);
            PUSHs(sv_2mortal(newSViv((IV)begin)));
            PUSHs(sv_2mortal(newSViv((IV)end)));
            PUSHs(sv_2mortal(newSViv((IV)expect_chars)));
            PUSHs(sv_2mortal(newSViv((IV)expect_lines)));
            skip_empty_lines(box);
            XSRETURN(4);
        }
    }

    if(scan_stripped_lines(box, expect_chars, expect_lines,
        &nr_chars, &nr_lines))
    {   EXTEND(SP, 4);
        PUSHs(sv_2mortal(newSViv((IV)begin)));
        PUSHs(sv_2mortal(newSViv((IV)file_position(box))));
        PUSHs(sv_2mortal(newSViv((IV)nr_chars)));
        PUSHs(sv_2mortal(newSViv((IV)nr_lines)));
        skip_empty_lines(box);
    }

#
# get_filehandle
#

FILE *
MBPC_get_filehandle(int boxnr)

  PREINIT:
    Mailbox * box;

  CODE:
    box       = get_box(boxnr);
    if(box==NULL) XSRETURN_UNDEF;

    RETVAL    = box->file;

  OUTPUT:
    RETVAL



( run in 2.195 seconds using v1.01-cache-2.11-cpan-5511b514fd6 )