diff options
Diffstat (limited to 'tcllib/modules/virtchannel_transform')
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 |