nakedmud-mod/
nakedmud-mod/html/tutorials/
nakedmud-mod/html/tutorials/building_extras/
nakedmud-mod/html/tutorials/c/
nakedmud-mod/html/tutorials/reference/
nakedmud-mod/html/tutorials/scripting/
nakedmud-mod/html/tutorials/scripting_extras/
nakedmud-mod/lib/
nakedmud-mod/lib/help/A/
nakedmud-mod/lib/help/B/
nakedmud-mod/lib/help/C/
nakedmud-mod/lib/help/D/
nakedmud-mod/lib/help/G/
nakedmud-mod/lib/help/H/
nakedmud-mod/lib/help/J/
nakedmud-mod/lib/help/L/
nakedmud-mod/lib/help/M/
nakedmud-mod/lib/help/O/
nakedmud-mod/lib/help/P/
nakedmud-mod/lib/help/R/
nakedmud-mod/lib/help/S/
nakedmud-mod/lib/help/W/
nakedmud-mod/lib/logs/
nakedmud-mod/lib/misc/
nakedmud-mod/lib/players/
nakedmud-mod/lib/pymodules/polc/
nakedmud-mod/lib/txt/
nakedmud-mod/lib/world/
nakedmud-mod/lib/world/zones/examples/
nakedmud-mod/lib/world/zones/examples/mproto/
nakedmud-mod/lib/world/zones/examples/oproto/
nakedmud-mod/lib/world/zones/examples/reset/
nakedmud-mod/lib/world/zones/examples/rproto/
nakedmud-mod/lib/world/zones/examples/trigger/
nakedmud-mod/lib/world/zones/limbo/
nakedmud-mod/lib/world/zones/limbo/room/
nakedmud-mod/lib/world/zones/limbo/rproto/
nakedmud-mod/src/alias/
nakedmud-mod/src/dyn_vars/
nakedmud-mod/src/editor/
nakedmud-mod/src/example_module/
nakedmud-mod/src/help2/
nakedmud-mod/src/set_val/
nakedmud-mod/src/socials/
nakedmud-mod/src/time/
//*****************************************************************************
//
// filebuf.h
//
// buffered file io
//
//*****************************************************************************

#include <stdio.h>
#include <time.h>
#include "mud.h"



//*****************************************************************************
// local structures and defines
//*****************************************************************************

#define FBMODE_READ              0
#define FBMODE_WRITE             1

struct buffered_file {
  FILE    *fl;
  BUFFER *buf;
  int     pos;
  int    mode;
};

//
// buffer up input from our file
void fb_buffer(FILEBUF *fb) {
  if(feof(fb->fl))
    return;

  char in[MAX_BUFFER+1];
  int amnt;
  do {
    amnt = fread(in, sizeof(char), MAX_BUFFER, fb->fl);
    in[amnt] = '\0';
    bufferCat(fb->buf, in);
  } while(amnt == MAX_BUFFER);
}

FILEBUF *fbopen(const char *fname, const char *mode) {
  // make sure we can access the file...
  FILE *fl = fopen(fname, mode);
  if(fl == NULL)
    return NULL;

  // clock our performance
  // struct timeval start_time;
  // gettimeofday(&start_time, NULL);

  FILEBUF *fb = malloc(sizeof(FILEBUF));
  fb->fl      = fl;
  fb->buf     = newBuffer(1024);
  fb->pos     = 0;

  if(*mode == 'r') {
    fb->mode = FBMODE_READ;
    fb_buffer(fb);
  }
  else
    fb->mode = FBMODE_WRITE;

  // finish clocking performance
  // struct timeval end_time;
  // gettimeofday(&end_time, NULL);
  // int usecs = (int)(end_time.tv_usec - start_time.tv_usec);
  // int secs  = (int)(end_time.tv_sec  - start_time.tv_sec);
  // log_string("buffer open time %d %s", (int)(secs*1000000 + usecs), fname);

  return fb;
}

//
// close, flush, and delete the buffered file reader
void fbclose(FILEBUF *fb) {
  fbflush(fb);
  fclose(fb->fl);
  deleteBuffer(fb->buf);
  free(fb);
}

//
// flush the buffered file reader
void fbflush(FILEBUF *fb) {
  if(fb->mode == FBMODE_WRITE && bufferLength(fb->buf) > fb->pos) {
    const char *to_flush = bufferString(fb->buf);
    fprintf(fb->fl, "%s", to_flush+fb->pos);
    fb->pos = bufferLength(fb->buf);
  }
}

//
// return the next char in the buffered file
char fbgetc(FILEBUF *fb) {
  if(fb->pos >= bufferLength(fb->buf))
    return EOF;
  else
    return bufferString(fb->buf)[fb->pos++];
}

//
// print the formatting to the file
int fbprintf(FILEBUF *fb, const char *fmt, ...) {
  va_list va;
  va_start(va, fmt);
  int res = vbprintf(fb->buf, fmt, va);
  va_end(va);
  return res;
}

//
// append the text to the buffer
void fbwrite(FILEBUF *fb, const char *str) {
  bufferCat(fb->buf, str);
}

//
// go to the position, from the specified offset. Uses SEEK_CUR, SEEK_SET,
// and SEEK_END from stdio.h
void fbseek(FILEBUF *fb, int offset, int origin) {
  if(origin == SEEK_SET)
    fb->pos = 0;
  else if(origin == SEEK_END)
    fb->pos = bufferLength(fb->buf) - 1;
  else if(origin != SEEK_CUR)
    return;
  fb->pos += offset;
}