Now I need to ensure that the byte ordering is consistent
Keith
I am planning to build a minimal squeak vm for unix and windows which can be added to the mercurial installation as an encoder for files of type *.image (the unix vm build will be sufficient to do the job on Mac OS X).
This is the best way that I can think of for supporting squeak activities using vm's and images of every description. This way the normalizing code doesn't need to be in every users vm.
Mercurial needs the encoder to be invokable from the commandline like so, which should be doable.
squeak -normalize INFILE OUTFILE
In this case I dont even need the image to properly start up, so I dont really need to unswizzle things having written the image.
I am not having much sucess with saving the image little-endian
any thoughts would be appreciated
Keith
appendix: The Story so far:
------------------------------------------
Interpreter-putLong: aWord toFile: aFile swap: swapFlag "sway byte order as requested"
| objectsWritten w | self var: #aFile type: 'sqImageFile '.
w := aWord. swapFlag ifTrue: [ w := self byteSwapped: aWord ].
objectsWritten := self cCode: 'sqImageFileWrite(&w, sizeof(w), 1, aFile)'. self success: objectsWritten = 1.
------------------------------------------
Interpreter-writeImageFileIO: imageBytes
| headerStart headerSize f bytesWritten sCWIfn okToWrite swapToLittle |
self var: #f type: 'sqImageFile'. self var: #headerStart type: 'squeakFileOffsetType '. self var: #sCWIfn type: 'void *'.
"If the security plugin can be loaded, use it to check for write permission. If not, assume it's ok" sCWIfn := self ioLoadFunction: 'secCanWriteImage' From: 'SecurityPlugin'. sCWIfn ~= 0 ifTrue:[okToWrite := self cCode: '((sqInt (*)(void))sCWIfn)()'. okToWrite ifFalse:[^self primitiveFail]].
"kph mod - to support binary diffs" self adjustAllOopsBy: (0 - self startOfMemory). swapToLittle := self isBigEnder.
"local constants" headerStart := 0. headerSize := 64. "header size in bytes; do not change!"
f := self cCode: 'sqImageFileOpen(imageName, "wb")'. f = nil ifTrue: [ "could not open the image file for writing" self success: false. ^ nil].
headerStart := self cCode: 'sqImageFileStartLocation(f,imageName,headerSize+imageBytes)'. self cCode: '/* Note: on Unix systems one could put an exec command here, padded to 512 bytes */'. "position file to start of header" self sqImageFile: f Seek: headerStart.
self putLong: (self imageFormatVersion) toFile: f swap: swapToLittle. self putLong: headerSize toFile: f swap: swapToLittle. self putLong: imageBytes toFile: f swap: swapToLittle. self putLong: 0 "(self startOfMemory) kph mod - for binary diffs" toFile: f swap: swapToLittle. self putLong: (specialObjectsOop - self startOfMemory) toFile: f swap: swapToLittle. self putLong: lastHash toFile: f swap: swapToLittle. self putLong: (self ioScreenSize) toFile: f swap: swapToLittle. self putLong: fullScreenFlag toFile: f swap: swapToLittle. self putLong: extraVMMemory toFile: f swap: swapToLittle. 1 to: 7 do: [:i | self putLong: 0 toFile: f]. "fill remaining header words with zeros" successFlag ifFalse: [ "file write or seek failure" self cCode: 'sqImageFileClose(f)'. ^ nil].
"position file after the header" self sqImageFile: f Seek: headerStart + headerSize.
"write the image data" swapToLittle ifTrue: [ self reverseBytesInImage].
bytesWritten := self cCode: 'sqImageFileWrite(pointerForOop(memory), sizeof(unsigned char), imageBytes, f)'. self success: bytesWritten = imageBytes. self cCode: 'sqImageFileClose(f)'.
swapToLittle ifTrue: [ self reverseBytesInImage]. self adjustAllOopsBy: (self startOfMemory).