diff -r 8a82bd4d7b19 -r ab800b3e45ab scripts/python/sis2rom/sis/sisreader.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/python/sis2rom/sis/sisreader.py Wed Jan 27 10:52:27 2010 +0000 @@ -0,0 +1,150 @@ +""" +Copyright (c) 2006, Jari Sukanen +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. + * Names of the contributors may not 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 THE COPYRIGHT OWNER OR CONTRIBUTORS +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. +""" + + +import struct +import sisfields + +class SISReader : + def __init__(self) : + pass + + def readUnsignedBytes(self, numBytes) : + buf = self.readPlainBytes(numBytes) + if len(buf) < numBytes : + return [] + + format = "" + for i in range(numBytes) : + format += "B" + return struct.unpack(format, buf) + + def readSignedBytes(self, numBytes) : + buf = self.readPlainBytes(numBytes) + if len(buf) < numBytes : + return [] + + format = "" + for i in range(numBytes) : + format += "b" + return struct.unpack(format, buf) + + def readBytesAsUint(self, numBytes) : + result = 0 + bytes = self.readUnsignedBytes(numBytes) + if len(bytes) == numBytes : + for i in range(numBytes) : + result |= bytes[i] << (i*8) + + return result + + def readBytesAsInt(self, numBytes) : + result = 0 + bytes = self.readSignedBytes(numBytes) + if len(bytes) == numBytes : + for i in range(numBytes) : + result |= bytes[i] << (i*8) + + return result + + def skipPadding(self) : + result = 0 + if self.bytesRead % 4 != 0 : + paddingLength = 4 - self.bytesRead % 4 + self.readPlainBytes(paddingLength) + result = paddingLength + + return result + + +class SISFileReader(SISReader) : + def __init__(self, inStream) : + self.inStream = inStream + self.eof = False + self.bytesRead = 0 + + def readPlainBytes(self, numBytes) : + if self.eof : + return "" + + if numBytes == 0 : + return "" + + buf = "" + buf = self.inStream.read(numBytes) + if len(buf) < numBytes : + self.eof = True + return "" + + self.bytesRead += numBytes + + return buf + + def isEof(self) : + return self.eof + +class SISBufferReader(SISReader) : + def __init__(self, buffer) : + self.buffer = buffer + self.bytesRead = 0 + + def readPlainBytes(self, numBytes) : + if self.isEof() : + return "" + + if numBytes == 0 : + return "" + + result = self.buffer[self.bytesRead:self.bytesRead+numBytes] + + self.bytesRead += numBytes + + return result + + def isEof(self) : + return self.bytesRead >= len(self.buffer) + +class SISFieldParser : + def __init__(self) : + self.lastReadBytes = 0 + + def parseField(self, fileReader) : + """Reads the next field from the fileReader stream and returns it""" + field = None + self.lastReadBytes = 0 + type = fileReader.readBytesAsUint(4) + self.lastReadBytes += 4 + if type != 0 : + field = sisfields.SISFieldTypes[type]() + field.type = type + field.initFromFile(fileReader) + self.lastReadBytes += field.length + 4 # Field length + length field + self.lastReadBytes += fileReader.skipPadding() + return field