Files
Android-pyApi/android_pyapi/java/nio.py
T
shuiyu1123 bfe27fdc08 feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python
52 个模块覆盖 Android + Java + org.json 标准库
2026-06-24 11:16:16 +00:00

622 lines
21 KiB
Python

"""
Java NIO standard library APIs implemented in Python.
java.nio package - Buffer, ByteBuffer, CharBuffer, etc.
"""
from .._core import Stub
from .lang import RuntimeException
from .io import IOException
import struct as _struct
import sys as _sys
IllegalStateException = type("IllegalStateException", (RuntimeException,), {})
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
__all__ = [
"Buffer", "ByteBuffer", "CharBuffer", "ShortBuffer",
"IntBuffer", "LongBuffer", "FloatBuffer", "DoubleBuffer",
"MappedByteBuffer", "ByteOrder",
"BufferOverflowException", "BufferUnderflowException",
"ReadOnlyBufferException", "InvalidMarkException",
]
# ============================================================
# Exception classes
# ============================================================
class BufferOverflowException(RuntimeException):
pass
class BufferUnderflowException(RuntimeException):
pass
class ReadOnlyBufferException(RuntimeException):
pass
class InvalidMarkException(IllegalStateException):
pass
# ============================================================
# ByteOrder
# ============================================================
class ByteOrder(Stub):
BIG_ENDIAN = None
LITTLE_ENDIAN = None
def __init__(self, name):
super().__init__()
self._name = name
@staticmethod
def nativeOrder():
if _sys.byteorder == "little":
return ByteOrder.LITTLE_ENDIAN
return ByteOrder.BIG_ENDIAN
def toString(self):
return self._name
ByteOrder.BIG_ENDIAN = ByteOrder("BIG_ENDIAN")
ByteOrder.LITTLE_ENDIAN = ByteOrder("LITTLE_ENDIAN")
# ============================================================
# Buffer
# ============================================================
class Buffer(Stub):
def __init__(self, capacity, backing=None):
super().__init__()
self._capacity = capacity
self._position = 0
self._limit = capacity
self._mark = -1
self._backing = backing if backing is not None else bytearray(capacity)
self._read_only = False
def capacity(self):
return self._capacity
def position(self):
return self._position
def position(self, new_position):
if new_position < 0 or new_position > self._limit:
raise IllegalArgumentException("Invalid position")
self._position = new_position
return self
def limit(self):
return self._limit
def limit(self, new_limit):
if new_limit < 0 or new_limit > self._capacity:
raise IllegalArgumentException("Invalid limit")
self._limit = new_limit
if self._position > self._limit:
self._position = self._limit
if self._mark > self._limit:
self._mark = -1
return self
def mark(self):
self._mark = self._position
return self
def reset(self):
if self._mark < 0:
raise InvalidMarkException()
self._position = self._mark
return self
def clear(self):
self._position = 0
self._limit = self._capacity
self._mark = -1
return self
def flip(self):
self._limit = self._position
self._position = 0
self._mark = -1
return self
def rewind(self):
self._position = 0
self._mark = -1
return self
def remaining(self):
return self._limit - self._position
def hasRemaining(self):
return self._position < self._limit
def isReadOnly(self):
return self._read_only
def isDirect(self):
return False
def array(self):
if self._read_only:
raise ReadOnlyBufferException()
return self._backing
def arrayOffset(self):
return 0
# ============================================================
# ByteBuffer
# ============================================================
class ByteBuffer(Buffer):
def __init__(self, capacity, backing=None, order=None):
super().__init__(capacity, backing)
self._order = order or ByteOrder.BIG_ENDIAN
@staticmethod
def allocate(capacity):
return ByteBuffer(capacity, bytearray(capacity))
@staticmethod
def allocateDirect(capacity):
return ByteBuffer(capacity, bytearray(capacity))
@staticmethod
def wrap(array, offset=0, length=None):
if length is None:
length = len(array) - offset
buf = ByteBuffer(length, bytearray(array))
buf._position = offset
buf._limit = offset + length
return buf
def put(self, b, index=None):
if self._read_only:
raise ReadOnlyBufferException()
if index is None:
if isinstance(b, int):
if self._position >= self._limit:
raise BufferOverflowException()
self._backing[self._position] = b & 0xFF
self._position += 1
elif isinstance(b, ByteBuffer):
n = b.remaining()
if self.remaining() < n:
raise BufferOverflowException()
self._backing[self._position:self._position+n] = b._backing[b._position:b._limit]
self._position += n
b._position = b._limit
elif isinstance(b, (bytes, bytearray)):
if self.remaining() < len(b):
raise BufferOverflowException()
self._backing[self._position:self._position+len(b)] = b
self._position += len(b)
else:
self._backing[index] = b & 0xFF
return self
def get(self, index=None):
if index is None:
if self._position >= self._limit:
raise BufferUnderflowException()
val = self._backing[self._position]
self._position += 1
return val & 0xFF
return self._backing[index] & 0xFF
def putInt(self, value, index=None):
data = _struct.pack(">i" if self._order == ByteOrder.BIG_ENDIAN else "<i", value)
if index is not None:
self._backing[index:index+4] = data
else:
if self.remaining() < 4:
raise BufferOverflowException()
self._backing[self._position:self._position+4] = data
self._position += 4
return self
def getInt(self, index=None):
if index is not None:
data = self._backing[index:index+4]
else:
if self.remaining() < 4:
raise BufferUnderflowException()
data = self._backing[self._position:self._position+4]
self._position += 4
return _struct.unpack(">i" if self._order == ByteOrder.BIG_ENDIAN else "<i", bytes(data))[0]
def putLong(self, value, index=None):
data = _struct.pack(">q" if self._order == ByteOrder.BIG_ENDIAN else "<q", value)
if index is not None:
self._backing[index:index+8] = data
else:
if self.remaining() < 8:
raise BufferOverflowException()
self._backing[self._position:self._position+8] = data
self._position += 8
return self
def getLong(self, index=None):
if index is not None:
data = self._backing[index:index+8]
else:
if self.remaining() < 8:
raise BufferUnderflowException()
data = self._backing[self._position:self._position+8]
self._position += 8
return _struct.unpack(">q" if self._order == ByteOrder.BIG_ENDIAN else "<q", bytes(data))[0]
def putFloat(self, value, index=None):
data = _struct.pack(">f" if self._order == ByteOrder.BIG_ENDIAN else "<f", value)
if index is not None:
self._backing[index:index+4] = data
else:
if self.remaining() < 4:
raise BufferOverflowException()
self._backing[self._position:self._position+4] = data
self._position += 4
return self
def getFloat(self, index=None):
if index is not None:
data = self._backing[index:index+4]
else:
if self.remaining() < 4:
raise BufferUnderflowException()
data = self._backing[self._position:self._position+4]
self._position += 4
return _struct.unpack(">f" if self._order == ByteOrder.BIG_ENDIAN else "<f", bytes(data))[0]
def putDouble(self, value, index=None):
data = _struct.pack(">d" if self._order == ByteOrder.BIG_ENDIAN else "<d", value)
if index is not None:
self._backing[index:index+8] = data
else:
if self.remaining() < 8:
raise BufferOverflowException()
self._backing[self._position:self._position+8] = data
self._position += 8
return self
def getDouble(self, index=None):
if index is not None:
data = self._backing[index:index+8]
else:
if self.remaining() < 8:
raise BufferUnderflowException()
data = self._backing[self._position:self._position+8]
self._position += 8
return _struct.unpack(">d" if self._order == ByteOrder.BIG_ENDIAN else "<d", bytes(data))[0]
def putShort(self, value, index=None):
data = _struct.pack(">h" if self._order == ByteOrder.BIG_ENDIAN else "<h", value)
if index is not None:
self._backing[index:index+2] = data
else:
if self.remaining() < 2:
raise BufferOverflowException()
self._backing[self._position:self._position+2] = data
self._position += 2
return self
def getShort(self, index=None):
if index is not None:
data = self._backing[index:index+2]
else:
if self.remaining() < 2:
raise BufferUnderflowException()
data = self._backing[self._position:self._position+2]
self._position += 2
return _struct.unpack(">h" if self._order == ByteOrder.BIG_ENDIAN else "<h", bytes(data))[0]
def putChar(self, value, index=None):
return self.putShort(ord(value), index)
def getChar(self, index=None):
return chr(self.getShort(index))
def asIntBuffer(self):
return IntBuffer(self.remaining() // 4, self._backing, self._position, self._order)
def asLongBuffer(self):
return LongBuffer(self.remaining() // 8, self._backing, self._position, self._order)
def asFloatBuffer(self):
return FloatBuffer(self.remaining() // 4, self._backing, self._position, self._order)
def asDoubleBuffer(self):
return DoubleBuffer(self.remaining() // 8, self._backing, self._position, self._order)
def asShortBuffer(self):
return ShortBuffer(self.remaining() // 2, self._backing, self._position, self._order)
def asCharBuffer(self):
return CharBuffer(self.remaining() // 2, self._backing, self._position, self._order)
def slice(self):
n = self.remaining()
buf = ByteBuffer(n, self._backing[self._position:self._limit])
return buf
def duplicate(self):
buf = ByteBuffer(self._capacity, bytearray(self._backing))
buf._position = self._position
buf._limit = self._limit
buf._order = self._order
return buf
def asReadOnlyBuffer(self):
buf = self.duplicate()
buf._read_only = True
return buf
def order(self, order=None):
if order is not None:
self._order = order
return self
return self._order
def compact(self):
if self._read_only:
raise ReadOnlyBufferException()
remaining = self.remaining()
self._backing[:remaining] = self._backing[self._position:self._limit]
self._position = remaining
self._limit = self._capacity
self._mark = -1
return self
def toString(self):
return f"ByteBuffer[pos={self._position} lim={self._limit} cap={self._capacity}]"
def hashCode(self):
return hash(bytes(self._backing)) & 0x7FFFFFFF
def equals(self, other):
if isinstance(other, ByteBuffer):
return bytes(self._backing[self._position:self._limit]) == bytes(other._backing[other._position:other._limit])
return False
def compareTo(self, other):
if isinstance(other, ByteBuffer):
a = bytes(self._backing[self._position:self._limit])
b = bytes(other._backing[other._position:other._limit])
return (a > b) - (a < b)
return -1
# ============================================================
# IntBuffer
# ============================================================
class IntBuffer(Buffer):
def __init__(self, capacity, backing, offset=0, order=None):
super().__init__(capacity, backing)
self._int_order = order or ByteOrder.BIG_ENDIAN
self._int_offset = offset
def get(self, index=None):
if index is not None:
idx = self._int_offset + index * 4
return _struct.unpack(">i" if self._int_order == ByteOrder.BIG_ENDIAN else "<i",
bytes(self._backing[idx:idx+4]))[0]
if self.remaining() < 4:
raise BufferUnderflowException()
val = _struct.unpack(">i" if self._int_order == ByteOrder.BIG_ENDIAN else "<i",
bytes(self._backing[self._position:self._position+4]))[0]
self._position += 4
return val
def put(self, value, index=None):
data = _struct.pack(">i" if self._int_order == ByteOrder.BIG_ENDIAN else "<i", value)
if index is not None:
idx = self._int_offset + index * 4
self._backing[idx:idx+4] = data
else:
if self.remaining() < 4:
raise BufferOverflowException()
self._backing[self._position:self._position+4] = data
self._position += 4
return self
# ============================================================
# LongBuffer
# ============================================================
class LongBuffer(Buffer):
def __init__(self, capacity, backing, offset=0, order=None):
super().__init__(capacity, backing)
self._long_order = order or ByteOrder.BIG_ENDIAN
self._long_offset = offset
def get(self, index=None):
if index is not None:
idx = self._long_offset + index * 8
return _struct.unpack(">q" if self._long_order == ByteOrder.BIG_ENDIAN else "<q",
bytes(self._backing[idx:idx+8]))[0]
if self.remaining() < 8:
raise BufferUnderflowException()
val = _struct.unpack(">q" if self._long_order == ByteOrder.BIG_ENDIAN else "<q",
bytes(self._backing[self._position:self._position+8]))[0]
self._position += 8
return val
def put(self, value, index=None):
data = _struct.pack(">q" if self._long_order == ByteOrder.BIG_ENDIAN else "<q", value)
if index is not None:
idx = self._long_offset + index * 8
self._backing[idx:idx+8] = data
else:
if self.remaining() < 8:
raise BufferOverflowException()
self._backing[self._position:self._position+8] = data
self._position += 8
return self
# ============================================================
# FloatBuffer
# ============================================================
class FloatBuffer(Buffer):
def __init__(self, capacity, backing, offset=0, order=None):
super().__init__(capacity, backing)
self._float_order = order or ByteOrder.BIG_ENDIAN
self._float_offset = offset
def get(self, index=None):
if index is not None:
idx = self._float_offset + index * 4
return _struct.unpack(">f" if self._float_order == ByteOrder.BIG_ENDIAN else "<f",
bytes(self._backing[idx:idx+4]))[0]
if self.remaining() < 4:
raise BufferUnderflowException()
val = _struct.unpack(">f" if self._float_order == ByteOrder.BIG_ENDIAN else "<f",
bytes(self._backing[self._position:self._position+4]))[0]
self._position += 4
return val
def put(self, value, index=None):
data = _struct.pack(">f" if self._float_order == ByteOrder.BIG_ENDIAN else "<f", value)
if index is not None:
idx = self._float_offset + index * 4
self._backing[idx:idx+4] = data
else:
if self.remaining() < 4:
raise BufferOverflowException()
self._backing[self._position:self._position+4] = data
self._position += 4
return self
# ============================================================
# DoubleBuffer
# ============================================================
class DoubleBuffer(Buffer):
def __init__(self, capacity, backing, offset=0, order=None):
super().__init__(capacity, backing)
self._double_order = order or ByteOrder.BIG_ENDIAN
self._double_offset = offset
def get(self, index=None):
if index is not None:
idx = self._double_offset + index * 8
return _struct.unpack(">d" if self._double_order == ByteOrder.BIG_ENDIAN else "<d",
bytes(self._backing[idx:idx+8]))[0]
if self.remaining() < 8:
raise BufferUnderflowException()
val = _struct.unpack(">d" if self._double_order == ByteOrder.BIG_ENDIAN else "<d",
bytes(self._backing[self._position:self._position+8]))[0]
self._position += 8
return val
def put(self, value, index=None):
data = _struct.pack(">d" if self._double_order == ByteOrder.BIG_ENDIAN else "<d", value)
if index is not None:
idx = self._double_offset + index * 8
self._backing[idx:idx+8] = data
else:
if self.remaining() < 8:
raise BufferOverflowException()
self._backing[self._position:self._position+8] = data
self._position += 8
return self
# ============================================================
# ShortBuffer
# ============================================================
class ShortBuffer(Buffer):
def __init__(self, capacity, backing, offset=0, order=None):
super().__init__(capacity, backing)
self._short_order = order or ByteOrder.BIG_ENDIAN
self._short_offset = offset
def get(self, index=None):
if index is not None:
idx = self._short_offset + index * 2
return _struct.unpack(">h" if self._short_order == ByteOrder.BIG_ENDIAN else "<h",
bytes(self._backing[idx:idx+2]))[0]
if self.remaining() < 2:
raise BufferUnderflowException()
val = _struct.unpack(">h" if self._short_order == ByteOrder.BIG_ENDIAN else "<h",
bytes(self._backing[self._position:self._position+2]))[0]
self._position += 2
return val
def put(self, value, index=None):
data = _struct.pack(">h" if self._short_order == ByteOrder.BIG_ENDIAN else "<h", value)
if index is not None:
idx = self._short_offset + index * 2
self._backing[idx:idx+2] = data
else:
if self.remaining() < 2:
raise BufferOverflowException()
self._backing[self._position:self._position+2] = data
self._position += 2
return self
# ============================================================
# CharBuffer
# ============================================================
class CharBuffer(Buffer):
def __init__(self, capacity, backing, offset=0, order=None):
super().__init__(capacity, backing)
self._char_order = order or ByteOrder.BIG_ENDIAN
self._char_offset = offset
def get(self, index=None):
if index is not None:
idx = self._char_offset + index * 2
val = _struct.unpack(">h" if self._char_order == ByteOrder.BIG_ENDIAN else "<h",
bytes(self._backing[idx:idx+2]))[0]
return chr(val)
if self.remaining() < 2:
raise BufferUnderflowException()
val = _struct.unpack(">h" if self._char_order == ByteOrder.BIG_ENDIAN else "<h",
bytes(self._backing[self._position:self._position+2]))[0]
self._position += 2
return chr(val)
def put(self, value, index=None):
char_val = ord(value) if isinstance(value, str) else value
data = _struct.pack(">h" if self._char_order == ByteOrder.BIG_ENDIAN else "<h", char_val)
if index is not None:
idx = self._char_offset + index * 2
self._backing[idx:idx+2] = data
else:
if self.remaining() < 2:
raise BufferOverflowException()
self._backing[self._position:self._position+2] = data
self._position += 2
return self
# ============================================================
# MappedByteBuffer
# ============================================================
class MappedByteBuffer(ByteBuffer):
def __init__(self, capacity, backing=None):
super().__init__(capacity, backing)
def force(self):
return self
def isLoaded(self):
return True
def load(self):
return self