FSA: File of Stream Array(C/C++ Library)

This software can be redistributed under GNU Lesser General Public License.
And every source codes can be obtained through GitHub
Copylight (c) 2023 Shigeo Kobayashi. All rights reserved.
[==>Japanese]
OverviewAPI referencesSample program(tans.c)

FSA(File of Stream Array) is a C/C++ API library for accessing FSA file,which is constructed by multiple stream structure.

Overview

Using FSA,you can create and access multiple streams in a file(FSA file). Each stream is mutually and completely independent. Just like an array index,stream index starting with 0 must be specified to access specific stream. Any stream,therefore,has its own stream size(length).

I/O steps by standard C libraryI/O steps by FSADescription
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int fd;
fd=open(pathname,openmode);
read(fd,buf,count);
write(fd,buf,count);
close(fd);
/* fsa.h must be included before using FSA API */
#include "fsa.h"

FSA_HANDLE h;
FsaOpen(&h,pathname, openmode);
FsaReadStream(h,i,buf,from,count);
FsaWriteStream(h,i,buf,from,count);
FsaClose(&h);
It is the same as in standard C/C++ API and FSA API that the target file to be accessed must be opened at first and closed when finished.
In standard C/C++, write() corresponds to FSA FsaWriteStream(),and read() to FsaReadStream().
In FSA,you need to specify starting byte position 'from' for I/O processing,because seek() is not supported.

Note the important difference that,in FsaReadStream() and FsaWriteStream(),one more argument i which is the index of the target stream is specified.
In FSA,I/O with different index i is completely independent and different. Also note that any stream identified by index i has its own stream size.


Standard C I/OFSA I/O


API references

