VM Maker: ImageFormat-dtl.48.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: ImageFormat-dtl.48.mcz

commits-2
 
David T. Lewis uploaded a new version of ImageFormat to project VM Maker:
http://source.squeak.org/VMMaker/ImageFormat-dtl.48.mcz

==================== Summary ====================

Name: ImageFormat-dtl.48
Author: dtl
Time: 9 January 2021, 3:57:11.202896 pm
UUID: 68bd5259-64ad-4c49-b8e9-cb296c94beea
Ancestors: ImageFormat-dtl.47

Update ImageFileHeader to support Cog/Spur image headers for 32-bit and 64-bit images. Update test tests to match current header formats. Tests are changed because previous implementations were written prior to availability of 64-bit Cog and Spur, this brings tests and implementation up to date.

=============== Diff against ImageFormat-dtl.47 ===============

Item was changed:
  ImageFileHeader subclass: #CogImageFileHeader
+ instanceVariableNames: 'desiredNumStackPages unknownShortOrCodeSizeInKs desiredEdenBytes maxExtSemTabSizeSet the2ndUnknownShort firstSegmentBytes bytesLeftInOldSpace'
- instanceVariableNames: 'desiredNumStackPages unknownShortOrCodeSizeInKs desiredEdenBytes maxExtSemTabSizeSet'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'ImageFormat-Header'!
 
  !CogImageFileHeader commentStamp: 'dtl 10/31/2012 20:23' prior: 0!
  CogImageFileHeader is an extension of ImageFileHeader with additional fields that are used by Cog and Stack VMs. Some of the additional fields are encoded as short short integers, which are 16 bits when the header word size is 32, and 32 bits when the header word size is 64. All current Cog VMs use 32 bit word size with 16 bit short integer fields.!

Item was changed:
  ----- Method: CogImageFileHeader>>fromEntryStream: (in category 'reading') -----
  fromEntryStream: streamOfHeaderStateObjects
 
  super fromEntryStream: streamOfHeaderStateObjects.
  desiredNumStackPages := streamOfHeaderStateObjects next.
  unknownShortOrCodeSizeInKs := streamOfHeaderStateObjects next.
  desiredEdenBytes := streamOfHeaderStateObjects next.
  maxExtSemTabSizeSet := streamOfHeaderStateObjects next.
+ the2ndUnknownShort := streamOfHeaderStateObjects next.
+ firstSegmentBytes := streamOfHeaderStateObjects next.
+ bytesLeftInOldSpace := streamOfHeaderStateObjects next.
  !

Item was added:
+ ----- Method: CogImageFileHeader>>packedLongSize (in category 'writing') -----
+ packedLongSize
+ "Standard interpreter VM writes integers to the file header as 64 bits for
+ a 64 bit image or 32 bits for a 32 bit image. Cog/Spur VMs use 32 bits
+ where possible, otherwise 64 bits for long values on a 64 bit system."
+
+ ^ 4!

Item was changed:
  ----- Method: CogImageFileHeader>>readFieldsFrom:startingAt:headerWordSize:littleEndian:into: (in category 'reading') -----
  readFieldsFrom: aStream startingAt: imageOffset headerWordSize: headerWordSize littleEndian: littleEndian into: aCollection
  "Read data fields and answer number of bytes read"
 
  | remainder bytesRead |
  bytesRead := super readFieldsFrom: aStream startingAt: imageOffset headerWordSize: headerWordSize littleEndian: littleEndian into: aCollection.
