#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys import re import types import binascii class EnvBuffer(): addr = None data = None # partition dump offset = None # ENV offset in partition len = 0 max_size = None var = {} # key=value encoding = 'ascii' crc_prefix = True delim = '\x00' def __init__(self, data = None, delim = '\x00', crc_prefix = True, encoding = 'ascii'): self.encoding = encoding self.delim = delim self.crc_prefix = crc_prefix self.var = {} if data is not None: prefix_len = 4 if crc_prefix else 0 if isinstance(data, str): self.var = self.parse_env(data, delim) else: end = data.find((delim + delim).encode(encoding), prefix_len) if (end > prefix_len): data = data[prefix_len:end+1] self.var = self.parse_env_b(data, delim, encoding) def parse_env_b(self, data, delim, encoding = 'ascii'): dict = {} self.len = len(data) data = data.split(delim.encode('ascii')) for i, s in enumerate(data): s = s.strip() if len(s) < 1: continue x = s.find(b'=') if x == 0: continue if x >= 1: key = s[0:x].decode(encoding) val = s[x+1:].decode(encoding) dict[key.strip()] = val.strip() else: key = s.decode(encoding) dict[key.strip()] = None return dict def parse_env(self, data, delim): dict = {} self.len = len(data) data = data.split(delim) for i, s in enumerate(data): s = s.strip() if len(s) < 1: continue x = s.find('=') if x == 0: continue if x >= 1: key = (s[0:x]).strip() if key: dict[key] = (s[x+1:]).strip() else: dict[s.strip()] = None return dict def set_env(self, key, value): var[key] = value def pack(self, bufsize, crc_prefix = None, encoding = None): crc_prefix = crc_prefix if crc_prefix is not None else self.crc_prefix encoding = encoding if encoding is not None else self.encoding buf = b'' if self.var: for i, (k, v) in enumerate(self.var.items()): v = '' if (v is None) else ('=' + v) buf += (k + v + '\x00').encode(encoding) if len(buf) + 64 > bufsize: raise OSError("Buffer overflow") prefix_len = 4 if crc_prefix else 0 buf += b'\x00' * (bufsize - len(buf) - prefix_len) crc = binascii.crc32(buf) buf = (crc).to_bytes(4, byteorder='little') + buf return buf