Skip to content
This repository has been archived by the owner on May 9, 2023. It is now read-only.

WIP: Support private ranges #12

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions multicodec/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,4 @@

NAME_TABLE = {name: value['prefix'] for name, value in CODECS.items()}
CODE_TABLE = {value['prefix']: name for name, value in CODECS.items()}
PRIVATE_RANGE = (0x300000, 0x3FFFFF)
29 changes: 24 additions & 5 deletions multicodec/multicodec.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import varint

from .constants import NAME_TABLE, CODE_TABLE
from .constants import NAME_TABLE, CODE_TABLE, PRIVATE_RANGE


def extract_prefix(bytes_):
Expand All @@ -22,11 +22,14 @@ def get_prefix(multicodec):
"""
Returns prefix for a given multicodec

:param str multicodec: multicodec codec name
:param str / int multicodec: str for multicodec name, int if you wish to use a private code
:return: the prefix for the given multicodec
:rtype: byte
:raises ValueError: if an invalid multicodec name is provided
"""
if is_private_codec(multicodec):
return varint.encode(multicodec)

try:
prefix = varint.encode(NAME_TABLE[multicodec])
except KeyError:
Expand All @@ -38,7 +41,7 @@ def add_prefix(multicodec, bytes_):
"""
Adds multicodec prefix to the given bytes input

:param str multicodec: multicodec to use for prefixing
:param str / int multicodec: str for multicodec to use for prefixing, int if you wish to use a private code
:param bytes bytes_: data to prefix
:return: prefixed byte data
:rtype: bytes
Expand All @@ -65,16 +68,32 @@ def get_codec(bytes_):
Gets the codec used for prefix the multicodec prefixed data

:param bytes bytes_: multicodec prefixed data bytes
:return: name of the multicodec used to prefix
:rtype: str
:return: name of the multicodec used to prefix, int codec if it is part of private space
:rtype: str / int
"""
prefix = extract_prefix(bytes_)
if is_private_codec(prefix):
return prefix

try:
return CODE_TABLE[prefix]
except KeyError:
raise ValueError('Prefix {} not present in the lookup table'.format(prefix))


def is_private_codec(codec):
"""
Check if the codec is within the private range or not

:param int codec: codec to check for permitted to use under private space
:return: True if the codec lies within the private usage range, False otherwise
:rtype: bool
"""
if isinstance(codec, int) and PRIVATE_RANGE[0] <= codec <= PRIVATE_RANGE[1]:
return True
return False


def is_codec(name):
"""
Check if the codec is a valid codec or not
Expand Down
11 changes: 11 additions & 0 deletions tests/test_multicodec.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ def test_verify_prefix_complete(multicodec, prefix):
assert extract_prefix(prefixed_data) == prefix_int


@pytest.mark.parametrize('multicodec', (0x300000, 0x3FFFFF,))
def test_verify_private_range_complete(multicodec):
data = b'testbytesbuffer'
prefix_int = multicodec
prefixed_data = add_prefix(multicodec, data)

assert get_codec(prefixed_data) == multicodec
assert remove_prefix(prefixed_data) == data
assert extract_prefix(prefixed_data) == prefix_int


@pytest.mark.parametrize('multicodec,_', INVALID_CODECS)
def test_get_prefix_invalid_prefix(multicodec, _):
with pytest.raises(ValueError) as excinfo:
Expand Down