Every API functions in FSA return integer value.
Note:
All data/informations are passed or received through arguments except function status.
Initial size of every streams are zero.
All function names exported by FSA begin "Fsa".
Before using any function listed bellow,fsa.h must be included in your codes(#include "fsa.h").

Major functions

FunctionDescription
FsaOpen(FSA_HANDLE *h,const char* file, const char mode) opens the target file.
  • FSA_HANDLE *h
    h receives FSA_HANDLE value when the file is successfully opened. This h will be specified at the first argument for any FSA functions.
  • const char* file
    target file path to be opened.
  • const char mode
    1 character(capital character is accepted) open mode listed bellow.
    • 't'
      creates new file for read &anp; write mode. If the file exists,it is truncated.
    • 'n'
      creates new file for read &anp; write mode. If the file exists, open failes.
    • 'w'
      opens exiting file for read &anp; write mode. If the file does not exist,open failes.
    • 'r'
      opens exiting file for read only mode. If the file does not exist,open failes.
FsaWriteStream(FSA_HANDLE h, U_INT i, void* buff,U_LONG from, U_INT bytes)writes data to specified stream.
  • FSA_HANDLE h
    FSA file handle opened.
  • U_INT i
    stream index number data written(0-n: see Note).
  • void* buff
    buffer address of the data written to the stream i.
  • U_LONG from
    byte location of in the stream i from where the data is written.
    (0 <= from <= current size of the stream i)
  • U_INT bytes
    total number of bytes written to the stream i.
FsaReadStream (FSA_HANDLE h, U_INT i, void* buff,U_LONG from, U_INT bytes) reads data from specified stream.
  • FSA_HANDLE h
    FSA file handle opened.
  • U_INT i
    stream index number data read(0-n: see Note).
  • void* buff
    buffer address of the data read from the stream i.
  • U_LONG from
    byte location of in the stream i from where the data is read.
    (from + bytes <= current size of the stream i)
  • U_INT bytes
    total number of bytes read from the stream i.
FsaClose(FSA_HANDLE* h)closes FSA file proccessed. Even if any error is detected,the error handler is not called if it is set.

Note:
n can be obtained by calling FsaGetMaxStreamCount(h,&m) where n=m-1. And,m can be extended to any number by FsaExtendMaxStreamCount(h,M). (Total count of streams will be increased at least M).

補助関数

関数名説明(引数)
FsaGetStreamSize(FSA_HANDLE h, U_INT i, U_LONG* size)sets the current byte size of the stream i to size.
FsaTrimStream(FSA_HANDLE h, U_INT i, U_LONG from)sets the current byte size of the stream i to 'from' (every data after from will be deleted).
FsaGetMaxStreamCount(FSA_HANDLE h, U_INT *cs)sets the maximum number of the streams currently accessible to cs.
FsaExtendMaxStreamCount(FSA_HANDLE h, U_INT cs)extens(increases) the maximum number of the streams at least cs.
FsaSetFsaTag(FSA_HANDLE h, U_LONG tag)sets user specific data tag,which is kept in the header,to FSA file(h).
FsaGetFsaTag(FSA_HANDLE h, U_LONG* tag)gets user specific data to tag from FSA file.
FsaSetStreamTag(FSA_HANDLE h, U_INT i, U_LONG tag)set user specific data tag,which is kept in each stream directory,to stream i.
FsaGetStreamTag(FSA_HANDLE h, U_INT i, U_LONG* tag)gets user specific data tag from stream i.
FsaSetErrHandler(FSA_HANDLE h, FSA_ERROR_HANDLER f)sets(registers) the address of the error handler f. If f is NULL(0),then previously registerred adress will be deleted.
FsaGetErrHandler(FSA_HANDLE h, FSA_ERROR_HANDLER *f)gets error handleraddress to f. If obtained f is NULL(0),then no error handler has not been registerred yet.
FsaGetOpenMode(FSA_HANDLE h, char *mode)gets open mode (capitalized)character to mode which was specified FsaOpen().

Error handler

Every FSA functions return function value 0 for successfull results,nonzero value otherwise. It sometimes is not easy to check every function's return value. You can register the error handler instead. If the error handler is registerred,then FSA function calls it every time when any error is detected. FSA function returns the value the error handler returned to the user.

See how the error handler is used in the sample program tans.c.
The error handler is defined like the list bellow.


int ErrorFunc(
	/* All arguments are set by FSA */
	FSA_HANDLE  handle,       /* FSA_HANDLE currently running.   */
	const char* function,     /* FSA function name the error detected */
	int         fsa_code,     /* FSA error code(see fsa.h) that FSA function detected.
                                     (If this is FSA_ERROR_UNDEFINED,then infomations after err_no may be undefined. */
	int         err_no,       /* copy of C system's errno. Use C standard function strerror(err_no) for detail. */
	const char* msg,          /* The error message that FSA function can describe. */
	const char* source_file,  /* The source file the error occured. */
	int         source_line   /* The source line the error occured. */
	)
{
	char ch;
	printf(" FSA Error: f=%s code=%d c_er=%d msg=%s file=%s line=%d\n", function, fsa_code, err_no, msg, source_file, source_line);
	if(err_no!=0) printf("        c error=%d:%s\n",err_no,strerror(err_no));
	printf("Continue or exit (c|e)?");
	do {
		ch = toupper(getchar());
	} while (ch != 'C' && ch != 'E');
	if (ch == 'E') {
		FsaClose(&handle);
		exit(EXIT_FAILURE);
	}
	return fsa_code;
}

Sanple program (tans.c)

For actual programming,see the sample program tans.c(The FSA file, tans.c opens is called TANS file).
Using tans.c,you can store any file to TANS file(to any stream),and withdraw any file(stream) from TANS file.
To invoke,command line will be: tans <open mode> <FSA(TANS) file>
where <open mode> is the same open mode character specified to
FsaOpen().
<FSA(TANS) file> is the target FSA file path.
You can specify '?' to see help messages.
Shigeo Kobayashi(shigeo@tinyforest.jp) 2023-2-10