+ aCollection add: (self nextNumber: 2 from: aStream littleEndian: littleEndian). "desiredNumStackPages"
+ aCollection add: (self nextNumber: 2 from: aStream littleEndian: littleEndian). "unknownShortOrCodeSizeInKs"
+ aCollection add: (self nextNumber: 4 from: aStream littleEndian: littleEndian). "desiredEdenBytes"
+ aCollection add: (self nextNumber: 2 from: aStream littleEndian: littleEndian). "maxExtSemTabSizeSet"
+ aCollection add: (self nextNumber: 2 from: aStream littleEndian: littleEndian). "the2ndUnknownShort"
+ aCollection add: (self nextNumber: 4 from: aStream littleEndian: littleEndian). "firstSegmentBytes"
+ aCollection add: (self nextNumber: 4 from: aStream littleEndian: littleEndian). "bytesLeftInOldSpace"
+ self nextNumber: 2 from: aStream littleEndian: littleEndian.
- aCollection add: (self nextNumber: headerWordSize / 2 from: aStream littleEndian: littleEndian). "desiredNumStackPages"
- aCollection add: (self nextNumber: headerWordSize / 2 from: aStream littleEndian: littleEndian). "unknownShortOrCodeSizeInKs"
- aCollection add: (self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "desiredEdenBytes"
- aCollection add: (self nextNumber: headerWordSize / 2 from: aStream littleEndian: littleEndian). "maxExtSemTabSizeSet"
- self nextNumber: headerWordSize / 2 from: aStream littleEndian: littleEndian.
  remainder := headerSize - (12 * imageFormat wordSize).
  self assert: remainder >= 0. "n.b. Mantis 7455 bug in original 64 bit image due to VMM error"
  ^3 * imageFormat wordSize + bytesRead.
  !

Item was added:
+ ----- Method: CogImageFileHeader>>writeFieldsTo:littleEndian: (in category 'writing') -----
+ writeFieldsTo: aStream littleEndian: littleEnder
+ "Write data fields and answer number of bytes written"
+
+ | bytesWritten |
+ bytesWritten := super writeFieldsTo: aStream littleEndian: littleEnder.
+ self nextNumber: 2 put: desiredNumStackPages to: aStream littleEndian: littleEnder.
+ self nextNumber: 2 put: unknownShortOrCodeSizeInKs to: aStream littleEndian: littleEnder.
+ self nextNumber: 4 put: desiredEdenBytes to: aStream littleEndian: littleEnder.
+ self nextNumber: 2 put: maxExtSemTabSizeSet to: aStream littleEndian: littleEnder.
+ self nextNumber: 2 put: (the2ndUnknownShort ifNil: [0]) to: aStream littleEndian: littleEnder.
+ self nextNumber: 4 put: (firstSegmentBytes ifNil: [0]) to: aStream littleEndian: littleEnder.
+ self nextNumber: 4 put: (bytesLeftInOldSpace ifNil: [0]) to: aStream littleEndian: littleEnder.
+ ^20 + bytesWritten.
+ !

Item was removed:
- ----- Method: CogImageFileHeader>>writeFieldsTo:littleEndian:headerWordSize: (in category 'writing') -----
- writeFieldsTo: aStream littleEndian: littleEnder headerWordSize: headerWordSize
- "Write data fields and answer number of bytes written"
-
- | bytesWritten |
- bytesWritten := super writeFieldsTo: aStream littleEndian: littleEnder headerWordSize: headerWordSize.
- self nextNumber: headerWordSize / 2 put: desiredNumStackPages to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize / 2 put: unknownShortOrCodeSizeInKs to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: desiredEdenBytes to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize / 2 put: maxExtSemTabSizeSet to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize / 2 put: 0 to: aStream littleEndian: littleEnder.
- ^3 * imageFormat wordSize + bytesWritten.
- !

Item was changed:
  ----- Method: ImageFileHeader>>nextNumber:put:to:littleEndian: (in category 'writing') -----
  nextNumber: n put: v to: aStream littleEndian: littleEnder
 
  littleEnder
+ ifTrue: [aStream nextLittleEndianNumber: n put: v]
+ ifFalse: [aStream nextNumber: n put: v].
+ ^ n.!
- ifTrue: [^aStream nextLittleEndianNumber: n put: v]
- ifFalse: [^aStream nextNumber: n put: v]!

Item was added:
+ ----- Method: ImageFileHeader>>packedLongSize (in category 'writing') -----
+ packedLongSize
+ "Standard interpreter VM writes integers to the file header as 64 bits for
+ a 64 bit image or 32 bits for a 32 bit image. Cog/Spur VMs use 32 bits
+ where possible, otherwise 64 bits for long values on a 64 bit system."
+
+ ^ imageFormat wordSize!

Item was changed:
  ----- Method: ImageFileHeader>>readFieldsFrom:startingAt:headerWordSize:littleEndian:into: (in category 'reading') -----
  readFieldsFrom: aStream startingAt: imageOffset headerWordSize: headerWordSize littleEndian: littleEndian into: aCollection
  "Read data fields and answer number of bytes read"
 
  | remainder screenSizeWord |
  headerSize := self nextNumber: headerWordSize from: aStream littleEndian: littleEndian.
  aCollection add: headerSize.
+ aCollection add: ( self nextNumber: imageFormat wordSize from: aStream littleEndian: littleEndian). "imageBytes"
+ aCollection add: (self nextNumber: imageFormat wordSize from: aStream littleEndian: littleEndian). "startOfMemory"
+ aCollection add: (self nextNumber: imageFormat wordSize from: aStream littleEndian: littleEndian). "specialObjectsOop"
+ aCollection add: (self nextNumber: imageFormat wordSize from: aStream littleEndian: littleEndian). "lastHash"
+ screenSizeWord := self nextNumber: imageFormat wordSize from: aStream littleEndian: littleEndian.
- aCollection add: ( self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "imageBytes"
- aCollection add: (self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "startOfMemory"
- aCollection add: (self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "specialObjectsOop"
- aCollection add: (self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "lastHash"
- screenSizeWord := self nextNumber: headerWordSize from: aStream littleEndian: littleEndian.
  aCollection add: ((screenSizeWord >> 16) @ (screenSizeWord bitAnd: 16rFFFF)).
+ aCollection add: (self nextNumber: imageFormat wordSize from: aStream littleEndian: littleEndian). "imageHeaderFlags"
- aCollection add: (self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "imageHeaderFlags"
  aCollection add: (self nextNumber: headerWordSize from: aStream littleEndian: littleEndian). "extraVMMemory"
  remainder := headerSize - (9 * imageFormat wordSize).
  self assert: remainder >= 0. "n.b. Mantis 7455 bug in original 64 bit image due to VMM error"
  ^9 * imageFormat wordSize.
  !

Item was changed:
  ----- Method: ImageFileHeader>>readImageVersionFrom:startingAt: (in category 'reading') -----
  readImageVersionFrom: aStream startingAt: imageOffset
  "Look for image format in the next 4 or 8 bytes and set imageFormat. Answer true
  if the header is written in little endian format."
 
  (aStream nextNumber: 4) caseOf:
  {
  [ 16r00001966 "6502" ] -> [ imageFormat := ImageFormat fromInteger: 6502. ^false ] .
  [ 16r66190000 "6502" ] -> [ imageFormat := ImageFormat fromInteger: 6502. ^true ] .
  [ 16r00001968 "6504" ] -> [ imageFormat := ImageFormat fromInteger: 6504. ^false ] .
  [ 16r68190000 "6504" ] -> [ imageFormat := ImageFormat fromInteger: 6504. ^true ] .
  [ 16r00001969 "6505" ] -> [ imageFormat := ImageFormat fromInteger: 6505. ^false ] .
  [ 16r69190000 "6505" ] -> [ imageFormat := ImageFormat fromInteger: 6505. ^true ] .
  [ 16r00001979 "6521" ] -> [ imageFormat := ImageFormat fromInteger: 6521. ^false ] .
  [ 16r79190000 "6521" ] -> [ imageFormat := ImageFormat fromInteger: 6521. ^true ] .
+ [ 16rA0090100 "68000" ] -> [ imageFormat := ImageFormat fromInteger: 68000. aStream next: 4. ^true ] . "format number in 64 bit integer"
- [ 16rA0090100 "68000" ] -> [ imageFormat := ImageFormat fromInteger: 68000. aStream next: 4. ^true ] .
  [ 16rA2090100 "68002" ] -> [ imageFormat := ImageFormat fromInteger: 68002. aStream next: 4. ^true ] .
  [ 16rA3090100 "68003" ] -> [ imageFormat := ImageFormat fromInteger: 68003. aStream next: 4. ^true ] .
+ [ 16rB3090100 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. ^true ] . "Cog/Spur always puts format number in first 32 bits"
+ [ 16r000109B3 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. ^false ] .
+ [ 16rB5090100 "68021" ] -> [ imageFormat := ImageFormat fromInteger: 68021. ^true ] .
+ [ 16r000109B5 "68021" ] -> [ imageFormat := ImageFormat fromInteger: 68021. ^false ] .
- [ 16rB3090100 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. aStream next: 4. ^true ] .
- [ 16r000109B3 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. aStream next: 4. ^false ] .
- [ 16rB5090100 "68021" ] -> [ imageFormat := ImageFormat fromInteger: 68021. aStream next: 4. ^true ] .
- [ 16r000109B5 "68021" ] -> [ imageFormat := ImageFormat fromInteger: 68021. aStream next: 4. ^false ] .
  [ 16r00000000 ] -> [
  "Standard interpreter VM puts the format number in the first 64 bits for a 64 bit image, so
  the leading 4 bytes are zero in this case. Cog/Spur VMs put the format number in the first
  32 bits for both 32 and 64 bit images."
  (aStream nextNumber: 4) caseOf: {
  [ 16r000109A0 "68000" ] -> [ imageFormat := ImageFormat fromInteger: 68000. ^false ] .
  [ 16r000109A2 "68002" ] -> [ imageFormat := ImageFormat fromInteger: 68002. ^false ] .
+ [ 16r000109A3 "68003" ] -> [ imageFormat := ImageFormat fromInteger: 68003. ^false ]
- [ 16r000109A3 "68003" ] -> [ imageFormat := ImageFormat fromInteger: 68003. ^false ] .
- [ 16r000109B3 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. ^false ]
  } otherwise: [self error: self asString , ' unrecognized format number']
  ]
  } otherwise: [self error: self asString , ' unrecognized format number']
 
  "ImageFormat versionNumberByteArrays do: [:e |
  Transcript cr; show: e printString , ': ', (ImageFormat fromBytes: e) description]
 
  #[0 0 25 102]: a 32-bit image with no closure support and no native platform float word order requirement (6502)
  #[102 25 0 0]: a 32-bit image with no closure support and no native platform float word order requirement (6502)
  #[0 0 25 104]: a 32-bit image with closure support and no native platform float word order requirement (6504)
  #[104 25 0 0]: a 32-bit image with closure support and no native platform float word order requirement (6504)
  #[0 0 0 0 0 1 9 160]: a 64-bit image with no closure support and no native platform float word order requirement (68000)
  #[160 9 1 0 0 0 0 0]: a 64-bit image with no closure support and no native platform float word order requirement (68000)
  #[0 0 0 0 0 1 9 162]: a 64-bit image with closure support and no native platform float word order requirement (68002)
  #[162 9 1 0 0 0 0 0]: a 64-bit image with closure support and no native platform float word order requirement (68002)
  #[0 0 25 105]: a 32-bit image with closure support and float words stored in native platform order (6505)
  #[105 25 0 0]: a 32-bit image with closure support and float words stored in native platform order (6505)
  #[0 0 0 0 0 1 9 163]: a 64-bit image with closure support and float words stored in native platform order (68003)
  #[163 9 1 0 0 0 0 0]: a 64-bit image with closure support and float words stored in native platform order (68003)
  #[0 0 25 121]: a 32-bit image with closure support and float words stored in native platform order using Spur object format (6521)
  #[121 25 0 0]: a 32-bit image with closure support and float words stored in native platform order using Spur object format (6521)
  #[0 0 0 0 0 1 9 179]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (obsolete) (68019)
  #[179 9 1 0 0 0 0 0]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (obsolete) (68019)
  #[0 0 0 0 0 1 9 181]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (68021)
  #[181 9 1 0 0 0 0 0]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (68021)
  "
  !

Item was added:
+ ----- Method: ImageFileHeader>>writeFieldsTo:littleEndian: (in category 'writing') -----
+ writeFieldsTo: aStream littleEndian: littleEnder
+ "Write data fields and answer number of bytes written"
+
+ | bytesWritten |
+ bytesWritten :=
+ self nextNumber: self packedLongSize put: imageFormat asInteger to: aStream littleEndian: littleEnder.
+ bytesWritten := bytesWritten +
+ (self nextNumber: self packedLongSize put: headerSize to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: imageFormat wordSize put: imageBytes to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: imageFormat wordSize put: startOfMemory to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: imageFormat wordSize put: specialObjectsOop to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: imageFormat wordSize put: lastHash to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: imageFormat wordSize put: ((screenSize x) << 16 + (screenSize y)) to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: imageFormat wordSize put: imageHeaderFlags to: aStream littleEndian: littleEnder).
+ bytesWritten := bytesWritten +
+ (self nextNumber: self packedLongSize put: extraVMMemory asInteger to: aStream littleEndian: littleEnder).
+ ^bytesWritten.
+ !

Item was removed:
- ----- Method: ImageFileHeader>>writeFieldsTo:littleEndian:headerWordSize: (in category 'writing') -----
- writeFieldsTo: aStream littleEndian: littleEnder headerWordSize: headerWordSize
- "Write data fields and answer number of bytes written"
-
- self nextNumber: headerWordSize put: imageFormat asInteger to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: headerSize to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: imageBytes to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: startOfMemory to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: specialObjectsOop to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: lastHash to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: ((screenSize x) << 16 + (screenSize y)) to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: imageHeaderFlags to: aStream littleEndian: littleEnder.
- self nextNumber: headerWordSize put: extraVMMemory to: aStream littleEndian: littleEnder.
- ^9 * imageFormat wordSize.
- !

Item was changed:
  ----- Method: ImageFileHeader>>writeTo:littleEndian: (in category 'writing') -----
  writeTo: aStream littleEndian: littleEnder
 
+ | remainder bytesWritten |
+ bytesWritten := self writeFieldsTo: aStream littleEndian: littleEnder.
- | headerWordSize remainder bytesWritten |
- headerWordSize := imageFormat wordSize.
- bytesWritten := self writeFieldsTo: aStream littleEndian: littleEnder headerWordSize: headerWordSize.
  remainder := headerSize - bytesWritten.
  self assert: remainder >= 0. "n.b. Mantis 7455 bug in original 64 bit image due to VMM error"
  remainder timesRepeat: [aStream nextPut: 0].
  !

Item was added:
+ ----- Method: ImageFileHeaderTest>>testCurrentImageHeaderFile (in category 'testing') -----
+ testCurrentImageHeaderFile
+ "Verify that the current image file can be read into an ImageHeader and written
+ back with matching bytes. Results may vary depending on the current image,
+ This is a check that the ImageFormat code is up to date with whatever image
+ is currently being run."
+
+ | headerClass fs bytes header result |
+ headerClass := Smalltalk isRunningCog
+ ifFalse: [ ImageFileHeader ]
+ ifTrue: [ CogImageFileHeader ].
+   fs := (FileStream readOnlyFileNamed: Smalltalk imageName) binary.
+   ([ bytes := fs next: 1000 ] ensure: [ fs close ]).
+ header := headerClass readFrom: bytes readStream.
+ result := ByteArray streamContents: [ :strm | header writeTo: strm littleEndian: Smalltalk isLittleEndian].
+ self assert: header headerSize equals: result size.
+ self assert: result equals: (bytes first: result size).
+
+
+ !

Item was changed:
  ----- Method: ImageFileHeaderTest>>testReadWrite64BitCogBigEndian (in category 'testing') -----
  testReadWrite64BitCogBigEndian
  "Read and write with data in all byte positions"
 
  | hdr ws b1 b2 |
  b1 := ByteArray new: 128.
+ #[0 1 9 181 0 0 0 128] withIndexDo: [ :e :i | b1 at: i put: e].
+ 9 to: 128 do: [ :i | b1 at: i put: i ].
- #[0 0 0 0 0 1 9 162 0 0 0 0 0 0 0 128] withIndexDo: [ :e :i | b1 at: i put: e].
- 17 to: 128 do: [ :i | b1 at: i put: i ].
  hdr := CogImageFileHeader readFrom: (ReadStream on: b1).
  ws := WriteStream on: ByteArray new.
  hdr writeTo: ws littleEndian: false.
  b2 := ws contents.
+ self assert: (b2 first: 80) = (b1 first: 80).
+ self assert: (b2 last: (128 - 80)) asSet size = 1. "all zeros"!
- self assert: (b2 first: 92) = (b1 first: 92).
- self assert: (b2 last: (128 - 92)) asSet size = 1. "all zeros"!

Item was changed:
  ----- Method: ImageFileHeaderTest>>testReadWrite64BitCogLittleEndian (in category 'testing') -----
  testReadWrite64BitCogLittleEndian
  "Read and write with data in all byte positions"
 
  | hdr ws b1 b2 |
  b1 := ByteArray new: 128.
+ #[181 9 1 0 128 0 0 0] withIndexDo: [ :e :i | b1 at: i put: e].
+ 9 to: 128 do: [ :i | b1 at: i put: i ].
- #[162 9 1 0 0 0 0 0 128 0 0 0 0 0 0 0] withIndexDo: [ :e :i | b1 at: i put: e].
- 17 to: 128 do: [ :i | b1 at: i put: i ].
  hdr := CogImageFileHeader readFrom: (ReadStream on: b1).
  ws := WriteStream on: ByteArray new.
  hdr writeTo: ws littleEndian: true.
  b2 := ws contents.
+ self assert: (b2 first: 80) = (b1 first: 80).
+ self assert: (b2 last: (128 - 80)) asSet size = 1. "all zeros"!
- self assert: (b2 first: 92) = (b1 first: 92).
- self assert: (b2 last: (128 - 92)) asSet size = 1. "all zeros"!

Item was changed:
  ----- Method: ImageFileHeaderTest>>testReadWriteCogBigEndian (in category 'testing') -----
  testReadWriteCogBigEndian
  "Read and write with data in all byte positions"
 
  | hdr ws b1 b2 |
  b1 := ByteArray new: 64.
  b1 at: 4 put: 104; at: 3 put: 25; at: 2 put: 0; at: 1 put: 0. "a valid image format number"
  b1 at: 8 put: 64; at: 7 put: 0; at: 6 put: 0; at: 5 put: 0. "header size 64"
  9 to: 64 do: [ :i | b1 at: i put: i ].
  hdr := CogImageFileHeader readFrom: (ReadStream on: b1).
  ws := WriteStream on: ByteArray new.
  hdr writeTo: ws littleEndian: false.
  b2 := ws contents.
+ self assert: (b2 first: 56) = (b1 first: 56).
+ self assert: (b2 last: (64 - 56)) asSet size = 1. "all zeros"!
- self assert: (b2 first: 46) = (b1 first: 46).
- self assert: (b2 last: (64 - 46)) asSet size = 1. "all zeros"!

Item was changed:
  ----- Method: ImageFileHeaderTest>>testReadWriteCogLittleEndian (in category 'testing') -----
  testReadWriteCogLittleEndian
  "Read and write with data in all byte positions"
 
  | hdr ws b1 b2 |
  b1 := ByteArray new: 64.
  b1 at: 1 put: 104; at: 2 put: 25; at: 3 put: 0; at: 4 put: 0. "a valid image format number"
  b1 at: 5 put: 64; at: 6 put: 0; at: 7 put: 0; at: 8 put: 0. "header size 64"
  9 to: 64 do: [ :i | b1 at: i put: i ].
  hdr := CogImageFileHeader readFrom: (ReadStream on: b1).
  ws := WriteStream on: ByteArray new.
  hdr writeTo: ws littleEndian: true.
  b2 := ws contents.
+ self assert: (b2 first: 56) = (b1 first: 56).
+ self assert: (b2 last: (64 - 56)) asSet size = 1. "all zeros"!
- self assert: (b2 first: 46) = (b1 first: 46).
- self assert: (b2 last: (64 - 46)) asSet size = 1. "all zeros"!