Skip to content

Commit

Permalink
Merge pull request #22 from mumez/develop
Browse files Browse the repository at this point in the history
develop: Pharo 11 and 12 support
  • Loading branch information
mumez authored Nov 9, 2024
2 parents 6df91d9 + 592ebb2 commit cd34844
Show file tree
Hide file tree
Showing 83 changed files with 497 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ jobs:
strategy:
fail-fast: false
matrix:
smalltalk: [Pharo64-10, Squeak64-6.0]
smalltalk: [Pharo64-10, Pharo64-11, Pharo64-12, Squeak64-6.0]
experimental: [false]
continue-on-error: ${{ matrix.experimental }}
name: ${{ matrix.smalltalk }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: hpi-swa/setup-smalltalkCI@v1
with:
smalltalk-image: ${{ matrix.smalltalk }}
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SIXX is an XML serializer/deserializer written in Smalltalk. The purpose is to s

[![CI](https://github.com/mumez/SIXX/actions/workflows/main.yml/badge.svg)](https://github.com/mumez/SIXX/actions/workflows/main.yml)

This repository is mainly for sources ([Cypress](<https://github.com/CampSmalltalk/Cypress>) format). For further info, see the [main site](http://www.mars.dti.ne.jp/~umejava/smalltalk/sixx/index.html) and [wiki site](https://swikis.ddo.jp/umejava/SIXX).
This repository is mainly for sources ([Cypress](https://github.com/CampSmalltalk/Cypress) format). For further info, see the [main site](http://www.mars.dti.ne.jp/~umejava/smalltalk/sixx/index.html) and [wiki site](https://swikis.ddo.jp/umejava/SIXX).

## Installation using Metacello

Expand All @@ -24,6 +24,10 @@ Metacello new
```Smalltalk
Installer squeaksource
project: 'MetacelloRepository';
install: 'ConfigurationOfSIXX'.
install: 'ConfigurationOfSIXX'.
(Smalltalk at: #ConfigurationOfSIXX) load
```

## Features

Please see [features.md](./doc/features.md)
181 changes: 181 additions & 0 deletions doc/features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Features

SIXX is a multi-platform XML serializer/deserializer for Smalltalk. You can exchange various Smalltalk objects among different (dialect) images.

## How to use

### Basic writing/reading

SIXX is very easy to use. Like #storeString, You can generate a SIXX string by #sixxString.

```smalltalk
array := Array with: 1 with: 'Hello' with: Date today.
array sixxString.
```

This code generates the following SIXX string:

```xml
'<sixx.object sixx.id="0" sixx.type="Array">
<sixx.object sixx.id="1" sixx.type="SmallInteger">1</sixx.object>
<sixx.object sixx.id="2" sixx.type="String">Hello</sixx.object>
<sixx.object sixx.id="3" sixx.type="Date">16 June 2002</sixx.object>
</sixx.object>'
```

This string can be read by #readSixxFrom:.

```smalltalk
Object readSixxFrom: sixxString. "sixxString is the above string"
```

### Stream writing/reading

SixxWriteStream and SixxReadStream are provided so that you can write/read Smalltalk objects in a way similar to binary object stream (BOSS in VW, and the ReferenceStream in Squeak).

In order to write objects to an external file, you can:

```smalltalk
sws := SixxWriteStream newFileNamed: 'obj.sixx'.
sws nextPut: object. "an object"
sws nextPutAll: objects. "collection of objects"
sws close.
```

And to read objects from an external file:

```smalltalk
srs := SixxReadStream readOnlyFileNamed: 'obj.sixx'.
objects := srs contents.
srs close.
```

### SIXX hooks

#### Customizing serialization

| Hook method | Description |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Object>>sixxPrepareWrite | It is called before the instance is written in SIXX. |
| Object>>sixxWriteValue | Return the object actually serialized. |
| Object>>sixxIgnorableInstVarNames | Specify the instance variables that are not written in SIXX. |
| Object>>sixxNonReferencableInstVarNames | Specify the instance variables that should not be referenced in SIXX. Values are always written redundantly. It is useful for small literal objects like String, Number, etc. |
| Object>>sixxReferenceIdInContext: | Return unique id that can be referenced from other objects in SIXX. It is useful when objects have their own unique id. |

#### Customizing deserialization

| Hook method | Description |
| ---------------------- | ---------------------------------------------------------------- |
| Object>>sixxInitialize | It is called immediately after the instance is read from SIXX |
| Object>>sixxReadValue | Return the object for the client from the deserialized instance. |

### ShapeChanger

SixxShapeChangeReadStream enables you to read class shape changed instances. It supports renamed, removed and newly added instance variables.

```smalltalk
srs := SixxShapeChangeReadStream on: oldSixx readStream.
srs shapeChangers at:#SmallIntegerOLD put: SmallInteger . "simple renaming"
srs shapeChangers at: #SixxShapeChangedObject put: SixxMockShapeChanger.
"You can implement ShapeChanger for more complex conversion. "
```

To define a new ShapeChanger, you should subclass base ShapeChanger class and override three methods.

| Hook method | Description |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| YourShapeChanger>>shapeChangedObjectClass | Return a newly introduced class for old instances. |
| YourShapeChanger>>sixxInstVarNamed: varName put: value | Override this method for setting converted values to the shape changed object. |
| YourShapeChanger>>initializeShapeChangedObject | Override this method for setting newly introduced values to the shape changed object. |

For example: (YourShapeChanger>>sixxInstVarNamed: varName put:)

```smalltalk
sixxInstVarNamed: varName put: value
"#oldNamedVar1 inst var was renamed to #renamedAtt1"
varName == #oldNamedVar1 ifTrue: [^self attributesMap at: #renamedAtt1 put: value].
"#oldNamedVar2 inst var was removed."
varName == #oldNamedVar2 ifTrue: [^self].
super sixxInstVarNamed: varName put: value
```

From SIXX 0.3, you can apply ShapeChanger(s) without using SixxShapeChangeReadStream.

```smalltalk
obj := SixxContext evaluate: [Object readSixxFrom: oldSixx] shapeChangersBy: [:shapeChangers | shapeChangers at: #SixxShapeChangedObject put: SixxSomeShapeChanger].
```

### Formatter

Formatter is a new SIXX function for customizing SIXX format without subclassing.

Normally, you can customize SIXX serialization format by overriding hooks such as #sixxWriteValue, #sixxIgnorableInstVarNames. However, sometimes you would like to customize serialization format more dynamically.
For example, you may want to change default Array serialization format to compact one, if the array includes only primitive (literal) elements.

Suppose there is an array like:

```smalltalk
array := #(1 2 3 4 5).
```

By default, the array will be serialized if you evaluate:

```smalltalk
array sixxString. "print it"
```

```xml
'<sixx.object sixx.id="0" sixx.type="Array">
<sixx.object sixx.id="1" sixx.type="SmallInteger">1</sixx.object>
<sixx.object sixx.id="2" sixx.type="SmallInteger">2</sixx.object>
<sixx.object sixx.id="3" sixx.type="SmallInteger">3</sixx.object>
<sixx.object sixx.id="4" sixx.type="SmallInteger">4</sixx.object>
<sixx.object sixx.id="5" sixx.type="SmallInteger">5</sixx.object>
</sixx.object>'
```

This format is reasonable for supporting complex array, but the format could be space-consuming if the array contains only primitive (literal) elements. By setting a Formatter, you can use more compact format for Array.

```smalltalk
SixxContext formatters: {SixxMockLiteralArrayFormatter on: Array}.
```

After that, the format will be:

```xml
'<sixx.object
sixx.id="0"
sixx.type="Array"
sixx.formatter="SixxMockLiteralArrayFormatter"
>
<sixx.object sixx.id="1" sixx.type="String">#(1 2 3 4 5)</sixx.object>
</sixx.object>'
```

You can reset the formatter by:

```smalltalk
SixxContext resetFormatters.
```

For convenience, there is a method to switch formatter temporarily.

```smalltalk
SixxContext applyFormatters: {SixxMockLiteralArrayFormatter on: Array} while: [
array sixxString.
]
```

Or, you can even use:

```smalltalk
SixxContext evaluate: [array sixxString] formattersBy: [:formatters | formatters add: (SixxMockLiteralArrayFormatter on: Array)].
```

In short, Formatter can be used:

- For customizing SIXX format dynamically.
- For overriding SIXX format of the existing classes temporarily.
5 changes: 3 additions & 2 deletions repository/BaselineOfSIXX.package/.filetree
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"noMethodMetaData" : true,
"separateMethodMetaAndSource" : false,
"useCypressPropertiesFile" : true }
"noMethodMetaData" : true,
"useCypressPropertiesFile" : true
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ baseline: spec
self xmlParser: spec.
spec package: 'SIXX-Pharo'.
spec package: 'SIXX-ParserAdapter' with: [spec requires: 'XMLParser'].
spec package: 'SIXX-InOut-Common'.
].
spec for: #(#'pharo1.x' #'pharo2.x' #'pharo3.x' #'pharo4.x' #'pharo5.x' #'pharo6.x' #'pharo7.x' #'pharo8.x' #'pharo9.x' #'pharo10.x') do:[
spec package: 'SIXX-InOut-Common' with: [spec includes: 'SIXX-InOut-Pharo'].
spec package: 'SIXX-InOut-Pharo' with: [spec requires: #('SIXX-Pharo' 'SIXX-InOut-Common')].
].
spec for: #(#'pharo11.x' #'pharo12.x') do:[
spec package: 'SIXX-InOut-Common' with: [spec includes: 'SIXX-InOut-Pharo110'].
spec package: 'SIXX-InOut-Pharo110' with: [spec requires: #('SIXX-Pharo' 'SIXX-InOut-Common')].
].

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
{
"category" : "BaselineOfSIXX",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "",
"instvars" : [
],
"name" : "BaselineOfSIXX",
"pools" : [
],
"super" : "BaselineOf",
"type" : "normal" }
"category" : "BaselineOfSIXX",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [ ],
"name" : "BaselineOfSIXX",
"type" : "normal"
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SystemOrganization addCategory: #BaselineOfSIXX!
self packageOrganizer ensurePackage: #BaselineOfSIXX withTags: #()!
1 change: 0 additions & 1 deletion repository/BaselineOfSIXX.package/monticello.meta/version

This file was deleted.

3 changes: 1 addition & 2 deletions repository/BaselineOfSIXX.package/properties.json
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
{
}
{ }
5 changes: 5 additions & 0 deletions repository/SIXX-InOut-Pharo110.package/.filetree
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"separateMethodMetaAndSource" : false,
"noMethodMetaData" : true,
"useCypressPropertiesFile" : true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*SIXX-InOut-Pharo110-instance creation
createInstanceOf: aClass withSixxElement: sixxElement

"For old format"
| stream |
(SixxXmlUtil hasSubElementsFrom: sixxElement ) ifTrue: [
^super createInstanceOf: aClass withSixxElement: sixxElement
].

stream := ReadStream on: (SixxXmlUtil characterDataFrom: sixxElement).
^self readSixxContentStringFrom: stream
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*SIXX-InOut-Pharo110-instance creation
readSixxContentStringFrom: aStream
| space familyName size emphasisCode |
space := Character space.
familyName := aStream upTo: space.
size := (aStream upTo: space) asInteger.
emphasisCode := (aStream upTo: space) asInteger.
^self sixxFamilyName: familyName size: size emphasized: emphasisCode.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*SIXX-InOut-Pharo110-instance creation
sixxFamilyName: familyName size: size emphasized: emphasisCode
^self familyName: familyName size: size emphasized: emphasisCode
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*SIXX-InOut-Pharo110-printing
sixxContentOn: aStream indent: level context: dictionary
aStream nextPutAll: self sixxContentString
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110-printing
sixxContentString
"Squeak Specific"
^self fontNameWithPointSize, ' ', self emphasis asString
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "AbstractFont"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*SIXX-InOut-Pharo110-printing
sixxContentOn: aStream indent: level context: dictionary
aStream
nextPutAll: '(' , self class name;
nextPutAll: ' r: '; print: (self red roundTo: 0.001);
nextPutAll: ' g: '; print: (self green roundTo: 0.001);
nextPutAll: ' b: '; print: (self blue roundTo: 0.001);
nextPutAll: ')'.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "Color"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110
createInstanceOf: aClass withSixxElement: sixxElement
SixxInvalidDeserialization signal: aClass name element: sixxElement.
^nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110
sixxContentOn: aStream indent: level context: dictionary
SixxInvalidSerialization signal: self class name context: dictionary.
SixxXmlUtil writeXmlText: self printString on: aStream
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "CompiledCode"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110-instance creation
createInstanceOf: aClass withSixxElement: sixxElement
SixxInvalidDeserialization signal: aClass name element: sixxElement.
^nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110-printing
sixxContentOn: aStream indent: level context: dictionary
SixxInvalidSerialization signal: self class name context: dictionary.
SixxXmlUtil writeXmlText: self printString on: aStream
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "Context"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110-private
readSixxContentStringFrom: aStream
"Squeak specific"
^ self readFrom: aStream
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*SIXX-InOut-Pharo110-private
sixxContentString
"Squeak Specific"
^self printString
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "Date"
}
Loading

0 comments on commit cd34844

Please sign in to comment.