diff --git a/pythoncardx/framework/tlv/__init__.py b/pythoncardx/framework/tlv/__init__.py index b9c6c86..6a3eb00 100644 --- a/pythoncardx/framework/tlv/__init__.py +++ b/pythoncardx/framework/tlv/__init__.py @@ -1,4 +1,4 @@ -from javacard.framework import CardRuntimeException +from pythoncard.framework import CardRuntimeException class TLVException(CardRuntimeException): EMPTY_TAG = 0 @@ -13,6 +13,8 @@ class TLVException(CardRuntimeException): TLV_LENGTH_GREATER_THAN_32767 = 9 TLV_SIZE_GREATER_THAN_32767 = 10 -from pythoncard.framework.tlv import bertag +from pythoncardx.framework.tlv import bertag BERTag = bertag.BERTag +PrimitiveBERTag = bertag.PrimitiveBERTag +ConstructedBERTag = bertag.ConstructedBERTag diff --git a/pythoncardx/framework/tlv/bertag.py b/pythoncardx/framework/tlv/bertag.py index 6e9fc9b..4757cca 100644 --- a/pythoncardx/framework/tlv/bertag.py +++ b/pythoncardx/framework/tlv/bertag.py @@ -1,6 +1,11 @@ -""" -It's 2.2 ... not that prioritary ... -""" +from pythoncardx.framework.tlv import TLVException + +class toBytes(object): + def __get__(self, obj, objtype=None): + if obj is not None: + return obj._toBytesBound + else: + return BERTag._toBytesStatic class BERTag(object): BER_TAG_CLASS_MASK_APPLICATION = 0 @@ -11,16 +16,87 @@ class BERTag(object): BER_TAG_TYPE_PRIMITIVE = 5 def __init__(self): - self._tag = 0 - self._length = 0 - self._value = [] - - def equals(self, otherTag): - pass - - @classmethod - def getInstance(classs, bArray, bOff): - c = classs() - c.init(bArray, bOff) - return c + self._tagClass = 0 + self._tagNumber = 0 + + def init(self, bArray, bOff): + self._tagClass = bArray[bOff] >> 6 + if (bArray[bOff] & 0x1f) == 0x1f: + self._tagNumber = 0 + bOff += 1 + while (bArray[bOff] & 0x80) == 0x80: + self._tagNumber = self._tagNumber << 7 + self._tagNumber += bArray[bOff] & 0x7f + bOff += 1 + self._tagNumber = self._tagNumber << 7 + self._tagNumber += bArray[bOff] & 0x7f + else: + self._tagNumber = bArray[bOff] & 0x1f + + def _toBytesBound(self, outBuf, bOffset): + outBuf[bOffset] = self._tagClass << 6 + outBuf[bOffset] += self._PC << 5 + if self._tagNumber <= 30: + outBuf[bOffset] += self._tagNumber + return 1 + else: + tagNumber = self._tagNumber + outBuf[bOffset] += 0x1f + chunks = [] + while tagNumber > 0: + chunks.append(tagNumber & 0x7f) + tagNumber = tagNumber >> 7 + bLen = 1 + for i in reversed(chunks): + outBuf[bOffset+bLen] = 0x80 + outBuf[bOffset+bLen] += i + bLen += 1 + #clear the high bit on the last part + outBuf[bOffset+bLen-1] &= 0x7f + return bLen + + @staticmethod + def _toBytesStatic(tagClass, isConstructed, tagNumber, outArray, bOff): + tag = {True: ConstructedBERTag, + False: PrimitiveBERTag}[isConstructed]() + tag.init(tagClass, tagNumber) + return tag.toBytes(outArray, bOff) + + toBytes = toBytes() + +class PrimitiveBERTag(BERTag): + def __init__(self): + BERTag.__init__(self) + self._PC = 0 # primitive + + def init(self, param1, param2): + self._tagClass = None + self._tagNumber = None + if isinstance(param1, list): + if (param1[param2] & 0x20) == 0x20: + # constructed tag + raise TLVException(TLVException.MALFORMED_TAG) + BERTag.init(self, param1, param2) + else: + tagClass = param1 + tagNumber = param2 + self._tagClass = tagClass + self._tagNumber = tagNumber + +class ConstructedBERTag(BERTag): + def __init__(self): + BERTag.__init__(self) + self._PC = 1 # constructed + + def init(self, param1, param2): + self._tagClass = None + self._tagNumber = None + if isinstance(param1, list): + if (param1[param2] & 0x20) == 0: + # primitive tag + raise TLVException(TLVException.MALFORMED_TAG) + BERTag.init(self, param1, param2) + else: + self._tagClass = param1 + self._tagNumber = param2 diff --git a/test/testTLVTag.py b/test/testTLVTag.py new file mode 100644 index 0000000..2b68933 --- /dev/null +++ b/test/testTLVTag.py @@ -0,0 +1,15 @@ +import unittest + +from pythoncardx.framework.tlv import BERTag, PrimitiveBERTag, ConstructedBERTag + +class BERTagTest(unittest.TestCase): + + def testtoBytes(self): + array = [0 for i in xrange(10)] + self.assertEquals(1, BERTag.toBytes(1, False, 5, array, 0)) + self.assertEquals(0x45, array[0]) + + self.assertEquals(3, BERTag.toBytes(1, False, 0x3fff, array, 0)) + self.assertEquals(0x5f, array[0]) + self.assertEquals(0xff, array[1]) + self.assertEquals(0x7f, array[2])