[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/vm/CodeStream.h
From: |
Chad Musick |
Subject: |
[Gnash-commit] gnash ChangeLog server/vm/CodeStream.h |
Date: |
Sun, 07 Oct 2007 03:19:48 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Chad Musick <cmusick> 07/10/07 03:19:48
Modified files:
. : ChangeLog
Added files:
server/vm : CodeStream.h
Log message:
A class for reading ActionScript 3 opcodes and stream information.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4559&r2=1.4560
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/CodeStream.h?cvsroot=gnash&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4559
retrieving revision 1.4560
diff -u -b -r1.4559 -r1.4560
--- ChangeLog 6 Oct 2007 12:00:59 -0000 1.4559
+++ ChangeLog 7 Oct 2007 03:19:48 -0000 1.4560
@@ -1,3 +1,8 @@
+2007-10-07 Chad Musick <address@hidden>
+
+ * server/vm/CodeStream.h: New file. Complete definition of a stream
+ for safely reading code, with necessary reader functions for AS3.
+
2007-10-06 Benjamin Wolsey <address@hidden>
* server/as_value.cpp (to_number): use boost::lexical_cast instead
Index: server/vm/CodeStream.h
===================================================================
RCS file: server/vm/CodeStream.h
diff -N server/vm/CodeStream.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/vm/CodeStream.h 7 Oct 2007 03:19:48 -0000 1.1
@@ -0,0 +1,211 @@
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This program 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.
+//
+// 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
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_CODESTREAM_H
+#define GNASH_CODESTREAM_H
+
+#include "tu_types.h"
+#include <boost/utility.hpp>
+
+namespace gnash {
+
+/// The exception which will be thrown by the CodeStream for access
+/// violations.
+class CodeStreamException { };
+
+/// A checked read character array
+///
+/// CodeStream provides a safe interface to read various things from a
+/// character array of known size. Any attempt to access memory outside
+/// of the given array will throw an exception of type CodeStreamException
+class CodeStream : private boost::noncopyable
+{
+public:
+ /// Construct a CodeStream
+ ///
+ /// @param pStart
+ /// The beginning of the character array
+ ///
+ /// @param length
+ /// The length of the array. Memory in [pStart, pStart + length) may
+ /// be accessed. It is not an error to send a length of 0.
+ ///
+ /// @param own
+ /// If true, the given memory will be copied. Otherwise, the caller
+ /// retains ownership and should not delete the memory before this
+ /// is invalid.
+ CodeStream(const char *pStart, std::size_t length, bool own = false) :
+ mRaw(pStart), mRawEnd(pStart + length), mEnd(pStart + length),
+ mOwn(false)
+ {
+ if (own && length > 0)
+ {
+ mCurrent = mRaw = new char[length];
+ memcpy(const_cast<char*>(mRaw), pStart, length);
+ mRawEnd = mEnd = mRaw + length;
+ mOwn = true;
+ }
+ }
+
+ /// Destruct a CodeStream
+ ///
+ /// If the stream owns the memory, it will destroy it.
+ ~CodeStream()
+ { if (mOwn) delete [] mRaw; }
+
+ /// Read a variable length encoded 32 bit unsigned integer
+ uint32_t read_V32()
+ {
+ if (mCurrent == mEnd) throw CodeStreamException();
+
+ // We can do an unchecked read in these cases.
+ if (mEnd - mCurrent > 4 || !(*(mEnd - 1) & 0x80))
+ {
+ uint32_t result = *mCurrent++;
+ if (!(result & 0x00000080)) return result;
+ result = (result & 0x0000007F) | *mCurrent++ << 7;
+ if (!(result & 0x00004000)) return result;
+ result = (result & 0x00003FFF) | *mCurrent++ << 14;
+ if (!(result & 0x00200000)) return result;
+ result = (result & 0x001FFFFF) | *mCurrent++ << 21;
+ if (!(result & 0x10000000)) return result;
+ return (result & 0x0FFFFFFF) | *mCurrent++ << 28;
+ }
+ uint32_t result = *mCurrent++;
+ if (!(result & 0x00000080)) return result;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ result = (result & 0x0000007F) | *mCurrent++ << 7;
+ if (!(result & 0x00004000)) return result;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ result = (result & 0x00003FFF) | *mCurrent++ << 14;
+ if (!(result & 0x00200000)) return result;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ result = (result & 0x001FFFFF) | *mCurrent++ << 21;
+ if (!(result & 0x10000000)) return result;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ return (result & 0x0FFFFFFF) | *mCurrent++ << 28;
+ }
+
+ /// Read an opcode for ActionScript 3
+ uint8_t read_as3op()
+ {
+ if (mCurrent == mEnd)
+ return 0;
+ return static_cast<uint8_t> (*mCurrent++);
+ }
+
+ /// Provide the offset into the stream of the current position. Can be
+ /// used for seeking.
+ std::size_t tell()
+ { return mCurrent - mRaw; }
+
+ /// Change the current position by a relative value.
+ void seekBy(int change)
+ {
+ if (change > 0 && change > (mEnd - mCurrent) ||
+ change < 0 && -change > (mCurrent - mRaw))
+ throw CodeStreamException();
+ mCurrent += change;
+ }
+
+ /// Set the current position to an absolute value (relative to the
start)
+ void seekTo(unsigned int set)
+ {
+ if (set > static_cast<unsigned int> (mEnd - mRaw))
+ throw CodeStreamException();
+ mCurrent = mRaw + set;
+ }
+
+ /// Read a signed integer encoded in 24 bits.
+ int32_t read_S24()
+ {
+ if (mEnd - mCurrent < 3)
+ throw CodeStreamException();
+ int result = *mCurrent++ + (*mCurrent++ << 8) + (*mCurrent ++
<< 16);
+ if (result & (1 << 23)) // Negative result, adjust
appropriately.
+ result = -(result & ~(1 << 23));
+ return static_cast<int32_t>(result);
+ }
+
+ /// Read a signed 8-bit character.
+ int8_t read_s8()
+ {
+ if (mCurrent == mEnd)
+ throw CodeStreamException();
+ return static_cast<int8_t> (*mCurrent++);
+ }
+
+ /// Read an unsigned 8-bit character.
+ uint8_t read_u8()
+ {
+ if (mCurrent == mEnd)
+ throw CodeStreamException();
+ return static_cast<uint8_t> (*mCurrent++);
+ }
+
+ /// Set a stop at position bytes from the start. This becomes the new
+ /// effective end of the code stream, but the end may be unstopped or
+ /// set to different length. In no case can the end be set to a point
+ /// beyond the original end of the stream.
+ void set_end(unsigned int position)
+ {
+ if (position > static_cast<unsigned int>(mRawEnd - mRaw))
+ throw CodeStreamException();
+ mEnd = mRaw + position;
+ if (mCurrent > mEnd)
+ mCurrent = mEnd;
+ }
+
+ /// Unset any stop placed on the stream.
+ void unset_end()
+ { mEnd = mRawEnd; }
+
+ /// Same as read_V32(), but doesn't bother with the arithmetic for
+ /// calculating the value.
+ void skip_V32()
+ {
+ if (mCurrent == mEnd) throw CodeStreamException();
+
+ // We can do an unchecked read in these cases.
+ if (mEnd - mCurrent > 4 || !(*(mEnd - 1) & 0x80))
+ {
+ // shortcut evalution is mandated as standard.
+ if ((*mCurrent++ & 0x80) && (*mCurrent++ & 0x80) &&
(*mCurrent++ &0x80)
+ && (*mCurrent++ & 0x80) && (*mCurrent++ & 0x80))
+ return;
+ return;
+ }
+ if (!(*mCurrent++ & 0x80)) return;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ if (!(*mCurrent++ & 0x80)) return;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ if (!(*mCurrent++ & 0x80)) return;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ if (!(*mCurrent++ & 0x80)) return;
+ if (mCurrent == mEnd) throw CodeStreamException();
+ ++mCurrent;
+ }
+
+private:
+ const char *mRaw; // Nobody may write into this, and we handle all
access.
+ const char *mRawEnd; // We own the memory in [mRaw, mRawEnd)
+ const char *mEnd; // We may not read this or beyond.
+ const char *mCurrent; // Our current read pointer.
+ bool mOwn; // Do we own the memory?
+};
+
+} // namespace gnash
+#endif /* GNASH_CODESTREAM_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/vm/CodeStream.h,
Chad Musick <=