-# -*- coding: ISO-8859-1 -*-\r
-\r
-# standard library imports\r
-from types import StringType\r
-from struct import unpack\r
-\r
-# custom import\r
-from DataTypeConverters import readBew, readVar, varLen\r
-\r
-\r
-class RawInstreamFile:\r
- \r
- """\r
- \r
- It parses and reads data from an input file. It takes care of big \r
- endianess, and keeps track of the cursor position. The midi parser \r
- only reads from this object. Never directly from the file.\r
- \r
- """\r
- \r
- def __init__(self, infile=''):\r
- """ \r
- If 'file' is a string we assume it is a path and read from \r
- that file.\r
- If it is a file descriptor we read from the file, but we don't \r
- close it.\r
- Midi files are usually pretty small, so it should be safe to \r
- copy them into memory.\r
- """\r
- if infile:\r
- if isinstance(infile, StringType):\r
- infile = open(infile, 'rb')\r
- self.data = infile.read()\r
- infile.close()\r
- else:\r
- # don't close the f\r
- self.data = infile.read()\r
- else:\r
- self.data = ''\r
- # start at beginning ;-)\r
- self.cursor = 0\r
-\r
-\r
- # setting up data manually\r
- \r
- def setData(self, data=''):\r
- "Sets the data from a string."\r
- self.data = data\r
- \r
- # cursor operations\r
-\r
- def setCursor(self, position=0):\r
- "Sets the absolute position if the cursor"\r
- self.cursor = position\r
-\r
-\r
- def getCursor(self):\r
- "Returns the value of the cursor"\r
- return self.cursor\r
- \r
- \r
- def moveCursor(self, relative_position=0):\r
- "Moves the cursor to a new relative position"\r
- self.cursor += relative_position\r
-\r
- # native data reading functions\r
- \r
- def nextSlice(self, length, move_cursor=1):\r
- "Reads the next text slice from the raw data, with length"\r
- c = self.cursor\r
- slc = self.data[c:c+length]\r
- if move_cursor:\r
- self.moveCursor(length)\r
- return slc\r
- \r
- \r
- def readBew(self, n_bytes=1, move_cursor=1):\r
- """\r
- Reads n bytes of date from the current cursor position.\r
- Moves cursor if move_cursor is true\r
- """\r
- return readBew(self.nextSlice(n_bytes, move_cursor))\r
-\r
-\r
- def readVarLen(self):\r
- """\r
- Reads a variable length value from the current cursor position.\r
- Moves cursor if move_cursor is true\r
- """\r
- MAX_VARLEN = 4 # Max value varlen can be\r
- var = readVar(self.nextSlice(MAX_VARLEN, 0))\r
- # only move cursor the actual bytes in varlen\r
- self.moveCursor(varLen(var))\r
- return var\r
-\r
-\r
-\r
-if __name__ == '__main__':\r
-\r
- test_file = 'test/midifiles/minimal.mid'\r
- fis = RawInstreamFile(test_file)\r
- print fis.nextSlice(len(fis.data))\r
-\r
- test_file = 'test/midifiles/cubase-minimal.mid'\r
- cubase_minimal = open(test_file, 'rb')\r
- fis2 = RawInstreamFile(cubase_minimal)\r
- print fis2.nextSlice(len(fis2.data))\r
- cubase_minimal.close()\r