Use separate function for tree parsing, allow C extension for tree parsing.
[jelmer/dulwich-libgit2.git] / dulwich / objects.py
index 3ae73b9fb80941802b0ac2d12c1de78bb3714072..3657029035db975c20b41b6699eee0c13a7b6da6 100644 (file)
@@ -1,4 +1,4 @@
-# objects.py -- Acces to base git objects
+# objects.py -- Access to base git objects
 # Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
 # Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
 # 
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.
 
+
+"""Access to base git objects."""
+
+
 import mmap
 import os
 import sha
@@ -45,17 +49,20 @@ def _decompress(string):
     dcomped += dcomp.flush()
     return dcomped
 
+
 def sha_to_hex(sha):
     """Takes a string and returns the hex of the sha within"""
     hexsha = "".join(["%02x" % ord(c) for c in sha])
     assert len(hexsha) == 40, "Incorrect length of sha1 string: %d" % hexsha
     return hexsha
 
+
 def hex_to_sha(hex):
     """Takes a hex sha and returns a binary sha"""
     assert len(hex) == 40, "Incorrent length of hexsha: %s" % hex
     return ''.join([chr(int(hex[i:i+2], 16)) for i in xrange(0, len(hex), 2)])
 
+
 class ShaFile(object):
     """A git SHA file."""
   
@@ -85,6 +92,9 @@ class ShaFile(object):
         text = text[1:]
         object._text = text
         return object
+
+    def as_legacy_object(self):
+        return zlib.compress("%s %d\0%s" % (self._type, len(self._text), self._text))
   
     def as_raw_string(self):
         return self._num_type, self._text
@@ -99,8 +109,8 @@ class ShaFile(object):
         try:
             object = num_type_map[num_type]()
         except KeyError:
-            assert False, "Not a known type: %d" % num_type
-        while((byte & 0x80) != 0):
+            raise AssertionError("Not a known type: %d" % num_type)
+        while (byte & 0x80) != 0:
             byte = ord(map[used])
             used += 1
         raw = map[used:]
@@ -352,7 +362,7 @@ class Tree(ShaFile):
     _num_type = 2
 
     def __init__(self):
-        self._entries = []
+        self._entries = {}
 
     @classmethod
     def from_file(cls, filename):
@@ -361,18 +371,27 @@ class Tree(ShaFile):
             raise NotTreeError(filename)
         return tree
 
+    def __getitem__(self, name):
+        return self._entries[name]
+
+    def __setitem__(self, name, value):
+        assert isinstance(value, tuple)
+        assert len(value) == 2
+        self._entries[name] = value
+
+    def __delitem__(self, name):
+        del self._entries[name]
+
     def add(self, mode, name, hexsha):
-        self._entries.append((mode, name, hexsha))
+        self._entries[name] = mode, hexsha
 
     def entries(self):
         """Return a list of tuples describing the tree entries"""
-        return self._entries
+        return [(mode, name, hexsha) for (name, (mode, hexsha)) in self._entries.iteritems()]
 
-    def __getitem__(self, name):
-        for mode, entry, hexsha in self.entries():
-            if entry == name:
-                return mode, hexsha
-        raise KeyError(name)
+    def iteritems(self):
+        for name in sorted(self._entries.keys()):
+            yield name, self._entries[name][0], self._entries[name][1]
 
     def _parse_text(self):
         """Grab the entries in the tree"""
@@ -380,7 +399,7 @@ class Tree(ShaFile):
 
     def serialize(self):
         self._text = ""
-        for mode, name, hexsha in self._entries:
+        for name, mode, hexsha in self.iteritems():
             self._text += "%04o %s\0%s" % (mode, name, hex_to_sha(hexsha))