WindowsCompoundBinaryFileReader.st
changeset 2134 8e07b9bbd007
equal deleted inserted replaced
2133:a739d816088e 2134:8e07b9bbd007
       
     1 "{ Package: 'stx:libbasic2' }"
       
     2 
       
     3 Object subclass:#WindowsCompoundBinaryFileReader
       
     4 	instanceVariableNames:'inStream fileType streamTypes client msb'
       
     5 	classVariableNames:'UnsupportedFormatErrorSignal'
       
     6 	poolDictionaries:''
       
     7 	category:'System-Support-FileFormats'
       
     8 !
       
     9 
       
    10 !WindowsCompoundBinaryFileReader class methodsFor:'documentation'!
       
    11 
       
    12 documentation
       
    13 "
       
    14     compoundBinary is actually (kind of) the FAT Disk format in a file.
       
    15     It is very old, but still used by visio (vsd) files.
       
    16     CompoundBinary is actually a container format.
       
    17 
       
    18     Warning:
       
    19         ongoing, unfinished work.
       
    20 "
       
    21 ! !
       
    22 
       
    23 !WindowsCompoundBinaryFileReader class methodsFor:'instance creation'!
       
    24 
       
    25 fromFile:aFilename
       
    26     |s reader|
       
    27 
       
    28     s := aFilename asFilename readStream.
       
    29     reader := self new fromStream:s.
       
    30     s close.
       
    31     ^ reader
       
    32 ! !
       
    33 
       
    34 !WindowsCompoundBinaryFileReader methodsFor:'reading from stream'!
       
    35 
       
    36 fromStream:aStream
       
    37     "read a stream from aStream."
       
    38 
       
    39     client := self.
       
    40     self processStream:aStream
       
    41 
       
    42     "
       
    43      WindowsCompoundBinaryFileReader fromFile:'C:\Users\cg\Downloads\vsdump\examples\Ian\Arrow & Text samples.vsd'      
       
    44     "
       
    45 !
       
    46 
       
    47 processStream:aStream
       
    48     "process a stream."
       
    49 
       
    50     inStream := aStream.
       
    51     self readHeaderSector.
       
    52 
       
    53     "
       
    54      WindowsCompoundBinaryFileReader fromFile:'C:\Users\cg\Downloads\vsdump\examples\Ian\Arrow & Text samples.vsd'      
       
    55     "
       
    56 !
       
    57 
       
    58 readHeaderSector
       
    59     "sector 0 is a header sector:
       
    60         _abSig = DOCF 11E0 A1B1 1AE1 
       
    61         _clid = 0000 0000 0000 0000 0000 0000 0000 0000 
       
    62         _uMinorVersion = 003B 
       
    63         _uDllVersion = 3 
       
    64         _uByteOrder = FFFE (Intel byte order) 
       
    65         _uSectorShift = 9 (512 bytes) 
       
    66         _uMiniSectorShift = 6 (64 bytes) 
       
    67         _usReserved = 0000 
       
    68         _ulReserved1 = 00000000 
       
    69         _ulReserved2 = 00000000 
       
    70         _csectFat = 00000001 
       
    71         _sectDirStart = 00000001 
       
    72         _signature = 00000000 
       
    73         _ulMiniSectorCutoff = 00001000 (4096 bytes) 
       
    74         _sectMiniFatStart = 00000002 
       
    75         _csectMiniFat = 00000001 
       
    76         _sectDifStart = FFFFFFFE (no DIF, file is < 7Mb) 
       
    77         _csectDIF = 00000000 _sectFat[] = 00000000 FFFFFFFF . . . (continues with FFFFFFFF)    
       
    78     "
       
    79 
       
    80     |sector sectorStream sig clsid uMinorVersion uDllVersion uByteOrder uSectorShift uMiniSectorShift usReserved ulReserved1 ulReserved2 csectFat sectDirStart signature ulMiniSectorCutoff sectMiniFatStart csectMiniFat sectDifStart csectDIF sectFat|
       
    81 
       
    82     sector := inStream nextBytes:512.
       
    83     sectorStream := sector readStream.
       
    84 
       
    85     sig := sectorStream nextBytes:8.
       
    86     sig = #[ 16rD0 16rCF 16r11 16rE0 16rA1 16rB1 16r1A 16rE1 ] ifFalse:[
       
    87         self error.
       
    88     ].
       
    89     clsid := sectorStream nextBytes:16.
       
    90 
       
    91     uMinorVersion := sectorStream nextUnsignedShortMSB:false. "/ = 003B 
       
    92     uDllVersion := sectorStream nextUnsignedShortMSB:false. "/ 3 
       
    93     uByteOrder := sectorStream nextUnsignedShortMSB:false. "/ = FFFE (Intel byte order)
       
    94     uByteOrder == 16rFFFE ifTrue:[
       
    95         msb := false.
       
    96     ] ifFalse:[
       
    97         uByteOrder == 16rFEFF ifTrue:[
       
    98             msb := true.
       
    99         ] ifFalse:[
       
   100             self error  
       
   101         ]
       
   102     ].
       
   103     uSectorShift := sectorStream nextUnsignedShortMSB:msb.      "/ = 9 (sector size 512 bytes) 
       
   104     uMiniSectorShift := sectorStream nextUnsignedShortMSB:msb.  "/ = 6 (mini sector size 64 bytes)
       
   105     usReserved := sectorStream nextUnsignedShortMSB:msb.
       
   106     ulReserved1 := sectorStream nextUnsignedLongMSB:msb. 
       
   107     ulReserved2 := sectorStream nextUnsignedLongMSB:msb.
       
   108     csectFat := sectorStream nextUnsignedLongMSB:msb.           "/ number of sectors in FAT chain
       
   109     sectDirStart := sectorStream nextUnsignedLongMSB:msb.       "/ first sector in directory chain
       
   110     signature := sectorStream nextUnsignedLongMSB:msb.
       
   111     ulMiniSectorCutoff := sectorStream nextUnsignedLongMSB:msb. "/ max size of ministreams (4096 bytes) 
       
   112     sectMiniFatStart := sectorStream nextUnsignedLongMSB:msb.   "/ first sect in mini-FAT = 00000002 
       
   113     csectMiniFat := sectorStream nextUnsignedLongMSB:msb.       "/ # of sects in mini-FAT chain = 00000001 
       
   114     sectDifStart := sectorStream nextUnsignedLongMSB:msb.       "/ first sect in DIF chain
       
   115     csectDIF := sectorStream nextUnsignedLongMSB:msb.           "/ # of sects in DIF chain = FFFFFFFE (no DIF, file is < 7Mb) 
       
   116     sectFat := OrderedCollection new.
       
   117     109 timesRepeat:[                                           "/ followed by first 109 FAT sectors.
       
   118         sectFat add:(sectorStream nextUnsignedLongMSB:msb).     "/ 00000000
       
   119     ].
       
   120     "/ ... FFFFFFFF
       
   121 self halt.
       
   122     "
       
   123      WindowsCompoundBinaryFileReader fromFile:'C:\Users\cg\Downloads\vsdump\examples\Ian\Arrow & Text samples.vsd'      
       
   124     "
       
   125 ! !
       
   126 
       
   127 !WindowsCompoundBinaryFileReader class methodsFor:'documentation'!
       
   128 
       
   129 version
       
   130     ^ '$Header: /cvs/stx/stx/libbasic2/WindowsCompoundBinaryFileReader.st,v 1.1 2009-04-30 21:20:57 cg Exp $'
       
   131 ! !