diff options
-rw-r--r-- | portato/eix.py | 146 | ||||
-rw-r--r-- | portato/eix/__init__.py | 40 | ||||
-rw-r--r-- | portato/eix/exceptions.py | 29 | ||||
-rw-r--r-- | portato/eix/parser.py | 86 |
4 files changed, 155 insertions, 146 deletions
diff --git a/portato/eix.py b/portato/eix.py deleted file mode 100644 index 5262bf2..0000000 --- a/portato/eix.py +++ /dev/null @@ -1,146 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/eix.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2006-2009 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann <necoro@necoro.net> - -from __future__ import absolute_import, with_statement - -import os -import struct -from functools import wraps - -from .helper import debug - -class EixError (Exception): - message = "Unknown error." - - def __str__ (self): - return self.message - -class EndOfFileException (EixError): - - def __init__ (self, filename): - self.message = "End of file reached though it was not expected: '%s'" % filename - -class EixReaderClosed (EixError): - message = "EixReader is already closed." - -class UnsupportedVersionError (EixError): - - def __init__ (self, version): - self.message = "Version '%s' is not supported." % version - -class EixReader (object): - supported_versions = (28, ) - - def __init__ (self, filename): - self.filename = filename - self.file = open(filename, "r") - self.closed = 0 - - try: - self.version = self.number() - - if self.version not in self.supported_versions: - raise UnsupportedVersionError(self.version) - - debug("Started EixReader for version %s.", self.version) - except: - self.close() - raise - - def check_closed (f): - @wraps(f) - def wrapper (self, *args, **kwargs): - if self.closed: - raise EixReaderClosed - - return f(self, *args, **kwargs) - return wrapper - - @check_closed - def number (self): - n = self._get_bytes(1) - - if n < 0xFF: - value = n - else: - count = 0 - - while (n == 0xFF): - count += 1 - n = self._get_bytes(1) - - if n == 0: - n = 0xFF # 0xFF is encoded as 0xFF 0x00 - count -= 1 - - value = n << (count*8) - - if count > 0: - rest = self._get_bytes(count, expect_list = True) - - for i, r in enumerate(rest): - value += r << ((count - i - 1)*8) - - return value - - @check_closed - def vector (self, get_type, skip = False): - nelems = self.number() - - if skip: - for i in range(nelems): - get_type(skip = True) - else: - return (get_type() for i in range(nelems)) - - @check_closed - def string (self, skip = False): - nelems = self.number() - - if skip: - self.file.seek(nelems, os.SEEK_CUR) - else: - s = self.file.read(nelems) - - if len(s) != nelems: - raise EndOfFileException, self.filename - - return s - - @check_closed - def overlay (self, skip = False): - if skip: - self.file.seek(self.number(), os.SEEK_CUR) # path - self.file.seek(self.number(), os.SEEK_CUR) # label - else: - return (self.string(), self.string()) - - def _get_bytes (self, length, expect_list = False): - s = self.file.read(length) - - if len(s) != length: - raise EndOfFileException, self.filename - - if length == 1 and not expect_list: - return ord(s) # is faster than unpack and we have a scalar - else: - return struct.unpack("%sB" % length, s) - - @check_closed - def close (self): - if self.closed: - raise EixReaderClosed - - self.file.close() - self.closed = 1 - - debug("EixReader closed.") diff --git a/portato/eix/__init__.py b/portato/eix/__init__.py new file mode 100644 index 0000000..3c1958e --- /dev/null +++ b/portato/eix/__init__.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# +# File: portato/eix/__init__.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2006-2009 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann <necoro@necoro.net> + +from __future__ import absolute_import, with_statement + +from . import parser +from . import exceptions as ex + +from ..helper import debug + +class EixReader(object): + supported_version = (28,) + + def __init__ (self, filename): + self.filename = filename + self.file = open(filename, "r") + + try: + self.version = parser.number(self.file) + + if self.version not in self.supported_versions: + raise ex.UnsupportedVersionError(self.version) + + debug("Started EixReader for version %s.", self.version) + except: + self.close() + raise + + def close (self): + self.file.close() + debug("EixReader closed.") diff --git a/portato/eix/exceptions.py b/portato/eix/exceptions.py new file mode 100644 index 0000000..fd72dcf --- /dev/null +++ b/portato/eix/exceptions.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# +# File: portato/eix/exceptions.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2006-2009 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann <necoro@necoro.net> + +from __future__ import absolute_import, with_statement + +class EixError (Exception): + message = _("Unknown error.") + + def __str__ (self): + return self.message + +class EndOfFileException (EixError): + + def __init__ (self, filename): + self.message = _("End of file reached though it was not expected: '%s'") % filename + +class UnsupportedVersionError (EixError): + + def __init__ (self, version): + self.message = _("Version '%s' is not supported.") % version diff --git a/portato/eix/parser.py b/portato/eix/parser.py new file mode 100644 index 0000000..e89bffe --- /dev/null +++ b/portato/eix/parser.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# +# File: portato/eix/parser.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2006-2009 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann <necoro@necoro.net> + +from __future__ import absolute_import, with_statement + +import os +import struct + +from .helper import debug + +from . import exceptions as ex + +def _get_bytes (file, length, expect_list = False): + s = file.read(length) + + if len(s) != length: + raise EndOfFileException, file.name + + if length == 1 and not expect_list: + return ord(s) # is faster than unpack and we have a scalar + else: + return struct.unpack("%sB" % length, s) + +def number (file): + n = _get_bytes(file, 1) + + if n < 0xFF: + value = n + else: + count = 0 + + while (n == 0xFF): + count += 1 + n = _get_bytes(file, 1) + + if n == 0: + n = 0xFF # 0xFF is encoded as 0xFF 0x00 + count -= 1 + + value = n << (count*8) + + if count > 0: + rest = _get_bytes(file, count, expect_list = True) + + for i, r in enumerate(rest): + value += r << ((count - i - 1)*8) + + return value + +def vector (file, get_type, skip = False): + nelems = number(file) + + if skip: + for i in range(nelems): + get_type(file, skip = True) + else: + return (get_type(file) for i in range(nelems)) + +def string (file, skip = False): + nelems = number(file) + + if skip: + file.seek(nelems, os.SEEK_CUR) + else: + s = file.read(nelems) + + if len(s) != nelems: + raise EndOfFileException, file.name + + return s + +def overlay (file, skip = False): + if skip: + string(file, skip = True) # path + string(file, skip = True) # label + else: + return (string(file), string(file)) |