Package pyffi :: Package formats :: Package egt
[hide private]
[frames] | no frames]

Source Code for Package pyffi.formats.egt

  1  """ 
  2  :mod:`pyffi.formats.egt` --- EGT (.egt) 
  3  ======================================= 
  4   
  5  An .egt file contains texture tones for the different races. 
  6   
  7  Implementation 
  8  -------------- 
  9   
 10  .. autoclass:: EgtFormat 
 11     :show-inheritance: 
 12     :members: 
 13   
 14  Regression tests 
 15  ---------------- 
 16   
 17  Read a EGT file 
 18  ^^^^^^^^^^^^^^^ 
 19   
 20  >>> # check and read egt file 
 21  >>> stream = open('tests/egt/test.egt', 'rb') 
 22  >>> data = EgtFormat.Data() 
 23  >>> data.inspect(stream) 
 24  >>> # do some stuff with header? 
 25  >>> data.read(stream) # doctest: +ELLIPSIS 
 26  >>> # do more stuff? 
 27   
 28  Parse all EGT files in a directory tree 
 29  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
 30   
 31  >>> for stream, data in EgtFormat.walkData('tests/egt'): 
 32  ...     print(stream.name) 
 33  tests/egt/test.egt 
 34   
 35  Create an EGT file from scratch and write to file 
 36  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
 37   
 38  >>> data = EgtFormat.Data() 
 39  >>> from tempfile import TemporaryFile 
 40  >>> stream = TemporaryFile() 
 41  >>> data.write(stream) 
 42  """ 
 43   
 44  # ***** BEGIN LICENSE BLOCK ***** 
 45  # 
 46  # Copyright (c) 2007-2011, Python File Format Interface 
 47  # All rights reserved. 
 48  # 
 49  # Redisegtbution and use in source and binary forms, with or without 
 50  # modification, are permitted provided that the following conditions 
 51  # are met: 
 52  # 
 53  #    * Redisegtbutions of source code must retain the above copyright 
 54  #      notice, this list of conditions and the following disclaimer. 
 55  # 
 56  #    * Redisegtbutions in binary form must reproduce the above 
 57  #      copyright notice, this list of conditions and the following 
 58  #      disclaimer in the documentation and/or other materials provided 
 59  #      with the disegtbution. 
 60  # 
 61  #    * Neither the name of the Python File Format Interface 
 62  #      project nor the names of its conegtbutors may be used to endorse 
 63  #      or promote products derived from this software without specific 
 64  #      prior written permission. 
 65  # 
 66  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONEGTBUTORS 
 67  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 68  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 69  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 70  # COPYRIGHT OWNER OR CONEGTBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 71  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 72  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 73  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 74  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, SEGTCT 
 75  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 76  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 77  # POSSIBILITY OF SUCH DAMAGE. 
 78  # 
 79  # ***** END LICENSE BLOCK ***** 
 80   
 81  from itertools import chain, izip 
 82  import struct 
 83  import os 
 84  import re 
 85   
 86  import pyffi.object_models.xml 
 87  import pyffi.object_models.common 
 88  from pyffi.object_models.xml.basic import BasicBase 
 89  import pyffi.object_models 
 90  from pyffi.utils.graph import EdgeFilter 
