summaryrefslogtreecommitdiffstats
path: root/tcllib/modules/virtchannel_transform
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2016-10-27 19:39:39 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2016-10-27 19:39:39 (GMT)
commitea28451286d3ea4a772fa174483f9a7a66bb1ab3 (patch)
tree6ee9d8a7848333a7ceeee3b13d492e40225f8b86 /tcllib/modules/virtchannel_transform
parentb5ca09bae0d6a1edce939eea03594dd56383f2c8 (diff)
parent7c621da28f07e449ad90c387344f07a453927569 (diff)
downloadblt-ea28451286d3ea4a772fa174483f9a7a66bb1ab3.zip
blt-ea28451286d3ea4a772fa174483f9a7a66bb1ab3.tar.gz
blt-ea28451286d3ea4a772fa174483f9a7a66bb1ab3.tar.bz2
Merge commit '7c621da28f07e449ad90c387344f07a453927569' as 'tcllib'
Diffstat (limited to 'tcllib/modules/virtchannel_transform')
-rw-r--r--tcllib/modules/virtchannel_transform/ChangeLog53
-rw-r--r--tcllib/modules/virtchannel_transform/README.txt38
-rw-r--r--tcllib/modules/virtchannel_transform/adler32.man70
-rw-r--r--tcllib/modules/virtchannel_transform/adler32.tcl103
-rw-r--r--tcllib/modules/virtchannel_transform/base64.tcl111
-rw-r--r--tcllib/modules/virtchannel_transform/counter.tcl94
-rw-r--r--tcllib/modules/virtchannel_transform/crc32.tcl103
-rw-r--r--tcllib/modules/virtchannel_transform/hex.man43
-rw-r--r--tcllib/modules/virtchannel_transform/hex.tcl58
-rw-r--r--tcllib/modules/virtchannel_transform/identity.man50
-rw-r--r--tcllib/modules/virtchannel_transform/identity.tcl59
-rw-r--r--tcllib/modules/virtchannel_transform/limitsize.man46
-rw-r--r--tcllib/modules/virtchannel_transform/limitsize.tcl88
-rw-r--r--tcllib/modules/virtchannel_transform/observe.man50
-rw-r--r--tcllib/modules/virtchannel_transform/observe.tcl80
-rw-r--r--tcllib/modules/virtchannel_transform/otp.tcl98
-rw-r--r--tcllib/modules/virtchannel_transform/pkgIndex.tcl14
-rw-r--r--tcllib/modules/virtchannel_transform/rot.man57
-rw-r--r--tcllib/modules/virtchannel_transform/rot.tcl95
-rw-r--r--tcllib/modules/virtchannel_transform/spacer.man45
-rw-r--r--tcllib/modules/virtchannel_transform/spacer.tcl151
-rw-r--r--tcllib/modules/virtchannel_transform/tcllib_zlib.man46
-rw-r--r--tcllib/modules/virtchannel_transform/vt_base64.man44
-rw-r--r--tcllib/modules/virtchannel_transform/vt_counter.man68
-rw-r--r--tcllib/modules/virtchannel_transform/vt_crc32.man70
-rw-r--r--tcllib/modules/virtchannel_transform/vt_otp.man53
-rw-r--r--tcllib/modules/virtchannel_transform/zlib.tcl100
27 files changed, 1887 insertions, 0 deletions
diff --git a/tcllib/modules/virtchannel_transform/ChangeLog b/tcllib/modules/virtchannel_transform/ChangeLog
new file mode 100644
index 0000000..ec450b8
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/ChangeLog
@@ -0,0 +1,53 @@
+2013-03-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * zlib.man: Renamed, clashes with Tcl core manpage.
+ * tcllib_zlib.man: New name.
+
+2013-02-01 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.15 ========================
+ *
+
+2011-12-13 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.14 ========================
+ *
+
+2011-02-21 Andreas Kupries <andreask@activestate.com>
+
+ * pkgIndex.tcl: Removed the superfluous [list] command in the
+ ifneeded script.
+
+2011-01-24 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.13 ========================
+ *
+
+2010-08-04 Andreas Kupries <andreask@activestate.com>
+
+ * adler32.man: New files, documentation for the packages in
+ * base64.man: this module.
+ * counter.man:
+ * crc32.man:
+ * hex.man:
+ * identity.man:
+ * limitsize.man:
+ * observe.man:
+ * otp.man:
+ * rot.man:
+ * spacer.man:
+ * zlib.man:
+
+2009-12-07 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.12 ========================
+ *
+
+2009-12-01 Andreas Kupries <andreask@activestate.com>
+
+ * New module 'virtchannel_transform, providing classes implementing
+ various channel transformation. TclOO based.
diff --git a/tcllib/modules/virtchannel_transform/README.txt b/tcllib/modules/virtchannel_transform/README.txt
new file mode 100644
index 0000000..46c7e9b
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/README.txt
@@ -0,0 +1,38 @@
+base64, hex
+
+ Base64 and hex de- and encoding of data flowing
+ through a channel.
+
+ Encodes on write, decodes on read.
+
+identity
+
+ No transformation
+
+counter
+
+ Identity, counting bytes.
+
+adler32, adler32pure, crc32
+
+ Compute checksums and write to external variables.
+
+observe
+
+ Divert copy of the data to additional channels.
+
+limitsize
+
+ Force EOF after reading N bytes, N configurable.
+
+spacer
+
+ Inserts separator string every n bytes.
+
+otp
+
+ One-Time-Pad encryption.
+
+zlib
+
+ zlib (de)compression (deflate, inflate).
diff --git a/tcllib/modules/virtchannel_transform/adler32.man b/tcllib/modules/virtchannel_transform/adler32.man
new file mode 100644
index 0000000..43c1cce
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/adler32.man
@@ -0,0 +1,70 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::adler32 n 1]
+[keywords adler32]
+[keywords {channel transformation}]
+[keywords checksum]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Adler32 transformation}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::adler32 [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::adler32] package provides a command
+creating a channel transformation which passes the read and written
+bytes through unchanged (like [package tcl::transform::identity]), but
+additionally continuously computes the adler32 checksums of the data
+it has seen for each direction and stores them in Tcl variables
+specified at construction time.
+
+[para] Related transformations in this module are
+[package tcl::transform::counter],
+[package tcl::transform::crc32],
+[package tcl::transform::identity], and
+[package tcl::transform::observe].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::adler32] [arg chan] [option -option] [arg value]...]
+
+This command creates an adler32 checksumming transformation on top of
+the channel [arg chan] and returns its handle. The accepted options are
+
+[list_begin options]
+[opt_def -read-variable varname]
+
+The value of the option is the name of a global or namespaced
+variable, the location where the transformation has to store the
+adler32 checksum of the data read from the channel.
+
+[para] If not specified, or the empty string, the checksum of the read
+direction is not saved.
+
+[opt_def -write-variable varname]
+
+The value of the option is the name of a global or namespaced
+variable, the location where the transformation has to store the
+adler32 checksum of the data written to the channel.
+
+[para] If not specified, or the empty string, the checksum of the
+write direction is not saved.
+
+[list_end]
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/adler32.tcl b/tcllib/modules/virtchannel_transform/adler32.tcl
new file mode 100644
index 0000000..441ea8e
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/adler32.tcl
@@ -0,0 +1,103 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::adler32 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes For other observers see crc32, counter,
+# Meta as::notes identity, and observer (stream copy).
+# Meta description Implementation of an adler32 checksum
+# Meta description transformation. Based on Tcl 8.6's
+# Meta description transformation reflection support (TIP
+# Meta description 230), and its zlib support (TIP 234) for
+# Meta description the adler32 functionality. An observer
+# Meta description instead of a transformation. For details
+# Meta description on the adler checksum see
+# Meta description http://en.wikipedia.org/wiki/Adler-32 .
+# Meta description The observer saves the checksums into two
+# Meta description namespaced external variables specified
+# Meta description at construction time. Exports a single
+# Meta description command adding a new transformation of
+# Meta description this type to a channel. One argument,
+# Meta description the channel to extend, plus options to
+# Meta description specify the variables for the checksums.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::adler32 {chan args} {
+ ::chan push $chan [adler32::implementation new {*}$args]
+}
+
+oo::class create ::tcl::transform::adler32::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ # This transformation continuously computes a checksum from the
+ # data it sees. This data may be arbitrary parts of the input or
+ # output if the channel is seeked while the transform is
+ # active. This may not be what is wanted and the desired behaviour
+ # may require the destruction of the transform before seeking.
+
+ method write {c data} {
+ my Adler32 -write-variable $data
+ return $data
+ }
+
+ method read {c data} {
+ my Adler32 -read-variable $data
+ return $data
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {args} {
+ array set options {
+ -read-variable {}
+ -write-variable {}
+ }
+ # todo: validity checking of options (legal names, legal
+ # values, etc.)
+ array set options $args
+ my Init -read-variable
+ my Init -write-variable
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable options
+
+ # # ## ### ##### ######## #############
+
+ method Init {o} {
+ if {$options($o) eq ""} return
+ upvar #0 $options($o) adler
+ set adler 1
+ return
+ }
+
+ method Adler32 {o data} {
+ if {$options($o) eq ""} return
+ upvar #0 $options($o) adler
+ set adler [zlib adler32 $data $adler]
+ return
+ }
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::adler32 1
+return
diff --git a/tcllib/modules/virtchannel_transform/base64.tcl b/tcllib/modules/virtchannel_transform/base64.tcl
new file mode 100644
index 0000000..bad2b68
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/base64.tcl
@@ -0,0 +1,111 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::base64 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes Possibilities for extension: Currently
+# Meta as::notes the mapping between read/write and
+# Meta as::notes decode/encode is fixed. Allow it to be
+# Meta as::notes configured at construction time.
+# Meta description Implementation of a base64
+# Meta description transformation (RFC 4648). Based on Tcl
+# Meta description 8.6's transformation reflection support
+# Meta description (TIP 230) and binary en/decode (TIP 317).
+# Meta description Exports a single command adding a new
+# Meta description transformation of this type to a channel.
+# Meta description One argument, the channel to extend. No
+# Meta description result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::base64 {chan} {
+ ::chan push $chan [base64::implementation new]
+ return
+}
+
+oo::class create ::tcl::transform::base64::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ method write {c data} {
+ my Code encodebuf encode $data 3
+ }
+
+ method read {c data} {
+ my Code decodebuf decode $data 4
+ }
+
+ method flush {c} {
+ set data [binary encode base64 $encodebuf]
+ set encodebuf {}
+ return $data
+ }
+
+ method drain {c} {
+ set data [binary decode base64 $decodebuf]
+ set decodebuf {}
+ return $data
+ }
+
+ method clear {c} {
+ set decodebuf {}
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {} {
+ set encodebuf {}
+ set decodebuf {}
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable encodebuf decodebuf
+
+ # # ## ### ##### ######## #############
+
+ method Code {bufvar op data n} {
+ upvar 1 $bufvar buffer
+
+ append buffer $data
+
+ set n [my Complete $buffer $n]
+ if {$n < 0} {
+ return {}
+ }
+
+ set result \
+ [binary $op base64 \
+ [string range $buffer 0 $n]]
+ incr n
+ set buffer \
+ [string range $buffer $n end]
+
+ return $result
+ }
+
+ method Complete {buffer n} {
+ set len [string length $buffer]
+ return [expr {(($len / $n) * $n)-1}]
+ }
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::base64 1
+return
diff --git a/tcllib/modules/virtchannel_transform/counter.tcl b/tcllib/modules/virtchannel_transform/counter.tcl
new file mode 100644
index 0000000..73bb9fd
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/counter.tcl
@@ -0,0 +1,94 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::counter 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes For other observers see adler32, crc32,
+# Meta as::notes identity, and observer (stream copy).
+# Meta as::notes Possibilities for extension: Separate
+# Meta as::notes counters per byte value. Count over
+# Meta as::notes fixed time-intervals = channel speed.
+# Meta as::notes Use callbacks or traces to save changes
+# Meta as::notes in the counters, etc. as time-series.
+# Meta as::notes Compute statistics over the time-series.
+# Meta description Implementation of a counter
+# Meta description transformation. Based on Tcl 8.6's
+# Meta description transformation reflection support (TIP
+# Meta description 230). An observer instead of a
+# Meta description transformation, it counts the number of
+# Meta description bytes read and written. The observer
+# Meta description saves the counts into two external
+# Meta description namespaced variables specified at
+# Meta description construction time. Exports a single
+# Meta description command adding a new transformation of
+# Meta description this type to a channel. One argument,
+# Meta description the channel to extend, plus options to
+# Meta description specify the variables for the counters.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::counter {chan args} {
+ ::chan push $chan [counter::implementation new {*}$args]
+}
+
+oo::class create ::tcl::transform::counter::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ method write {c data} {
+ my Count -write-variable $data
+ return $data
+ }
+
+ method read {c data} {
+ my Count -read-variable $data
+ return $data
+ }
+
+ # No partial data, nor state => no flush, drain, nor clear needed.
+
+ # # ## ### ##### ######## #############
+
+ constructor {args} {
+ array set options {
+ -read-variable {}
+ -write-variable {}
+ }
+ # todo: validity checking of options (legal names, legal
+ # values, etc.)
+ array set options $args
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable options
+
+ # # ## ### ##### ######## #############
+
+ method Count {o data} {
+ if {$options($o) eq ""} return
+ upvar #0 $options($o) counter
+ incr counter [string length $data]
+ return
+ }
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::counter 1
+return
diff --git a/tcllib/modules/virtchannel_transform/crc32.tcl b/tcllib/modules/virtchannel_transform/crc32.tcl
new file mode 100644
index 0000000..83e7224
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/crc32.tcl
@@ -0,0 +1,103 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::crc32 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes For other observers see adler32, counter,
+# Meta as::notes identity, and observer (stream copy).
+# Meta description Implementation of a crc32 checksum
+# Meta description transformation. Based on Tcl 8.6's
+# Meta description transformation reflection support (TIP
+# Meta description 230), and its zlib support (TIP 234) for
+# Meta description the crc32 functionality. An observer
+# Meta description instead of a transformation. For details
+# Meta description on the crc checksum see
+# Meta description http://en.wikipedia.org/wiki/Cyclic_redundancy_check#Commonly_used_and_standardised_CRCs .
+# Meta description The observer saves the checksums into two
+# Meta description namespaced external variables specified
+# Meta description at construction time. Exports a single
+# Meta description command adding a new transformation of
+# Meta description this type to a channel. One argument,
+# Meta description the channel to extend, plus options to
+# Meta description specify the variables for the checksums.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::crc32 {chan args} {
+ ::chan push $chan [crc32::implementation new {*}$args]
+}
+
+oo::class create ::tcl::transform::crc32::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ # This transformation continuously computes a checksum from the
+ # data it sees. This data may be arbitrary parts of the input or
+ # output if the channel is seeked while the transform is
+ # active. This may not be what is wanted and the desired behaviour
+ # may require the destruction of the transform before seeking.
+
+ method write {c data} {
+ my Crc32 -write-variable $data
+ return $data
+ }
+
+ method read {c data} {
+ my Crc32 -read-variable $data
+ return $data
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {args} {
+ array set options {
+ -read-variable {}
+ -write-variable {}
+ }
+ # todo: validity checking of options (legal names, legal
+ # values, etc.)
+ array set options $args
+ my Init -read-variable
+ my Init -write-variable
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable options
+
+ # # ## ### ##### ######## #############
+
+ method Init {o} {
+ if {$options($o) eq ""} return
+ upvar #0 $options($o) crc
+ set crc 0
+ return
+ }
+
+ method Crc32 {o data} {
+ if {$options($o) eq ""} return
+ upvar #0 $options($o) crc
+ set crc [zlib crc32 $data $crc]
+ return
+ }
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::crc32 1
+return
diff --git a/tcllib/modules/virtchannel_transform/hex.man b/tcllib/modules/virtchannel_transform/hex.man
new file mode 100644
index 0000000..6193070
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/hex.man
@@ -0,0 +1,43 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::hex n 1]
+[keywords {channel transformation}]
+[keywords hexadecimal]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Hexadecimal encoding transformation}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::hex [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::hex] package provides a command creating
+a channel transformation which hex encodes data written to it, and
+decodes the data read from it.
+
+[para] A related transformations in this module is
+[package tcl::transform::base64].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::hex] [arg chan]]
+
+This command creates a hex transformation on top of the channel
+[arg chan] and returns its handle.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/hex.tcl b/tcllib/modules/virtchannel_transform/hex.tcl
new file mode 100644
index 0000000..f3be104
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/hex.tcl
@@ -0,0 +1,58 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::hex 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta description Implementation of a hex transformation,
+# Meta description using Tcl 8.6's transformation
+# Meta description reflection support. Uses the binary
+# Meta description command to implement the transformation.
+# Meta description Exports a single command adding a new
+# Meta description transform of this type to a channel. One
+# Meta description argument, the channel to extend. No
+# Meta description result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::hex {chan} {
+ ::chan push $chan [hex::implementation new]
+ return
+}
+
+oo::class create ::tcl::transform::hex::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ method write {c data} {
+ # bytes -> hex
+ binary scan $data H* hex
+ return $hex
+ }
+
+ method read {c data} {
+ # hex -> bytes
+ return [binary format H* $data]
+ }
+
+ # No partial data, nor state => no flush, drain, nor clear needed.
+
+ # # ## ### ##### ######## #############
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::hex 1
+return
diff --git a/tcllib/modules/virtchannel_transform/identity.man b/tcllib/modules/virtchannel_transform/identity.man
new file mode 100644
index 0000000..7089e8f
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/identity.man
@@ -0,0 +1,50 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::identity n 1]
+[keywords {channel transformation}]
+[keywords identity]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Identity transformation}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::identity [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::identity] package provides a command
+creating an identity channel transformation, which does nothing but
+pass the read and written bytes through it unchanged. Not really
+useful in an application, however as the prototypical observer
+transformation its code is a useful starting point for any other
+observers people may wish to write.
+
+[para] The transformations in this module which derived from
+identity's code are
+[package tcl::transform::adler32],
+[package tcl::transform::counter],
+[package tcl::transform::crc32], and
+[package tcl::transform::observe].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::identity] [arg chan]]
+
+This command creates an identity transformation on top of the channel
+[arg chan] and returns its handle.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/identity.tcl b/tcllib/modules/virtchannel_transform/identity.tcl
new file mode 100644
index 0000000..9ad80b7
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/identity.tcl
@@ -0,0 +1,59 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::identity 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes The prototypical observer transformation.
+# Meta as::notes To observers what null is to reflected
+# Meta as::notes base channels. For other observers see
+# Meta as::notes adler32, crc32, counter, and observer
+# Meta as::notes (stream copy).
+# Meta description Implementation of an identity
+# Meta description transformation, i.e one which does not
+# Meta description change the data in any way, shape, or
+# Meta description form. Based on Tcl 8.6's transformation
+# Meta description reflection support. Exports a single
+# Meta description command adding a new transform of this
+# Meta description type to a channel. One argument, the
+# Meta description channel to extend. No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::identity {chan} {
+ ::chan push $chan [identity::implementation new]
+}
+
+oo::class create ::tcl::transform::identity::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ method write {c data} {
+ return $data
+ }
+
+ method read {c data} {
+ return $data
+ }
+
+ # No partial data, nor state => no flush, drain, nor clear needed.
+
+ # # ## ### ##### ######## #############
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::identity 1
+return
diff --git a/tcllib/modules/virtchannel_transform/limitsize.man b/tcllib/modules/virtchannel_transform/limitsize.man
new file mode 100644
index 0000000..2f4a2bb
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/limitsize.man
@@ -0,0 +1,46 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::limitsize n 1]
+[keywords {channel transformation}]
+[keywords limitsize]
+[keywords {reflected channel}]
+[keywords {size limit}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {limiting input}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::limitsize [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::limitsize] package provides a command
+creating a channel transformation which limits the number of
+characters which can be read from the channel. A generator for an
+artificial EOF.
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::limitsize] [arg chan] [arg max]]
+
+This command creates a size limiting transformation on top of the
+channel [arg chan] and returns its handle.
+
+[para] [arg max] is the number of bytes which can be read from the
+channel before EOF is signaled by the transformation. Note that
+popping the transformation clears the EOF it generated as well.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/limitsize.tcl b/tcllib/modules/virtchannel_transform/limitsize.tcl
new file mode 100644
index 0000000..72d79ef
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/limitsize.tcl
@@ -0,0 +1,88 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::limitsize 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes Possibilities for extension: Trigger the
+# Meta as::notes EOF when finding specific patterns in
+# Meta as::notes the input. Trigger the EOF based on some
+# Meta as::notes external signal routed into the limiter.
+# Meta as::notes Make the limit reconfigurable.
+# Meta description Implementation of a transformation
+# Meta description limiting the number of bytes read
+# Meta description from its channel. An observer instead of
+# Meta description a transformation, forcing an artificial
+# Meta description EOF marker. Based on Tcl 8.6's
+# Meta description transformation reflection support.
+# Meta description Exports a single command adding a new
+# Meta description transform of this type to a channel. One
+# Meta description argument, the channel to extend, and the
+# Meta description number of bytes to allowed to be read.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# This may help with things like zlib compression of messages. Have
+# the message format a length at the front, followed by a payload of
+# that size. Now we may compress messages. On the read side we can use
+# the limiter to EOF on a message, then reset the limit for the
+# next. This is a half-baked idea.
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::limitsize {chan max} {
+ ::chan push $chan [limitsize::implementation new $max]
+}
+
+oo::class create ::tcl::transform::limitsize::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ method write {c data} {
+ return $data
+ }
+
+ method read {c data} {
+ # Reduce the limit of bytes allowed in the future according to
+ # the number of bytes we have seen already.
+
+ if {$max > 0} {
+ incr max -[string length $data]
+ if {$max < 0} {
+ set max 0
+ }
+ }
+ return $data
+ }
+
+ method limit? {c} {
+ return $max
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {themax} {
+ set max $themax
+ return
+ }
+
+ variable max
+
+ # # ## ### ##### ######## #############
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::limitsize 1
+return
diff --git a/tcllib/modules/virtchannel_transform/observe.man b/tcllib/modules/virtchannel_transform/observe.man
new file mode 100644
index 0000000..1e20312
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/observe.man
@@ -0,0 +1,50 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::observe n 1]
+[keywords {channel transformation}]
+[keywords observer]
+[keywords {reflected channel}]
+[keywords {stream copy}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Observer transformation, stream copy}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::observe [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::observer] package provides a command
+creating a channel transformation which passes the read and written
+bytes through unchanged (like [package tcl::transform::identity]), but
+additionally copies the data it has seen for each direction into
+channels specified at construction time.
+
+[para] Related transformations in this module are
+[package tcl::transform::adler32],
+[package tcl::transform::counter],
+[package tcl::transform::crc32], and
+[package tcl::transform::identity].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::observe] [arg chan] [arg logw] [arg logr]]
+
+This command creates an observer transformation on top of the channel
+[arg chan] and returns its handle. The channel handles [arg logr] and
+[arg logw] are there the data is copied to.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/observe.tcl b/tcllib/modules/virtchannel_transform/observe.tcl
new file mode 100644
index 0000000..65f5754
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/observe.tcl
@@ -0,0 +1,80 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::observe 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes For other observers see adler32, crc32,
+# Meta as::notes identity, and counter.
+# Meta as::notes Possibilities for extension: Save the
+# Meta as::notes observed bytes to variables instead of
+# Meta as::notes channels. Use callbacks to save the
+# Meta as::notes observed bytes.
+# Meta description Implementation of an observer
+# Meta description transformation copying the bytes going
+# Meta description through it into two channels configured
+# Meta description at construction time. Based on Tcl 8.6's
+# Meta description transformation reflection support.
+# Meta description Exports a single command adding a new
+# Meta description transformation of this type to a channel.
+# Meta description Three arguments, the channel to extend,
+# Meta description plus the channels to write the bytes to.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::observe {chan logw logr} {
+ ::chan push $chan [observe::implementation new $logw $logr]
+}
+
+oo::class create ::tcl::transform::observe::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ method write {c data} {
+ if {$logw ne {}} {
+ puts -nonewline $logw $data
+ }
+ return $data
+ }
+
+ method read {c data} {
+ if {$logr ne {}} {
+ puts -nonewline $logr $data
+ }
+ return $data
+ }
+
+ # No partial data, nor state => no flush, drain, nor clear needed.
+
+ # # ## ### ##### ######## #############
+
+ constructor {lw lr} {
+ set logr $lr
+ set logw $lw
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable logr logw
+
+ # # ## ### ##### ######## #############
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::observe 1
+return
diff --git a/tcllib/modules/virtchannel_transform/otp.tcl b/tcllib/modules/virtchannel_transform/otp.tcl
new file mode 100644
index 0000000..e955ddd
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/otp.tcl
@@ -0,0 +1,98 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::otp 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta description Implementation of an onetimepad
+# Meta description encryption transformation. Based on Tcl
+# Meta description 8.6's transformation reflection support.
+# Meta description The key bytes are read from two channels
+# Meta description configured at construction time. Exports
+# Meta description a single command adding a new
+# Meta description transformation of this type to a channel.
+# Meta description Three arguments, the channel to extend,
+# Meta description plus the channels to read the keys from.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::otp {chan keychanw keychanr} {
+ ::chan push $chan [otp::implementation new $keychanw $keychanr]
+}
+
+oo::class create ::tcl::transform::otp::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ # This transformation is intended for streaming operation. Seeking
+ # the channel while it is active may cause undesirable
+ # output. Proper behaviour may require the destruction of the
+ # transform before seeking.
+
+ method write {c data} {
+ return [my Xor $data $keychanw]
+ }
+
+ method read {c data} {
+ return [my Xor $data $keychanr]
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {keyw keyr} {
+ set keychanr $keyr
+ set keychanw $keyw
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable keychanr keychanw
+
+ # # ## ### ##### ######## #############
+
+ # A very convoluted way to perform the XOR would be to use TIP
+ # #317's hex encoding to convert the bytes into strings, then zip
+ # key and data into an interleaved string (nibble wise), then
+ # perform the xor as a 'string map' of the whole thing, and at
+ # last 'binary decode hex' the string back into bytes. Even so
+ # most ops would run on the whole message at C level. Except for
+ # the interleave. :(
+
+ method Xor {data keychan} {
+ # xor is done byte-wise. to keep IO down we read the key bytes
+ # once, before the loop handling the bytes. Note that we are
+ # having binary data at this point, making it necessary to
+ # convert into numbers (scan), and back (binary format).
+
+ set keys [read $keychan [string length $data]]
+ set result {}
+ foreach d [split $data {}] k [split $keys {}] {
+ append result \
+ [binary format c \
+ [expr {
+ [scan $d %c] ^
+ [scan $k %c]
+ }]]
+ }
+ return $result
+ }
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::otp 1
+return
diff --git a/tcllib/modules/virtchannel_transform/pkgIndex.tcl b/tcllib/modules/virtchannel_transform/pkgIndex.tcl
new file mode 100644
index 0000000..604f1af
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/pkgIndex.tcl
@@ -0,0 +1,14 @@
+if {![package vsatisfies [package provide Tcl] 8.6]} {return}
+
+package ifneeded tcl::transform::adler32 1 [list source [file join $dir adler32.tcl]]
+package ifneeded tcl::transform::base64 1 [list source [file join $dir base64.tcl]]
+package ifneeded tcl::transform::counter 1 [list source [file join $dir counter.tcl]]
+package ifneeded tcl::transform::crc32 1 [list source [file join $dir crc32.tcl]]
+package ifneeded tcl::transform::hex 1 [list source [file join $dir hex.tcl]]
+package ifneeded tcl::transform::identity 1 [list source [file join $dir identity.tcl]]
+package ifneeded tcl::transform::limitsize 1 [list source [file join $dir limitsize.tcl]]
+package ifneeded tcl::transform::observe 1 [list source [file join $dir observe.tcl]]
+package ifneeded tcl::transform::otp 1 [list source [file join $dir otp.tcl]]
+package ifneeded tcl::transform::rot 1 [list source [file join $dir rot.tcl]]
+package ifneeded tcl::transform::spacer 1 [list source [file join $dir spacer.tcl]]
+package ifneeded tcl::transform::zlib 1.0.1 [list source [file join $dir zlib.tcl]]
diff --git a/tcllib/modules/virtchannel_transform/rot.man b/tcllib/modules/virtchannel_transform/rot.man
new file mode 100644
index 0000000..b64b395
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/rot.man
@@ -0,0 +1,57 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::rot n 1]
+[keywords {caesar cipher}]
+[keywords {channel transformation}]
+[keywords cipher]
+[keywords decryption]
+[keywords encryption]
+[keywords {reflected channel}]
+[keywords rot]
+[keywords rot13]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {rot-encryption}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::rot [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::rot] package provides a command creating
+a channel transformation which performs primitive encryption (on
+writing) and decryption (on reading) on the alphabetic characters. The
+algorithm is the Caesar-cipher, a specific variant of which is rot13.
+
+[para] A related transformations in this module is
+[package tcl::transform::otp].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::rot] [arg chan] [arg key]]
+
+This command creates a rot encryption transformation on top of the
+channel [arg chan] and returns its handle.
+
+[para] The "[arg key]" specifies how far characters are rotated in the
+alphabet, and is wrapped to the range "0...25".
+
+[para] Note that this transformation affects only bytes in the ranges
+ASCII 65...90, and 97...122, i.e. the upper- and lower-case alphabetic
+characters, i.e. "A...Z" and "a...z". All other bytes are passed
+through unchanged.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/rot.tcl b/tcllib/modules/virtchannel_transform/rot.tcl
new file mode 100644
index 0000000..c184da8
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/rot.tcl
@@ -0,0 +1,95 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::rot 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta description Implementation of a rot
+# Meta description encryption transformation. Based on Tcl
+# Meta description 8.6's transformation reflection support.
+# Meta description The key byte is
+# Meta description configured at construction time. Exports
+# Meta description a single command adding a new
+# Meta description transformation of this type to a channel.
+# Meta description Two arguments, the channel to extend,
+# Meta description plus the key byte.
+# Meta description No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::rot {chan key} {
+ ::chan push $chan [rot::implementation new $key]
+}
+
+oo::class create ::tcl::transform::rot::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ # This transformation is intended for streaming operation. Seeking
+ # the channel while it is active may cause undesirable
+ # output. Proper behaviour may require the destruction of the
+ # transform before seeking.
+
+ method write {c data} {
+ return [my Rot $data $key]
+ }
+
+ method read {c data} {
+ return [my Rot $data $ikey]
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {thekey} {
+ set key [expr {$thekey % 26}]
+ set ikey [expr {26 - $key}]
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable key ikey
+
+ # # ## ### ##### ######## #############
+
+ method Rot {data key} {
+ # rot'ation is done byte-wise. Note that we are having binary
+ # data at this point, making it necessary to convert into
+ # numbers (scan), and back (binary format).
+
+ set result {}
+ foreach d [split $data {}] {
+ set dx [scan $d %c]
+ if {(65 <= $dx) && ($dx <= 90)} {
+ set n [binary format c \
+ [expr { (($dx - 65 + $key) % 26) + 65 }]]
+ } elseif {(97 <= $dx) && ($dx <= 122)} {
+ set n [binary format c \
+ [expr { (($dx - 97 + $key) % 26) + 97 }]]
+ } else {
+ set n $d
+ }
+
+ append result $n
+
+ }
+ return $result
+ }
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::rot 1
+return
diff --git a/tcllib/modules/virtchannel_transform/spacer.man b/tcllib/modules/virtchannel_transform/spacer.man
new file mode 100644
index 0000000..febff22
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/spacer.man
@@ -0,0 +1,45 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::spacer n 1]
+[keywords {channel transformation}]
+[keywords {reflected channel}]
+[keywords spacing]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Space insertation and removal}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::spacer [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::spacer] package provides a command
+creating a channel transformation which adds spacing to the data
+written to it, and removes such spacing from the data read from it.
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::spacer] [arg chan] [arg n] [opt [arg space]]]
+
+This command creates a spacer transformation on top of the channel
+[arg chan] and returns its handle.
+
+[para] The [arg space] character sequence will be added every [arg n]
+bytes of data written, and on the read side the same is done in
+reverse, removing the spacing. If [arg space] is not specified it
+defaults to a single space character (ASCII 32).
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/spacer.tcl b/tcllib/modules/virtchannel_transform/spacer.tcl
new file mode 100644
index 0000000..5bcf4c0
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/spacer.tcl
@@ -0,0 +1,151 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::spacer 1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta description Implementation of a spacer
+# Meta description transformation, using Tcl 8.6's
+# Meta description transformation reflection support. Uses
+# Meta description counters to implement the transformation,
+# Meta description i.e. decide where to insert the spacing.
+# Meta description Exports a single command adding a new
+# Meta description transform of this type to a channel. One
+# Meta description argument, the channel to extend. No
+# Meta description result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::spacer {chan n {space { }}} {
+ ::chan push $chan [spacer::implementation new $n $space]
+ return
+}
+
+oo::class create ::tcl::transform::spacer::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ # This transformation is intended for streaming operation. Seeking
+ # the channel while it is active may cause undesirable
+ # output. Proper behaviour may require the destruction of the
+ # transform before seeking.
+
+ method write {c data} {
+ # add spacing, data is split into groups of delta chars.
+ set result {}
+ set len [string length $data]
+
+ if {$woffset} {
+ # The beginning of the buffer is the remainder of the
+ # partial group found at the end of the buffer in the last
+ # call. It may still be partial, if the current buffer is
+ # short enough.
+
+ if {($woffset + $len) < $delta} {
+ # Yes, the group is still not fully covered.
+ # Move the offset forward, and return the whole
+ # buffer. spacing is not needed yet.
+ incr woffset $len
+ return $data
+ }
+
+ # The buffer completes the group. Add it and the following
+ # spacing, then fix the offset to start the processing of
+ # the groups coming after at the proper location.
+
+ set stop [expr {$delta - $woffset - 1}]
+
+ append result [string range $data 0 $stop]
+ append result $spacing
+
+ set woffset $stop
+ incr woffset
+ }
+
+ # Process full groups in the middle of the incoming buffer.
+
+ set at $woffset
+ set stop [expr {$at + $delta - 1}]
+ while {$stop < $len} {
+ append result [string range $data $at $stop]
+ append result $spacing
+ incr at $delta
+ incr stop $delta
+ }
+
+ # Process partial group at the end of the buffer and remember
+ # the offset, for the processing of the group remainder in the
+ # next call.
+
+ if {($at < $len) && ($stop >= $len)} {
+ append result [string range $data $at end]
+ }
+ set woffset [expr {$len - $at}]
+ return $result
+ }
+
+ method read {c data} {
+ # remove spacing from groups of delta+sdelta chars, keeping
+ # the first delta in each group.
+ set result {}
+ set iter [expr {$delta + $sdelta}]
+ set at 0
+ if {$roffset} {
+ if {$roffset < $delta} {
+ append result [string range $data 0 ${roffset}-1]
+ }
+ incr at [expr {$iter - $roffset}]
+ }
+ set len [string length $data]
+ set end [expr {$at + $delta - 1}]
+ set stop [expr {$at + $iter - 1}]
+ while {$stop < $len} {
+ append result [string range $data $at $end]
+ incr at $iter
+ incr end $iter
+ incr stop $iter
+ }
+ if {$end < $len} {
+ append result [string range $data $at $end]
+ set roffset [expr {$len - $end + 1}]
+ } elseif {$at < $len} {
+ append result [string range $data $at end]
+ set roffset [expr {$len - $at}]
+ }
+ return [list $result $roffset]
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {n space} {
+ set roffset 0
+ set woffset 0
+ set delta $n
+ set spacing $space
+ set sdelta [string length $spacing]
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable roffset woffset delta spacing sdelta
+
+ # # ## ### ##### ######## #############
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::spacer 1
+return
diff --git a/tcllib/modules/virtchannel_transform/tcllib_zlib.man b/tcllib/modules/virtchannel_transform/tcllib_zlib.man
new file mode 100644
index 0000000..31b1a53
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/tcllib_zlib.man
@@ -0,0 +1,46 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::zlib n 1]
+[keywords {channel transformation}]
+[keywords compression]
+[keywords decompression]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords {tip 234}]
+[keywords transformation]
+[keywords {virtual channel}]
+[keywords zlib]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {zlib (de)compression}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::zlib [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::zlib] package provides a command creating
+a channel transformation which zlib compresses the written data, and
+decompresses on reading.
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::zlib] [arg chan] [opt [arg level]]]
+
+This command creates a zlib compressor transformation on top of the
+channel [arg chan] and returns its handle.
+
+[para] The [arg level] specifies how much effort is put into the
+compression, from [const 0] to [const 9], and defaults to [const 4].
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/vt_base64.man b/tcllib/modules/virtchannel_transform/vt_base64.man
new file mode 100644
index 0000000..224fe36
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/vt_base64.man
@@ -0,0 +1,44 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::base64 n 1]
+[keywords base64]
+[keywords {channel transformation}]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords {tip 317}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Base64 encoding transformation}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::base64 [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::base64] package provides a command
+creating a channel transformation which base64 encodes data written to
+it, and decodes the data read from it.
+
+[para] A related transformations in this module is
+[package tcl::transform::hex].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::base64] [arg chan]]
+
+This command creates a base64 transformation on top of the channel
+[arg chan] and returns its handle.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/vt_counter.man b/tcllib/modules/virtchannel_transform/vt_counter.man
new file mode 100644
index 0000000..d5ac201
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/vt_counter.man
@@ -0,0 +1,68 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::counter n 1]
+[keywords {channel transformation}]
+[keywords counter]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Counter transformation}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::counter [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::counterr] package provides a command
+creating a channel transformation which passes the read and written
+bytes through unchanged (like [package tcl::transform::identity]), but
+additionally counts the bytes it has seen for each direction and
+stores these counts in Tcl variables specified at construction time.
+
+[para] Related transformations in this module are
+[package tcl::transform::adler32],
+[package tcl::transform::crc32],
+[package tcl::transform::identity], and
+[package tcl::transform::observe].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::counter] [arg chan] [option -option] [arg value]...]
+
+This command creates a counter transformation on top of the channel
+[arg chan] and returns its handle. The accepted options are
+
+[list_begin options]
+[opt_def -read-variable varname]
+
+The value of the option is the name of a global or namespaced
+variable, the location where the transformation has to store the
+byte count of the data read from the channel.
+
+[para] If not specified, or the empty string, the counter of the read
+direction is not saved.
+
+[opt_def -write-variable varname]
+
+The value of the option is the name of a global or namespaced
+variable, the location where the transformation has to store the
+byte count of the data written to the channel.
+
+[para] If not specified, or the empty string, the counter of the
+write direction is not saved.
+
+[list_end]
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/vt_crc32.man b/tcllib/modules/virtchannel_transform/vt_crc32.man
new file mode 100644
index 0000000..6345ccc
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/vt_crc32.man
@@ -0,0 +1,70 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::crc32 n 1]
+[keywords {channel transformation}]
+[keywords checksum]
+[keywords crc32]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Crc32 transformation}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::crc32 [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::crc32] package provides a command
+creating a channel transformation which passes the read and written
+bytes through unchanged (like [package tcl::transform::identity]), but
+additionally continuously computes the crc32 checksums of the data it
+has seen for each direction and stores them in Tcl variables specified
+at construction time. The checksum in question is zlib's crc32.
+
+[para] Related transformations in this module are
+[package tcl::transform::adler32],
+[package tcl::transform::counter],
+[package tcl::transform::identity], and
+[package tcl::transform::observe].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::crc32] [arg chan] [option -option] [arg value]...]
+
+This command creates a crc32 checksumming transformation on top of
+the channel [arg chan] and returns its handle. The accepted options are
+
+[list_begin options]
+[opt_def -read-variable varname]
+
+The value of the option is the name of a global or namespaced
+variable, the location where the transformation has to store the
+crc32 checksum of the data read from the channel.
+
+[para] If not specified, or the empty string, the checksum of the read
+direction is not saved.
+
+[opt_def -write-variable varname]
+
+The value of the option is the name of a global or namespaced
+variable, the location where the transformation has to store the
+crc32 checksum of the data written to the channel.
+
+[para] If not specified, or the empty string, the checksum of the
+write direction is not saved.
+
+[list_end]
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/vt_otp.man b/tcllib/modules/virtchannel_transform/vt_otp.man
new file mode 100644
index 0000000..786a2d6
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/vt_otp.man
@@ -0,0 +1,53 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tcl::transform::otp n 1]
+[keywords {channel transformation}]
+[keywords cipher]
+[keywords decryption]
+[keywords encryption]
+[keywords {one time pad}]
+[keywords otp]
+[keywords {reflected channel}]
+[keywords {tip 230}]
+[keywords transformation]
+[keywords {virtual channel}]
+[keywords xor]
+[copyright {2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Reflected/virtual channel support}]
+[category Channels]
+[titledesc {Encryption via one-time pad}]
+[require Tcl 8.6]
+[require tcl::transform::core [opt 1]]
+[require tcl::transform::otp [opt 1]]
+[description]
+[para]
+
+The [package tcl::transform::otp] package provides a command creating
+a channel transformation which uses externally provided one-time pads
+to perform encryption (on writing) and decryption (on reading).
+
+[para] A related transformations in this module is
+[package tcl::transform::rot].
+
+[para] The internal [package TclOO] class implementing the transform
+handler is a sub-class of the [package tcl::transform::core]
+framework.
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd ::tcl::transform::otp] [arg chan] [arg keychanw] [arg keychanr]]
+
+This command creates a one-time pad based encryption transformation on
+top of the channel [arg chan] and returns its handle.
+
+[para] The two channels [arg keychanw] and [arg keychanr] contain the
+one-time pads for the write and read directions, respectively. Their
+contents are reads and xored with the bytes written to and read from
+the channel.
+
+[list_end]
+
+[vset CATEGORY virtchannel]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/virtchannel_transform/zlib.tcl b/tcllib/modules/virtchannel_transform/zlib.tcl
new file mode 100644
index 0000000..d7c244d
--- /dev/null
+++ b/tcllib/modules/virtchannel_transform/zlib.tcl
@@ -0,0 +1,100 @@
+# -*- tcl -*-
+# # ## ### ##### ######## #############
+# (C) 2009 Andreas Kupries
+
+# @@ Meta Begin
+# Package tcl::transform::zlib 1.0.1
+# Meta as::author {Andreas Kupries}
+# Meta as::copyright 2009
+# Meta as::license BSD
+# Meta as::notes Possibilities for extension: Currently
+# Meta as::notes the mapping between read/write and
+# Meta as::notes de/compression is fixed. Allow it to be
+# Meta as::notes configured at construction time.
+# Meta description Implementation of a zlib (de)compressor.
+# Meta description Based on Tcl 8.6's transformation
+# Meta description reflection support (TIP 230) and zlib
+# Meta description support (TIP 234). Compresses on write.
+# Meta description Exports a single command adding a new
+# Meta description transformation of this type to a channel.
+# Meta description Two arguments, the channel to extend,
+# Meta description and the compression level. No result.
+# Meta platform tcl
+# Meta require tcl::transform::core
+# Meta require {Tcl 8.6}
+# @@ Meta End
+
+# # ## ### ##### ######## #############
+
+package require Tcl 8.6
+package require tcl::transform::core
+
+# # ## ### ##### ######## #############
+
+namespace eval ::tcl::transform {}
+
+proc ::tcl::transform::zlib {chan {level 4}} {
+ ::chan push $chan [zlib::implementation new $level]
+ return
+}
+
+oo::class create ::tcl::transform::zlib::implementation {
+ superclass tcl::transform::core ;# -> initialize, finalize, destructor
+
+ # This transformation is intended for streaming operation. Seeking
+ # the channel while it is active may cause undesirable
+ # output. Proper behaviour may require the destruction of the
+ # transform before seeking.
+
+ method initialize {c mode} {
+ set compressor [zlib stream deflate -level $level]
+ set decompressor [zlib stream inflate]
+
+ next $c $mode
+ }
+
+ method finalize {c} {
+ $compressor close
+ $decompressor close
+
+ next $c
+ }
+
+ method write {c data} {
+ $compressor put $data
+ return [$compressor get]
+ }
+
+ method read {c data} {
+ $decompressor put $data
+ return [$decompressor get]
+ }
+
+ method flush {c} {
+ $compressor flush
+ return [$compressor get]
+ }
+
+ method drain {c} {
+ $decompressor flush
+ return [$decompressor get]
+ }
+
+ # # ## ### ##### ######## #############
+
+ constructor {thelevel} {
+ # Should validate input (level in (0 ...9))
+ set level $thelevel
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ variable level compressor decompressor
+
+ # # ## ### ##### ######## #############
+}
+
+# # ## ### ##### ######## #############
+package provide tcl::transform::zlib 1.0.1
+return