algorithms.c: Add bindings for STROBE.
[catacomb-python] / catacomb / pwsafe.py
index 7951e0a..944cfa7 100644 (file)
 
 from __future__ import with_statement
 
+import binascii as _B
 import errno as _E
 import os as _OS
-from cStringIO import StringIO as _StringIO
+import sys as _SYS
+
+if _SYS.version_info >= (3,): from io import StringIO as _StringIO
+else: from cStringIO import StringIO as _StringIO
 
 import catacomb as _C
 
 ###--------------------------------------------------------------------------
 ### Python version portability.
 
-def _iterkeys(dict): return dict.iterkeys()
-def _itervalues(dict): return dict.itervalues()
-def _iteritems(dict): return dict.iteritems()
-
-def _bin(text): return text
-def _text(bin): return bin
+if _SYS.version_info >= (3,):
+  def _iterkeys(dict): return dict.keys()
+  def _itervalues(dict): return dict.values()
+  def _iteritems(dict): return dict.items()
+  def _bin(text): return text.encode(errors = "surrogateescape")
+  def _text(bin): return bin.decode(errors = "surrogateescape")
+else:
+  def _iterkeys(dict): return dict.iterkeys()
+  def _itervalues(dict): return dict.itervalues()
+  def _iteritems(dict): return dict.iteritems()
+  def _bin(text): return text
+  def _text(bin): return bin
 
 _NUL = _bin('\0')
 _CIPHER = _bin('cipher:')
 _MAC = _bin('mac:')
 
+def _with_metaclass(meta, *supers):
+  return meta("#<anonymous base %s>" % meta.__name__,
+              supers or (object,), dict())
+
 def _excval(): return SYS.exc_info()[1]
 
 _M600 = int("600", 8)
@@ -99,10 +113,10 @@ def _dec_metaname(name):
 
 def _b64(s):
   """Encode S as base64, without newlines, and trimming `=' padding."""
-  return s.encode('base64').replace('\n', '').rstrip('=')
+  return _text(_B.b2a_base64(s)).replace('\n', '').rstrip('=')
 def _unb64(s):
   """Decode S as base64 with trimmed `=' padding."""
-  return (s + '='*((4 - len(s))%4)).decode('base64')
+  return _B.a2b_base64(s + '='*((4 - len(s))%4))
 
 def _enc_metaval(val):
   """Encode VAL as a metadata item value, returning the result."""
@@ -235,7 +249,7 @@ class StorageBackendClass (type):
     except AttributeError: pass
     else: StorageBackend.register_concrete_subclass(me)
 
-class StorageBackend (object):
+class StorageBackend (_with_metaclass(StorageBackendClass)):
   """
   I provide basic protocol for password storage backends.
 
@@ -303,7 +317,6 @@ class StorageBackend (object):
                         priority order when opening an existing database.
   """
 
-  __metaclass__ = StorageBackendClass
   PRIO = 10
 
   ## The registry of subclasses.