|
/***************************************************************************
|
|
$RCSfile$
|
|
-------------------
|
|
cvs : $Id$
|
|
begin : Fri Feb 07 2003
|
|
copyright : (C) 2003 by Martin Preuss
|
|
email : martin@libchipcard.de
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Lesser General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2.1 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library 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 *
|
|
* Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
* License along with this library; if not, write to the Free Software *
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
|
|
* MA 02111-1307 USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef GWENHYWFAR_BUFFEREDIO_H
|
|
#define GWENHYWFAR_BUFFEREDIO_H
|
|
|
|
#include <gwenhywfar/gwenhywfarapi.h>
|
|
#include <gwenhywfar/inherit.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** A flexible I/O class with buffer for input or for output.
|
|
*
|
|
* - Create one by creating one of the derived classes, e. g. by
|
|
* GWEN_BufferedIO_File_new().
|
|
* - Then assign an appropriate buffer
|
|
* to be used by GWEN_BufferedIO_SetWriteBuffer() or
|
|
* GWEN_BufferedIO_SetReadBuffer().
|
|
* - Then use it for input or output.
|
|
* - In the end close it with GWEN_BufferedIO_Close().
|
|
*/
|
|
typedef struct GWEN_BUFFEREDIOSTRUCT GWEN_BUFFEREDIO;
|
|
|
|
GWEN_INHERIT_FUNCTION_LIB_DEFS(GWEN_BUFFEREDIO, GWENHYWFAR_API)
|
|
/* No trailing semicolon because this is a macro call */
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#include <gwenhywfar/error.h>
|
|
|
|
/* for compatibility only */
|
|
#include <gwenhywfar/bio_file.h>
|
|
#include <gwenhywfar/bio_socket.h>
|
|
#include <gwenhywfar/bio_buffer.h>
|
|
#include <gwenhywfar/buffer.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define GWEN_BUFFEREDIO_ERROR_TYPE "BufferedIO"
|
|
#define GWEN_BUFFEREDIO_ERROR_READ 1
|
|
#define GWEN_BUFFEREDIO_ERROR_WRITE 2
|
|
#define GWEN_BUFFEREDIO_ERROR_CLOSE 3
|
|
#define GWEN_BUFFEREDIO_ERROR_TIMEOUT 4
|
|
#define GWEN_BUFFEREDIO_ERROR_PARTIAL 5
|
|
#define GWEN_BUFFEREDIO_ERROR_EOF 6
|
|
#define GWEN_BUFFEREDIO_ERROR_NO_DATA 7
|
|
|
|
|
|
#define GWEN_BUFFEREDIO_CHAR_ERROR (-1)
|
|
#define GWEN_BUFFEREDIO_CHAR_EOF (-2)
|
|
#define GWEN_BUFFEREDIO_CHAR_NO_DATA (-3)
|
|
|
|
|
|
/** If set then @ref GWEN_BufferedIO_Close is enabled */
|
|
#define GWEN_BUFFEREDIO_FLAGS_CLOSE 0x00000001
|
|
#define GWEN_BUFFEREDIO_FLAGS_UNTIL_EMPTY_LINE 0x00000002
|
|
|
|
#define GWEN_BUFFEREDIO_FLAGS_DEFAULT \
|
|
(\
|
|
GWEN_BUFFEREDIO_FLAGS_CLOSE\
|
|
)
|
|
|
|
|
|
|
|
typedef enum {
|
|
GWEN_LineModeUnix=0,
|
|
GWEN_LineModeDOS
|
|
} GWEN_BUFFEREDIOLINEMODE;
|
|
|
|
typedef int (*GWEN_BUFFEREDIOREADFN)(GWEN_BUFFEREDIO *dm,
|
|
char *buffer,
|
|
int *size,
|
|
int timeout);
|
|
typedef int (*GWEN_BUFFEREDIOWRITEFN)(GWEN_BUFFEREDIO *dm,
|
|
const char *buffer,
|
|
int *size,
|
|
int timeout);
|
|
typedef int (*GWEN_BUFFEREDIOCLOSEFN)(GWEN_BUFFEREDIO *dm);
|
|
|
|
|
|
|
|
/**
|
|
* This function should not be used directly. It is used by "inheriting"
|
|
* code (e.g. @ref GWEN_BufferedIO_File_new).
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API GWEN_BUFFEREDIO *GWEN_BufferedIO_new();
|
|
|
|
/**
|
|
* Frees a buffered IO context no matter of what type it is.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API void GWEN_BufferedIO_free(GWEN_BUFFEREDIO *dm);
|
|
|
|
/**
|
|
* Set the read buffer to be used. If you want to read from a
|
|
* stream this function must be called beforehand! Otherwise the
|
|
* first reading call will fail. (For writing this is not needed.)
|
|
*
|
|
* Either supply a buffer by the @c buffer argument, or leave that
|
|
* argument as @c NULL so that the BufferedIO object will assign a
|
|
* new internal buffer for itself.
|
|
*
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*
|
|
* @param bt The BufferedIO.
|
|
*
|
|
* @param buffer Pointer to the buffer to be used. If 0 then this
|
|
* function will allocate a buffer of @c len size by itself. In
|
|
* any case this function will take ownership of this buffer! This
|
|
* means you should never free this buffer, this will be done by
|
|
* this module itself.
|
|
*
|
|
* @param len Length of the buffer (in bytes)
|
|
*/
|
|
GWENHYWFAR_API void GWEN_BufferedIO_SetReadBuffer(GWEN_BUFFEREDIO *bt,
|
|
char *buffer,
|
|
int len);
|
|
|
|
/**
|
|
* Set the write buffer to be used. If you want to write to a
|
|
* stream this function must be called beforehand! Otherwise the
|
|
* first writing call will fail. (For reading this is not needed.)
|
|
*
|
|
* Either supply a buffer by the @c buffer argument, or leave that
|
|
* argument as @c NULL so that the BufferedIO object will assign a
|
|
* new internal buffer for itself.
|
|
*
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*
|
|
* @param bt The BufferedIO.
|
|
*
|
|
* @param buffer Pointer to the buffer to be used. If 0 then this
|
|
* function will allocate a buffer of @c len size by itself. In
|
|
* any case this function will take ownership of this buffer! This
|
|
* means you should never free this buffer, this will be done by
|
|
* this module itself.
|
|
*
|
|
* @param len Length of the buffer (in bytes)
|
|
*/
|
|
GWENHYWFAR_API void GWEN_BufferedIO_SetWriteBuffer(GWEN_BUFFEREDIO *bt,
|
|
char *buffer,
|
|
int len);
|
|
|
|
/**
|
|
* Checks whether the end of stream is reached.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
* @return 0 if not, !=0 otherwise
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_CheckEOF(GWEN_BUFFEREDIO *dm);
|
|
|
|
/**
|
|
* Peeks at the next character in the stream. This functions reads the
|
|
* next character without advancing the internal pointers, so the next
|
|
* peek or read will return the very same character.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
* @return -1 on error, character otherwise
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_PeekChar(GWEN_BUFFEREDIO *dm);
|
|
|
|
/**
|
|
* Reads the next character from the stream.
|
|
*
|
|
* @note For performance reasons, the given argument is @e not checked
|
|
* for sanity. During initial development, you should do this for
|
|
* yourself, e.g. by adding @c assert(bio); before you call this
|
|
* function.
|
|
*
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
* @return -1 on error, character otherwise
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_ReadChar(GWEN_BUFFEREDIO *bio);
|
|
|
|
/**
|
|
* Really writes the content of the write buffer to the stream. This is
|
|
* automatically called upon @ref GWEN_BufferedIO_Close.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_Flush(GWEN_BUFFEREDIO *bt);
|
|
|
|
/**
|
|
* Really writes the content of the write buffer to the stream.
|
|
* This function only flushes as much bytes as possible. If after
|
|
* calling this function some bytes still remain inside the write
|
|
* buffer, a warning will be returned
|
|
* (error code=GWEN_BUFFEREDIO_ERROR_PARTIAL,
|
|
* severity=GWEN_ERROR_SEVERITY_WARN). You should then call this function as
|
|
* long as it returns this warning in order to really save the data.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_ShortFlush(GWEN_BUFFEREDIO *bt);
|
|
|
|
/**
|
|
* Returns !=0 if the read buffer is empty, 0 if it is not.
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_ReadBufferEmpty(GWEN_BUFFEREDIO *bt);
|
|
|
|
|
|
/**
|
|
* Returns !=0 if the write buffer is empty, 0 if it is not.
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_WriteBufferEmpty(GWEN_BUFFEREDIO *bt);
|
|
|
|
/**
|
|
* Reads a line until a CR (in Unix mode) or a CRLF (DOS mode) is found
|
|
* or the buffer is filled, whichever comes first.
|
|
* The trailing CR or CRLF is not copied into the buffer.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_ReadLine(GWEN_BUFFEREDIO *bt,
|
|
char *buffer,
|
|
unsigned int s);
|
|
|
|
/**
|
|
* Reads a line until a CR (in Unix mode) or a CRLF (DOS mode) is found.
|
|
* The trailing CR or CRLF is not copied into the buffer.
|
|
* This function uses a GWEN_BUFFER to store the data.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_ReadLine2Buffer(GWEN_BUFFEREDIO *bt,
|
|
GWEN_BUFFER *buffer);
|
|
|
|
/**
|
|
* Writes a character into the stream.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_WriteChar(GWEN_BUFFEREDIO *dm,
|
|
char c);
|
|
|
|
/**
|
|
* Writes the content of the buffer to the stream until a null byte is
|
|
* found.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_Write(GWEN_BUFFEREDIO *bt,
|
|
const char *buffer);
|
|
|
|
/**
|
|
* Writes the content of the given buffer plus appropriate line end
|
|
* character(s) (CR in Unix mode and CR/LF in DOS mode) into the stream.
|
|
* Please note that the buffer should not contain CR or CR/LF characters.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_WriteLine(GWEN_BUFFEREDIO *bt,
|
|
const char *buffer);
|
|
|
|
/**
|
|
* Closes the stream after flushing the output buffer (if needed).
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API int GWEN_BufferedIO_Close(GWEN_BUFFEREDIO *dm);
|
|
|
|
|
|
/**
|
|
* Set the line mode to be used. Currently there are:
|
|
* <ul>
|
|
* <li>LineModeUnix (using CR as line terminator)</li>
|
|
* <li>LineModeDOS (using CR/LF as line terminator)</li>
|
|
* </ul>
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SetLineMode(GWEN_BUFFEREDIO *dm,
|
|
GWEN_BUFFEREDIOLINEMODE lm);
|
|
|
|
/**
|
|
* Returns the current flags for this bufferedIO.
|
|
* See @ref GWEN_BUFFEREDIO_FLAGS_CLOSE and others for details.
|
|
*/
|
|
GWENHYWFAR_API
|
|
uint32_t GWEN_BufferedIO_GetFlags(const GWEN_BUFFEREDIO *bt);
|
|
|
|
/**
|
|
* Sets the flags for this bufferedIO.
|
|
* See @ref GWEN_BUFFEREDIO_FLAGS_CLOSE and others for details.
|
|
*/
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SetFlags(GWEN_BUFFEREDIO *bt, uint32_t f);
|
|
|
|
/**
|
|
* Adds the given flags to the current flags for this bufferedIO.
|
|
* See @ref GWEN_BUFFEREDIO_FLAGS_CLOSE and others for details.
|
|
*/
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_AddFlags(GWEN_BUFFEREDIO *bt, uint32_t f);
|
|
|
|
/**
|
|
* Removes the given flags from the current flags for this bufferedIO.
|
|
* See @ref GWEN_BUFFEREDIO_FLAGS_CLOSE and others for details.
|
|
*/
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SubFlags(GWEN_BUFFEREDIO *bt, uint32_t f);
|
|
|
|
|
|
/**
|
|
* Return the currently used line mode.
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API
|
|
GWEN_BUFFEREDIOLINEMODE GWEN_BufferedIO_GetLineMode(const GWEN_BUFFEREDIO *dm);
|
|
|
|
|
|
/**
|
|
* Set the timeout for read- and write operations in milliseconds.
|
|
* Some values have special meanings:
|
|
* <ul>
|
|
* <li>GWEN_TIMEOUT_NONE: no timeout (not blocking)</li>
|
|
* <li>GWEN_TIMEOUT_FOREVER: wait forever (blocking)</li>
|
|
* </ul>
|
|
* @author Martin Preuss<martin@aquamaniac.de>
|
|
*/
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SetTimeout(GWEN_BUFFEREDIO *dm, int timeout);
|
|
|
|
|
|
/**
|
|
* Returns the currently used timeout value in milliseconds.
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_GetTimeout(const GWEN_BUFFEREDIO *dm);
|
|
|
|
/** Returns the number of lines that have been read or written so
|
|
far. */
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_GetLines(const GWEN_BUFFEREDIO *dm);
|
|
|
|
/** Returns the position index in the current line that is being
|
|
read or written. */
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_GetLinePos(const GWEN_BUFFEREDIO *dm);
|
|
|
|
/** Returns the number of bytes that have been read so far. */
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_GetBytesRead(const GWEN_BUFFEREDIO *dm);
|
|
|
|
/** Returns the number of bytes that have been written so far. */
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_GetBytesWritten(const GWEN_BUFFEREDIO *dm);
|
|
|
|
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SetReadFn(GWEN_BUFFEREDIO *dm,
|
|
GWEN_BUFFEREDIOREADFN fn);
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SetWriteFn(GWEN_BUFFEREDIO *dm,
|
|
GWEN_BUFFEREDIOWRITEFN fn);
|
|
GWENHYWFAR_API
|
|
void GWEN_BufferedIO_SetCloseFn(GWEN_BUFFEREDIO *dm,
|
|
GWEN_BUFFEREDIOCLOSEFN fn);
|
|
|
|
|
|
/**
|
|
* Closes the stream without flushing any buffers. Call this in case
|
|
* of a severe error. The content of the internal buffers will be lost !
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_Abandon(GWEN_BUFFEREDIO *dm);
|
|
|
|
|
|
/**
|
|
* Writes the content of the given buffer. If there still is some data
|
|
* inside the internal buffer that data will be flushed first.
|
|
* This allows for mixing calls to this function with calls to the
|
|
* character based write functions.
|
|
*
|
|
* @param bt The BufferedIO.
|
|
* @param buffer The buffer to which bytes should be written.
|
|
* @param bsize Pointer to a variable which holds the number of bytes
|
|
* to write. Upon return this variable shows the number of bytes actually
|
|
* written. Please note that if this function has to flush internal buffers
|
|
* the return value might be 0 (indicating that no error occurred, but the
|
|
* internal buffers still contain some bytes which will be flushed upon the
|
|
* next call to this function).
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_WriteRaw(GWEN_BUFFEREDIO *bt,
|
|
const char *buffer,
|
|
unsigned int *bsize);
|
|
|
|
|
|
/**
|
|
* Reads multiple bytes. If there is some data inside the internal buffers
|
|
* then that data will be returned first. This allows for mixing with
|
|
* character based read functions.
|
|
*
|
|
* @param bt The BufferedIO.
|
|
* @param buffer The buffer from which bytes should be read.
|
|
* @param bsize Pointer to a variable which holds the number of bytes
|
|
* to read. Upon return this variable shows the number of bytes actually
|
|
* read.
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_ReadRaw(GWEN_BUFFEREDIO *bt,
|
|
char *buffer,
|
|
unsigned int *bsize);
|
|
|
|
/**
|
|
* Reads exactly the amount of bytes given or returns an error.
|
|
* If less bytes are read than requested the GWN_BUFFEREDIO error
|
|
* @ref GWEN_BUFFEREDIO_ERROR_PARTIAL is returned (which corresponds
|
|
* to the GWEN_ERROR code @ref GWEN_ERROR_PARTIAL when converted via
|
|
* @ref GWEN_Error_GetSimpleCode).
|
|
* The parameter bsize will be updated in any case.
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_ReadRawForced(GWEN_BUFFEREDIO *bt,
|
|
char *buffer,
|
|
unsigned int *bsize);
|
|
|
|
/**
|
|
* Writes exactly the amount of bytes given or returns an error.
|
|
* If less bytes are written than requested the GWN_BUFFEREDIO error
|
|
* @ref GWEN_BUFFEREDIO_ERROR_PARTIAL is returned (which corresponds
|
|
* to the GWEN_ERROR code @ref GWEN_ERROR_PARTIAL when converted via
|
|
* @ref GWEN_Error_GetSimpleCode).
|
|
* The parameter bsize will be updated in any case.
|
|
*/
|
|
GWENHYWFAR_API
|
|
int GWEN_BufferedIO_WriteRawForced(GWEN_BUFFEREDIO *bt,
|
|
const char *buffer,
|
|
unsigned int *bsize);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif /* GWENHYWFAR_BUFFEREDIO_H */
|
|
|
|
|
|
|
|
|
|
|