home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 5 / hacker05 / 05_HACK_05.ISO / programacao / freewrap / TCLLIBsampleApp.exe / sample / tcllib / tcllib1.0 / struct / queue.tcl < prev    next >
Encoding:
Text File  |  2001-08-17  |  5.2 KB  |  237 lines

  1. # queue.tcl --
  2. #
  3. #    Queue implementation for Tcl.
  4. #
  5. # Copyright (c) 1998-2000 by Ajuba Solutions.
  6. #
  7. # See the file "license.terms" for information on usage and redistribution
  8. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  9. # RCS: @(#) $Id: queue.tcl,v 1.3 2000/06/02 18:43:56 ericm Exp $
  10.  
  11. namespace eval ::struct {}
  12.  
  13. namespace eval ::struct::queue {
  14.     # The queues array holds all of the queues you've made
  15.     variable queues
  16.     
  17.     # counter is used to give a unique name for unnamed queues
  18.     variable counter 0
  19.  
  20.     # commands is the list of subcommands recognized by the queue
  21.     variable commands [list \
  22.         "clear"    \
  23.         "destroy"    \
  24.         "get"    \
  25.         "peek"    \
  26.         "put"    \
  27.         "size"    \
  28.         ]
  29.  
  30.     # Only export one command, the one used to instantiate a new queue
  31.     namespace export queue
  32. }
  33.  
  34. # ::struct::queue::queue --
  35. #
  36. #    Create a new queue with a given name; if no name is given, use
  37. #    queueX, where X is a number.
  38. #
  39. # Arguments:
  40. #    name    name of the queue; if null, generate one.
  41. #
  42. # Results:
  43. #    name    name of the queue created
  44.  
  45. proc ::struct::queue::queue {{name ""}} {
  46.     variable queues
  47.     variable counter
  48.     
  49.     if { [llength [info level 0]] == 1 } {
  50.     incr counter
  51.     set name "queue${counter}"
  52.     }
  53.  
  54.     if { ![string equal [info commands ::$name] ""] } {
  55.     error "command \"$name\" already exists, unable to create queue"
  56.     }
  57.  
  58.     # Initialize the queue as empty
  59.     set queues($name) [list ]
  60.  
  61.     # Create the command to manipulate the queue
  62.     interp alias {} ::$name {} ::struct::queue::QueueProc $name
  63.  
  64.     return $name
  65. }
  66.  
  67. ##########################
  68. # Private functions follow
  69.  
  70. # ::struct::queue::QueueProc --
  71. #
  72. #    Command that processes all queue object commands.
  73. #
  74. # Arguments:
  75. #    name    name of the queue object to manipulate.
  76. #    args    command name and args for the command
  77. #
  78. # Results:
  79. #    Varies based on command to perform
  80.  
  81. proc ::struct::queue::QueueProc {name {cmd ""} args} {
  82.     # Do minimal args checks here
  83.     if { [llength [info level 0]] == 2 } {
  84.     error "wrong # args: should be \"$name option ?arg arg ...?\""
  85.     }
  86.     
  87.     # Split the args into command and args components
  88.     if { [string equal [info commands ::struct::queue::_$cmd] ""] } {
  89.     variable commands
  90.     set optlist [join $commands ", "]
  91.     set optlist [linsert $optlist "end-1" "or"]
  92.     error "bad option \"$cmd\": must be $optlist"
  93.     }
  94.     return [eval [list ::struct::queue::_$cmd $name] $args]
  95. }
  96.  
  97. # ::struct::queue::_clear --
  98. #
  99. #    Clear a queue.
  100. #
  101. # Arguments:
  102. #    name    name of the queue object.
  103. #
  104. # Results:
  105. #    None.
  106.  
  107. proc ::struct::queue::_clear {name} {
  108.     variable queues
  109.     set queues($name) [list ]
  110.     return
  111. }
  112.  
  113. # ::struct::queue::_destroy --
  114. #
  115. #    Destroy a queue object by removing it's storage space and 
  116. #    eliminating it's proc.
  117. #
  118. # Arguments:
  119. #    name    name of the queue object.
  120. #
  121. # Results:
  122. #    None.
  123.  
  124. proc ::struct::queue::_destroy {name} {
  125.     variable queues
  126.     unset queues($name)
  127.     interp alias {} ::$name {}
  128.     return
  129. }
  130.  
  131. # ::struct::queue::_get --
  132. #
  133. #    Get an item from a queue.
  134. #
  135. # Arguments:
  136. #    name    name of the queue object.
  137. #    count    number of items to get; defaults to 1
  138. #
  139. # Results:
  140. #    item    first count items from the queue; if there are not enough 
  141. #        items in the queue, throws an error.
  142.  
  143. proc ::struct::queue::_get {name {count 1}} {
  144.     variable queues
  145.     if { $count < 1 } {
  146.     error "invalid item count $count"
  147.     }
  148.  
  149.     if { $count > [llength $queues($name)] } {
  150.     error "insufficient items in queue to fill request"
  151.     }
  152.  
  153.     if { $count == 1 } {
  154.     # Handle this as a special case, so single item gets aren't listified
  155.     set item [lindex $queues($name) 0]
  156.     set queues($name) [lreplace $queues($name) 0 0]
  157.     return $item
  158.     }
  159.  
  160.     # Otherwise, return a list of items
  161.     set index [expr {$count - 1}]
  162.     set result [lrange $queues($name) 0 $index]
  163.     set queues($name) [lreplace $queues($name) 0 $index]
  164.  
  165.     return $result
  166. }
  167.  
  168. # ::struct::queue::_peek --
  169. #
  170. #    Retrive the value of an item on the queue without removing it.
  171. #
  172. # Arguments:
  173. #    name    name of the queue object.
  174. #    count    number of items to peek; defaults to 1
  175. #
  176. # Results:
  177. #    items    top count items from the queue; if there are not enough items
  178. #        to fufill the request, throws an error.
  179.  
  180. proc ::struct::queue::_peek {name {count 1}} {
  181.     variable queues
  182.     if { $count < 1 } {
  183.     error "invalid item count $count"
  184.     }
  185.  
  186.     if { $count > [llength $queues($name)] } {
  187.     error "insufficient items in queue to fill request"
  188.     }
  189.  
  190.     if { $count == 1 } {
  191.     # Handle this as a special case, so single item pops aren't listified
  192.     return [lindex $queues($name) 0]
  193.     }
  194.  
  195.     # Otherwise, return a list of items
  196.     set index [expr {$count - 1}]
  197.     return [lrange $queues($name) 0 $index]
  198. }
  199.  
  200. # ::struct::queue::_put --
  201. #
  202. #    Put an item into a queue.
  203. #
  204. # Arguments:
  205. #    name    name of the queue object
  206. #    args    items to put.
  207. #
  208. # Results:
  209. #    None.
  210.  
  211. proc ::struct::queue::_put {name args} {
  212.     variable queues
  213.     if { [llength $args] == 0 } {
  214.     error "wrong # args: should be \"$name put item ?item ...?\""
  215.     }
  216.     foreach item $args {
  217.     lappend queues($name) $item
  218.     }
  219.     return
  220. }
  221.  
  222. # ::struct::queue::_size --
  223. #
  224. #    Return the number of objects on a queue.
  225. #
  226. # Arguments:
  227. #    name    name of the queue object.
  228. #
  229. # Results:
  230. #    count    number of items on the queue.
  231.  
  232. proc ::struct::queue::_size {name} {
  233.     variable queues
  234.     return [llength $queues($name)]
  235. }
  236.