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

buffer.c

/*
 * Copyright (c) 2003, 2004 Nokia
 * Author: tsavola@movial.fi
 *
 * This program is licensed under GPL (see COPYING for details)
 */

#include "types.h"
#include "buffer.h"
#include "protocol.h"
#include "common.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

/**
 * Allocates and initializes the buffer_t structure and allocates the buffer.
 */
buffer_t *buf_alloc()
{
      buffer_t *buf = calloc(1, sizeof (buffer_t));
      if (buf) {
            buf->mem_size = BUFFER_SIZE;
            buf->mem = malloc(BUFFER_SIZE);
            if (!buf->mem) {
                  free(buf);
                  buf = 0;
            }
      }
      return buf;
}

/**
 * Frees memory allocated by buffer and the buffer.
 * @param buf the buffer
 */
void buf_free(buffer_t *buf)
{
      if (buf->mem)
            free(buf->mem);

      free(buf);
}

/**
 * Sets the EOF flag. When the buffer is written completely, this causes the
 * @param buf the buffer
 * target file to be closed.
 */
void buf_set_eof(buffer_t *buf)
{
      buf->eof = TRUE;
}

/**
 * Calculates the amount of data currently in the buffer.
 * @param buf the buffer
 * @return the amount of data in the buffer
 */
size_t buf_size(buffer_t *buf)
{
      return buf->end - buf->start;
}

/**
 * Checks if the buffer is empty and doesn't have the EOF flag set.
 * @param buf the buffer
 * @returns TRUE or FALSE
 */
bool_t buf_is_empty(buffer_t *buf)
{
      return buf->end == 0 && buf->eof == FALSE;
}

/**
 * Appends data to a buffer from a file. If buffer is full, a larger block of
 * memory is allocated for it.
 * @param buf the buffer
 * @param fd the file descriptor
 * @param len the amount of data to be copied
 * @return the number of bytes actually read, -1 on error
 */
ssize_t buf_read_in(buffer_t *buf,
                int fd,
                size_t len)
{
      size_t size;

      assert (!buf->eof);

      size = buf->end + len;
      if (size > buf->mem_size) {
            /* TODO: use relloac() */

            uint8_t *mem;

            mem = malloc(size);
            if (!mem) {
                  return -1;
            }

            memcpy(mem, buf->mem, buf->mem_size);
            free(buf->mem);

            buf->mem_size = size;
            buf->mem = mem;
      }

      if (read_buf(fd, buf->mem + buf->end, len) < 0) {
            return -1;
      }

      buf->end += len;

      return len;
}

/**
 * Writes as much data from a buffer to a file as possible.
 * @param buf the buffer
 * @param fd the file descriptor
 * @return the amount of data actually written or -1 if fd doesn't want data
 */
ssize_t buf_write_out(buffer_t *buf,
                  int *fd)
{
      size_t size;
      ssize_t len = 0;

      size = buf_size(buf);
      if (size) {
            assert(buf->start < buf->mem_size);

            len = write_ni(*fd, &buf->mem[buf->start], size);
            if (len < 0) {
                  if (errno == EAGAIN) {
                        len = 0;
                  } else {
                        close(*fd);
                        *fd = -1;

                        return -1;
                  }
            }

            buf->start += len;

            size = buf_size(buf);
            if (size == 0) {
                  buf->start = 0;
                  buf->end = 0;
            }
      }

      if (size == 0 && buf->eof) {
            close(*fd);
            *fd = -1;
            errno = 0;

            /* Make buffer empty. */
            buf->eof = FALSE;
      }

      return len;
}

Generated by  Doxygen 1.6.0   Back to index