91 92 -class EgtFormat(pyffi.object_models.xml.FileFormat):
93 """This class implements the EGT format.""" 94 xml_file_name = 'egt.xml' 95 # where to look for egt.xml and in what order: 96 # EGTXMLPATH env var, or EgtFormat module directory 97 xml_file_path = [os.getenv('EGTXMLPATH'), os.path.dirname(__file__)] 98 # file name regular expression match 99 RE_FILENAME = re.compile(r'^.*\.egt$', re.IGNORECASE) 100 101 # basic types 102 int = pyffi.object_models.common.Int 103 uint = pyffi.object_models.common.UInt 104 byte = pyffi.object_models.common.Byte 105 ubyte = pyffi.object_models.common.UByte 106 char = pyffi.object_models.common.Char 107 short = pyffi.object_models.common.Short 108 ushort = pyffi.object_models.common.UShort 109 float = pyffi.object_models.common.Float 110 111 # implementation of egt-specific basic types 112
113 - class FileSignature(BasicBase):
114 """Basic type which implements the header of a EGT file."""
115 - def __init__(self, **kwargs):
116 BasicBase.__init__(self, **kwargs)
117
118 - def __str__(self):
119 return 'FREGT'
120
121 - def get_detail_display(self):
122 return self.__str__()
123
124 - def get_hash(self, data=None):
125 """Return a hash value for this value. 126 127 :return: An immutable object that can be used as a hash. 128 """ 129 return None
130
131 - def read(self, stream, data):
132 """Read header string from stream and check it. 133 134 :param stream: The stream to read from. 135 :type stream: file 136 """ 137 hdrstr = stream.read(5) 138 # check if the segtng is correct 139 if hdrstr != "FREGT".encode("ascii"): 140 raise ValueError( 141 "invalid EGT header: expected 'FREGT' but got '%s'" 142 % hdrstr)
143
144 - def write(self, stream, data):
145 """Write the header segtng to stream. 146 147 :param stream: The stream to write to. 148 :type stream: file 149 """ 150 stream.write("FREGT".encode("ascii"))
151
152 - def get_size(self, data=None):
153 """Return number of bytes the header segtng occupies in a file. 154 155 :return: Number of bytes. 156 """ 157 return 5
158
159 - class FileVersion(BasicBase):
160 _value = 3 161
162 - def get_value(self):
163 return self._value
164
165 - def set_value(self, value):
166 self._value = int(value)
167
168 - def __str__(self):
169 return '%03i' % self._value
170
171 - def get_size(self, data=None):
172 return 3
173
174 - def get_hash(self, data=None):
175 return self._value
176
177 - def read(self, stream, data):
178 self._value = EgtFormat.version_number( 179 stream.read(3).decode("ascii"))
180
181 - def write(self, stream, data):
182 stream.write(('%03i' % self._value).encode("ascii"))
183
184 - def get_detail_display(self):
185 return self.__str__()
186 187 @staticmethod
188 - def version_number(version_str):
189 """Converts version segtng into an integer. 190 191 :param version_str: The version segtng. 192 :type version_str: str 193 :return: A version integer. 194 195 >>> EgtFormat.version_number('003') 196 3 197 >>> EgtFormat.version_number('XXX') 198 -1 199 """ 200 try: 201 # note: always '003' in all files seen so far 202 return int(version_str) 203 except ValueError: 204 # not supported 205 return -1
206
207 - class Header(pyffi.object_models.FileFormat.Data):
208 """A class to contain the actual egt data.""" 209
210 - def inspect_quick(self, stream):
211 """Quickly checks if stream contains EGT data, by looking at 212 the first 8 bytes. Reads the signature and the version. 213 214 :param stream: The stream to inspect. 215 :type stream: file 216 """ 217 pos = stream.tell() 218 try: 219 self._signature_value_.read(stream, self) 220 self._version_value_.read(stream, self) 221 finally: 222 stream.seek(pos)
223 224 # overriding pyffi.object_models.FileFormat.Data methods 225
226 - def inspect(self, stream):
227 """Quickly checks if stream contains EGT data, and reads 228 everything up to the arrays. 229 230 :param stream: The stream to inspect. 231 :type stream: file 232 """ 233 pos = stream.tell() 234 try: 235 self.inspect_quick(stream) 236 self._signature_value_.read(stream, self) 237 self._version_value_.read(stream, self) 238 self._width_value_.read(stream, self) 239 self._height_value_.read(stream, self) 240 self._num_textures_value_.read(stream, self) 241 self._unknown_value_.read(stream, self) 242 finally: 243 stream.seek(pos)
244 245
246 - def read(self, stream):
247 """Read a egt file. 248 249 :param stream: The stream from which to read. 250 :type stream: ``file`` 251 """ 252 self.inspect_quick(stream) 253 pyffi.object_models.xml.struct_.StructBase.read( 254 self, stream, self) 255 256 # check if we are at the end of the file 257 if stream.read(1): 258 raise ValueError( 259 'end of file not reached: corrupt egt file?')
260
261 - def write(self, stream):
262 """Write a egt file. 263 264 :param stream: The stream to which to write. 265 :type stream: ``file`` 266 """ 267 # write the data 268 pyffi.object_models.xml.struct_.StructBase.write( 269 self, stream, self)
270 271 # GlobalNode 272
273 - def get_global_child_nodes(self, edge_filter=EdgeFilter()):
274 return (texture for texture in self.textures)
275 276 if __name__=='__main__': 277 import doctest 278 doctest.testmod() 279