uttlv


Nameuttlv JSON
Version 0.7.1 PyPI version JSON
download
home_pagehttps://github.com/ustropo/uttlv
SummaryPython Library for TLV objects
upload_time2024-03-12 17:14:46
maintainer
docs_urlNone
authorFernando Cleber de Souza
requires_python>=3.7,<4.0
licenseMIT
keywords tlv
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # TLV Python Parser - Version 0.7.1

A **Tag-Length-Value** (also known as **Type-Length-Value**) is an encoding scheme used for many protocols.

The _tag_ is fixed in size (can be set from 1 to 4 bytes).
The _length_ is automatically determined by how many bytes it would take to represent the size of the _value_ by default, 
but could be set to a fixed size (from 1 to 4 bytes). The _value_ field is of variable size.

The fields are:

* __Tag__: An alphanumeric code that represents the kind of field the object represents;
* __Length__: Size of the value field (in bytes);
* __Value__: Variable-sized series of bytes which contains data for this field object.

Advantages of using TLV:

*  Sequences are usually easy to parse;
*  Unknown tags or elements can be skipped or ignored, so new versions can be added without a problem;
*  Elements can be placed in any order;
*  New elements can be created without breaking the protocol itself or the parsing function.

For more information, you can see: https://en.wikipedia.org/wiki/Type-length-value

## Installation

You can install directly from PyPI:

```
  pip install uttlv
```

Or download the source code and install using pip:
```
  pip install .
```

## How to use

To start using this package, just import the package and create an object

```python
  from uttlv import TLV

  # Create object
  t = TLV()
```

To add a tag to object, do it like a dict value:

```python
  # A tag of int value
  t[0x01] = 10
  # A tag of string value
  t[0x02] = 'test'
  # A tag of an array of bytes
  t[0x03] = bytes([1, 2, 3])
  # Or another TLV object
  another_one = TLV()
  another_one[0x05] = 234
  t[0x04] = another_one
```

A tag can only be _int_, _str_, _bytes_ or a _TLV_ itself. Any other type will raise a _TypeError_ exception.
If a tag is inserted and another object with same tag value already exists on the object, the tag will be overriden with the new value.

To get the underlying array, just call `to_byte_array()` method:

```python
  arr = t.to_byte_array()
  print('TLV:', arr)
```


## Parse

To parse an array, just call the method `parse_array()`:

```python
  # create object
  t = TLV()
  # parse from object
  data = bytes([0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A])
  t.parse_array(data)
```


## Pretty print

If you call `tree()`, the object will create a string with a _tree-like_ structure to print:

```python
  from prtlv import TLV

  # Create object
  t = TLV()
  # Add value
  t[0x01] = 10
  # Print it
  print('Value:\n', t.tree())
  ## <output>
  ## Value: 
  ## 1: 10
  ##
```

## _Tag_ map

You can also add a dictionary to map a tag to its underline class type, so it's showed as correct type
instead of a bytearray.

The dictionary must have all keys as the tag values and its respective values as the class type of the 
tag:

```python
  config = {
      0x01: {TLV.Config.Type: int, TLV.Config.Name: 'NUM_POINTS'},
      0x02: {TLV.Config.Type: int, TLV.Config.Name: 'IDLE_PERIOD'},
      0x03: {TLV.Config.Type: str, TLV.Config.Name: 'NAME'},
      0x04: {TLV.Config.Type: str, TLV.Config.Name: 'CITY'},
      0x05: {TLV.Config.Type: bytes, TLV.Config.Name: 'VERSION'},
      0x06: {TLV.Config.Type: bytes, TLV.Config.Name: 'DATA'},
      0x07: {TLV.Config.Type: TLV, TLV.Config.Name: 'RELATED'},
      0x08: {TLV.Config.Type: TLV, TLV.Config.Name: 'COMMENT'},
      0x09: {TLV.Config.Type: TLV, TLV.Config.Name: 'Empty'}
  }

  # Set global default map
  TLV.set_global_tag_map(config)

  # Set tag map for a specific instance (this will override the global setting)
  t = TLV()
  t.set_local_tag_map(config)
```

For now, only 'int', 'str', 'bytes', 'TLV', and a dictionary are accepted as valid classes. Any other class will raise
AttributeError.

If a tag map is configured, one can use the tag name to access its value:

```python
 t = TLV()
 t['NUM_POINTS'] = 10
 print(t['NUM_POINTS'])
```

Nested tag maps can be configured by replacing the configured type with another configuration dictionary:

```python
  config = {
    0x01: {TLV.Config.Name: 'FIRST_NEST', TLV.Config.Type: {
      0x01: {TLV.Config.Name: 'SECOND_NEST', TLV.Config.Type: {
        0x01: {TLV.Config.Name: 'THIRD_NEST', TLV.Config.Type: int}
      }}
    }}
  }
```

