#!/usr/bin/python
# -- Content-Encoding: utf-8 --
"""
Implements the support of the Java-specific kind of UTF-8 encoding.
This module is a modified version of ``py2jdbc.mutf8`` provided by
`@guywithface `_.
The project the original file comes from is available at:
https://github.com/swstephe/py2jdbc/
:authors: Scott Stephens (@swstephe), @guywithface
:license: Apache License 2.0
:version: 0.6.1
:status: Alpha
"""
import sys
# Module version
__version_info__ = (0, 6, 1)
__version__ = ".".join(str(x) for x in __version_info__)
# Documentation strings format
__docformat__ = "restructuredtext en"
# Note: this module deliberately does NOT `from __future__ import
# unicode_literals`. UnicodeDecodeError requires its encoding-name,
# object and reason arguments to be the *native* str type; on Python 2
# that means plain bytes-string literals, not unicode ones.
# Encoding name: not cesu-8, which uses a different zero-byte
NAME = "mutf8"
# ------------------------------------------------------------------------------
if sys.version_info[0] >= 3:
unicode_char = chr # pylint:disable=C0103
def byte_to_int(data):
# type: (bytes) -> int
"""
Converts the first byte of the given data to an integer
"""
if isinstance(data, int):
return data
if isinstance(data, bytes):
return data[0]
raise ValueError(
"Expected byte or int as input, got: {0}".format(
type(data).__name__
)
)
else:
unicode_char = (
unichr # pylint:disable=C0103,undefined-variable # noqa: F821
)
def byte_to_int(data):
# type: (bytes) -> int
"""
Converts the first byte of the given data to an integer
"""
if isinstance(data, int):
return data
if isinstance(data, str):
return ord(data[0])
raise ValueError(
"Expected byte or int as input, got: {0}".format(
type(data).__name__
)
)
# ------------------------------------------------------------------------------
class DecodeMap(object): # pylint:disable=R0205
"""
A utility class which manages masking, comparing and mapping in bits.
If the mask and compare fails, this will raise UnicodeDecodeError so
encode and decode will correctly handle bad characters.
"""
def __init__(self, count, mask, value, bits):
"""
Initialize a DecodeMap, entry from a static dictionary for the module.
It automatically calculates the mask for the bits for the value
(always assumed to be at the bottom of the byte).
:param count: The number of bytes in this entire sequence.
:param mask: The mask to apply to the byte at this position.
:param value: The value of masked bits, (without shifting).
:param bits: The number of bits.
"""
self.count = count
self.mask = mask
self.value = value
self.bits = bits
self.mask2 = (1