File: digest.rb

package info (click to toggle)
ruby-xmlparser 0.7.3-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 980 kB
  • sloc: ruby: 9,342; ansic: 2,017; makefile: 11
file content (106 lines) | stat: -rw-r--r-- 2,994 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
## -*- Ruby -*-
## DOMHASH test implementation
## 1999 by yoshidam
##
## Apr 20, 1999 Change for draft-hiroshi-dom-hash-01.txt
##

require 'xml/dom/core'
require 'digest/md5'

module XML
  module DOM
    def self.tou16(str)
      if defined?(::Encoding)
        str.encode(::Encoding::UTF_16BE).force_encoding(::Encoding::ASCII_8BIT)
      else
        str.unpack("U*").map {|v|
          if v >= 0x10000 && v <= 0x10ffff
            ## surrogate pair
            hi = ((v - 0x10000) >> 10) | 0xd800
            low = (v & 1023) | 0xdc00
            [hi, low].pack("n*")
          else
            [v].pack("n*")
          end
        }.join
      end
    end

    class Node
      def getDigest(algorithm = Digest::MD5, force = false)
        nil
      end
    end

    class Text
      def getDigest(algorithm = Digest::MD5, force = false)
        (!force && @digest) ||
          @digest = algorithm.digest([TEXT_NODE].pack("N") + DOM.tou16(nodeValue))
        @digest
      end
    end

##    class Comment
##      def getDigest(algorithm = Digest::MD5, force = false)
##        (!force && @digest) ||
##          @digest = algorithm.digest([COMMENT_NODE].pack("N") + DOM.tou16(data)).digest
##      end
##    end

    class ProcessingInstruction
      def getDigest(algorithm = Digest::MD5, force = false)
        (!force && @digest) ||
          @digest = algorithm.digest([PROCESSING_INSTRUCTION_NODE].pack("N") +
                                     DOM.tou16(target) + "\0\0" + DOM.tou16(data))
      end
    end

    class Attr
      def getDigest(algorithm = Digest::MD5, force = false)
        (!force && @digest) ||
          @digest = algorithm.digest([ATTRIBUTE_NODE].pack("N") +
                                     DOM.tou16(nodeName) + "\0\0" + DOM.tou16(nodeValue))
      end
    end

    class NamedNodeMap
      include Enumerable
    end

    class NodeList
      include Enumerable
    end

    class Element
      def getDigest(algorithm = Digest::MD5, force = false)
        return @digest if (!force && @digest)
        attr = attributes
        children = childNodes
        attr_digests = ""
        children_digests = ""
        if attr
          attr_array = attr.sort {|a, b|
            DOM.tou16(a.nodeName) <=> DOM.tou16(b.nodeName)}
          attr_array.each {|a|
            attr_digests << a.getDigest(algorithm, force)
          }
        end
        children_num = 0
        children.each {|c|
          next if c.nodeType == COMMENT_NODE
          children_num += 1
          children_digests << c.getDigest(algorithm, force)
        }
        @digest = algorithm.digest([ELEMENT_NODE].pack("N") +
                                   DOM.tou16(nodeName) +
                                   "\0\0" +
                                   [attr.length].pack("N") +
                                   attr_digests +
                                   [children_num].pack("N") +
                                   children_digests)
      end
    end

  end
end