aboutsummaryrefslogtreecommitdiff
path: root/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py
blob: 34435eb0c5844ea36c9968f8381554cfe32ad767 (plain)
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
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
import os, sys

shutilLibFound = False
structLibFound = False

try:
	import shutil 
except ImportError:
	print "[Error] Shutil python library is required to be installed!" 
else:
	shutilLibFound = True

try:
	import struct 
except ImportError:
	print "[Error] struct python library is required to be installed!" 
else:
	structLibFound = True

if 	(not shutilLibFound) 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:
	numOfTextResources = -1
	def __init__(self):
		return


class treFile:
	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]))
				#print "[Debug] 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()
	print "[Debug] Running %s as main module" % (my_module_name)
	# assumes a file of name ACTORS.TRE in same directory
	inTREFile = None
	inTREFileName =  'ACTORS.TRE'

	errorFound = False
	
	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.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 imported from another module" % (my_module_name)
	pass