0c2eba60a818142637f326ea8e885618c325deb0
[minwii.git] / src / mxmMidi / RawInstreamFile.py
1 # -*- coding: ISO-8859-1 -*-
2
3 # standard library imports
4 from types import StringType
5 from struct import unpack
6
7 # custom import
8 from DataTypeConverters import readBew, readVar, varLen
9
10
11 class RawInstreamFile:
12
13 """
14
15 It parses and reads data from an input file. It takes care of big
16 endianess, and keeps track of the cursor position. The midi parser
17 only reads from this object. Never directly from the file.
18
19 """
20
21 def __init__(self, infile=''):
22 """
23 If 'file' is a string we assume it is a path and read from
24 that file.
25 If it is a file descriptor we read from the file, but we don't
26 close it.
27 Midi files are usually pretty small, so it should be safe to
28 copy them into memory.
29 """
30 if infile:
31 if isinstance(infile, StringType):
32 infile = open(infile, 'rb')
33 self.data = infile.read()
34 infile.close()
35 else:
36 # don't close the f
37 self.data = infile.read()
38 else:
39 self.data = ''
40 # start at beginning ;-)
41 self.cursor = 0
42
43
44 # setting up data manually
45
46 def setData(self, data=''):
47 "Sets the data from a string."
48 self.data = data
49
50 # cursor operations
51
52 def setCursor(self, position=0):
53 "Sets the absolute position if the cursor"
54 self.cursor = position
55
56
57 def getCursor(self):
58 "Returns the value of the cursor"
59 return self.cursor
60
61
62 def moveCursor(self, relative_position=0):
63 "Moves the cursor to a new relative position"
64 self.cursor += relative_position
65
66 # native data reading functions
67
68 def nextSlice(self, length, move_cursor=1):
69 "Reads the next text slice from the raw data, with length"
70 c = self.cursor
71 slc = self.data[c:c+length]
72 if move_cursor:
73 self.moveCursor(length)
74 return slc
75
76
77 def readBew(self, n_bytes=1, move_cursor=1):
78 """
79 Reads n bytes of date from the current cursor position.
80 Moves cursor if move_cursor is true
81 """
82 return readBew(self.nextSlice(n_bytes, move_cursor))
83
84
85 def readVarLen(self):
86 """
87 Reads a variable length value from the current cursor position.
88 Moves cursor if move_cursor is true
89 """
90 MAX_VARLEN = 4 # Max value varlen can be
91 var = readVar(self.nextSlice(MAX_VARLEN, 0))
92 # only move cursor the actual bytes in varlen
93 self.moveCursor(varLen(var))
94 return var
95
96
97
98 if __name__ == '__main__':
99
100 test_file = 'test/midifiles/minimal.mid'
101 fis = RawInstreamFile(test_file)
102 print fis.nextSlice(len(fis.data))
103
104 test_file = 'test/midifiles/cubase-minimal.mid'
105 cubase_minimal = open(test_file, 'rb')
106 fis2 = RawInstreamFile(cubase_minimal)
107 print fis2.nextSlice(len(fis2.data))
108 cubase_minimal.close()