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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
osLibFound = False
sysLibFound = False
shutilLibFound = False
structLibFound = False
try:
import os
except ImportError:
print "[Error] os python library is required to be installed!"
else:
osLibFound = True
try:
import sys
except ImportError:
print "[Error] sys python library is required to be installed!"
else:
sysLibFound = True
try:
import struct
except ImportError:
print "[Error] struct python library is required to be installed!"
else:
structLibFound = True
if (not osLibFound) \
or (not sysLibFound) \
or (not structLibFound):
sys.stdout.write("[Error] Errors were found when trying to import required python libraries\n")
sys.exit(1)
from struct import *
MY_MODULE_VERSION = "0.50"
MY_MODULE_NAME = "treFileLib"
class TreHeader(object):
numOfTextResources = -1
def __init__(self):
return
class treFile(object):
m_header = TreHeader()
simpleTextResourceFileName = 'GENERIC.TRE'
stringEntriesLst = [] # list of two-value tuples. First value is ID, second value is String content
stringOffsets = []
m_traceModeEnabled = False
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True):
del self.stringEntriesLst[:]
del self.stringOffsets[:]
self.simpleTextResourceFileName = 'GENERIC.TRE'
self.m_traceModeEnabled = traceModeEnabled
return
def loadTreFile(self, treBytesBuff, maxLength, treFileName):
self.simpleTextResourceFileName = treFileName
offsInTreFile = 0
#
# parse TRE file fields for header
#
try:
tmpTuple = struct.unpack_from('I', treBytesBuff, offsInTreFile) # unsigned integer 4 bytes
self.header().numOfTextResources = tmpTuple[0]
offsInTreFile += 4
#
# string IDs table (each entry is unsigned integer 4 bytes)
#
if self.m_traceModeEnabled:
print "[Info] Total texts in Text Resource file: %d" % (self.header().numOfTextResources)
for idx in range(0, self.header().numOfTextResources):
tmpTuple = struct.unpack_from('I', treBytesBuff, offsInTreFile) # unsigned integer 4 bytes
self.stringEntriesLst.append( (tmpTuple[0], '') )
offsInTreFile += 4
# string offsets table (each entry is unsigned integer 4 bytes)
for idx in range(0, self.header().numOfTextResources):
tmpTuple = struct.unpack_from('I', treBytesBuff, offsInTreFile) # unsigned integer 4 bytes
self.stringOffsets.append( tmpTuple[0] )
offsInTreFile += 4
#
# strings (all entries are null terminated)
# TODO +++
absStartOfIndexTable = 4
#absStartOfOffsetTable = absStartOfIndexTable + (self.header().numOfTextResources * 4)
#absStartOfStringTable = absStartOfOffsetTable + ((self.header().numOfTextResources+1) * 4)
#print "[Debug] buffer type: " , type(treBytesBuff) # it is str
for idx in range(0, self.header().numOfTextResources):
currOffset = self.stringOffsets[idx] + absStartOfIndexTable
# the buffer (treBytesBuff) where we read the TRE file into, is "str" type but contains multiple null terminated strings
# the solution here (to not get out of index errors when reading the null terminator points) is
# to split the substring starting at the indicated offset each time, at the null character, and get the first string token.
# This works ok.
#
allTextsFound = treBytesBuff[currOffset:].split('\x00')
### check "problematic" character cases:
##if self.m_traceModeEnabled:
## if currOffset == 5982 or currOffset == 6050 or currOffset == 2827 or currOffset == 2880:
## print "[Debug] Offs: %d\tFound String: %s" % ( currOffset,''.join(allTextsFound[0]) )
(theId, stringOfIdx) = self.stringEntriesLst[idx]
self.stringEntriesLst[idx] = (theId, ''.join(allTextsFound[0]))
if self.m_traceModeEnabled:
print "[Trace] ID: %d\tFound String: %s" % ( theId,''.join(allTextsFound[0]) )
return True
except:
print "[Error] Loading Text Resource %s failed!" % (self.simpleTextResourceFileName)
return False
def header(self):
return self.m_header
#
#
#
if __name__ == '__main__':
# main()
errorFound = False
# By default assumes a file of name ACTORS.TRE in same directory
# otherwise tries to use the first command line argument as input file
inTREFile = None
inTREFileName = 'ACTORS.TRE'
if len(sys.argv[1:]) > 0 \
and os.path.isfile(os.path.join('.', sys.argv[1])) \
and len(sys.argv[1]) >= 5 \
and sys.argv[1][-3:].upper() == 'TRE':
inTREFileName = sys.argv[1]
print "[Info] Attempting to use %s as input TRE file..." % (inTREFileName)
elif os.path.isfile(os.path.join('.', inTREFileName)):
print "[Info] Using default %s as input TRE file..." % (inTREFileName)
else:
print "[Error] No valid input file argument was specified and default input file %s is missing." % (inTREFileName)
errorFound = True
if not errorFound:
try:
print "[Info] Opening %s" % (inTREFileName)
inTREFile = open(os.path.join('.',inTREFileName), 'rb')
except:
errorFound = True
print "[Error] Unexpected event: ", sys.exc_info()[0]
raise
if not errorFound:
allOfTreFileInBuffer = inTREFile.read()
treFileInstance = treFile(True)
if treFileInstance.m_traceModeEnabled:
print "[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION)
if treFileInstance.loadTreFile(allOfTreFileInBuffer, len(allOfTreFileInBuffer), inTREFileName):
print "[Info] Text Resource file loaded successfully!"
else:
print "[Error] Error while loading Text Resource file!"
inTREFile.close()
else:
#debug
#print "[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION)
pass
|