source: trunk/gui/scripts/utils.tcl @ 3177

Last change on this file since 3177 was 3177, checked in by mmc, 12 years ago

Updated all of the copyright notices to reference the transfer to
the new HUBzero Foundation, LLC.

File size: 5.2 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: utils - miscellaneous utilities
3#
4#  Misc routines used throughout the GUI.
5# ======================================================================
6#  AUTHOR:  Michael McLennan, Purdue University
7#  Copyright (c) 2004-2012  HUBzero Foundation, LLC
8#
9#  See the file "license.terms" for information on usage and
10#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11# ======================================================================
12namespace eval Rappture { # forward declaration }
13namespace eval Rappture::utils { # forward declaration }
14
15# ----------------------------------------------------------------------
16# USAGE: hexdump ?-lines num? <data>
17#
18# Returns a hex dump for a blob of binary <data>.  This is used to
19# represent the data in an input/output <string> object.  The -lines
20# flag can be used to limit the output to the specified number of
21# lines.
22# ----------------------------------------------------------------------
23proc Rappture::utils::hexdump {args} {
24    Rappture::getopts args params {
25        value -lines unlimited
26    }
27    if {[llength $args] != 1} {
28        error "wrong # args: should be \"hexdump ?-lines num? data\""
29    }
30    set newval [lindex $args 0]
31    set args ""
32
33    set rval "<binary> [Rappture::utils::binsize [string length $newval]]"
34
35    if {$params(-lines) != "unlimited" && $params(-lines) <= 0} {
36        return $rval
37    }
38
39    append rval "\n\n"
40    set len [string length $newval]
41    for {set i 0} {$i < $len} {incr i 8} {
42        append rval [format "%#06x: " $i]
43        set ascii ""
44        for {set j 0} {$j < 8} {incr j} {
45            if {$i+$j < $len} {
46                set char [string index $newval [expr {$i+$j}]]
47                binary scan $char c ichar
48                set hexchar [format "%02x" [expr {0xff & $ichar}]]
49            } else {
50                set char " "
51                set hexchar "  "
52            }
53            append rval "$hexchar "
54            if {[regexp {[\000-\037\177-\377]} $char]} {
55                append ascii "."
56            } else {
57                append ascii $char
58            }
59        }
60        append rval " | $ascii\n"
61
62        if {"unlimited" != $params(-lines) && $i/8+1 >= $params(-lines)} {
63            if {$i < $len-1} {
64                append rval "more..."
65            }
66            break
67        }
68    }
69    return $rval
70}
71
72# ----------------------------------------------------------------------
73# USAGE: binsize <length>
74#
75# Returns a user-friendly expression of data size, like "12 kB" or
76# "144 MB".
77# ----------------------------------------------------------------------
78proc Rappture::utils::binsize {size} {
79    foreach {factor units} {
80        1073741824 GB
81        1048576 MB
82        1024 kB
83        1 bytes
84    } {
85        if {$size/$factor > 0} {
86            if {$factor > 1} {
87                set size [format "%.1f" [expr {double($size)/$factor}]]
88            }
89            break
90        }
91    }
92    return "$size $units"
93}
94
95# ----------------------------------------------------------------------
96# USAGE: datatype <binary>
97#
98# Examines the given <binary> string and returns a description of
99# the data format.
100# ----------------------------------------------------------------------
101proc Rappture::utils::datatype {binary} {
102    set fileprog [auto_execok file]
103    if {[string length $binary] == 0} {
104        set desc "Empty"
105    } elseif {"" != $fileprog} {
106        #
107        # Use Unix "file" program to get info about type
108        # HACK ALERT! must send binary data in by creating a tmp file
109        #   or else it gets corrupted and misunderstood
110        #
111        set id [pid]
112        while {[file exists /tmp/datatype$id]} {
113            incr id
114        }
115        set fname "/tmp/datatype$id"
116        set fid [open $fname w]
117        fconfigure $fid -translation binary -encoding binary
118        puts -nonewline $fid [string range $binary 0 1024]
119        close $fid
120        if {[catch {exec $fileprog -b $fname} desc]} {
121            set desc "Binary data"
122        }
123        catch {file delete $fname}
124    } else {
125        set desc "Binary data"
126    }
127    return $desc
128}
129
130# ----------------------------------------------------------------------
131# USAGE: expandPath <path>
132#
133# Returns the true location of the provided path,
134# automatically expanding links to form an absolute path.
135# ----------------------------------------------------------------------
136proc Rappture::utils::expandPath {args} {
137    set path ""
138    set dirs [file split [lindex $args 0]]
139
140    while {[llength $dirs] > 0} {
141        set d [lindex $dirs 0]
142        set dirs [lrange $dirs 1 end]
143        if {[catch {file link [file join $path $d]} out] == 0} {
144            # directory d is a link, follow it
145            set outdirs [file split $out]
146            if {[string compare "/" [lindex $outdirs 0]] == 0} {
147                # directory leads back to root
148                # clear path
149                # reset dirs list
150                set path ""
151                set dirs $outdirs
152            } else {
153                # relative path for the link
154                # prepend directory to dirs list
155                set dirs [concat $outdirs $dirs]
156            }
157        } else {
158            set path [file join $path $d]
159        }
160    }
161    return $path
162}
163
Note: See TracBrowser for help on using the repository browser.