/* * Copyright (c) 2003, 2004 Michael Pyne * * This software 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. * * This software 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 library; see the file COPYING. * If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _BYTETAPE_H #define _BYTETAPE_H #include #include class ByteTapeShared : public KShared { public: unsigned int pos; }; /** * Class to simulate a seekable byte stream. Very similar to QByteArray, * but the difference is that this class "knows" what a current position * is. Also, the copy constructor will share the byte stream of the * ByteTape being copied. This means that any copies made of an object of * this class will share BOTH the data and the current position. This is * by design. * * @author Michael Pyne * @see QByteArray */ class ByteTape { public: /** * Constructs a new ByteTape object from @p array. The * current position will be set to @p pos. * * @param array a data buffer to use for reading and writing. * The tape will be fixed to the size of this buffer. * @param pos the initial position of the tape head. It must be * a position within the buffer contained in @p array. */ ByteTape (QByteArray &array, int pos = 0); /** * Creates a ByteTape as a copy of @p tape. The newly created * object will share both data and the current position with @p tape. * This is done using reference counts. * * @param tape the ByteTape to copy */ ByteTape (const ByteTape &tape); /** * Increments the current position by @p i. It is the responsibility * of the function caller to ensure that the new position is in bounds. * The position will be capped to remain in bounds regardless. * * @param i the amount to increment the current position by * @return t reference to the object incremented */ ByteTape & operator += (const unsigned int i); /** * Decrements the current position by @p i. It is the responsibility * of the function caller to ensure that the new position is in bounds. * Unlike a real Turing machine, attempting to decrement past the * start will be capped to the beginning instead of crashing the * computer. * * @param i the amount to decrement the current position by * @return a reference to the object decremented */ ByteTape & operator -= (const unsigned int i); /** * Increments the current position by 1. This is a postfix * operator (i++). The current position will be capped to the end * of the buffer. * * @return the object before the increment operation */ ByteTape operator ++ (int); /** * Increments the current position by 1. This is a prefix * operator (++i). The current position will be capped to the end * of the buffer. * * @return a reference to the object incremented */ ByteTape & operator ++ (); /** * Decrements the current position by 1. This is a postfix * operator (i--). The current position will be capped to the start * of the buffer. * * @return the object before the decrement operation */ ByteTape operator -- (int); /** * Decrements the current position by 1. This is a prefix * operator (--i). The current position will be capped to the start * of the buffer. * * @return a reference to the object decremented */ ByteTape & operator -- (); /** * Returns the byte within the array indexed by @p i. It is * the responsibility of the caller to ensure that @p i is in bounds. * Although out-of-range errors will be detected, no exceptions will * be thrown. Since a reference is not returned, you won't be able * to assign to the result. Example: tape[i] = 'a' will not work. * * The reason a reference isn't returned is because no exceptions are * thrown by this class, and we can't return a reference to an out-of- * bounds character. * * @param i the index of the byte to return * @return the byte at the given index. 0 may be returned on error, * but does not necessarily indicate an error. */ char operator [] (const unsigned int i); /** * Returns the byte at the tape's current position. You can assign * to the reference returned. * * @return a reference to the byte at the tape head's current position */ char &operator * (); /** * Returns the position in memory of data at the given index, @p i. * Unlike operator [], this function returns a pointer, so it can be * used to access memory. * * @param i index of the byte to lookup. * @return 0 if @p i is out of range, else the address of memory * at that index */ char *at(const unsigned int i); /** * Returns the current position of the tape head. * * @return the tape head's current position */ unsigned int pos() const { return m_shared->pos; } /** * Sets the current position of the tape head to @p pos. If the * position given is out-of-bounds, it will be capped to be within * the array. * * @param pos the new position of the tape head * @return whether the set operation was successful */ bool setPos(unsigned int pos); /** * Returns a reference to the QByteArray used to hold all the data. * * @return the QByteArray used to hold the data * @see QByteArray */ QByteArray &data() { return m_array; } private: QByteArray &m_array; KSharedPtr m_shared; }; #endif /* _BYTETAPE_H */ // vim: set et ts=4 sw=4: