Professional Documents
Culture Documents
Michael Lucas-Smith
Martin Kobetic
Platforms
VisualWorks
Squeak and Pharo (Nicolas Cellier)
Gemstone (Dale Henrichs)
Slate (Brian Rice)
composition
no deep class hierarchy any more
capabilities
transformations
substreams
scalability
chunks vs elements
recycling
Structure
core
Defines the API and Core Classes.
Support package is for portability.
terminals
Unique to each platform, wraps the
source and destination objects in to streams.
transforms
collecting, rejecting, selecting...
character encoding
binary transformations
object marshaling
Structure
substreams / parsing
limiting, element or subcollection ending
slicing and stitching
parsing expression grammars
multiplexing (experimental)
xtras
compression
cryptography
chunking
applications
SSH2 (Xtreams-SSH2)
IRC (Xtreams-IRC)
EXIF Metadata (Xtreams-Photo)
reading / writing
collections
'example' reading.
OrderedCollection new writing.
Transcript writing.
transcendentals
[0] reading. /dev/zero
[:x | ] writing. /dev/null
Kernel.ObjectMemory reading.
Random new reading.
API
common
Incomplete.
stream terminal.
stream close.
stream isReadable; isWritable; isPositionable.
reading
input get.
input read: 5.
input read: 5 into: collection.
input read: 5 into: collection at: 2.
input rest.
output print: #( 1 2 3 ).
output cr; bell; q; qq; space; space: 2; tab; tab: 3
API
seeking
positionable := stream positioning.
transform a non-positionable stream in to
a positionable stream
stream ++ 200.
seek forward from where we are
stream -- 200.
seek backward from where we are
stream += 200.
seek forward from the start of the stream
stream available.
elements left to consume on the stream
(not to be mistaken with data
left in socket buffer)
stream length.
elements in the stream
QA
Questions?
Transforms
Collection Style
collecting:, selecting:, injecting:into:, doing:, ...
Specialized Transforms
encoding:, encodingBase64, encodingHex,
compressing, en/decrypting:key:iv:, hashing:
interpreting:, marshaling
General Transforms
transforming: [ :in :out | out put: in get ]
Collection Transforms
random := Random new reading.
random := random collecting: [ :f | (f * 256) floor ].
random contentsSpecies: ByteArray.
random read: 10.
current := 0.
integers := [current := current + 1] reading.
integers read: 10.
even := integers selecting: [ :i | i even ].
even read: 10.
Character Encoding
input := 'xtreams.cha' asFilename reading.
input := input encoding: #utf8.
input read: 50.
input close.
DecodingTree
- << * >> .
T E
M N A I
O G K D W R U S
Q Z Y C X B J P L F V H
size
(Object comment reading limiting: 10) rest.
bounding criteria
(Object comment reading ending: $.) rest.
(Object comment reading ending: [:e | '.?!' includes:
(Object comment reading ending: ' is the') rest.
streams of substreams
slicing streams into substreams
stitching streams from substreams
Substreams - limiting:
output := String new writing.
Number withAllSubclasses do: [ :class |
[ (output limiting: 40) write: class comment.
] on: Incomplete do: [ :ex | output -- 3; write: '...' ].
output cr ].
output conclusion.
Substreams - ending:
output := String new writing.
Number withAllSubclasses do: [ :class |
[ (output ending: $. inclusive: true)
write: class comment
] on: Incomplete do: [].
output cr ].
output conclusion
Slicing
reading
input := 'xtreams.cha' asFilename reading.
input := input encoding: #utf8.
[ lines := (input ending: Character cr) slicing.
(lines ++ 10000; get) rest
] ensure: [ input close ].
writing
output := String new writing.
blurbs := (output limiting: 40) slicing.
Number withAllSubclasses do: [ :class |
[ blurbs get write: class comment.
] on: Incomplete do: [ :ex | output -- 3; write: '...'
output cr ].
output conclusion.
Slices of Slices
reading
input := 'aaa#bb#c##!1#22#33#444' reading.
messages := (input ending: $!) slicing.
parts := (messages get ending: $#) slicing.
parts collect: [ :p | p rest ].
writing
output := String new writing.
messages := (output closing: [ output put: $! ])
slicing.
#((aa bb cc dd ee) (xxx yy z)) do: [ :m |
message := messages get.
parts := (message closing: [ message put: $# ])
slicing.
m do: [ :p | parts get write: p ] ].
output conclusion
Stitching Reads
((1 to: 5) reading, (6 to: 10) reading) rest.
((1 to: 10) reading limiting: 3) slicing stitching rest.
to replace...
BOSS
Opentalk-STST
Parcels (sort of)
SIXX
Marshaling
ObjectMarshaler
Separate from the Read/Write streams.
Pluggable marshaling strategy, for different protocols
Uses Pragmas to allow extensions with
a computed hash to detect different
versions.
Analysis
Read without instantiating objects to
diagnose a stream.
Marshaling
output := ByteArray new writing marshaling.
output put: 100 asValue.
output conclusion =
#[83 84 83 84 20 4 21 199 91 7 32 29 82
111 111 116 46 83 109 97 108 108 116
97 108 107 46 85 73 46 86 97 108 117
101 72 111 108 100 101 114 0 1 28 22
100]
Marshaling
(Xtreams.ObjectAnalyseStream on:
output conclusion reading) rest =
'0+10 header: #[83 84 83 84 20 4 105 117 236 8]
10+36 record
10+1 class id: 32
11+31 class description: UI.ValueHolder
42+1 object id: 1
43+3 object: UI.ValueHolder
43+1 dependents
43+1 class id: 28 Core.UndefinedObject
43+1 class id: 28
44+0 nil
44+2 value
44+2 class id: 22 Core.SmallInteger
44+1 class id: 22
45+1 byte integer: 100'
Marshaling
output conclusion reading marshaling get.
a ValueHolder on: 100
Parsing
Parsing Expression Grammars
Erlang 'bit syntax'
Reusable Grammars
Grammar composition
Parsing
Parsing Expression Grammars
grammar :=
'Sentence <- Whitespace? (Word / Punctuation)*
Word <- [a-zA-Z'']+
Punctuation <- [,;:()]'.
Moving beyond...
Grammar Composition
Compile grammar into bytecode
on lightweight class
Read one character: {character/utf8}
Read one byte: {integer/unsigned/little}:8
Read one of many characters in utf16:
[a-zA-Z]/utf16
Read a sequence of characters in utf8:
''TITLE''/utf8
QA
Questions?
Xtras
Various non-core transformations
Compression
calls ZLib
Cryptography
calls BCrypt (CNG) on Windows
calls OpenSSL's libcrypto everywhere else
hashing (MD5, SHA1, SHA256, SHA512, ...)
hashing with key (HMAC with MD5, SHA1, ...)
encryption (RC4, AES, DES, ...)
HTTP Chunking
Xtras - Examples
hashing
(ObjectMemory imageFilename reading
hashing: 'MD5'
) -= 0; close; digest.
encryption
key := random read: 16.
((String new writing
encodingBase64
encrypting: 'RC4' key: key)
compressing
encoding: #utf8
) write: Object comment;
conclusion.
Xtras - SSH2
does
transport
authentication: public-key, password
channel/session management
data transfer
channel requests: exec, env, exit-status
scp
does not
terminal session/emulation: pty-req, shell
port forwarding (tunnels)
scp atime/mtime
Xtras - SSH2
keys := SSH2KeysTest sampleKeys.
config := SSH2Configuration new keys: keys.
server := ('-thishost-' asIPv4: 2222) listen accepting.
[ (SSH2ServerConnection on: server get)
configuration: config;
when: SSH2Announcement
do: [ :m | Transcript cr; print: m ];
accept;
waitForDisconnect;
close
] ensure: [ server close. keys release ]
Xtras - SSH2
home := '$(HOME)' asLogicalFileSpecification asFilenam
user := home tail.
keys := SSH2Keys fromUser: home.
config := SSH2Configuration new keys: keys.
client := ('localhost' asIPv4: 22) connect.
client := SSH2ClientConnection on: client.
client configuration: config.
client when: SSH2Announcement
do: [ :m | Transcript cr; print: m ].
[ service := client connect: user.
session := service session.
[ session exec: 'ls -l'
] ensure: [ session close ]
] ensure: [ client close. keys release ]
QA
Questions?