Logo Search packages:      
Sourcecode: fastjar version File versions  Download package


  pushback.c - code for a pushback buffer to handle file I/O
  Copyright (C) 1999  Bryan Burns
  Copyright (C) 2007  Dalibor Topic
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include "jartool.h"
#include "pushback.h"

void pb_init(pb_file *pbf, int fd){
  pbf->fd = fd;
  pbf->next = pbf->pb_buff;
  pbf->buff_amt = 0;

size_t pb_push(pb_file *pbf, void *buff, size_t amt){
  size_t in_amt;
  size_t wrap = 0;

#ifdef DEBUG
  printf("%d bytes being pushed back to the buffer\n", amt);

  /* determine how much we can take */
  if((RDSZ - pbf->buff_amt) < amt)
    in_amt = RDSZ - pbf->buff_amt;
    in_amt = amt;

  if(in_amt == 0)
    return 0;

  /* figure out if we need to wrap around, and if so, by how much */
  if((size_t) ((pbf->pb_buff + RDSZ) - pbf->next) < in_amt)
    wrap = in_amt - ((pbf->pb_buff + RDSZ) - pbf->next);

  /* write everything up til the end of the buffer */
  memcpy(pbf->next, buff, (in_amt - wrap));

  /* finish writing what's wrapped around */
  memcpy(pbf->pb_buff, ((char *)buff + (in_amt - wrap)), wrap);
  /* update the buff_amt field */
  pbf->buff_amt += in_amt;

#ifdef DEBUG
  printf("%d bytes we can't accept\n", (amt - in_amt));

  return in_amt;

size_t pb_read(pb_file *pbf, void *buff, size_t amt){
  size_t out_amt = 0;
  size_t wrap = 0;
  void *bp = buff;
  size_t tmp;

#ifdef DEBUG
  printf("%d bytes requested from us\n", amt);
  while(out_amt < amt){
    /* if our push-back buffer contains some data */
    if(pbf->buff_amt > 0){
#ifdef DEBUG
      printf("giving data from buffer\n");
      /* calculate how much we can actually give the caller */
      if( (amt - out_amt) < pbf->buff_amt )
        tmp = (amt - out_amt);
        tmp = pbf->buff_amt;
      /* Determine if we're going to need to wrap around the buffer */
      if(tmp > ((size_t) ((pbf->pb_buff + RDSZ) - pbf->next)))
        wrap = tmp - ((pbf->pb_buff + RDSZ) - pbf->next);
      memcpy(bp, pbf->next, (tmp - wrap));
      bp = &(((char *)bp)[tmp - wrap]);
      /* If we need to wrap, read from the start of the buffer */
      if(wrap > 0){
        memcpy(bp, pbf->pb_buff, wrap);
        bp = &(((char *)bp)[wrap]);
      /* update the buff_amt field */
      pbf->buff_amt -= tmp;
      pbf->next += tmp;
#ifdef DEBUG
      printf("%d bytes remaining in buffer\n", pbf->buff_amt);
      /* if the buffer is empty, reset the next header to the front of the
         buffer so subsequent pushbacks/reads won't have to wrap */
      if(pbf->buff_amt == 0)
        pbf->next = pbf->pb_buff;
      out_amt += tmp;

    } else {
      ssize_t num_read;
#ifdef DEBUG
      printf("Reading from file..\n");
      /* The pushback buffer was empty, so we just need to read from the file */
      num_read = read(pbf->fd, bp, (amt - out_amt));
      if(-1 == num_read) {
      if(num_read == 0)
      else {
        tmp = (size_t) num_read;
        out_amt += tmp;
      bp = &(((char *)bp)[tmp]);

#ifdef DEBUG
  printf("managed to read %d bytes\n", out_amt);
  return out_amt;

Generated by  Doxygen 1.6.0   Back to index