/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/_dirstate_helpers_c.pyx

  • Committer: Vincent Ladeuil
  • Date: 2008-09-11 19:36:38 UTC
  • mfrom: (3703 +trunk)
  • mto: (3705.1.1 trunk2)
  • mto: This revision was merged to the branch mainline in revision 3708.
  • Revision ID: v.ladeuil+lp@free.fr-20080911193638-wtjyc1kcmacc6t1f
merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
 
1
# Copyright (C) 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
19
19
This is the python implementation for DirState functions.
20
20
"""
21
21
 
 
22
from bzrlib import errors
22
23
from bzrlib.dirstate import DirState
23
24
 
24
25
 
50
51
# inner loops, we don't need to do that at all, as the reference only lasts for
51
52
# a very short time.
52
53
cdef extern from "Python.h":
 
54
    ctypedef int Py_ssize_t
53
55
    int PyList_Append(object lst, object item) except -1
54
56
    void *PyList_GetItem_object_void "PyList_GET_ITEM" (object lst, int index)
55
57
    int PyList_CheckExact(object)
59
61
    char *PyString_AsString(object p)
60
62
    char *PyString_AS_STRING_void "PyString_AS_STRING" (void *p)
61
63
    object PyString_FromString(char *)
62
 
    object PyString_FromStringAndSize(char *, int)
 
64
    object PyString_FromStringAndSize(char *, Py_ssize_t)
63
65
    int PyString_Size(object p)
64
66
    int PyString_GET_SIZE_void "PyString_GET_SIZE" (void *p)
65
67
    int PyString_CheckExact(object p)
110
112
        return None
111
113
    return <char*>found - <char*>_s
112
114
 
 
115
cdef object safe_string_from_size(char *s, Py_ssize_t size):
 
116
    if size < 0:
 
117
        raise AssertionError(
 
118
            'tried to create a string with an invalid size: %d @0x%x'
 
119
            % (size, <int>s))
 
120
    return PyString_FromStringAndSize(s, size)
 
121
 
113
122
 
114
123
cdef int _is_aligned(void *ptr):
115
124
    """Is this pointer aligned to an integer size offset?
470
479
cdef class Reader:
471
480
    """Maintain the current location, and return fields as you parse them."""
472
481
 
 
482
    cdef object state # The DirState object
473
483
    cdef object text # The overall string object
474
484
    cdef char *text_cstr # Pointer to the beginning of text
475
485
    cdef int text_size # Length of text
478
488
    cdef char *cur_cstr # Pointer to the current record
479
489
    cdef char *next # Pointer to the end of this record
480
490
 
481
 
    def __init__(self, text):
 
491
    def __init__(self, text, state):
 
492
        self.state = state
482
493
        self.text = text
483
494
        self.text_cstr = PyString_AsString(text)
484
495
        self.text_size = PyString_Size(text)
485
496
        self.end_cstr = self.text_cstr + self.text_size
486
497
        self.cur_cstr = self.text_cstr
487
498
 
488
 
    cdef char *get_next(self, int *size):
 
499
    cdef char *get_next(self, int *size) except NULL:
489
500
        """Return a pointer to the start of the next field."""
490
501
        cdef char *next
 
502
        cdef Py_ssize_t extra_len
 
503
 
 
504
        if self.cur_cstr == NULL:
 
505
            raise AssertionError('get_next() called when cur_str is NULL')
 
506
        elif self.cur_cstr >= self.end_cstr:
 
507
            raise AssertionError('get_next() called when there are no chars'
 
508
                                 ' left')
491
509
        next = self.cur_cstr
492
 
        self.cur_cstr = <char*>memchr(next, c'\0', self.end_cstr-next)
 
510
        self.cur_cstr = <char*>memchr(next, c'\0', self.end_cstr - next)
 
511
        if self.cur_cstr == NULL:
 
512
            extra_len = self.end_cstr - next
 
