2008-11-07 08:45:18 +00:00
|
|
|
/*
|
|
|
|
Monster - an advanced game scripting language
|
2009-02-08 18:41:03 +00:00
|
|
|
Copyright (C) 2007-2009 Nicolay Korslund
|
2008-11-07 08:45:18 +00:00
|
|
|
Email: <korslund@gmail.com>
|
|
|
|
WWW: http://monster.snaptoad.com/
|
|
|
|
|
|
|
|
This file (codestream.d) is part of the Monster script language
|
|
|
|
package.
|
|
|
|
|
|
|
|
Monster is distributed as free software: you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License
|
|
|
|
version 3, as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This program 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
|
|
|
|
version 3 along with this program. If not, see
|
|
|
|
http://www.gnu.org/licenses/ .
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
module monster.vm.codestream;
|
|
|
|
|
2008-11-07 13:14:46 +00:00
|
|
|
import std.string;
|
|
|
|
import std.stdio;
|
2008-11-07 08:45:18 +00:00
|
|
|
import monster.vm.error;
|
|
|
|
|
|
|
|
// CodeStream is a simple utility structure for reading data
|
|
|
|
// sequentially. It holds a piece of byte compiled code, and keeps
|
|
|
|
// track of the position within the code.
|
|
|
|
struct CodeStream
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
ubyte[] data;
|
|
|
|
int len;
|
|
|
|
ubyte *pos;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2009-01-16 12:56:54 +00:00
|
|
|
void setData(ubyte[] data)
|
2008-11-07 08:45:18 +00:00
|
|
|
{
|
|
|
|
this.data = data;
|
|
|
|
len = data.length;
|
|
|
|
pos = data.ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Called when the end of the stream was unexpectedly encountered
|
|
|
|
void eos(char[] func)
|
|
|
|
{
|
2009-01-16 12:56:54 +00:00
|
|
|
char[] res = format("Premature end of input: %s() missing %s byte(s)",
|
2008-11-07 08:45:18 +00:00
|
|
|
func, -len);
|
|
|
|
fail(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Jump to given position
|
|
|
|
void jump(int newPos)
|
|
|
|
{
|
|
|
|
if(newPos<0 || newPos>=data.length)
|
|
|
|
fail("Jump out of range");
|
|
|
|
len = data.length - newPos;
|
|
|
|
pos = &data[newPos];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the current position
|
|
|
|
int getPos()
|
|
|
|
{
|
|
|
|
return pos-data.ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
ubyte get()
|
|
|
|
{
|
|
|
|
if(len--) return *(pos++);
|
|
|
|
eos("get");
|
|
|
|
}
|
|
|
|
|
|
|
|
int getInt()
|
|
|
|
{
|
|
|
|
len -= 4;
|
|
|
|
if(len < 0) eos("getInt");
|
|
|
|
int i = *(cast(int*)pos);
|
|
|
|
pos+=4;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get a slice of the 'size' next ints
|
|
|
|
int[] getIntArray(uint size)
|
|
|
|
{
|
|
|
|
size *=4; // Convert size to bytes
|
|
|
|
len -= size;
|
|
|
|
if(len < 0) eos("getArray");
|
|
|
|
int[] res = cast(int[])pos[0..size];
|
|
|
|
pos += size;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|