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