src/dna_astream.h
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_ */