diff --git a/sortix/Makefile b/sortix/Makefile index a3901189..1b0f0182 100644 --- a/sortix/Makefile +++ b/sortix/Makefile @@ -78,6 +78,7 @@ sound.o \ pci.o \ uart.o \ terminal.o \ +linebuffer.o \ vgaterminal.o \ serialterminal.o \ descriptors.o \ diff --git a/sortix/linebuffer.cpp b/sortix/linebuffer.cpp new file mode 100644 index 00000000..583e35cb --- /dev/null +++ b/sortix/linebuffer.cpp @@ -0,0 +1,124 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + + This file is part of Sortix. + + Sortix 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 (at your option) any later + version. + + Sortix 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 Sortix. If not, see . + + linebuffer.cpp + Provides a simple queue-like line buffering for terminals. + +******************************************************************************/ + +#include "platform.h" +#include +#include "linebuffer.h" + +using namespace Maxsi; + +namespace Sortix +{ + static size_t OffsetIndex(size_t offset, size_t index, size_t length) + { + // TODO: Possible overflow here. + return (offset + index) % length; + } + + LineBuffer::LineBuffer() + { + buffer = NULL; + bufferlength = 0; + bufferoffset = 0; + buffercommitted = 0; + bufferfrozen = 0; + bufferused = 0; + } + + LineBuffer::~LineBuffer() + { + delete[] buffer; + } + + bool LineBuffer::Push(uint32_t unicode) + { + // Check if we need to allocate or resize the circular queue. + if ( bufferused == bufferlength ) + { + size_t newbufferlength = (bufferlength) ? bufferlength * 2 : 32UL; + uint32_t* newbuffer = new uint32_t[newbufferlength]; + if ( !newbuffer ) { return false; } + size_t elemsize = sizeof(*buffer); + size_t leadingavai = bufferlength-bufferoffset; + size_t leading = (leadingavai < bufferused) ? leadingavai : bufferused; + size_t trailing = bufferused - leading; + Memory::Copy(newbuffer, buffer + bufferoffset, leading * elemsize); + Memory::Copy(newbuffer + leading, buffer, trailing * elemsize); + delete[] buffer; + buffer = newbuffer; + bufferlength = newbufferlength; + bufferoffset = 0; + } + + size_t index = OffsetIndex(bufferoffset, bufferused++, bufferlength); + buffer[index] = unicode; + return true; + } + + uint32_t LineBuffer::Pop() + { + if ( !CanPop() ) { return 0; } + uint32_t result = Peek(); + bufferoffset = (bufferoffset+1) % bufferlength; + buffercommitted--; + bufferfrozen--; + bufferused--; + return result; + } + + uint32_t LineBuffer::Peek() const + { + if ( !CanPop() ) { return 0; } + size_t index = OffsetIndex(bufferoffset, 0, bufferlength); + return buffer[index]; + } + + uint32_t LineBuffer::Backspace() + { + if ( !CanBackspace() ) { return 0; } + size_t index = OffsetIndex(bufferoffset, --bufferused, bufferlength); + return buffer[index]; + } + + void LineBuffer::Commit() + { + buffercommitted = bufferfrozen = bufferused; + } + + void LineBuffer::Freeze() + { + bufferfrozen = bufferused; + } + + bool LineBuffer::CanPop() const + { + return buffercommitted; + } + + bool LineBuffer::CanBackspace() const + { + return bufferused - bufferfrozen; + } +} + diff --git a/sortix/linebuffer.h b/sortix/linebuffer.h new file mode 100644 index 00000000..8c84e3c8 --- /dev/null +++ b/sortix/linebuffer.h @@ -0,0 +1,58 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + + This file is part of Sortix. + + Sortix 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 (at your option) any later + version. + + Sortix 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 Sortix. If not, see . + + linebuffer.h + Provides a simple queue-like line buffering for terminals. + +******************************************************************************/ + +#ifndef SORTIX_LINEBUFFER_H +#define SORTIX_LINEBUFFER_H + +namespace Sortix +{ + class LineBuffer + { + public: + LineBuffer(); + ~LineBuffer(); + + public: + bool Push(uint32_t unicode); + uint32_t Pop(); + uint32_t Peek() const; + uint32_t Backspace(); + void Commit(); + void Freeze(); + bool CanPop() const; + bool CanBackspace() const; + + private: + uint32_t* buffer; + size_t bufferlength; + size_t bufferoffset; + size_t buffercommitted; + size_t bufferfrozen; + size_t bufferused; + + }; +} + +#endif +