And also can print it with all tag names instead of values:

```python
 t.tree(use_names=True)
 ## <output>
 ## NUM_POINTS: 10
```

You can access also the tags directly:

```python
 t = TLV()
 t['NUM_POINTS'] = 10
 print(t.NUM_POINTS)
```

By default, a field defined as type str in the tag map would be encoded or decoded as utf-8. The encoder can be replaced
to use utf16, utf32 or ascii by setting it in 

```python
 uttlv.tlv.ALLOWED_TYPES[str] = uttlv.tlv.encoder.Utf16Encoder
```
or 
```python
 uttlv.tlv.ALLOWED_TYPES[str] = uttlv.tlv.encoder.Utf32Encoder
```
or 
```python
 uttlv.tlv.ALLOWED_TYPES[str] = uttlv.tlv.encoder.AsciiEncoder
```
respectively.

## Iterator

You can iterate through the available tags inside a TLV object by using `iter()`:

```python
t = TLV()
t.parse_array(bytes(command_data))

for command in t:
  pass
```
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ustropo/uttlv",
    "name": "uttlv",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7,<4.0",
    "maintainer_email": "",
    "keywords": "tlv",
    "author": "Fernando Cleber de Souza",
    "author_email": "cleberdsouza@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/59/1b/38936eb5e223ec7655db94d982943e698eea41da32a6d7263cdf7ee0f04f/uttlv-0.7.1.tar.gz",
    "platform": null,
    "description": "# TLV Python Parser - Version 0.7.1\n\nA **Tag-Length-Value** (also known as **Type-Length-Value**) is an encoding scheme used for many protocols.\n\nThe _tag_ is fixed in size (can be set from 1 to 4 bytes).\nThe _length_ is automatically determined by how many bytes it would take to represent the size of the _value_ by default, \nbut could be set to a fixed size (from 1 to 4 bytes). The _value_ field is of variable size.\n\nThe fields are:\n\n* __Tag__: An alphanumeric code that represents the kind of field the object represents;\n* __Length__: Size of the value field (in bytes);\n* __Value__: Variable-sized series of bytes which contains data for this field object.\n\nAdvantages of using TLV:\n\n*  Sequences are usually easy to parse;\n*  Unknown tags or elements can be skipped or ignored, so new versions can be added without a problem;\n*  Elements can be placed in any order;\n*  New elements can be created without breaking the protocol itself or the parsing function.\n\nFor more information, you can see: https://en.wikipedia.org/wiki/Type-length-value\n\n## Installation\n\nYou can install directly from PyPI:\n\n```\n  pip install uttlv\n```\n\nOr download the source code and install using pip:\n```\n  pip install .\n```\n\n## How to use\n\nTo start using this package, just import the package and create an object\n\n```python\n  from uttlv import TLV\n\n  # Create object\n  t = TLV()\n```\n\nTo add a tag to object, do it like a dict value:\n\n```python\n  # A tag of int value\n  t[0x01] = 10\n  # A tag of string value\n  t[0x02] = 'test'\n  # A tag of an array of bytes\n  t[0x03] = bytes([1, 2, 3])\n  # Or another TLV object\n  another_one = TLV()\n  another_one[0x05] = 234\n  t[0x04] = another_one\n```\n\nA tag can only be _int_, _str_, _bytes_ or a _TLV_ itself. Any other type will raise a _TypeError_ exception.\nIf a tag is inserted and another object with same tag value already exists on the object, the tag will be overriden with the new value.\n\nTo get the underlying array, just call `to_byte_array()` method:\n\n```python\n  arr = t.to_byte_array()\n  print('TLV:', arr)\n```\n\n\n## Parse\n\nTo parse an array, just call the method `parse_array()`:\n\n```python\n  # create object\n  t = TLV()\n  # parse from object\n  data = bytes([0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A])\n  t.parse_array(data)\n```\n\n\n## Pretty print\n\nIf you call `tree()`, the object will create a string with a _tree-like_ structure to print:\n\n```python\n  from prtlv import TLV\n\n  # Create object\n  t = TLV()\n  # Add value\n  t[0x01] = 10\n  # Print it\n  print('Value:\\n', t.tree())\n  ## <output>\n  ## Value: \n  ## 1: 10\n  ##\n```\n\n## _Tag_ map\n\nYou can also add a dictionary to map a tag to its underline class type, so it's showed as correct type\ninstead of a bytearray.\n\nThe dictionary must have all keys as the tag values and its respective values as the class type of the \ntag:\n\n```python\n  config = {\n      0x01: {TLV.Config.Type: int, TLV.Config.Name: 'NUM_POINTS'},\n      0x02: {TLV.Config.Type: int, TLV.Config.Name: 'IDLE_PERIOD'},\n      0x03: {TLV.Config.Type: str, TLV.Config.Name: 'NAME'},\n      0x04: {TLV.Config.Type: str, TLV.Config.Name: 'CITY'},\n      0x05: {TLV.Config.Type: bytes, TLV.Config.Name: 'VERSION'},\n      0x06: {TLV.Config.Type: bytes, TLV.Config.Name: 'DATA'},\n      0x07: {TLV.Config.Type: TLV, TLV.Config.Name: 'RELATED'},\n      0x08: {TLV.Config.Type: TLV, TLV.Config.Name: 'COMMENT'},\n      0x09: {TLV.Config.Type: TLV, TLV.Config.Name: 'Empty'}\n  }\n\n  # Set global default map\n  TLV.set_global_tag_map(config)\n\n  # Set tag map for a specific instance (this will override the global setting)\n  t = TLV()\n  t.set_local_tag_map(config)\n```\n\nFor now, only 'int', 'str', 'bytes', 'TLV', and a dictionary are accepted as valid classes. Any other class will raise\nAttributeError.\n\nIf a tag map is configured, one can use the tag name to access its value:\n\n```python\n t = TLV()\n t['NUM_POINTS'] = 10\n print(t['NUM_POINTS'])\n```\n\nNested tag maps can be configured by replacing the configured type with another configuration dictionary:\n\n```python\n  config = {\n    0x01: {TLV.Config.Name: 'FIRST_NEST', TLV.Config.Type: {\n      0x01: {TLV.Config.Name: 'SECOND_NEST', TLV.Config.Type: {\n        0x01: {TLV.Config.Name: 'THIRD_NEST', TLV.Config.Type: int}\n      }}\n    }}\n  }\n```\n\nAnd also can print it with all tag names instead of values:\n\n```python\n t.tree(use_names=True)\n ## <output>\n ## NUM_POINTS: 10\n```\n\nYou can access also the tags directly:\n\n```python\n t = TLV()\n t['NUM_POINTS'] = 10\n print(t.NUM_POINTS)\n```\n\nBy default, a field defined as type str in the tag map would be encoded or decoded as utf-8. The encoder can be replaced\nto use utf16, utf32 or ascii by setting it in \n\n```python\n uttlv.tlv.ALLOWED_TYPES[str] = uttlv.tlv.encoder.Utf16Encoder\n```\nor \n```python\n uttlv.tlv.ALLOWED_TYPES[str] = uttlv.tlv.encoder.Utf32Encoder\n```\nor \n```python\n uttlv.tlv.ALLOWED_TYPES[str] = uttlv.tlv.encoder.AsciiEncoder\n```\nrespectively.\n\n## Iterator\n\nYou can iterate through the available tags inside a TLV object by using `iter()`:\n\n```python\nt = TLV()\nt.parse_array(bytes(command_data))\n\nfor command in t:\n  pass\n```",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python Library for TLV objects",
    "version": "0.7.1",
    "project_urls": {
        "Homepage": "https://github.com/ustropo/uttlv",
        "Repository": "https://github.com/ustropo/uttlv"
    },
    "split_keywords": [
        "tlv"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "71b4c1c2ce613c48e7925010fa63aff1282ef0a04eaf898a3c1e331521c4fbd6",
                "md5": "f4a038637ac8ebe94cdbef1b14d1f0f1",
                "sha256": "0729452afa2de5531e1d624c382ac44c72c6aecb1de1acd249a1bed74aafc72c"
            },
            "downloads": -1,
            "filename": "uttlv-0.7.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f4a038637ac8ebe94cdbef1b14d1f0f1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7,<4.0",
            "size": 8766,
            "upload_time": "2024-03-12T17:14:15",
            "upload_time_iso_8601": "2024-03-12T17:14:15.400852Z",
            "url": "https://files.pythonhosted.org/packages/71/b4/c1c2ce613c48e7925010fa63aff1282ef0a04eaf898a3c1e331521c4fbd6/uttlv-0.7.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "591b38936eb5e223ec7655db94d982943e698eea41da32a6d7263cdf7ee0f04f",
                "md5": "ef746622ea033c547d1f14b0a6e7a599",
                "sha256": "68c39b83383ca93a1e229ed1bdefb648cab49e272bff05803004bf80392ae5a7"
            },
            "downloads": -1,
            "filename": "uttlv-0.7.1.tar.gz",
            "has_sig": false,
            "md5_digest": "ef746622ea033c547d1f14b0a6e7a599",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7,<4.0",
            "size": 8845,
            "upload_time": "2024-03-12T17:14:46",
            "upload_time_iso_8601": "2024-03-12T17:14:46.871469Z",
            "url": "https://files.pythonhosted.org/packages/59/1b/38936eb5e223ec7655db94d982943e698eea41da32a6d7263cdf7ee0f04f/uttlv-0.7.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-12 17:14:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ustropo",
    "github_project": "uttlv",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "uttlv"
}
        
Elapsed time: 0.19203s