CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/08/28 08:45:11
Modified files: . : ChangeLog server : Makefile.am testsuite/server: Makefile.am Added files: server : BitsReader.cpp BitsReader.h testsuite/server: BitsReaderTest.cpp Log message: * server/: Makefile.am, BitsReader.{cpp,h}: new memory bits reader. * testsuite/server/: Makefile.am, BitsReaderTest.cpp: unit testing for the new bits reader. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4130&r2=1.4131 http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.123&r2=1.124 http://cvs.savannah.gnu.org/viewcvs/gnash/server/BitsReader.cpp?cvsroot=gnash&rev=1.1 http://cvs.savannah.gnu.org/viewcvs/gnash/server/BitsReader.h?cvsroot=gnash&rev=1.1 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/server/Makefile.am?cvsroot=gnash&r1=1.32&r2=1.33 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/server/BitsReaderTest.cpp?cvsroot=gnash&rev=1.1 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4130 retrieving revision 1.4131 diff -u -b -r1.4130 -r1.4131 --- ChangeLog 28 Aug 2007 07:21:25 -0000 1.4130 +++ ChangeLog 28 Aug 2007 08:45:10 -0000 1.4131 @@ -1,3 +1,9 @@ +2007-08-28 Sandro Santilli <[EMAIL PROTECTED]> + + * server/: Makefile.am, BitsReader.{cpp,h}: new memory bits reader. + * testsuite/server/: Makefile.am, BitsReaderTest.cpp: unit testing + for the new bits reader. + 2007-08-28 Deanna Phillips <deanna> * libbase/utility.h: define exp2 and log2 if not available Index: server/Makefile.am =================================================================== RCS file: /sources/gnash/gnash/server/Makefile.am,v retrieving revision 1.123 retrieving revision 1.124 diff -u -b -r1.123 -r1.124 --- server/Makefile.am 26 Aug 2007 15:14:10 -0000 1.123 +++ server/Makefile.am 28 Aug 2007 08:45:11 -0000 1.124 @@ -18,7 +18,7 @@ # # -# $Id: Makefile.am,v 1.123 2007/08/26 15:14:10 cmusick Exp $ +# $Id: Makefile.am,v 1.124 2007/08/28 08:45:11 strk Exp $ AUTOMAKE_OPTIONS = @@ -54,6 +54,7 @@ libgnashserver_la_SOURCES = \ BitmapMovieInstance.cpp \ + BitsReader.cpp \ GetterSetter.cpp \ PropertyList.cpp \ URLAccessManager.cpp \ @@ -110,6 +111,7 @@ $(NULL) noinst_HEADERS = \ + BitsReader.h \ GetterSetter.h \ Property.h \ PropertyList.h \ Index: testsuite/server/Makefile.am =================================================================== RCS file: /sources/gnash/gnash/testsuite/server/Makefile.am,v retrieving revision 1.32 retrieving revision 1.33 diff -u -b -r1.32 -r1.33 --- testsuite/server/Makefile.am 27 Aug 2007 08:11:43 -0000 1.32 +++ testsuite/server/Makefile.am 28 Aug 2007 08:45:11 -0000 1.33 @@ -35,6 +35,7 @@ check_PROGRAMS = \ StreamTest \ + BitsReaderTest \ MatrixTest \ PointTest \ EdgeTest \ @@ -62,6 +63,11 @@ GNASH_LIBS += $(FFMPEG_LIBS) endif +BitsReaderTest_SOURCES = BitsReaderTest.cpp +BitsReaderTest_LDADD = \ + $(GNASH_LIBS) \ + $(NULL) + StreamTest_SOURCES = StreamTest.cpp StreamTest_LDADD = \ $(GNASH_LIBS) \ Index: server/BitsReader.cpp =================================================================== RCS file: server/BitsReader.cpp diff -N server/BitsReader.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ server/BitsReader.cpp 28 Aug 2007 08:45:10 -0000 1.1 @@ -0,0 +1,104 @@ +// BitsReader.cpp: bits reader, for Gnash. +// +// Copyright (C) 2005, 2006, 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 +// + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "BitsReader.h" + +#include "log.h" + +namespace gnash { + +bool BitsReader::read_bit() +{ + bool ret = (*ptr&(128>>usedBits)); + if ( ++usedBits == 8 ) advanceToNextByte(); + return ret; +} + +unsigned BitsReader::read_uint(unsigned short bitcount) +{ + assert(bitcount <= 32); + + uint32_t value = 0; + + unsigned short bits_needed = bitcount; + do + { + int unusedMask = 0xFF >> usedBits; + int unusedBits = 8-usedBits; + + if (bits_needed == unusedBits) + { + // Consume all the unused bits. + value |= (*ptr&unusedMask); + advanceToNextByte(); + break; + + } + else if (bits_needed > unusedBits) + { + // Consume all the unused bits. + + bits_needed -= unusedBits; // assert(bits_needed>0) + + value |= ((*ptr&unusedMask) << bits_needed); + advanceToNextByte(); + } + else + { + assert(bits_needed <= unusedBits); + + // Consume some of the unused bits. + + unusedBits -= bits_needed; + + value |= ((*ptr&unusedMask) >> unusedBits); + + usedBits += bits_needed; + if ( usedBits >= 8 ) advanceToNextByte(); + + // We're done. + break; + } + } + while (bits_needed > 0); + + //std::cerr << "Returning value: " << value << " unused bits: " << (int)m_unused_bits << std::endl; + return value; + +} + + +int32_t BitsReader::read_sint(unsigned short bitcount) +{ + int32_t value = int32_t(read_uint(bitcount)); + + // Sign extend... + if (value & (1 << (bitcount - 1))) + value |= -1 << bitcount; + + return value; +} + + +} // end namespace gnash + Index: server/BitsReader.h =================================================================== RCS file: server/BitsReader.h diff -N server/BitsReader.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ server/BitsReader.h 28 Aug 2007 08:45:11 -0000 1.1 @@ -0,0 +1,180 @@ +// BitsReader.h: bits reader, for Gnash. +// +// Copyright (C) 2005, 2006, 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 BITSREADER_H +#define BITSREADER_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "container.h" +#include "swf.h" +#include "tu_config.h" +#include "GnashException.h" +#include "log.h" + +#include <string> +#include <sstream> + +namespace gnash { + +/// BitsReader is used to encapsulate bit-packed buffer reads. +// +/// TODO: implement boundary checking, maybe by throwing an exception +/// when attempts are made to read past end of buffer +/// +class DSOEXPORT BitsReader +{ +public: + typedef unsigned char byte; + + /// Ownership of buffer left to caller + BitsReader(byte* input, size_t len) + : + start(input), + ptr(input), + end(ptr+len), + usedBits(0) + { + } + + ~BitsReader() {} + + /// Set a new buffer to work with + void setBuffer(byte* input, size_t len) + { + start = ptr = input; + end = start+len; + usedBits = 0; + } + + /// \brief + /// Reads a bit-packed unsigned integer from the stream + /// and returns it. The given bitcount determines the + /// number of bits to read. + unsigned read_uint(unsigned short bitcount); + + /// \brief + /// Reads a single bit off the stream + /// and returns it. + bool read_bit(); + + /// \brief + /// Reads a bit-packed little-endian signed integer + /// from the stream. The given bitcount determines the + /// number of bits to read. + int32_t read_sint(unsigned short bitcount); + + /// Read a byte as an unsigned int (aligned) + uint8_t read_u8() + { + align(); + return *ptr++; + } + + /// Read one bytes as a signed int (aligned) + int8_t read_s8() + { + return static_cast<int8_t>(read_u8()); + } + + /// Read two bytes as an unsigned int (aligned) + uint16_t read_u16() + { + align(); + assert(ptr+2 < end); + uint16_t result = *ptr++; + result |= *ptr++ << 8; + return result ; + } + + /// Read two bytes as a signed int (aligned) + int16_t read_s16() + { + return static_cast<int16_t>(read_u16()); + } + + /// Read four bytes as an unsigned int (aligned) + uint32_t read_u32() + { + align(); + assert(ptr+4 < end); + uint32_t result = *ptr++; + result |= *ptr++ << 8; + result |= *ptr++ << 16; + result |= *ptr++ << 24; + return(result); + } + + /// Read four bytes as an signed int (aligned) + int32_t read_s32() + { + return static_cast<int32_t>(read_u32()); + } + + /// \brief + /// Discard any unused bit in the current byte + /// and advance to next + void align() + { + if ( usedBits ) advanceToNextByte(); + } + +private: + + void advanceToNextByte() + { + if ( ++ptr == end ) + { + log_debug("Going round"); + ptr=start; + } + usedBits=0; + } + + /// Pointer to first byte + byte* start; + + /// Pointer to current byte + byte* ptr; + + /// Pointer to one past last byte + byte* end; + + /// Number of used bits in current byte + unsigned usedBits; + +}; + + +} // end namespace gnash + + +#endif // BITSREADER_H + + +// Local Variables: +// mode: C++ +// c-basic-offset: 8 +// tab-width: 8 +// indent-tabs-mode: t +// End: Index: testsuite/server/BitsReaderTest.cpp =================================================================== RCS file: testsuite/server/BitsReaderTest.cpp diff -N testsuite/server/BitsReaderTest.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/server/BitsReaderTest.cpp 28 Aug 2007 08:45:11 -0000 1.1 @@ -0,0 +1,286 @@ +// +// Copyright (C) 2005, 2006, 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 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#undef HAVE_DEJAGNU_H + +#ifdef HAVE_DEJAGNU_H +#include "dejagnu.h" +#else +#include "check.h" +#endif + +#include "BitsReader.h" + +#include <cstdio> +#include <iostream> +#include <cassert> + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <sstream> +#include <boost/scoped_array.hpp> + +using namespace std; +using namespace gnash; + +#define CHUNK_SIZE 4 + +TestState runtest; + +struct ByteReader +{ + unsigned char b; + + ByteReader(unsigned char by) + : + b(by) + {} + + void setByte(unsigned char by) + { + b=by; + } + + size_t read(void *dst, size_t bytes) + { + unsigned char* ptr = static_cast<unsigned char*>(dst); + for (size_t i=0; i<bytes; ++i) + { + memcpy(ptr+i, &b, sizeof(unsigned char)); + } + return bytes; + } + +}; + +int +main(int /*argc*/, char** /*argv*/) +{ + ByteReader in(0xAA); + + boost::scoped_array<unsigned char> buf(new unsigned char[1024]); + + in.read(buf.get(), 1024); + + BitsReader s(buf.get(), 1024); + + int ret; + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(1); check_equals(ret, 1); + ret = s.read_uint(1); check_equals(ret, 0); + ret = s.read_uint(1); check_equals(ret, 1); + ret = s.read_uint(1); check_equals(ret, 0); + ret = s.read_uint(1); check_equals(ret, 1); + ret = s.read_uint(1); check_equals(ret, 0); + ret = s.read_uint(1); check_equals(ret, 1); + ret = s.read_uint(1); check_equals(ret, 0); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(2); check_equals(ret, 2); + ret = s.read_uint(2); check_equals(ret, 2); + ret = s.read_uint(2); check_equals(ret, 2); + ret = s.read_uint(2); check_equals(ret, 2); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(3); check_equals(ret, 5); + ret = s.read_uint(3); check_equals(ret, 2); + ret = s.read_uint(2); check_equals(ret, 2); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(3); check_equals(ret, 5); + ret = s.read_uint(2); check_equals(ret, 1); + ret = s.read_uint(3); check_equals(ret, 2); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(2); check_equals(ret, 2); + ret = s.read_uint(3); check_equals(ret, 5); + ret = s.read_uint(3); check_equals(ret, 2); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(4); check_equals(ret, 10); + ret = s.read_uint(4); check_equals(ret, 10); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(5); check_equals(ret, 21); + ret = s.read_uint(3); check_equals(ret, 2); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(3); check_equals(ret, 5); + ret = s.read_uint(5); check_equals(ret, 10); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(6); check_equals(ret, 42); + ret = s.read_uint(2); check_equals(ret, 2); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(2); check_equals(ret, 2); + ret = s.read_uint(6); check_equals(ret, 42); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(7); check_equals(ret, 85); + ret = s.read_uint(1); check_equals(ret, 0); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(1); check_equals(ret, 1); + ret = s.read_uint(7); check_equals(ret, 42); + + /// bits: 10101010 (0xAA) + + s.align(); + ret = s.read_uint(8); check_equals(ret, 170); + + /// bits: 10101 01010 10101 0 (0xAAAA) + + s.align(); + ret = s.read_uint(5); check_equals(ret, 21); + ret = s.read_uint(5); check_equals(ret, 10); + ret = s.read_uint(5); check_equals(ret, 21); + + /// bits: 101010 101 0101010 (0xAAAA) + + s.align(); + ret = s.read_uint(6); check_equals(ret, 42); + ret = s.read_uint(3); check_equals(ret, 5); + ret = s.read_uint(7); check_equals(ret, 42); + + /// bits: 1010101010101010 (0xAAAA) + + s.align(); + ret = s.read_uint(16); check_equals(ret, 43690); + + /// bits: 101010 10101010101010 1010 (0xAAAAAA) + + s.align(); + ret = s.read_uint(6); check_equals(ret, 42); + ret = s.read_uint(14); check_equals(ret, 10922); + ret = s.read_uint(4); check_equals(ret, 10); + + /// bits: 101010101010101010101010 (0xAAAAAA) + + s.align(); + ret = s.read_uint(24); check_equals(ret, 11184810); + + /// bits: 1010101010101010 (0xAAAA) + + s.align(); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + + /// bits: 10011001 (0x99) + + in.setByte(0x99); + in.read(buf.get(), 1024); + + s.align(); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 1); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 0); + ret = s.read_bit(); check_equals(ret, 1); + + /// bits: 10011001 10011001 (0x999999) + + int16_t s16 = s.read_s16(); check_equals(s16, (int16_t)0x9999); + uint16_t u16 = s.read_u16(); check_equals(u16, (uint16_t)0x9999); + int32_t s32 = s.read_s32(); check_equals(s32, (int32_t)0x99999999); + uint32_t u32 = s.read_u32(); check_equals(u32, (uint32_t)0x99999999); + + /// bits: 10011001 10011001 10011001 10011001 (0x99999999) + /// - + /// ------- -------- -- + /// -------- + + s.align(); + ret = s.read_bit(); check_equals(ret, 1); + u16 = s.read_uint(17); check_equals(u16, 26214); + u16 = s.read_uint(7); check_equals(u16, 51); + + /// bits: 10011001 10011001 10011001 10011001 (0x99999999) + /// - + /// ------- -------- + /// ---------- + + s.align(); + ret = s.read_bit(); check_equals(ret, 1); + u16 = s.read_uint(15); check_equals(u16, 6553); + u16 = s.read_uint(9); check_equals(u16, 307); + + /// bits: 10011001 10011001 10011001 10011001 (0x99999999) + /// - + /// ------- -------- --- + /// ----- ----- + /// --- + + s.align(); + ret = s.read_bit(); check_equals(ret, 1); + u32 = s.read_uint(18); check_equals(u32, 52428); + u16 = s.read_uint(10); check_equals(u16, 819); + u16 = s.read_uint(3); check_equals(u16, 1); + + return 0; +} + _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit