src/data_buffer.h

changeset 73
1ee9b312dc18
child 75
bf8c57437231
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/data_buffer.h	Sat Jan 11 22:36:31 2014 +0200
@@ -0,0 +1,149 @@
+/*
+	Copyright (c) 2013-2014, Santeri Piippo
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+		* Redistributions of source code must retain the above copyright
+		  notice, this list of conditions and the following disclaimer.
+
+		* Redistributions in binary form must reproduce the above copyright
+		  notice, this list of conditions and the following disclaimer in the
+		  documentation and/or other materials provided with the distribution.
+
+		* Neither the name of the <organization> nor the
+		  names of its contributors may be used to endorse or promote products
+		  derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+	DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef BOTC_DATABUFFER_H
+#define BOTC_DATABUFFER_H
+
+#include <stdio.h>
+#include <string.h>
+#include "main.h"
+#include "stringtable.h"
+
+#define MAX_MARKS 512
+
+extern int g_NextMark;
+
+// ============================================================================
+// DataBuffer: A dynamic data buffer.
+class data_buffer
+{
+public:
+	// The actual buffer
+	byte* buffer;
+
+	// Allocated size of the buffer
+	int allocsize;
+
+	// Written size of the buffer
+	int writesize;
+
+	// Marks and references
+	ScriptMark* marks[MAX_MARKS];
+	ScriptMarkReference* refs[MAX_MARKS];
+
+	data_buffer (int size = 128);
+	~data_buffer ();
+
+	// ====================================================================
+	// Write stuff to the buffer
+	// TODO: un-template and remove the union, move to source file
+	template<class T> void write (T stuff)
+	{
+		if (writesize + sizeof (T) >= allocsize)
+		{
+			// We don't have enough space in the buffer to write
+			// the stuff - thus resize. First, store the old
+			// buffer temporarily:
+			char* copy = new char[allocsize];
+			memcpy (copy, buffer, allocsize);
+
+			// Remake the buffer with the new size. Have enough space
+			// for the stuff we're going to write, as well as a bit
+			// of leeway so we don't have to resize immediately again.
+			size_t newsize = allocsize + sizeof (T) + 128;
+
+			delete buffer;
+			buffer = new unsigned char[newsize];
+			allocsize = newsize;
+
+			// Now, copy the stuff back.
+			memcpy (buffer, copy, allocsize);
+			delete copy;
+		}
+
+		// Buffer is now guaranteed to have enough space.
+		// Write the stuff one byte at a time.
+		generic_union<T> uni;
+		uni.as_t = stuff;
+
+		for (int x = 0; x < sizeof (T); x++)
+		{
+			if (writesize >= allocsize) // should NEVER happen because resizing is done above
+				error ("DataBuffer: written size exceeds allocated size!\n");
+
+			buffer[writesize] = uni.b[x];
+			writesize++;
+		}
+	}
+
+	// ====================================================================
+	// Merge another data buffer into this one.
+	void merge (data_buffer* other);
+
+	// Clones this databuffer to a new one and returns it.
+	data_buffer* clone ();
+
+	// ====================================================================
+	// Adds a mark to the buffer. 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 will be used
+	// to "mark" a position like that for future use.
+	int add_mark (string name);
+
+	// ====================================================================
+	// A ref 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
+	int add_reference (int marknum, bool placeholder = true);
+
+	// Delete a mark and all references to it.
+	void delete_mark (int marknum);
+
+	// Adjusts a mark to the current position
+	void move_mark(int i);
+
+	void offset_mark (int mark, int offset);
+
+	// Dump the buffer (for debugging purposes)
+	void dump();
+
+	// Count the amount of marks
+	int count_marks ();
+
+	// Count the amount of refs
+	int count_references ();
+
+	// Write a float into the buffer
+	void write_float (string floatstring);
+
+	void write_string (string a);
+};
+
+#endif // BOTC_DATABUFFER_H

mercurial