513
            raise errors.DirstateCorrupt(self.state,
 
514
                'failed to find trailing NULL (\\0).'
 
515
                ' Trailing garbage: %r'
 
516
                % safe_string_from_size(next, extra_len))
493
517
        size[0] = self.cur_cstr - next
494
518
        self.cur_cstr = self.cur_cstr + 1
495
519
        return next
499
523
        cdef int size
500
524
        cdef char *next
501
525
        next = self.get_next(&size)
502
 
        return PyString_FromStringAndSize(next, size)
 
526
        return safe_string_from_size(next, size)
503
527
 
504
528
    cdef int _init(self) except -1:
505
529
        """Get the pointer ready.
570
594
                       # <object>
571
595
                       PyString_AS_STRING_void(p_current_dirname[0]),
572
596
                       cur_size+1) != 0):
573
 
            dirname = PyString_FromStringAndSize(dirname_cstr, cur_size)
 
597
            dirname = safe_string_from_size(dirname_cstr, cur_size)
574
598
            p_current_dirname[0] = <void*>dirname
575
599
            new_block[0] = 1
576
600
        else:
621
645
        # marker.
622
646
        trailing = self.get_next(&cur_size)
623
647
        if cur_size != 1 or trailing[0] != c'\n':
624
 
            raise AssertionError(
 
648
            raise errors.DirstateCorrupt(self.state,
625
649
                'Bad parse, we expected to end on \\n, not: %d %s: %s'
626
 
                % (cur_size, PyString_FromStringAndSize(trailing, cur_size),
 
650
                % (cur_size, safe_string_from_size(trailing, cur_size),
627
651
                   ret))
628
652
        return ret
629
653
 
630
 
    def _parse_dirblocks(self, state):
 
654
    def _parse_dirblocks(self):
631
655
        """Parse all dirblocks in the state file."""
632
656
        cdef int num_trees
633
657
        cdef object current_block
637
661
        cdef int expected_entry_count
638
662
        cdef int entry_count
639
663
 
640
 
        num_trees = state._num_present_parents() + 1
641
 
        expected_entry_count = state._num_entries
 
664
        num_trees = self.state._num_present_parents() + 1
 
665
        expected_entry_count = self.state._num_entries
642
666
 
643
667
        # Ignore the first record
644
668
        self._init()
645
669
 
646
670
        current_block = []
647
 
        state._dirblocks = [('', current_block), ('', [])]
 
671
        dirblocks = [('', current_block), ('', [])]
 
672
        self.state._dirblocks = dirblocks
648
673
        obj = ''
649
674
        current_dirname = <void*>obj
650
675
        new_block = 0
662
687
            if new_block:
663
688
                # new block - different dirname
664
689
                current_block = []
665
 
                PyList_Append(state._dirblocks,
 
690
                PyList_Append(dirblocks,
666
691
                              (<object>current_dirname, current_block))
667
692
            PyList_Append(current_block, entry)
668
693
            entry_count = entry_count + 1
669
694
        if entry_count != expected_entry_count:
670
 
            raise AssertionError('We read the wrong number of entries.'
 
695
            raise errors.DirstateCorrupt(self.state,
 
696
                    'We read the wrong number of entries.'
671
697
                    ' We expected to read %s, but read %s'
672
698
                    % (expected_entry_count, entry_count))
673
 
        state._split_root_dirblock_into_contents()
 
699
        self.state._split_root_dirblock_into_contents()
674
700
 
675
701
 
676
702
def _read_dirblocks_c(state):
689
715
    text = state._state_file.read()
690
716
    # TODO: check the crc checksums. crc_measured = zlib.crc32(text)
691
717
 
692
 
    reader = Reader(text)
 
718
    reader = Reader(text, state)
693
719
 
694
 
    reader._parse_dirblocks(state)
 
720
    reader._parse_dirblocks()
695
721
    state._dirblock_state = DirState.IN_MEMORY_UNMODIFIED