/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/chk_serializer.py

  • Committer: Jelmer Vernooij
  • Date: 2009-04-15 01:37:51 UTC
  • mto: (4398.5.2 bencode_serializer)
  • mto: This revision was merged to the branch mainline in revision 4410.
  • Revision ID: jelmer@samba.org-20090415013751-15rmuh9btxihnist
Add simple revision serializer based on RIO.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Serializer object for CHK based inventory storage."""
 
18
 
 
19
from cStringIO import (
 
20
    StringIO,
 
21
    )
 
22
 
 
23
from bzrlib import (
 
24
    cache_utf8,
 
25
    inventory,
 
26
    osutils,
 
27
    revision as _mod_revision,
 
28
    rio,
 
29
    xml5,
 
30
    xml6,
 
31
    )
 
32
 
 
33
class RIORevisionSerializer1(object):
 
34
    """Simple line-based revision serializer. 
 
35
    
 
36
    This writes simple key/value pairs for all elements on the revision, 
 
37
    each on a separate line and using colons to separate key and value. Newlines
 
38
    are backslash-escaped where necessary.
 
39
 
 
40
    The commit message is always serialized last and can span multiple lines.
 
41
    """
 
42
 
 
43
    def write_revision(self, rev, f):
 
44
        decode_utf8 = cache_utf8.decode
 
45
        w = rio.RioWriter(f)
 
46
        s = rio.Stanza()
 
47
        revision_id = rev.revision_id
 
48
        if isinstance(revision_id, str):
 
49
            revision_id = decode_utf8(revision_id)
 
50
        s.add("revision-id", revision_id)
 
51
        s.add("timestamp", "%.3f" % rev.timestamp)
 
52
        if rev.parent_ids:
 
53
            s.add("parent-ids", 
 
54
                " ".join([decode_utf8(p) for p in rev.parent_ids]))
 
55
        s.add("inventory-sha1", rev.inventory_sha1)
 
56
        s.add("committer", rev.committer)
 
57
        if rev.timezone is not None:
 
58
            s.add("timezone", str(rev.timezone))
 
59
        if rev.properties:
 
60
            revprops_stanza = rio.Stanza()
 
61
            for k, v in rev.properties.iteritems():
 
62
                if isinstance(v, str):
 
63
                    v = decode_utf8(v)
 
64
                revprops_stanza.add(decode_utf8(k), v)
 
65
            s.add("properties", revprops_stanza.to_unicode())
 
66
        s.add("message", rev.message)
 
67
        w.write_stanza(s)
 
68
 
 
69
    def write_revision_to_string(self, rev):
 
70
        f = StringIO()
 
71
        self.write_revision(rev, f)
 
72
        return f.getvalue()
 
73
 
 
74
    def read_revision(self, f):
 
75
        s = rio.read_stanza(f)
 
76
        rev = _mod_revision.Revision(None)
 
77
        for (field, value) in s.iter_pairs():
 
78
            if field == "revision-id":
 
79
                rev.revision_id = cache_utf8.encode(value)
 
80
            elif field == "parent-ids":
 
81
                rev.parent_ids = [cache_utf8.encode(p) for p in value.split(" ")]
 
82
            elif field == "committer":
 
83
                rev.committer = value
 
84
            elif field == "inventory-sha1":
 
85
                rev.inventory_sha1 = value
 
86
            elif field == "timezone":
 
87
                rev.timezone = int(value)
 
88
            elif field == "timestamp":
 
89
                rev.timestamp = float(value)
 
90
            elif field == "message":
 
91
                rev.message = value
 
92
            elif field == "properties":
 
93
                rev.properties = rio.read_stanza_unicode(
 
94
                    osutils.split_lines(value)).as_dict()
 
95
            else:
 
96
                raise AssertionError("Unknown field %s" % field)
 
97
            l = f.readline()
 
98
        return rev
 
99
 
 
100
    def read_revision_from_string(self, xml_string):
 
101
        f = StringIO(xml_string)
 
102
        rev = self.read_revision(f)
 
103
        return rev
 
104
 
 
105
 
 
106
class CHKSerializerSubtree(RIORevisionSerializer1,xml6.Serializer_v6):
 
107
    """A CHKInventory based serializer that supports tree references"""
 
108
 
 
109
    supported_kinds = set(['file', 'directory', 'symlink', 'tree-reference'])
 
110
    format_num = '9'
 
111
    revision_format_num = None
 
112
    support_altered_by_hack = False
 
113
 
 
114
    def _unpack_entry(self, elt):
 
115
        kind = elt.tag
 
116
        if not kind in self.supported_kinds:
 
117
            raise AssertionError('unsupported entry kind %s' % kind)
 
118
        if kind == 'tree-reference':
 
119
            file_id = elt.attrib['file_id']
 
120
            name = elt.attrib['name']
 
121
            parent_id = elt.attrib['parent_id']
 
122
            revision = elt.get('revision')
 
123
            reference_revision = elt.get('reference_revision')
 
124
            return inventory.TreeReference(file_id, name, parent_id, revision,
 
125
                                           reference_revision)
 
126
        else:
 
127
            return xml6.Serializer_v6._unpack_entry(self, elt)
 
128
 
 
129
    def __init__(self, node_size, search_key_name):
 
130
        self.maximum_size = node_size
 
131
        self.search_key_name = search_key_name
 
132
 
 
133
 
 
134
class CHKSerializer(RIORevisionSerializer1,xml5.Serializer_v5):
 
135
    """A CHKInventory based serializer with 'plain' behaviour."""
 
136
 
 
137
    format_num = '9'
 
138
    revision_format_num = None
 
139
    support_altered_by_hack = False
 
140
 
 
141
    def __init__(self, node_size, search_key_name):
 
142
        self.maximum_size = node_size
 
143
        self.search_key_name = search_key_name
 
144
 
 
145
 
 
146
chk_serializer_255_bigpage = CHKSerializer(65536, 'hash-255-way')