]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/vint.py
get: adjust for python 3 and test there
[bup.git] / lib / bup / vint.py
index 378234c62d2a2a5ec1f2ed9b62598a132e8dd07d..086cb302087d8edae343631c04c68a87440c35f8 100644 (file)
@@ -5,37 +5,50 @@
 # This code is covered under the terms of the GNU Library General
 # Public License as described in the bup LICENSE file.
 
+# Variable length integers are encoded as vints -- see lucene.
+
+from __future__ import absolute_import
 from io import BytesIO
+import sys
+
+from bup import compat
 
-# Variable length integers are encoded as vints -- see jakarta lucene.
 
 def write_vuint(port, x):
+    write = port.write
+    bytes_from_uint = compat.bytes_from_uint
     if x < 0:
         raise Exception("vuints must not be negative")
     elif x == 0:
-        port.write('\0')
+        write(bytes_from_uint(0))
     else:
-        while x:
+        while True:
             seven_bits = x & 0x7f
             x >>= 7
             if x:
-                port.write(chr(0x80 | seven_bits))
+                write(bytes_from_uint(0x80 | seven_bits))
             else:
-                port.write(chr(seven_bits))
+                write(bytes_from_uint(seven_bits))
+                break
 
 
 def read_vuint(port):
     c = port.read(1)
-    if c == '':
-        raise EOFError('encountered EOF while reading vuint');
+    if not c:
+        raise EOFError('encountered EOF while reading vuint')
+    assert isinstance(c, bytes)
+    if ord(c) == 0:
+        return 0
     result = 0
     offset = 0
-    while c:
+    while True:
         b = ord(c)
         if b & 0x80:
             result |= ((b & 0x7f) << offset)
             offset += 7
             c = port.read(1)
+            if not c:
+                raise EOFError('encountered EOF while reading vuint')
         else:
             result |= (b << offset)
             break
@@ -45,8 +58,10 @@ def read_vuint(port):
 def write_vint(port, x):
     # Sign is handled with the second bit of the first byte.  All else
     # matches vuint.
+    write = port.write
+    bytes_from_uint = compat.bytes_from_uint
     if x == 0:
-        port.write('\0')
+        write(bytes_from_uint(0))
     else:
         if x < 0:
             x = -x
@@ -55,38 +70,40 @@ def write_vint(port, x):
             sign_and_six_bits = x & 0x3f
         x >>= 6
         if x:
-            port.write(chr(0x80 | sign_and_six_bits))
+            write(bytes_from_uint(0x80 | sign_and_six_bits))
             write_vuint(port, x)
         else:
-            port.write(chr(sign_and_six_bits))
+            write(bytes_from_uint(sign_and_six_bits))
 
 
 def read_vint(port):
     c = port.read(1)
-    if c == '':
-        raise EOFError('encountered EOF while reading vint');
+    if not c:
+        raise EOFError('encountered EOF while reading vint')
+    assert isinstance(c, bytes)
     negative = False
     result = 0
     offset = 0
     # Handle first byte with sign bit specially.
-    if c:
-        b = ord(c)
-        if b & 0x40:
-            negative = True
-        result |= (b & 0x3f)
-        if b & 0x80:
-            offset += 6
-            c = port.read(1)
-        elif negative:
-            return -result
-        else:
-            return result
-    while c:
+    b = ord(c)
+    if b & 0x40:
+        negative = True
+    result |= (b & 0x3f)
+    if b & 0x80:
+        offset += 6
+        c = port.read(1)
+    elif negative:
+        return -result
+    else:
+        return result
+    while True:
         b = ord(c)
         if b & 0x80:
             result |= ((b & 0x7f) << offset)
             offset += 7
             c = port.read(1)
+            if not c:
+                raise EOFError('encountered EOF while reading vint')
         else:
             result |= (b << offset)
             break
@@ -109,11 +126,9 @@ def read_bvec(port):
 def skip_bvec(port):
     port.read(read_vuint(port))
 
-
-def pack(types, *args):
+def send(port, types, *args):
     if len(types) != len(args):
         raise Exception('number of arguments does not match format string')
-    port = BytesIO()
     for (type, value) in zip(types, args):
         if type == 'V':
             write_vuint(port, value)
@@ -123,12 +138,9 @@ def pack(types, *args):
             write_bvec(port, value)
         else:
             raise Exception('unknown xpack format string item "' + type + '"')
-    return port.getvalue()
-
 
-def unpack(types, data):
+def recv(port, types):
     result = []
-    port = BytesIO(data)
     for type in types:
         if type == 'V':
             result.append(read_vuint(port))
@@ -139,3 +151,12 @@ def unpack(types, data):
         else:
             raise Exception('unknown xunpack format string item "' + type + '"')
     return result
+
+def pack(types, *args):
+    port = BytesIO()
+    send(port, types, *args)
+    return port.getvalue()
+
+def unpack(types, data):
+    port = BytesIO(data)
+    return recv(port, types)