Version 1 of tcl::chan::join

Updated 2019-03-25 22:53:05 by ABU

tcl::chan::join 1.0 Reflected/virtual channel support

Concatenation channel

SYNOPSIS

package require Tcl 8.5

package require TclOO

package require tcl::chan::empty ?1?

package require tcl::chan::join ?1.0?

  • ::tcl::chan::join ?chan?...

DESCRIPTION

The tcl::chan::join package provides a command creating a read-only concatenation channel much like the tcl::chan::cat command. Unlike tcl::chan::cat, a channel created with tcl::chan::join supports random.access, i.e. the seek and tell commands. Note that if any of the sub-channels does not support random-access (seeking) the join-channel won't support seeking too, and it will be usable only as a sequential, read-only channel. The created channel takes ownership of the sub-channels they were constructed with. Closing the join-channel will close all its sub-channels. For the above rule, a join-channel may be built using the same subchannel more times,

 set subch [open "fileA.txt" rb]
 set jch  [tcl::chan::join $subch $subch $subch]  ;#  join $subch 3 times

but sharing the same sub-channel among two join-channels may produce unexpected results when one of the join-channels is closed, leaving the other join-channel with a closed subchannel.

 package require tcl::chan::string
 
 set subch [tcl::chan::string "0123456789"] ;# or open a true file ...
 set jch1  [tcl::chan::join $subch]  ;#  jch1 'owns' subch
 set jch2  [tcl::chan::join $subch]  ;#  jch2 is going to use a subchannel owned by another channel;
                                     ;#    this is not an error, but the beginning of chaos ...
 set res1 [read $jch1 4]             ;#  expected "0123" --> "0123"
 set res1 [read $jch1 4]             ;#  expected "3567" --> "3567"
 set res2 [read $jch2 4]             ;#  expected "0123" --> ""    ???? first unexpected result ..
 close $jch2                         ;#  by closing jch2, all its subchannels will be closed. (!including the shared subchannel!)
 set res1 [read $jch1 4]             ;#  expected "89" --> error : cannot find channel named xxx (the subchannel name)" 

API

::tcl::chan::join ?chan?...
This command creates a read-only, random-access channel, joining all the provided channels, and returns its handle.

Examples

Premise: Altough not indispensable per-se, the presence of the official tcl::chan::* commands of the official Tcllib suite, such as tcl::chan:string, is strongly recommended for composing channels like shown in the following examples.

WARNING : Many Tcl distributions still provide Tcllib 1.18. You need Tcllib 1.19, and in particular tcl::chan::string 1.0.3 (version 1.0.2 has a serious bug about the size of 'string' channels)

  • Get the overall size of a channel
 package require tcl::chan::string
 
 set subch1 [tcl::chan::string "0123456789"]
 set subch2 [tcl::chan::string "ABCDEFGHIJ"]
 set jch  [tcl::chan::join $subch1 $subch2]
 chan seek $jch 0 end
 set nBytes [chan tell $jch]   ;#  --> 20
  • Join the same subchannel more times. Let's suppose we have 3 big files that must be joined, interleaved with a fixed separator ...
 # be fd1, fd2, fd3   three channelID
 set chSep [tcl::chan::string "-----separator------"]
 set jch  [tcl::chan::join $fd1 $chSep $fd2 $chSep $fd3]
  • Join nothing. This may seem a pathological case, but it's legal to create an empty channel!
 set jch  [tcl::chan::join]                ;# !no subchannels !
 if { [eof $jch] } { puts "EOF reached"}   ;# --> .. nothing
 set contents [read $jch]
 puts "contents: \"$contents\""            ;# --> contents: ""
 if { [eof $jch] } { puts "EOF reached"}   ;# --> "EOF reached"
  • Dealing with errors. Usually when a join-channel is closed, all its sub-channels are closed. Note that if a join-channel fails at creation-time, its sub-channels won't be closed.
 set subch1 [tcl::chan::string "0123456789"]
 set subch2 "fakeChannel
 set subch3 [tcl::chan::string "ABCDEFGHIJ"]
 set jch  [tcl::chan::join $subch1 $subch2 $subch2] ;#  -->  error: can not find channel named "fakeChannel"
 ...
 # ....  $subch1 and $subch2  are still open valid channelID

KEYWORDS

concatenation channel, reflected channel, tip 219, virtual channel

CATEGORY

Channels

COPYRIGHT

 Copyright (c) 2019 Aldo Buratti <[email protected]>
 based on tcl::chan::cat by Andreas Kupries