35
35
import datetime as dt
36
36
from pprint import pformat
37
37
38
- from compoundfiles .errors import CompoundFileError ,CompoundFileWarning
38
+ from compoundfiles .errors import (
39
+ CompoundFileDirEntryWarning ,
40
+ CompoundFileDirNameWarning ,
41
+ CompoundFileDirTypeWarning ,
42
+ CompoundFileDirIndexWarning ,
43
+ CompoundFileDirTimeWarning ,
44
+ CompoundFileDirSectorWarning ,
45
+ CompoundFileDirSizeWarning ,
46
+ )
39
47
from compoundfiles .const import (
40
48
NO_STREAM ,
41
49
DIR_INVALID ,
@@ -120,53 +128,88 @@ def __init__(self, parent, stream, index):
120
128
try :
121
129
self .name = self .name [:self .name .index ('\0 ' )]
122
130
except ValueError :
123
- self ._check (False ,'missing NULL terminator in name' )
131
+ warnings .warn (
132
+ CompoundFileDirNameWarning (
133
+ 'missing NULL terminator in name' ))
124
134
self .name = self .name [:name_len ]
125
135
if index == 0 :
126
- self ._check (self ._entry_type == DIR_ROOT ,'invalid type' )
136
+ if self ._entry_type != DIR_ROOT :
137
+ warnings .warn (
138
+ CompoundFileDirTypeWarning ('invalid type' ))
127
139
self ._entry_type = DIR_ROOT
128
140
elif not self ._entry_type in (DIR_STREAM ,DIR_STORAGE ,DIR_INVALID ):
129
- self ._check (False ,'invalid type' )
130
- self ._entry_type = DIR_INVALID
141
+ warnings .warn (
142
+ CompoundFileDirTypeWarning ('invalid type' ))
143
+ self ._entry_type = DIR_INVALID
131
144
if self ._entry_type == DIR_INVALID :
132
- self ._check (self .name == '' ,'non-empty name' )
133
- self ._check (name_len == 0 ,'invalid name length (%d)' % name_len )
134
- self ._check (user_flags == 0 ,'non-zero user flags' )
145
+ if self .name != '' :
146
+ warnings .warn (
147
+ CompoundFileDirNameWarning ('non-empty name' ))
148
+ if name_len != 0 :
149
+ warnings .warn (
150
+ CompoundFileDirNameWarning ('non-zero name length' ))
151
+ if user_flags != 0 :
152
+ warnings .warn (
153
+ CompoundFileDirEntryWarning ('non-zero user flags' ))
135
154
else :
136
155
# Name length is in bytes, including NULL terminator ... for a
137
156
# unicode encoded name ... *headdesk*
138
- self ._check (
139
- ( len ( self . name ) + 1 ) * 2 == name_len ,
140
- 'invalid name length (%d)' % name_len )
157
+ if ( len ( self .name ) + 1 ) * 2 != name_len :
158
+ warnings . warn (
159
+ CompoundFileDirNameWarning ( 'invalid name length (%d)' % name_len ) )
141
160
if self ._entry_type in (DIR_INVALID ,DIR_ROOT ):
142
- self ._check (self ._left_index == NO_STREAM ,'invalid left sibling' )
143
- self ._check (self ._right_index == NO_STREAM ,'invalid right sibling' )
161
+ if self ._left_index != NO_STREAM :
162
+ warnings .warn (
163
+ CompoundFileDirIndexWarning ('invalid left sibling' ))
164
+ if self ._right_index != NO_STREAM :
165
+ warnings .warn (
166
+ CompoundFileDirIndexWarning ('invalid right sibling' ))
144
167
self ._left_index = NO_STREAM
145
168
self ._right_index = NO_STREAM
146
169
if self ._entry_type in (DIR_INVALID ,DIR_STREAM ):
147
- self ._check (self ._child_index == NO_STREAM ,'invalid child index' )
148
- self ._check (self .uuid == b'\0 ' * 16 ,'non-zero UUID' )
149
- self ._check (created == 0 ,'non-zero creation timestamp' )
150
- self ._check (modified == 0 ,'non-zero modification timestamp' )
170
+ if self ._child_index != NO_STREAM :
171
+ warnings .warn (
172
+ CompoundFileDirIndexWarning ('invalid child index' ))
173
+ if self .uuid != b'\0 ' * 16 :
174
+ warnings .warn (
175
+ CompoundFileDirEntryWarning ('non-zero UUID' ))
176
+ if created != 0 :
177
+ warnings .warn (
178
+ CompoundFileDirTimeWarning ('non-zero creation timestamp' ))
179
+ if modified != 0 :
180
+ warnings .warn (
181
+ CompoundFileDirTimeWarning ('non-zero modification timestamp' ))
151
182
self ._child_index = NO_STREAM
152
183
self .uuid = b'\0 ' * 16
153
184
created = 0
154
185
modified = 0
155
186
if self ._entry_type in (DIR_INVALID ,DIR_STORAGE ):
156
- self ._check (self ._start_sector == 0 ,
157
- 'non-zero start sector (%d)' % self ._start_sector )
158
- self ._check (size_low == 0 ,
159
- 'non-zero size low-bits (%d)' % size_low )
160
- self ._check (size_high == 0 ,
161
- 'non-zero size high-bits (%d)' % size_high )
187
+ if self ._start_sector != 0 :
188
+ warnings .warn (
189
+ CompoundFileDirSectorWarning (
190
+ 'non-zero start sector (%d)' % self ._start_sector ))
191
+ if size_low != 0 :
192
+ warnings .warn (
193
+ CompoundFileDirSizeWarning (
194
+ 'non-zero size low-bits (%d)' % size_low ))
195
+ if size_high != 0 :
196
+ warnings .warn (
197
+ CompoundFileDirSizeWarning (
198
+ 'non-zero size high-bits (%d)' % size_high ))
162
199
self ._start_sector = 0
163
200
size_low = 0
164
201
size_high = 0
165
202
if parent ._normal_sector_size == 512 :
166
203
# Surely this should be checking DLL version instead of sector
167
204
# size?! But the spec does state sector size ...
168
- self ._check (size_high == 0 ,'invalid size in small sector file' )
169
- self ._check (size_low < 1 << 31 ,'size too large for small sector file' )
205
+ if size_high != 0 :
206
+ warnings .warn (
207
+ CompoundFileDirSizeWarning (
208
+ 'invalid size in small sector file' ))
209
+ if size_low >= 1 << 31 :
210
+ warnings .warn (
211
+ CompoundFileDirSizeWarning (
212
+ 'size too large for small sector file' ))
170
213
size_high = 0
171
214
self .size = (size_high << 32 )| size_low
172
215
epoch = dt .datetime (1601 ,1 ,1 )
@@ -185,12 +228,6 @@ def isfile(self):
185
228
def isdir (self ):
186
229
return self ._entry_type in (DIR_STORAGE ,DIR_ROOT )
187
230
188
- def _check (self ,valid ,message ):
189
- if not valid :
190
- warnings .warn (
191
- CompoundFileWarning (
192
- '%s in dir entry %d' % (message ,self ._index )))
193
-
194
231
def _build_tree (self ,entries ):
195
232
196
233
# XXX Need cycle detection in here - add a visited flag?
@@ -199,13 +236,15 @@ def walk(node):
199
236
try :
200
237
walk (entries [node ._left_index ])
201
238
except IndexError :
202
- node ._check (False ,'invalid left index' )
239
+ warnings .warn (
240
+ CompoundFileDirIndexWarning ('invalid left index' ))
203
241
self ._children .append (node )
204
242
if node ._right_index != NO_STREAM :
205
243
try :
206
244
walk (entries [node ._right_index ])
207
245
except IndexError :
208
- node ._check (False ,'invalid right index' )
246
+ warnings .warn (
247
+ CompoundFileDirIndexWarning ('invalid right index' ))
209
248
node ._build_tree (entries )
210
249
211
250
if self .isdir :
@@ -214,7 +253,8 @@ def walk(node):
214
253
walk (entries [self ._child_index ])
215
254
except IndexError :
216
255
if self ._child_index != NO_STREAM :
217
- self ._check (False ,'invalid child index' )
256
+ warnings .warn (
257
+ CompoundFileDirIndexWarning ('invalid child index' ))
218
258
219
259
def __len__ (self ):
220
260
return len (self ._children )