--- a/src/DataBuffer.h Wed Feb 26 18:31:53 2014 +0200 +++ b/src/DataBuffer.h Mon Mar 03 01:04:16 2014 +0200 @@ -34,57 +34,124 @@ #include "Main.h" #include "StringTable.h" -// ============================================================================ -// data_buffer: A dynamic data buffer. -// -// Notes: -// -// - A mark is a "pointer" to a particular position in the bytecode. The actual -// permanent position cannot be predicted in any way or form, thus these things -// are used to "mark" a position like that for future use. -// -// - A reference is another "mark" that references a mark. When the bytecode -// is written to file, they are changed into their marks' current -// positions. Marks themselves are never written to files, only refs are -// +/** + * @class DataBuffer + * @brief Stores a buffer of bytecode + * + * The DataBuffer class stores a section of bytecode. Buffers are allocated on + * the heap and written to using the @c write* functions. Buffers can be cut and + * pasted together with @c mergeAndDestroy, note that this function destroys the + * parameter buffer in the process + * + * A mark is a "pointer" to a particular position in the bytecode. The actual + * permanent position cannot be predicted in any way or form, thus these things + * are used to "bookmark" a position like that for future use. + * + * A reference acts as a pointer to a mark. The reference is four bytes in the + * bytecode which will be replaced with its mark's position when the bytecode + * is written to the output file. + * + * This mark/reference system is used to know bytecode offset values when + * compiling, even though actual final positions cannot be known. + */ class DataBuffer { - PROPERTY (private, char*, Buffer, SetBuffer, STOCK_WRITE) - PROPERTY (private, int, AllocatedSize, SetAllocatedSize, STOCK_WRITE) - PROPERTY (private, char*, Position, SetPosition, STOCK_WRITE) - PROPERTY (private, List<ByteMark*>, Marks, SetMarks, STOCK_WRITE) - PROPERTY (private, List<MarkReference*>, References, SetReferences, STOCK_WRITE) + //! @ + PROPERTY (private, char*, buffer, setBuffer, STOCK_WRITE) + PROPERTY (private, int, allocatedSize, setAllocatedSize, STOCK_WRITE) + PROPERTY (private, char*, position, setPosition, STOCK_WRITE) + PROPERTY (private, List<ByteMark*>, marks, setMarks, STOCK_WRITE) + PROPERTY (private, List<MarkReference*>, references, setReferences, STOCK_WRITE) public: + //! Constructs a new databuffer with @c size bytes. DataBuffer (int size = 128); + + //! Destructs the databuffer. ~DataBuffer(); - // ==================================================================== - // Merge another data buffer into this one. - // Note: @other is destroyed in the process! - void MergeAndDestroy (DataBuffer* other); + //! Adds a new mark to the current position with the name @c name. + //! @param name the name of the new mark + //! @return a pointer to the new mark + ByteMark* addMark (const String& name); + + //! Adds a new reference to @c mark at the current position. This + //! function will write 4 bytes to the buffer whose value will + //! be determined at final output writing. + //! @param mark the mark which the new reference will attach to + //! @return a pointer to the new reference + MarkReference* addReference (ByteMark* mark); + + //! Moves @c mark to the current bytecode position. + //! @param mark the mark to adjust + void adjustMark (ByteMark* mark); + + //! Ensures there's at least @c bytes left in the buffer. Will resize + //! if necessary, no-op if not. On resize, 512 extra bytes are allocated + //! to reduce the amount of resizes. + //! @param bytes the amount of space in bytes to ensure allocated + void checkSpace (int bytes); + + //! Creates a clone of this data buffer. + //! @note All marks will be moved into the new databuffer as marks are + //! @note never duplicated. + //! @return The newly cloned databuffer. + DataBuffer* clone(); + + //! Prints the buffer to stdout. Useful for debugging. + void dump(); + + //! Finds the given mark by name. + //! @param name the name of the mark to find + ByteMark* findMarkByName (const String& name); + + //! Merge another data buffer into this one. + //! Note: @c other is destroyed in the process. + //! @param other the buffer to merge in + void mergeAndDestroy (DataBuffer* other); - ByteMark* AddMark (String name); - MarkReference* AddReference (ByteMark* mark); - void CheckSpace (int bytes); - DataBuffer* Clone(); - void DeleteMark (int marknum); - void AdjustMark (ByteMark* mark); - void OffsetMark (ByteMark* mark, int offset); - ByteMark* FindMarkByName (const String& target); - void Dump(); - void TransferMarks (DataBuffer* other); - void WriteStringIndex (const String& a); - void WriteString (const String& a); - void WriteByte (int8_t data); - void WriteWord (int16_t data); - void WriteDWord (int32_t data); - void CopyBuffer (const DataBuffer* buf); + //! Moves @c mark to the given bytecode position. + //! @param mark the mark to adjust + //! @param position where to adjust the mark + void offsetMark (ByteMark* mark, int position); + + //! Transfers all marks of this buffer to @c other. + //! @param other the data buffer to transfer marks to + void transferMarksTo (DataBuffer* other); + + //! Writes the index of the given string to the databuffer. + //! 4 bytes will be written to the bytecode. + //! @param a the string whose index to write + void writeStringIndex (const String& a); + + //! Writes the given string as-is into the databuffer. + //! @c a.length + 4 bytes will be written to the buffer. + //! @param a the string to write + void writeString (const String& a); - inline int WrittenSize() const + //! Writes the given byte to the buffer. 1 byte will be written. + //! @c data the byte to write + void writeByte (int8_t data); + + //! Writes the given word to the buffer. 2 byte will be written. + //! @c data the word to write + void writeWord (int16_t data); + + //! Writes the given double word to the buffer. 4 bytes will be written. + //! @c data the double word to write + void writeDWord (int32_t data); + + //! @return the amount of bytes written to this buffer. + inline int writtenSize() const { - return Position() - Buffer(); + return position() - buffer(); } + + protected: + //! Writes the buffer's contents from @c buf. + //! @c buf.writtenSize() bytes will be written. + //! @param buf the buffer to copy + void copyBuffer (const DataBuffer* buf); }; #endif // BOTC_DATABUFFER_H