1
# Copyright (C) 2008 Canonical Ltd
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.
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.
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
17
"""Serializer object for CHK based inventory storage."""
19
from cStringIO import (
28
revision as _mod_revision,
33
class BEncodeRevisionSerializer1(object):
34
"""Simple revision serializer based around bencode.
38
def write_revision_to_string(self, rev):
39
encode_utf8 = cache_utf8.encode
41
"revision-id": rev.revision_id,
42
"timestamp": "%.3f" % rev.timestamp,
43
"parent-ids": rev.parent_ids,
44
"inventory-sha1": rev.inventory_sha1,
45
"committer": encode_utf8(rev.committer),
46
"message": encode_utf8(rev.message),
49
for key, value in rev.properties.iteritems():
50
revprops[key] = encode_utf8(value)
51
ret["properties"] = revprops
52
if rev.timezone is not None:
53
ret["timezone"] = rev.timezone
54
return bencode.bencode(ret)
56
def write_revision(self, rev, f):
57
f.write(self.write_revision_to_string(rev))
59
def read_revision_from_string(self, text):
60
decode_utf8 = cache_utf8.decode
61
ret = bencode.bdecode(text)
62
rev = _mod_revision.Revision(
63
committer=decode_utf8(ret["committer"]),
64
revision_id=ret["revision-id"],
65
parent_ids=ret["parent-ids"],
66
inventory_sha1=ret["inventory-sha1"],
67
timestamp=float(ret["timestamp"]),
68
message=decode_utf8(ret["message"]),
71
rev.timezone = ret["timezone"]
74
for key, value in ret["properties"].iteritems():
75
rev.properties[key] = decode_utf8(value)
78
def read_revision(self, f):
79
return self.read_revision_from_string(f.read())
82
class CHKSerializerSubtree(BEncodeRevisionSerializer1, xml6.Serializer_v6):
83
"""A CHKInventory based serializer that supports tree references"""
85
supported_kinds = set(['file', 'directory', 'symlink', 'tree-reference'])
87
revision_format_num = None
88
support_altered_by_hack = False
90
def _unpack_entry(self, elt):
92
if not kind in self.supported_kinds:
93
raise AssertionError('unsupported entry kind %s' % kind)
94
if kind == 'tree-reference':
95
file_id = elt.attrib['file_id']
96
name = elt.attrib['name']
97
parent_id = elt.attrib['parent_id']
98
revision = elt.get('revision')
99
reference_revision = elt.get('reference_revision')
100
return inventory.TreeReference(file_id, name, parent_id, revision,
103
return xml6.Serializer_v6._unpack_entry(self, elt)
105
def __init__(self, node_size, search_key_name):
106
self.maximum_size = node_size
107
self.search_key_name = search_key_name
110
class CHKSerializer(xml5.Serializer_v5):
111
"""A CHKInventory based serializer with 'plain' behaviour."""
114
revision_format_num = None
115
support_altered_by_hack = False
117
def __init__(self, node_size, search_key_name):
118
self.maximum_size = node_size
119
self.search_key_name = search_key_name
122
chk_serializer_255_bigpage = CHKSerializer(65536, 'hash-255-way')
125
class CHKBEncodeSerializer(BEncodeRevisionSerializer1, CHKSerializer):
126
"""A CHKInventory and BEncode based serializer with 'plain' behaviour."""
131
chk_bencode_serializer = CHKBEncodeSerializer(65536, 'hash-255-way')