e46f15e6 |
/*
* dna_astream.h
*
* Created on: 07.10.2013
* Author: wolfgang
*/
#ifndef DNA_ASTREAM_H_
#define DNA_ASTREAM_H_
#include "dna_fstream.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// dna file stream
// Keeps two (equal sized) character buffers (raw and processed) and two iterators
//
// Raw buffer can be (re-) filled from dna_fstream.
// Client struct can define functions for searching and coypying content into
// processed buffer.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
//
// Define buffer size and delimiting characters
//
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
static const char das_char_eos ='\0';
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
//
// Define status flags
//
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
static const int das_err =-1; // Unrecoverable error state
static const int das_ok = 0; // Must be 0 !!!
static const int das_empty = 1; // Future raw size =0
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
//
// Struct definition
//
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
typedef struct dna_astream
{
dfStream *dnaf;
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
// Character array declarations
unsigned nchar; // Maximal number of characters in rfc and pos
// (array size=nchar+1)
// Pointers to character arrays (= begin pointers)
char * rfc; // Raw file content : rfc-array
char * pos; // Processed output sequence : pos-array
// Iterators which reside inside arrays
char * r_iter; // iterator for rfc
char * p_iter; // iterator for pos
// Point to past-the-end character of arrays ('\0')
char * r_end; // rfc array
char * p_end; // behind last retrievable character
int npPos; // Number of character values in pos array (=strlen)
//
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
int state; // Carries stream state flags
unsigned nFill;
unsigned nFillWhole;
unsigned nFillWholeIncomp;
unsigned nFillPart;
unsigned nFillPartIncomp;
} daStream;
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
//
// Check routines
//
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
static inline int dasEmpty(daStream *das) { return das->r_iter == das->r_end; }
static inline int dasProcEmpty(daStream *das) { return das->p_iter == das->p_end; }
static inline int dasIsError(daStream *das) { return das->state & das_err; }
static inline int dasIsOpen(daStream *das) { return dfs_isOpen(das->dnaf); }
static inline int dasIsEof(daStream *das) { return dfs_stream_eof(das->dnaf); }
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
//
// Constructing and and File operations
//
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //
void das_destroy(daStream *das)
{
if(das)
{
dfs_destroy(das->dnaf);
das->dnaf=0;
free(das->rfc);
das->rfc=0;
free(das->pos);
das->pos=0;
free(das);
}
}
int das_fill(daStream *das)
{
//printf("[das_fill] before: '%s'\n",das->rfc);
size_t count = 0;
int rhs= (int)(das->r_end - das->r_iter); // Number of unprocessed characters in array
int lhs= (int)(das->r_iter - das->rfc); // Number of processed characters in array
if(dfs_isOpen(das->dnaf))
{
if(rhs>0)
{
//printf("[das_fill] rhs= %u\n",rhs);
if(lhs<rhs)
{
// Enough space at begin of array?
//printf("[das_fill] Partial fill ERROR!\n");
das->state = das_err;
return das->state;
}
// Shift unused suffix to begin
memcpy(das->rfc, das->r_iter, (size_t) rhs);
count = dfs_read(das->dnaf, das->rfc + rhs, (unsigned) lhs);
/* lhs < 0 should not be possible */
if(count < ((size_t) lhs))
++das->nFillPartIncomp;
++das->nFillPart;
}
else
{ // Refill whole array
//printf("[das_fill] rhs== %u\n",rhs);
count = dfs_read(das->dnaf, das->rfc, das->nchar);
if(count < das->nchar)
++das->nFillWholeIncomp;
++das->nFillWhole;
}
das->r_end = das->rfc + count; // past-the-end
*das->r_end = das_char_eos; // '\0'
das->r_iter = das->rfc; // Re-init iter
++das->nFill;
}
if(count==0)
{
//printf("[das_fill] count==0.\n");
das->state |= das_empty;
return das->state;
}
// Return success
das->state &= (~das_empty);
return das_ok;
}
daStream * das_init(const char* filename, unsigned das_size)
{
daStream *das = calloc(sizeof(daStream), 1);
if(!das)
{
//printf("[das_init] das calloc returned 0!\n");
return 0;
}
das->dnaf = dfs_stream_init(filename);
if(!das->dnaf)
{
//printf("[das_init] dfs_stream_init returned 0!\n");
das->state = das_err;
return das;
}
das->nchar = das_size;
das->rfc = calloc(das_size + 1, sizeof(char));
if(!das->rfc)
{
//printf("[das_init] rfc calloc returned 0!\n");
das->state = das_err;
return das;
}
das->pos = calloc(das_size + 1, sizeof(char));
if(!das->pos)
{
//printf("[das_init] pos calloc returned 0!\n");
das->state = das_err;
return das;
}
das->r_end = das->rfc + das_size;
// Indicates empty buffer
// -> first das_fill will
// read complete buffer
das->r_iter = das->r_end;
// Returns memory initialized structure
// but dfs file is possibly closed
// (e.g. file not found).
return das;
}
#endif /* DNA_ASTREAM_H_ */
|