/[suikacvs]/webroot/swe/lib/SWE/DB/IDDOM.pm
Suika

Contents of /webroot/swe/lib/SWE/DB/IDDOM.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sun Nov 9 06:46:47 2008 UTC (16 years, 5 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
++ swe/lib/SWE/DB/ChangeLog	9 Nov 2008 06:46:33 -0000
2008-11-09  Wakaba  <wakaba@suika.fam.cx>

	* Lock.pm, HashedProps.pm, IDDOM.pm, IDGenerator.pm, IDProps.pm,
	IDText.pm, SuikaWiki3PageList.pm: New modules.

	* SuikaWiki3.pm, SuikaWiki3LastModified.pm: Changed to use plain
	base 16 encoded file name string as key, rather than array
	reference as in SuikaWiki3.

	* SuikaWiki3LastModified.pm (save_data, set_data): Removed.
	(load_data): Renamed as |_load_data|.
	(get_data): Invoke |_load_data| if and only if necessary.

	* SuikaWiki3Props.pm: Don't treat "%" as a part of hash key.

1 wakaba 1.1 package SWE::DB::IDDOM;
2     use strict;
3    
4     require SWE::DB::IDProps;
5     push our @ISA, 'SWE::DB::IDProps';
6    
7     require Message::DOM::DOMImplementation;
8    
9     sub new ($) {
10     my $self = shift->SUPER::new (@_);
11     $self->{leaf_suffix} = '.dom';
12     return $self;
13     } # new
14    
15     sub get_data ($$) {
16     my $self = shift;
17     my $file_name = $self->_get_file_name ($_[0]);
18    
19     unless (-f $file_name) {
20     return undef;
21     }
22    
23     open my $file, '<:encoding(utf8)', $file_name or die "$0: $file_name: $!";
24     return _load_dom ($file);
25     } # get_data
26    
27     sub set_data ($$$) {
28     my $self = shift;
29     my $file_name = $self->_get_file_name ($_[0], 1);
30     my $dom = $_[1];
31    
32     my $has_file = -f $file_name;
33    
34     open my $file, '>:encoding(utf8)', $file_name or die "$0: $file_name: $!";
35     _store_dom ($file, $dom);
36    
37     ## TODO: cvs
38     } # set_data
39    
40     sub _load_dom ($) {
41     my $handle = shift;
42    
43     my $dom = Message::DOM::DOMImplementation->new;
44     my @node = ($dom->create_document);
45    
46     $node[0]->strict_error_checking (0);
47     $node[0]->dom_config->set_parameter
48     ('http://suika.fam.cx/www/2006/dom-config/strict-document-children' => 0);
49    
50     my $unescape = sub {
51     my $s = shift;
52     $s =~ s/\\([0-9A-Fa-f]{2})/pack 'C', hex $1/ge;
53     return $s;
54     }; # $unescape
55    
56     while (<$handle>) {
57     tr/\x0D\x0A//d;
58     if (s/^n(\d+);//) {
59     $node[$1] = $unescape->($_);
60     } elsif (s/^t(\d+);//) {
61     my $parent_id = $1;
62     $node[$parent_id]->append_child
63     ($node[0]->create_text_node ($unescape->($_)));
64     } elsif (s/^e(\d+);(\d+);(\d+);//) {
65     my ($this_id, $parent_id, $ns_id) = ($1, $2, $3);
66     $node[$this_id] = $node[0]->create_element_ns
67     ($node[$ns_id], [undef, $unescape->($_)]);
68     $node[$parent_id]->append_child ($node[$this_id]);
69     } elsif (s/^a(\d+);(\d+);([^;]+);//) {
70     my ($parent_id, $ns_id, $ln) = ($1, $2, $3);
71     $node[$parent_id]->set_attribute_ns
72     ($node[$ns_id], [undef, $unescape->($ln)], $unescape->($_));
73     }
74     }
75    
76     return $node[0];
77     } # _load_dom
78    
79     sub _store_dom ($$) {
80     my $handle = shift;
81     my @item = ([0, shift]);
82    
83     my $escape = sub {
84     my $v = $_[0];
85     $v =~ s/([;\\\x0D\x0A])/sprintf '\\%02X', ord $1/ge;
86     return $v;
87     }; # $escape
88    
89     my $ns;
90     my $next_id = 1;
91     while (@item) {
92     my ($parent_id, $node) = @{shift @item};
93     if ($node->node_type == $node->ELEMENT_NODE) {
94     my $nsuri = $node->namespace_uri // '';
95     my $nsid = $ns->{$nsuri};
96     unless (defined $nsid) {
97     $nsid = $next_id++;
98     $ns->{$nsuri} = $nsid;
99     print $handle "n", $nsid, ';', $escape->($nsuri), "\n";
100     }
101     my $el_id = $next_id++;
102     print $handle "e", $el_id, ';', $parent_id, ';', $nsid, ';',
103     $escape->($node->manakai_local_name), "\n";
104     for my $attr (@{$node->attributes}) {
105     my $nsuri = $attr->namespace_uri // '';
106     my $nsid = $ns->{$nsuri};
107     unless (defined $nsid) {
108     $nsid = $next_id++;
109     $ns->{$nsuri} = $nsid;
110     print $handle "n", $nsid, ';', $escape->($nsuri), "\n";
111     }
112     print $handle "a", $el_id, ';', $nsid, ';',
113     $escape->($attr->manakai_local_name), ';',
114     $escape->($attr->value), "\n";
115     }
116     unshift @item, map {[$el_id, $_]} @{$node->child_nodes};
117     } elsif ($node->node_type == $node->TEXT_NODE or
118     $node->node_type == $node->CDATA_SECTION_NODE) {
119     print $handle "t", $parent_id, ';', $escape->($node->data), "\n";
120     } elsif ($node->node_type == $node->DOCUMENT_NODE or
121     $node->node_type == $node->DOCUMENT_FRAGMENT_NODE) {
122     unshift @item, map {[0, $_]} @{$node->child_nodes};
123     }
124     }
125     } # _store_dom
126    
127     1;

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24