/****************************************************************************************************/
/* */
/* fileReader.lib.c: */
/* */
/****************************************************************************************************/
/****************************************************************************************************/
/* */
/* Copyright (C) 2004 Joerg Kunze */
/* */
/* This file is part of siliconBrain. */
/* */
/* siliconBrain is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* siliconBrain is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* */
/****************************************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <pwd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "siliconBrainLib"
#include "siliconBrainSpecification"
#include "siliconBrainOption"
// static const char *siliconBrainRelease = "$siliconBrainRelease: 0.2.3 $";
// static const char *siliconBrainRcsIdentifier = "$Id: fileReader.lib.c,v 1.10 2004/12/14 23:31:26 joerg Exp $";
// static const char *siliconBrainSaveStamp = "$siliconBrainSaveStamp: 2004/12/14 22:15:38, Joerg Kunze$";
/****************************************************************************************************/
/* */
/* fileReader: */
/* */
/****************************************************************************************************/
static CommandReturnCode fileRead( UserCommand userCommand, void *options, void *commandData, int file ) {
CommandReturnCode returnCode = commandOk;
bool stopit = 0;
bool stopable = 0;
struct stat fileStatus;
off_t bufferSize = BUFSIZ;
size_t fileSize = 0;
if( fstat( file, &fileStatus ) != -1 ) {
fileSize = fileStatus.st_size;
bufferSize = fileStatus.st_blksize ?: BUFSIZ;
if( S_ISREG( fileStatus.st_mode ) ) stopable = 1;
}
if( fileSize ) {
String source = {
// .begin = mmap( 0, fileSize, PROT_READ, MAP_SHARED, file, 0 ),
.begin = mmap( 0, fileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, file, 0 ),
.length = fileSize,
.capacity = fileSize
};
if( (int)source.begin != -1 ) {
returnCode = (*userCommand)( options, commandData, source );
munmap( source.begin, source.length );
return returnCode;
}
}
String source = {
.begin = alloca( bufferSize ),
.length = 0,
.capacity = bufferSize
};
while( !stopit && (source.length = read( file, source.begin, source.capacity )) )
stopit = ( commandStop == (returnCode = (*userCommand)( options, commandData, source )) );
/*-----------------------------------------------------------------------------------------------------*/
/* if it is something like a pipe, it is better to consume up the complete file, thus not stopping the */
/* pipe writing process. */
/*-----------------------------------------------------------------------------------------------------*/
if( stopit && !stopable )
while( read( file, source.begin, source.capacity ) );
return returnCode;
}
/****************************************************************************************************/
/* */
/* fileReader: */
/* */
/****************************************************************************************************/
extern CommandReturnCode fileReader( FileReaderContext *context, void *options, int argc, char *argv[] ) {
CommandReturnCode returnCode = commandOk;
bool stopit = 0;
int file;
void *commandData = 0;
if( context->openCommand ) commandData = context->openCommand( options );
if( argc ) {
int fileNumber;
for( fileNumber = 0; fileNumber < argc && !stopit; ++fileNumber ) {
file = open( argv[ fileNumber ], O_RDONLY );
String fileName = { .begin = argv[ fileNumber ], .length = strlen( argv[ fileNumber ] ), .capacity = strlen( argv[ fileNumber ] ) };
if( context->openFile ) context->openFile( options, commandData, fileName );
stopit = ( commandStop == (returnCode = fileRead( context->userCommand, options, commandData, file )) );
if( context->openFile ) returnCode = context->closeFile( options, commandData, fileName );
close( file );
}
}
else {
if( context->openFile ) context->openFile( options, commandData, c( "" ) );
returnCode = fileRead( context->userCommand, options, commandData, 0 );
if( context->openFile ) returnCode = context->closeFile( options, commandData, c( "" ) );
}
if( context->closeCommand ) returnCode = context->closeCommand( options, commandData );
return returnCode;
}
/****************************************************************************************************/
/* */
/* pipeReader: */
/* */
/****************************************************************************************************/
extern CommandReturnCode pipeReader( FileReaderContext *context, void *options, int file ) {
CommandReturnCode returnCode = commandOk;
bool stopit = 0;
void *commandData = 0;
if( context->openCommand ) commandData = context->openCommand( options );
if( context->openFile ) context->openFile( options, commandData, c( "" ) );
off_t bufferSize = BUFSIZ;
String source = {
.begin = alloca( bufferSize ),
.length = 0,
.capacity = bufferSize
};
while( !stopit && (source.length = read( file, source.begin, source.capacity )) )
stopit = ( commandStop == (returnCode = (*context->userCommand)( options, commandData, source )) );
/*-----------------------------------------------------------------------------------------------------*/
/* if it is something like a pipe, it is better to consume up the complete file, thus not stopping the */
/* pipe writing process. */
/*-----------------------------------------------------------------------------------------------------*/
if( stopit ) while( read( file, source.begin, source.capacity ) );
if( context->openFile ) returnCode = context->closeFile( options, commandData, c( "" ) );
if( context->closeCommand ) returnCode = context->closeCommand( options, commandData );
return returnCode;
}
/*
$Log: fileReader.lib.c,v $
Revision 1.10 2004/12/14 23:31:26 joerg
published for new release 0.2.3
Revision 1.9 2004/12/14 23:17:05 joerg
published for new release 0.2.2
Revision 1.8 2004/12/14 22:20:09 joerg
pipe output of make command into stringSearch c-function
without creating a process for stringSearch. The later is used as a C-function command, not as a main.
*/