~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/rio.py

  • Committer: John Arbash Meinel
  • Date: 2009-03-27 22:29:55 UTC
  • mto: (3735.39.2 clean)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090327222955-utifmfm888zerixt
Implement apply_delta_to_source which doesn't have to malloc another string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 
33
33
import re
34
34
 
35
 
from bzrlib import osutils
36
35
from bzrlib.iterablefile import IterableFile
37
36
 
38
37
# XXX: some redundancy is allowing to write stanzas in isolation as well as
130
129
                            % (value, type(value)))
131
130
        self.items.append((tag, value))
132
131
 
133
 
    @classmethod
134
 
    def from_pairs(cls, pairs):
135
 
        ret = cls()
136
 
        ret.items = pairs
137
 
        return ret
138
 
 
139
132
    def __contains__(self, find_tag):
140
133
        """True if there is any field in this stanza with the given tag."""
141
134
        for tag, value in self.items:
198
191
 
199
192
        result = []
200
193
        for tag, value in self.items:
201
 
            if value == u'':
202
 
                result.append(tag + u': \n')
203
 
            elif u'\n' in value:
 
194
            if value == '':
 
195
                result.append(tag + ': \n')
 
196
            elif '\n' in value:
204
197
                # don't want splitlines behaviour on empty lines
205
 
                val_lines = value.split(u'\n')
206
 
                result.append(tag + u': ' + val_lines[0] + u'\n')
 
198
                val_lines = value.split('\n')
 
199
                result.append(tag + ': ' + val_lines[0] + '\n')
207
200
                for line in val_lines[1:]:
208
 
                    result.append(u'\t' + line + u'\n')
 
201
                    result.append('\t' + line + '\n')
209
202
            else:
210
 
                result.append(tag + u': ' + value + u'\n')
 
203
                result.append(tag + ': ' + value + '\n')
211
204
        return u''.join(result)
212
205
 
213
206
    def write(self, to_file):
243
236
            d[tag] = value
244
237
        return d
245
238
 
246
 
 
 
239
_tag_re = re.compile(r'^[-a-zA-Z0-9_]+$')
247
240
def valid_tag(tag):
248
 
    return _valid_tag(tag)
 
241
    return bool(_tag_re.match(tag))
249
242
 
250
243
 
251
244
def read_stanza(line_iter):
261
254
 
262
255
    The raw lines must be in utf-8 encoding.
263
256
    """
264
 
    return _read_stanza_utf8(line_iter)
 
257
    unicode_iter = (line.decode('utf-8') for line in line_iter)
 
258
    return read_stanza_unicode(unicode_iter)
265
259
 
266
260
 
267
261
def read_stanza_unicode(unicode_iter):
281
275
    :return: A Stanza object if there are any lines in the file.
282
276
        None otherwise
283
277
    """
284
 
    return _read_stanza_unicode(unicode_iter)
 
278
    stanza = Stanza()
 
279
    tag = None
 
280
    accum_value = None
 
281
 
 
282
    # TODO: jam 20060922 This code should raise real errors rather than
 
283
    #       using 'assert' to process user input, or raising ValueError
 
284
    #       rather than a more specific error.
 
285
 
 
286
    for line in unicode_iter:
 
287
        if line is None or line == '':
 
288
            break       # end of file
 
289
        if line == '\n':
 
290
            break       # end of stanza
 
291
        real_l = line
 
292
        if line[0] == '\t': # continues previous value
 
293
            if tag is None:
 
294
                raise ValueError('invalid continuation line %r' % real_l)
 
295
            accum_value += '\n' + line[1:-1]
 
296
        else: # new tag:value line
 
297
            if tag is not None:
 
298
                stanza.add(tag, accum_value)
 
299
            try:
 
300
                colon_index = line.index(': ')
 
301
            except ValueError:
 
302
                raise ValueError('tag/value separator not found in line %r'
 
303
                                 % real_l)
 
304
            tag = str(line[:colon_index])
 
305
            if not valid_tag(tag):
 
306
                raise ValueError("invalid rio tag %r" % (tag,))
 
307
            accum_value = line[colon_index+2:-1]
 
308
 
 
309
    if tag is not None: # add last tag-value
 
310
        stanza.add(tag, accum_value)
 
311
        return stanza
 
312
    else:     # didn't see any content
 
313
        return None
285
314
 
286
315
 
287
316
def to_patch_lines(stanza, max_width=72):
370
399
    :return: a Stanza
371
400
    """
372
401
    return read_stanza(_patch_stanza_iter(line_iter))
373
 
 
374
 
 
375
 
try:
376
 
    from bzrlib._rio_pyx import (
377
 
        _read_stanza_utf8,
378
 
        _read_stanza_unicode,
379
 
        _valid_tag,
380
 
        )
381
 
except ImportError, e:
382
 
    osutils.failed_to_load_extension(e)
383
 
    from bzrlib._rio_py import (
384
 
       _read_stanza_utf8,
385
 
       _read_stanza_unicode,
386
 
       _valid_tag,
387
 
       )