//----------------------------------------------------------------------------// // GNU GPL OS/K // // // // Desc: Buffer library // // // // // // Copyright © 2018-2019 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K 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 3 of the License, or // // any later version. // // // // OS/K 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 OS/K. If not, see . // //----------------------------------------------------------------------------// #ifndef _KALEXTRAS_LOCKS_H #include #endif #ifndef _KALEXTRAS_BUF_H #define _KALEXTRAS_BUF_H // // Buffer flags // enum { BF_TERM = 1, // Terminal buffer BF_LINE = 1<<1, // Line-buffered BF_FILE = 1<<2, // Linked to a file BF_BALLOC = 1<<3, // Buffer structure was malloc'd BF_SALLOC = 1<<4, // Internal buffer was malloc'd BF_FONCLOSE = 1<<5, // Flush on close BF_AUTOSCROLL = 1<<6, // Scroll-down automatically BF_EOF = 1<<7, // End of file reached BF_ERR = 1<<8, // An error happened }; // // Buffer states // enum { BS_CLOSED = 0, // Buffer closed (need allocation) // Buffer ready for... BS_RDWR, // Both reading and writing BS_RDONLY, // Only for reading BS_WRONLY, // Only for writing }; typedef struct Buffer_t Buffer_t; // // For line/terminal buffers, the flusher by bputc() is called every '\n' // For pure buffers, the flusher is called by bputc() after it fills // the buffer (unless flush-on-close is enabled) // // When a buffer is full, if the flusher doesn'tchange buf->wp and bputc() // is called again, it will produce a EENDF error and set the BF_EOF flag // // Unless line buffering with auto-scrolldown enabled, nothing is // removed from the buffer by the libbuf functions themselves, if you want // the buffer to be emptied on flush then do that in the flusher // typedef error_t (*BFlusher_t)(Buffer_t *); struct Buffer_t { uint initDone; Lock_t lock; int flags; // Buffer flags int state; // Buffer state size_t size; // Current size uchar *buf; // Beginning of buffer uchar *rp; // Read pointer uchar *wp; // Write pointer BFlusher_t flusher; // See above // The following parameters are only used in terminal buf mode int lastLF; // Characters since beginning of line int lineLen; // Line length (for line buffers) int nLines; // Number of lines in "true" buffer // size/(lineLen*nLines) - 1 playback buffers }; extern Buffer_t *BStdIn, *BStdOut, *BStdDbg; // For pure buffers only void BEnableLineBuffering(Buffer_t *); void BDisaleLineBuffering(Buffer_t *); // For terminal buffers only error_t BScrollDownBuf(Buffer_t *); void BEnableAutoScroll(Buffer_t *); void BDisableAutoScroll(Buffer_t *); // // Buffer creation functions // // 'source' is the internal buffer, if you want // to give it yourself // // If *pbuf==NULL, malloc's the structure // If source==NULL, malloc's the buffer // BCloseBuf() handles the de-allocations // error_t BCloseBuf(Buffer_t *); // Creates a pure buffer of a given size error_t BOpenPureBuf(Buffer_t **pbuf, int mode, size_t size); error_t BOpenPureBufEx(Buffer_t **, char *source, int mode, size_t, BFlusher_t); // Creates a terminal buffer of pbCount*nLines lines each // of lineLen length (pb = playback buffer, for scrolling up) error_t BOpenTermBuf(Buffer_t **pbuf, int mode, int lineLen, int nLines, int pbCount); error_t BOpenTermBufEx(Buffer_t **pbuf, char *source, int mode, int lineLen, int nLines, int pbCount, BFlusher_t); int BGetFlags(Buffer_t *); int BGetState(Buffer_t *); error_t BFlushBuf(Buffer_t *); error_t BPutOnBuf(Buffer_t *, uchar); error_t BPrintOnBuf(Buffer_t *, const char *fmt, ...); error_t BPrintOnBufV(Buffer_t *, const char *fmt, va_list); void BLockBuf(Buffer_t *); void BUnlockBuf(Buffer_t *); bool BTrylockBuf(Buffer_t *); // Internal, non-locking functions; don't use unless you // have a good reason why error_t bputc(Buffer_t *buf, uchar ch); error_t bprintf(Buffer_t *buf, const char *fmt, ...); error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap); error_t bscrolldown(Buffer_t *buf); #endif