19
19
"Containers" and "records" are described in doc/developers/container-format.txt.
22
# XXX: probably rename this to pack.py
24
22
from bzrlib import errors
27
25
FORMAT_ONE = "bzr pack format 1"
30
class ContainerReader(object):
31
"""A class for reading Bazaar's container format."""
28
class ContainerWriter(object):
29
"""A class for writing containers."""
31
def __init__(self, write_func):
34
:param write_func: a callable that will be called when this
35
ContainerWriter needs to write some bytes.
37
self.write_func = write_func
40
"""Begin writing a container."""
41
self.write_func(FORMAT_ONE + "\n")
44
"""Finish writing a container."""
47
def add_bytes_record(self, bytes, names):
48
"""Add a Bytes record with the given names."""
52
self.write_func(str(len(bytes)) + "\n")
55
self.write_func(name + "\n")
58
# Finally, the contents.
59
self.write_func(bytes)
62
class BaseReader(object):
33
64
def __init__(self, reader_func):
40
71
self.reader_func = reader_func
74
"""Read a line from the input stream.
76
This is a simple but inefficient implementation that just reads one byte
77
at a time. Lines should not be very long, so this is probably
80
:returns: a line, without the trailing newline
82
# XXX: Have a maximum line length, to prevent malicious input from
83
# consuming an unreasonable amount of resources?
84
# -- Andrew Bennetts, 2007-05-07.
86
while not line.endswith('\n'):
87
line += self.reader_func(1)
91
class ContainerReader(BaseReader):
92
"""A class for reading Bazaar's container format."""
42
94
def iter_records(self):
43
95
"""Iterate over the container, yielding each record as it is read.
45
97
Each yielded record will be a 2-tuple of (names, bytes), where names is
46
98
a ``list`` and bytes is a ``str`.
100
:raises UnknownContainerFormatError: if the format of the container is
48
103
format = self._read_line()
49
104
if format != FORMAT_ONE:
67
123
# Unknown record type.
68
124
raise errors.UnknownRecordTypeError(record_kind)
70
def _read_bytes_record(self):
71
length = int(self._read_line())
127
class ContainerWriter(object):
128
"""A class for writing containers."""
130
def __init__(self, write_func):
133
:param write_func: a callable that will be called when this
134
ContainerWriter needs to write some bytes.
136
self.write_func = write_func
139
"""Begin writing a container."""
140
self.write_func(FORMAT_ONE + "\n")
143
"""Finish writing a container."""
146
def add_bytes_record(self, bytes, names):
147
"""Add a Bytes record with the given names."""
151
self.write_func(str(len(bytes)) + "\n")
154
self.write_func(name + "\n")
156
self.write_func("\n")
157
# Finally, the contents.
158
self.write_func(bytes)
161
class BytesRecordReader(BaseReader):
164
# Read the content length.
165
length_line = self._read_line()
167
length = int(length_line)
169
raise errors.InvalidRecordError(
170
"%r is not a valid length." % (length_line,))
172
# Read the list of names.
74
175
name = self._read_line()
79
180
# XXX: deal with case where len(bytes) != length
80
181
return names, bytes
83
"""Read a line from the input stream.
85
This is a simple but inefficient implementation that just reads one byte
86
at a time. Lines should not be very long, so this is probably
89
:returns: a line, without the trailing newline
91
# XXX: Have a maximum line length, to prevent malicious input from
92
# consuming an unreasonable amount of resources?
93
# -- Andrew Bennetts, 2007-05-07.
95
while not line.endswith('\n'):
96
line += self.reader_func(1)
100
class ContainerWriter(object):
101
"""A class for writing containers."""
103
def __init__(self, write_func):
106
:param write_func: a callable that will be called when this
107
ContainerWriter needs to write some bytes.
109
self.write_func = write_func
112
"""Begin writing a container."""
113
self.write_func(FORMAT_ONE + "\n")
116
"""Finish writing a container."""
119
def add_bytes_record(self, bytes, names):
120
"""Add a Bytes record with the given names."""
124
self.write_func(str(len(bytes)) + "\n")
127
self.write_func(name + "\n")
129
self.write_func("\n")
130
# Finally, the contents.
131
self.write_func(bytes)