summaryrefslogtreecommitdiff
path: root/pyasn1/codec/ber/encoder.py
diff options
context:
space:
mode:
authorelie <elie>2011-01-26 13:54:41 +0000
committerelie <elie>2011-01-26 13:54:41 +0000
commitdc64479c3abcb7fe98c885dd1dec9c711f1be627 (patch)
tree0143ea09dedb784c28f05852b1726e0fae26e662 /pyasn1/codec/ber/encoder.py
parentd43f42495fb22fbd14753869f2be65ce6922160c (diff)
downloadpyasn1-dc64479c3abcb7fe98c885dd1dec9c711f1be627.tar.gz
major codec re-design, Any ASN.1 type implemented
Diffstat (limited to 'pyasn1/codec/ber/encoder.py')
-rw-r--r--pyasn1/codec/ber/encoder.py51
1 files changed, 38 insertions, 13 deletions
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index 760dea5..d7c749a 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -186,7 +186,7 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
return string.join(octets, ''), 0
-class SequenceOfEncoder(AbstractItemEncoder):
+class SequenceEncoder(AbstractItemEncoder):
def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
value.setDefaultComponents()
value.verifySizeSpec()
@@ -195,10 +195,20 @@ class SequenceOfEncoder(AbstractItemEncoder):
idx = idx - 1
if value[idx] is None: # Optional component
continue
- if isinstance(value, univ.SequenceAndSetBase):
- component = value.getDefaultComponentByPosition(idx)
- if component is not None and component == value[idx]:
- continue
+ component = value.getDefaultComponentByPosition(idx)
+ if component is not None and component == value[idx]:
+ continue
+ substrate = encodeFun(
+ value[idx], defMode, maxChunkSize
+ ) + substrate
+ return substrate, 1
+
+class SequenceOfEncoder(AbstractItemEncoder):
+ def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ value.verifySizeSpec()
+ substrate = ''; idx = len(value)
+ while idx > 0:
+ idx = idx - 1
substrate = encodeFun(
value[idx], defMode, maxChunkSize
) + substrate
@@ -208,7 +218,9 @@ class ChoiceEncoder(AbstractItemEncoder):
def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
return encodeFun(value.getComponent(), defMode, maxChunkSize), 1
-codecMap = {
+class AnyEncoder(OctetStringEncoder): pass
+
+tagMap = {
eoo.endOfOctets.tagSet: EndOfOctetsEncoder(),
univ.Boolean.tagSet: IntegerEncoder(),
univ.Integer.tagSet: IntegerEncoder(),
@@ -238,25 +250,38 @@ codecMap = {
useful.UTCTime.tagSet: OctetStringEncoder()
}
+# Type-to-codec map for ambiguous ASN.1 types
+typeMap = {
+ univ.Set.typeId: SequenceEncoder(),
+ univ.SetOf.typeId: SequenceOfEncoder(),
+ univ.Sequence.typeId: SequenceEncoder(),
+ univ.SequenceOf.typeId: SequenceOfEncoder(),
+ univ.Choice.typeId: ChoiceEncoder(),
+ univ.Any.typeId: AnyEncoder()
+ }
+
class Encoder:
- def __init__(self, _codecMap):
- self.__codecMap = _codecMap
+ def __init__(self, tagMap, typeMap={}):
+ self.__tagMap = tagMap
+ self.__typeMap = typeMap
def __call__(self, value, defMode=1, maxChunkSize=0):
tagSet = value.getTagSet()
if len(tagSet) > 1:
concreteEncoder = explicitlyTaggedItemEncoder
else:
- if tagSet in self.__codecMap:
- concreteEncoder = self.__codecMap[tagSet]
+ if value.typeId is not None and value.typeId in self.__typeMap:
+ concreteEncoder = self.__typeMap[value.typeId]
+ elif tagSet in self.__tagMap:
+ concreteEncoder = self.__tagMap[tagSet]
else:
baseTagSet = value.baseTagSet
- if baseTagSet in self.__codecMap:
- concreteEncoder = self.__codecMap[baseTagSet]
+ if baseTagSet in self.__tagMap:
+ concreteEncoder = self.__tagMap[baseTagSet]
else:
raise Error('No encoder for %s' % value)
return concreteEncoder.encode(
self, value, defMode, maxChunkSize
)
-encode = Encoder(codecMap)
+encode = Encoder(tagMap, typeMap)