Index: xotcl/library/comm/Mime.xotcl =================================================================== diff -u -rf7894d9be99a8da3a04218abcdb9bd46b6d625c8 -r435b41481fb51bf000ebe736d8574fefbeec1710 --- xotcl/library/comm/Mime.xotcl (.../Mime.xotcl) (revision f7894d9be99a8da3a04218abcdb9bd46b6d625c8) +++ xotcl/library/comm/Mime.xotcl (.../Mime.xotcl) (revision 435b41481fb51bf000ebe736d8574fefbeec1710) @@ -1,233 +1,239 @@ -# $Id: Mime.xotcl,v 1.1 2004/05/23 22:50:39 neumann Exp $ +# $Id: Mime.xotcl,v 1.2 2005/09/09 21:07:23 neumann Exp $ + package provide xotcl::comm::mime 0.9 -####################################################################### -Class MimeTypeLoader -MimeTypeLoader instproc loadMimeTypes {file} { - if {![file exists $file]} return +package require XOTcl - puts stderr "Loading Mime types from $file" - set f [open $file r] - set content [read $f] - close $f - regsub -all "\\\\ *\n" $content " " content - foreach line [split $content \n] { - set line [string trim $line] - if {[regexp ^\# $line]} continue - if {$line == ""} continue - regsub -all " +" $line " " line - #puts stderr <$line> - while {$line != ""} { - if {[regexp {^ *([^ ]+)=\"([^\"]+)\" *(.*)$} $line _ key value line]} { - set v([string tolower $key]) $value - } elseif {[regexp {^ *([^ ]+)=([^ ]+) *(.*)$} $line _ key value line]} { - set v([string tolower $key]) $value - } else { - set tokens [split $line] - if {![regexp / [lindex $line 0]]} { - puts stderr "Mime: cannot parse line '$line' in $file" +namespace eval ::xotcl::comm::mime { + namespace import ::xotcl::* + + ####################################################################### + Class MimeTypeLoader + MimeTypeLoader instproc loadMimeTypes {file} { + if {![file exists $file]} return + + puts stderr "Loading Mime types from $file" + set f [open $file r] + set content [read $f] + close $f + regsub -all "\\\\ *\n" $content " " content + foreach line [split $content \n] { + set line [string trim $line] + if {[regexp ^\# $line]} continue + if {$line == ""} continue + regsub -all " +" $line " " line + #puts stderr <$line> + while {$line != ""} { + if {[regexp {^ *([^ ]+)=\"([^\"]+)\" *(.*)$} $line _ key value line]} { + set v([string tolower $key]) $value + } elseif {[regexp {^ *([^ ]+)=([^ ]+) *(.*)$} $line _ key value line]} { + set v([string tolower $key]) $value } else { - set v(exts) [join [lrange $tokens 1 end] ,] - set v(type) [lindex $tokens 0] + set tokens [split $line] + if {![regexp / [lindex $line 0]]} { + puts stderr "Mime: cannot parse line '$line' in $file" + } else { + set v(exts) [join [lrange $tokens 1 end] ,] + set v(type) [lindex $tokens 0] + } + break } - break } + if {[info exists v(exts)] && [info exists v(type)]} { + set v(exts) [string tolower $v(exts)] + set v(type) [string tolower $v(type)] + foreach ext [split $v(exts) ,] { + set ext [string trimleft $ext .] + #puts stderr "ext '$ext', contentType = '$v(type)'" + my set extTable($ext) $v(type) + } + unset v(exts) v(type) + } else { + puts stderr "invalid mime entry in $file" + } + } + } + MimeTypeLoader instproc guessContentType {name} { + my loadMimeTypes ~/.mime.types + my mixin {} + return [next] + } + + Class MIME + MIME instproc guessContentType {name} { + my instvar extTable nameTable + if {[regexp {\.([a-zA-Z0-9]+)$} $name _ ext]} { + catch {set contentType $extTable([string tolower $ext])} } - if {[info exists v(exts)] && [info exists v(type)]} { - set v(exts) [string tolower $v(exts)] - set v(type) [string tolower $v(type)] - foreach ext [split $v(exts) ,] { - set ext [string trimleft $ext .] - #puts stderr "ext '$ext', contentType = '$v(type)'" - my set extTable($ext) $v(type) + if {![info exists contentType]} { + foreach namePattern [array names nameTable] { + if {[regexp $namePattern $name]} { + set contentType text/plain + break + } } - unset v(exts) v(type) - } else { - puts stderr "invalid mime entry in $file" } - } -} -MimeTypeLoader instproc guessContentType {name} { - my loadMimeTypes ~/.mime.types - my mixin {} - return [next] -} - -Class MIME -MIME instproc guessContentType {name} { - my instvar extTable nameTable - if {[regexp {\.([a-zA-Z0-9]+)$} $name _ ext]} { - catch {set contentType $extTable([string tolower $ext])} + if {![info exists contentType]} { + set contentType unknown/unknown + } + return $contentType } - if {![info exists contentType]} { - foreach namePattern [array names nameTable] { - if {[regexp $namePattern $name]} { - set contentType text/plain - break + MIME instproc multipart-decode-header {header obj} { + $obj instvar name filename contentType + foreach line [split $header \r] { + set line [string trim $line \n] + #puts stderr line=$line + if {[regexp -nocase {^Content-Disposition: *([^;]+);(.*)$} $line _ \ + dispo detail]} { + if {$dispo != "form-data"} { + error "Unknown Content Disposition '$line'" + } + if {![regexp -nocase { name *= *"([^\"]+)"} $line _ name]} { + error "can't parse form-data name '$line'" + } + regexp -nocase {filename *= *"([^\"]+)"} $line _ filename + } elseif {[regexp -nocase {^Content-Type: *([^; ]+)} $line _ contentType]} { + } else { + my showMsg "ignoring '$line'" } } } - if {![info exists contentType]} { - set contentType unknown/unknown + + MIME create Mime -mixin MimeTypeLoader + Mime array set nameTable { + README text/plain } - return $contentType -} -MIME instproc multipart-decode-header {header obj} { - $obj instvar name filename contentType - foreach line [split $header \r] { - set line [string trim $line \n] - #puts stderr line=$line - if {[regexp -nocase {^Content-Disposition: *([^;]+);(.*)$} $line _ \ - dispo detail]} { - if {$dispo != "form-data"} { - error "Unknown Content Disposition '$line'" - } - if {![regexp -nocase { name *= *"([^\"]+)"} $line _ name]} { - error "can't parse form-data name '$line'" - } - regexp -nocase {filename *= *"([^\"]+)"} $line _ filename - } elseif {[regexp -nocase {^Content-Type: *([^; ]+)} $line _ contentType]} { - } else { - my showMsg "ignoring '$line'" - } + Mime array set extTable { + gif image/gif + xpm image/x-xpixmap + xbm image/x-xbitmap + jpg image/jpeg + png image/x-png + html text/html + htm text/html + xml text/xml + css text/css + ps application/postscript + pdf application/pdf + doc application/msword + xls application/msexel } -} -MIME Mime -mixin MimeTypeLoader -Mime array set nameTable { - README text/plain -} -Mime array set extTable { - gif image/gif - xpm image/x-xpixmap - xbm image/x-xbitmap - jpg image/jpeg - png image/x-png - html text/html - htm text/html - xml text/xml - css text/css - ps application/postscript - pdf application/pdf - doc application/msword - xls application/msexel -} - -################################################################## -Class FormData -FormData instproc encode list {;#RFC 1867 - my showCall -} -FormData formData -################################################################## -Class Base64 -Base64 instproc init args { - my instvar base64 base64_en - # Emit base64 encoding for a string - set i 0 - foreach char {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \ - a b c d e f g h i j k l m n o p q r s t u v w x y z \ - 0 1 2 3 4 5 6 7 8 9 + /} { - set base64($char) $i - set base64_en($i) $char - incr i + ################################################################## + Class FormData + FormData instproc encode list {;#RFC 1867 + my showCall } - next -} -Base64 instproc encode string { - my instvar base64_en - set result {} - set length 0 - foreach {a b c} [split $string {}] { - scan $a %c x - if {$c != ""} { - scan $b %c y - scan $c %c z - append result \ - $base64_en([expr {($x>>2) & 0x3F}]) \ - $base64_en([expr {(($x<<4) & 0x30) | (($y>>4) & 0xF)}]) \ - $base64_en([expr {(($y<<2) & 0x3C) | (($z>>6) & 0x3)}]) \ - $base64_en([expr {$z & 0x3F}]) - } elseif {$b != ""} { - scan $b %c y - append result \ - $base64_en([expr {($x>>2) & 0x3F}]) \ - $base64_en([expr {(($x<<4) & 0x30) | (($y>>4) & 0xF)}]) \ - $base64_en([expr {($y<<2) & 0x3C}]) \ - = - } else { - append result \ - $base64_en([expr {($x>>2) & 0x3F}]) \ - $base64_en([expr {($x<<4) & 0x30}]) \ - == + FormData formData + ################################################################## + Class Base64 + Base64 instproc init args { + my instvar base64 base64_en + # Emit base64 encoding for a string + set i 0 + foreach char {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \ + a b c d e f g h i j k l m n o p q r s t u v w x y z \ + 0 1 2 3 4 5 6 7 8 9 + /} { + set base64($char) $i + set base64_en($i) $char + incr i } - if {[incr length 4] >= 72} { - append result \n - set length 0 - } + next } - return $result -} -Base64 instproc decode string { - my instvar base64 - set output {} - set group 0 - set j 18 - foreach char [split $string {}] { - if {$char != "="} { - set group [expr {$group | ($base64($char) << $j)}] - if {[incr j -6] < 0} { - scan [format %06x $group] %2x%2x%2x a b c - append output [format %c%c%c $a $b $c] - set group 0 - set j 18 - } - } else { - scan [format %04x $group] %2x%2x a b - if {$j==6} { - append output [format %c $a] + Base64 instproc encode string { + my instvar base64_en + set result {} + set length 0 + foreach {a b c} [split $string {}] { + scan $a %c x + if {$c != ""} { + scan $b %c y + scan $c %c z + append result \ + $base64_en([expr {($x>>2) & 0x3F}]) \ + $base64_en([expr {(($x<<4) & 0x30) | (($y>>4) & 0xF)}]) \ + $base64_en([expr {(($y<<2) & 0x3C) | (($z>>6) & 0x3)}]) \ + $base64_en([expr {$z & 0x3F}]) + } elseif {$b != ""} { + scan $b %c y + append result \ + $base64_en([expr {($x>>2) & 0x3F}]) \ + $base64_en([expr {(($x<<4) & 0x30) | (($y>>4) & 0xF)}]) \ + $base64_en([expr {($y<<2) & 0x3C}]) \ + = } else { - append output [format %c%c $a $b] + append result \ + $base64_en([expr {($x>>2) & 0x3F}]) \ + $base64_en([expr {($x<<4) & 0x30}]) \ + == } - break + if {[incr length 4] >= 72} { + append result \n + set length 0 + } } + return $result } - return $output -} -Base64 base64 -################################################################## -Class Url -Url instproc encode list { - set result "" - set sep "" - foreach i $list { - append result $sep [my encodeItem $i] - if {$sep != "="} { - set sep = - } else { - set sep & + Base64 instproc decode string { + my instvar base64 + set output {} + set group 0 + set j 18 + foreach char [split $string {}] { + if {$char != "="} { + set group [expr {$group | ($base64($char) << $j)}] + if {[incr j -6] < 0} { + scan [format %06x $group] %2x%2x%2x a b c + append output [format %c%c%c $a $b $c] + set group 0 + set j 18 + } + } else { + scan [format %04x $group] %2x%2x a b + if {$j==6} { + append output [format %c $a] + } else { + append output [format %c%c $a $b] + } + break + } } + return $output } - return $result -} -Url instproc encodeItem string { - my instvar httpFormMap - set alphanumeric a-zA-Z0-9. - if {![info exists httpFormMap]} { - for {set i 1} {$i <= 256} {incr i} { - set c [format %c $i] - if {![string match \[$alphanumeric\] $c]} { - set httpFormMap($c) %[format %.2x $i] + Base64 base64 + ################################################################## + Class Url + Url instproc encode list { + set result "" + set sep "" + foreach i $list { + append result $sep [my encodeItem $i] + if {$sep != "="} { + set sep = + } else { + set sep & } } - # these are handled specially - array set httpFormMap { " " + \n %0d%0a } + return $result } - regsub -all \[^$alphanumeric\] $string {$httpFormMap(&)} string - regsub -all \n $string {\\n} string - regsub -all \t $string {\\t} string - regsub -all {[][{})\\]\)} $string {\\&} string + Url instproc encodeItem string { + my instvar httpFormMap + set alphanumeric a-zA-Z0-9. + if {![info exists httpFormMap]} { + for {set i 1} {$i <= 256} {incr i} { + set c [format %c $i] + if {![string match \[$alphanumeric\] $c]} { + set httpFormMap($c) %[format %.2x $i] + } + } + # these are handled specially + array set httpFormMap { " " + \n %0d%0a } + } + regsub -all \[^$alphanumeric\] $string {$httpFormMap(&)} string + regsub -all \n $string {\\n} string + regsub -all \t $string {\\t} string + regsub -all {[][{})\\]\)} $string {\\&} string return [subst $string] } Url instproc hexToChar hex { @@ -260,3 +266,9 @@ return $result } Url url + +namespace export Mime url base64 +} + +namespace import ::xotcl::comm::mime::* +#puts stderr "importing ::xotcl::comm::mime::* to [namespace current]"