⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgin.tcl

📁 用于TCL/TK的可视化集成开发环境.(GUI)
💻 TCL
📖 第 1 页 / 共 3 页
字号:
      set fcn $fname      set amatch ""    }    pg_select $db "select oid from pg_proc where proname='$fcn' $amatch" d {      set fnoids($fname) $d(oid)    }    if {![info exists fnoids($fname)]} {      error "Unable to get OID of database function $fname"    }  }  return $fnoids($fname)}# Internal procedure to implement PostgreSQL "fast-path" function calls.# $fn_oid is the OID of the PostgreSQL function. See pgtcl::getfnoid.# $result_name is the name of the variable to store the backend function#   result into.# $arginfo is a list of argument descriptors, each is I or S or a number.#   I means the argument is an integer32.#   S means the argument is a string, and its actual length is used.#   A number means send exactly that many bytes (null-pad if needed) from# the argument.# $arglist  is a list of arguments to the PostgreSQL function. (This#    is actually a pass-through argument 'args' from the wrappers.)# Throws Tcl error on error, otherwise returns size of the result# stored into the $result_name variable.proc pgtcl::callfn {db fn_oid result_name arginfo arglist} {  upvar $result_name result  set nargs [llength $arginfo]  if {$pgtcl::debug} {    puts "+callfn oid=$fn_oid nargs=$nargs info=$arginfo args=$arglist"  }  # Function call: F " " oid argcount {arglen arg}...  set out [binary format a2xII {F } $fn_oid $nargs]  foreach k $arginfo arg $arglist {    if {$k == "I"} {      append out [binary format II 4 $arg]    } elseif {$k == "S"} {      append out [binary format I [string length $arg]] $arg    } else {      append out [binary format Ia$k $k $arg]    }  }  puts -nonewline $db $out  set result {}  set result_size 0  # Fake up a partial result structure for pgtcl::common_message :  set res(error) ""  # Function response: VG...0 (OK, data); V0 (OK, null) or E or ...  # Also handles common messages (notify, notice).  while {[set c [read $db 1]] != "Z"} {    if {$c == "V"} {      set c2 [read $db 1]      if {$c2 == "G"} {        binary scan [read $db 4] I result_size        set result [read $db $result_size]        set c2 [read $db 1]      }      if {$c2 != "0"} {        error "Unexpected reply from database: V$c2"      }    } elseif {![pgtcl::common_message $c $db res]} {      error "Unexpected reply from database: $c"    }  }  if {$res(error) != ""} {    error $res(error)  }  return $result_size}# Public interface to pgtcl::callfn.proc pg_callfn {db fname result_name arginfo args} {  upvar $result_name result  return [pgtcl::callfn $db [pgtcl::getfnoid $db $fname] result $arginfo $args]}# Public, simplified interface to pgtcl::callfn when an int32 return value is# expected. Returns the backend function return value.proc pg_callfn_int {db fname arginfo args} {  set n [pgtcl::callfn $db [pgtcl::getfnoid $db $fname] result $arginfo $args]  if {$n != 4} {     error "Unexpected response size ($result_size) to pg function call $fname"  }  binary scan $result I val  return $val}# Convert a LO mode string into the value of the constants used by libpq.# Note: libpgtcl uses a mode like INV_READ|INV_WRITE for lo_creat, but# r, w, or rw for lo_open (which it translates to INV_READ|INV_WRITE).# This seems like a mistake. The code here accepts either form for either.proc pgtcl::lomode {mode} {  set imode 0  if {[string match -nocase *INV_* $mode]} {    if {[string match -nocase *INV_READ* $mode]} {      set imode 0x40000    }    if {[string match -nocase *INV_WRITE* $mode]} {      set imode [expr {$imode + 0x20000}]    }  } else {    if {[string match -nocase *r* $mode]} {      set imode 0x40000    }    if {[string match -nocase *w* $mode]} {      set imode [expr {$imode + 0x20000}]    }  }  if {$imode == 0} {    error "pgtcl: Invalid large object mode $mode"  }  return $imode}# Create large object and return OID.# See note regarding mode above at pgtcl::lomode.proc pg_lo_creat {db mode} {  return [pg_callfn_int $db lo_creat I [pgtcl::lomode $mode]]}# Open large object and return large object file descriptor.# See note regarding mode above at pgtcl::lomode.proc pg_lo_open {db loid mode} {  return [pg_callfn_int $db lo_open "I I" $loid [pgtcl::lomode $mode]]}# Close large object file descriptor.proc pg_lo_close {db lofd} {  return [pg_callfn_int $db lo_close I $lofd]}# Delete large object:proc pg_lo_unlink {db loid} {  return [pg_callfn_int $db lo_unlink I $loid]}# Read from large object.proc pg_lo_read {db lofd buf_name maxlen} {  upvar $buf_name buf  return [pg_callfn $db loread buf "I I" $lofd $maxlen]}# Write to large object. At most $len bytes are written.proc pg_lo_write {db lofd buf len} {  if {[set buflen [string length $buf]] < $len} {    set len $buflen  }  return [pg_callfn_int $db lowrite "I $len" $lofd $buf]}# Seek to offset inside large object:proc pg_lo_lseek {db lofd offset whence} {  switch $whence {    SEEK_SET { set iwhence 0 }    SEEK_CUR { set iwhence 1 }    SEEK_END { set iwhence 2 }    default { error "Invalid whence argument ($whence) in pg_lo_lseek" }  }  return [pg_callfn_int $db lo_lseek "I I I" $lofd $offset $iwhence]}# Return location of file offset in large object:proc pg_lo_tell {db lofd} {  return [pg_callfn_int $db lo_tell I $lofd]}# Import large object. Wrapper for lo_creat, lo_open, lo_write.# Returns Large Object OID, which should be stored in a table somewhere.proc pg_lo_import {db filename} {  set f [open $filename]  fconfigure $f -translation binary  set loid [pg_lo_creat $db INV_READ|INV_WRITE]  set lofd [pg_lo_open $db $loid w]  while {1} {    set buf [read $f 32768]    if {[set len [string length $buf]] == 0} break    if {[pg_lo_write $db $lofd $buf $len] != $len} {      error "pg_lo_import failed to write $len bytes"    }  }  pg_lo_close $db $lofd  close $f  return $loid}# Export large object. Wrapper for lo_open, lo_read.proc pg_lo_export {db loid filename} {  set f [open $filename w]  fconfigure $f -translation binary  set lofd [pg_lo_open $db $loid r]  while {[set len [pg_lo_read $db $lofd buf 32768]] > 0} {    puts -nonewline $f $buf  }  pg_lo_close $db $lofd  close $f}# ===== MD5 Checksum ====# Coded in Tcl by ljb <lbayuk@mindspring.com>, using these sources:#  RFC1321#  PostgreSQL: src/backend/libpq/md5.c# If you want a better/faster MD5 implementation, see tcllib.namespace eval md5 { }# Round 1 helper, e.g.:#   a = b + ROT_LEFT((a + F(b, c, d) + X[0] + 0xd76aa478), 7)#       p1            p2    p1 p3 p4   p5        p6        p7# Where F(x,y,z) = (x & y) | (~x & z)#proc md5::round1 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p1 & $p3 | ~$p1 & $p4) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Round 2 helper, e.g.:#   a = b + ROT_LEFT((a + G(b, c, d) + X[1] + 0xf61e2562), 5)#       p1            p2    p1 p3 p4   p5        p6        p7# Where G(x,y,z) = (x & z) | (y & ~z)#proc md5::round2 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p1 & $p4 | $p3 & ~$p4) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Round 3 helper, e.g.:#   a = b + ROT_LEFT((a + H(b, c, d) + X[5] + 0xfffa3942), 4)#       p1            p2    p1 p3 p4   p5     p6           p7# Where H(x, y, z) = x ^ y ^ z#proc md5::round3 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p1 ^ $p3 ^ $p4) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Round 4 helper, e.g.:#   a = b + ROT_LEFT((a + I(b, c, d) + X[0] + 0xf4292244), 6)#       p1            p2    p1 p3 p4   p5     p6           p7# Where I(x, y, z) = y ^ (x | ~z)#proc md5::round4 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p3 ^ ($p1 | ~$p4)) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Do one set of rounds. Updates $state(0:3) with results from $x(0:16).proc md5::round {x_name state_name} {  upvar $x_name x $state_name state  set a $state(0)  set b $state(1)  set c $state(2)  set d $state(3)  # Round 1, steps 1-16  set a [round1 $b $a $c $d $x(0)  0xd76aa478  7]  set d [round1 $a $d $b $c $x(1)  0xe8c7b756 12]  set c [round1 $d $c $a $b $x(2)  0x242070db 17]  set b [round1 $c $b $d $a $x(3)  0xc1bdceee 22]  set a [round1 $b $a $c $d $x(4)  0xf57c0faf  7]  set d [round1 $a $d $b $c $x(5)  0x4787c62a 12]  set c [round1 $d $c $a $b $x(6)  0xa8304613 17]  set b [round1 $c $b $d $a $x(7)  0xfd469501 22]  set a [round1 $b $a $c $d $x(8)  0x698098d8  7]  set d [round1 $a $d $b $c $x(9)  0x8b44f7af 12]  set c [round1 $d $c $a $b $x(10) 0xffff5bb1 17]  set b [round1 $c $b $d $a $x(11) 0x895cd7be 22]  set a [round1 $b $a $c $d $x(12) 0x6b901122  7]  set d [round1 $a $d $b $c $x(13) 0xfd987193 12]  set c [round1 $d $c $a $b $x(14) 0xa679438e 17]  set b [round1 $c $b $d $a $x(15) 0x49b40821 22]  # Round 2, steps 17-32  set a [round2 $b $a $c $d $x(1)  0xf61e2562  5]  set d [round2 $a $d $b $c $x(6)  0xc040b340  9]  set c [round2 $d $c $a $b $x(11) 0x265e5a51 14]  set b [round2 $c $b $d $a $x(0)  0xe9b6c7aa 20]  set a [round2 $b $a $c $d $x(5)  0xd62f105d  5]  set d [round2 $a $d $b $c $x(10) 0x02441453  9]  set c [round2 $d $c $a $b $x(15) 0xd8a1e681 14]  set b [round2 $c $b $d $a $x(4)  0xe7d3fbc8 20]  set a [round2 $b $a $c $d $x(9)  0x21e1cde6  5]  set d [round2 $a $d $b $c $x(14) 0xc33707d6  9]  set c [round2 $d $c $a $b $x(3)  0xf4d50d87 14]  set b [round2 $c $b $d $a $x(8)  0x455a14ed 20]  set a [round2 $b $a $c $d $x(13) 0xa9e3e905  5]  set d [round2 $a $d $b $c $x(2)  0xfcefa3f8  9]  set c [round2 $d $c $a $b $x(7)  0x676f02d9 14]  set b [round2 $c $b $d $a $x(12) 0x8d2a4c8a 20]  # Round 3, steps 33-48  set a [round3 $b $a $c $d $x(5)  0xfffa3942  4]  set d [round3 $a $d $b $c $x(8)  0x8771f681 11]  set c [round3 $d $c $a $b $x(11) 0x6d9d6122 16]  set b [round3 $c $b $d $a $x(14) 0xfde5380c 23]  set a [round3 $b $a $c $d $x(1)  0xa4beea44  4]  set d [round3 $a $d $b $c $x(4)  0x4bdecfa9 11]  set c [round3 $d $c $a $b $x(7)  0xf6bb4b60 16]  set b [round3 $c $b $d $a $x(10) 0xbebfbc70 23]  set a [round3 $b $a $c $d $x(13) 0x289b7ec6  4]  set d [round3 $a $d $b $c $x(0)  0xeaa127fa 11]  set c [round3 $d $c $a $b $x(3)  0xd4ef3085 16]  set b [round3 $c $b $d $a $x(6)  0x04881d05 23]  set a [round3 $b $a $c $d $x(9)  0xd9d4d039  4]  set d [round3 $a $d $b $c $x(12) 0xe6db99e5 11]  set c [round3 $d $c $a $b $x(15) 0x1fa27cf8 16]  set b [round3 $c $b $d $a $x(2)  0xc4ac5665 23]  # Round 4, steps 49-64  set a [round4 $b $a $c $d $x(0)  0xf4292244  6]  set d [round4 $a $d $b $c $x(7)  0x432aff97 10]  set c [round4 $d $c $a $b $x(14) 0xab9423a7 15]  set b [round4 $c $b $d $a $x(5)  0xfc93a039 21]  set a [round4 $b $a $c $d $x(12) 0x655b59c3  6]  set d [round4 $a $d $b $c $x(3)  0x8f0ccc92 10]  set c [round4 $d $c $a $b $x(10) 0xffeff47d 15]  set b [round4 $c $b $d $a $x(1)  0x85845dd1 21]  set a [round4 $b $a $c $d $x(8)  0x6fa87e4f  6]  set d [round4 $a $d $b $c $x(15) 0xfe2ce6e0 10]  set c [round4 $d $c $a $b $x(6)  0xa3014314 15]  set b [round4 $c $b $d $a $x(13) 0x4e0811a1 21]  set a [round4 $b $a $c $d $x(4)  0xf7537e82  6]  set d [round4 $a $d $b $c $x(11) 0xbd3af235 10]  set c [round4 $d $c $a $b $x(2)  0x2ad7d2bb 15]  set b [round4 $c $b $d $a $x(9)  0xeb86d391 21]  incr state(0) $a  incr state(1) $b  incr state(2) $c  incr state(3) $d}# Pad out buffer per MD5 spec:proc md5::pad {buf_name} {  upvar $buf_name buf  # Length in bytes:  set len [string length $buf]  # Length in bits as 2 32 bit words:  set len64hi [expr {$len >> 29 & 7}]  set len64lo [expr {$len << 3}]  # Append 1 special byte, then append 0 or more 0 bytes until  # (length in bytes % 64) == 56  set pad [expr {64 - ($len + 8) % 64}]  append buf [binary format a$pad "\x80"]  # Append the length in bits as a 64 bit value, low bytes first.  append buf [binary format i1i1 $len64lo $len64hi]}# Calculate MD5 Digest over a string, return as 32 hex digit string.proc md5::digest {buf} {  # This is 0123456789abcdeffedcba9876543210 in byte-swapped order:  set state(0) 0x67452301  set state(1) 0xEFCDAB89  set state(2) 0x98BADCFE  set state(3) 0x10325476  # Pad buffer per RFC to exact multiple of 64 bytes.  pad buf  # Calculate digest in 64 byte chunks:  set nwords 0  set nbytes 0  set word 0  binary scan $buf c* bytes  # Unclear, but the data seems to get byte swapped here.  foreach c $bytes {    set word [expr {$c << 24 | ($word >> 8 & 0xffffff) }]    if {[incr nbytes] == 4} {      set nbytes 0      set x($nwords) $word      set word 0      if {[incr nwords] == 16} {        round x state        set nwords 0      }    }  }  # Result is state(0:3), but each word is taken low byte first.  set result {}  for {set i 0} {$i <= 3} {incr i} {    set w $state($i)    append result [format %02x%02x%02x%02x \             [expr {$w & 255}] \             [expr {$w >> 8 & 255}] \             [expr {$w >> 16 & 255}] \             [expr {$w >> 24 & 255}]]  }  return $result}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -