mirror of
https://github.com/ihaveamac/custom-install.git
synced 2025-12-06 06:41:45 +00:00
initial commit
This commit is contained in:
82
pyctr/common.py
Normal file
82
pyctr/common.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# This file is a part of ninfs.
|
||||
#
|
||||
# Copyright (c) 2017-2019 Ian Burgwin
|
||||
# This file is licensed under The MIT License (MIT).
|
||||
# You can find the full license text in LICENSE.md in the root of this project.
|
||||
|
||||
from functools import wraps
|
||||
from io import BufferedIOBase
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# this is a lazy way to make type checkers stop complaining
|
||||
from typing import BinaryIO
|
||||
BufferedIOBase = BinaryIO
|
||||
|
||||
|
||||
class PyCTRError(Exception):
|
||||
"""Common base class for all PyCTR errors."""
|
||||
|
||||
|
||||
def _raise_if_closed(method):
|
||||
@wraps(method)
|
||||
def decorator(self: '_ReaderOpenFileBase', *args, **kwargs):
|
||||
if self._reader.closed:
|
||||
self.closed = True
|
||||
if self.closed:
|
||||
raise ValueError('I/O operation on closed file')
|
||||
return method(self, *args, **kwargs)
|
||||
return decorator
|
||||
|
||||
|
||||
class _ReaderOpenFileBase(BufferedIOBase):
|
||||
"""Base class for all open files for Reader classes."""
|
||||
|
||||
_seek = 0
|
||||
_info = None
|
||||
closed = False
|
||||
|
||||
def __init__(self, reader, path):
|
||||
self._reader = reader
|
||||
self._path = path
|
||||
|
||||
def __repr__(self):
|
||||
return f'<{type(self).__name__} path={self._path!r} info={self._info!r} reader={self._reader!r}>'
|
||||
|
||||
@_raise_if_closed
|
||||
def read(self, size: int = -1) -> bytes:
|
||||
if size == -1:
|
||||
size = self._info.size - self._seek
|
||||
data = self._reader.get_data(self._info, self._seek, size)
|
||||
self._seek += len(data)
|
||||
return data
|
||||
|
||||
read1 = read # probably make this act like read1 should, but this for now enables some other things to work
|
||||
|
||||
@_raise_if_closed
|
||||
def seek(self, seek: int, whence: int = 0) -> int:
|
||||
if whence == 0:
|
||||
if seek < 0:
|
||||
raise ValueError(f'negative seek value {seek}')
|
||||
self._seek = min(seek, self._info.size)
|
||||
elif whence == 1:
|
||||
self._seek = max(self._seek + seek, 0)
|
||||
elif whence == 2:
|
||||
self._seek = max(self._info.size + seek, 0)
|
||||
return self._seek
|
||||
|
||||
@_raise_if_closed
|
||||
def tell(self) -> int:
|
||||
return self._seek
|
||||
|
||||
@_raise_if_closed
|
||||
def readable(self) -> bool:
|
||||
return True
|
||||
|
||||
@_raise_if_closed
|
||||
def writable(self) -> bool:
|
||||
return False
|
||||
|
||||
@_raise_if_closed
|
||||
def seekable(self) -> bool:
|
||||
return True
|
||||
Reference in New Issue
Block a user