| Index: third_party/google-endpoints/pyasn1/codec/cer/encoder.py
|
| diff --git a/third_party/google-endpoints/pyasn1/codec/cer/encoder.py b/third_party/google-endpoints/pyasn1/codec/cer/encoder.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..61ce8a1507c209ec14e4d4400d284ca5a54c3889
|
| --- /dev/null
|
| +++ b/third_party/google-endpoints/pyasn1/codec/cer/encoder.py
|
| @@ -0,0 +1,130 @@
|
| +# CER encoder
|
| +from pyasn1.type import univ
|
| +from pyasn1.type import useful
|
| +from pyasn1.codec.ber import encoder
|
| +from pyasn1.compat.octets import int2oct, str2octs, null
|
| +from pyasn1 import error
|
| +
|
| +class BooleanEncoder(encoder.IntegerEncoder):
|
| + def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
|
| + if client == 0:
|
| + substrate = int2oct(0)
|
| + else:
|
| + substrate = int2oct(255)
|
| + return substrate, 0
|
| +
|
| +class BitStringEncoder(encoder.BitStringEncoder):
|
| + def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
|
| + return encoder.BitStringEncoder.encodeValue(
|
| + self, encodeFun, client, defMode, 1000
|
| + )
|
| +
|
| +class OctetStringEncoder(encoder.OctetStringEncoder):
|
| + def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
|
| + return encoder.OctetStringEncoder.encodeValue(
|
| + self, encodeFun, client, defMode, 1000
|
| + )
|
| +
|
| +class RealEncoder(encoder.RealEncoder):
|
| + def _chooseEncBase(self, value):
|
| + m, b, e = value
|
| + return self._dropFloatingPoint(m, b, e)
|
| +
|
| +# specialized GeneralStringEncoder here
|
| +
|
| +class GeneralizedTimeEncoder(OctetStringEncoder):
|
| + zchar = str2octs('Z')
|
| + pluschar = str2octs('+')
|
| + minuschar = str2octs('-')
|
| + zero = str2octs('0')
|
| + def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
|
| + octets = client.asOctets()
|
| +# This breaks too many existing data items
|
| +# if '.' not in octets:
|
| +# raise error.PyAsn1Error('Format must include fraction of second: %r' % octets)
|
| + if len(octets) < 15:
|
| + raise error.PyAsn1Error('Bad UTC time length: %r' % octets)
|
| + if self.pluschar in octets or self.minuschar in octets:
|
| + raise error.PyAsn1Error('Must be UTC time: %r' % octets)
|
| + if octets[-1] != self.zchar[0]:
|
| + raise error.PyAsn1Error('Missing timezone specifier: %r' % octets)
|
| + return encoder.OctetStringEncoder.encodeValue(
|
| + self, encodeFun, client, defMode, 1000
|
| + )
|
| +
|
| +class UTCTimeEncoder(encoder.OctetStringEncoder):
|
| + zchar = str2octs('Z')
|
| + pluschar = str2octs('+')
|
| + minuschar = str2octs('-')
|
| + def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
|
| + octets = client.asOctets()
|
| + if self.pluschar in octets or self.minuschar in octets:
|
| + raise error.PyAsn1Error('Must be UTC time: %r' % octets)
|
| + if octets and octets[-1] != self.zchar[0]:
|
| + client = client.clone(octets + self.zchar)
|
| + if len(client) != 13:
|
| + raise error.PyAsn1Error('Bad UTC time length: %r' % client)
|
| + return encoder.OctetStringEncoder.encodeValue(
|
| + self, encodeFun, client, defMode, 1000
|
| + )
|
| +
|
| +class SetOfEncoder(encoder.SequenceOfEncoder):
|
| + def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
|
| + if isinstance(client, univ.SequenceAndSetBase):
|
| + client.setDefaultComponents()
|
| + client.verifySizeSpec()
|
| + substrate = null; idx = len(client)
|
| + # This is certainly a hack but how else do I distinguish SetOf
|
| + # from Set if they have the same tags&constraints?
|
| + if isinstance(client, univ.SequenceAndSetBase):
|
| + # Set
|
| + comps = []
|
| + while idx > 0:
|
| + idx = idx - 1
|
| + if client[idx] is None: # Optional component
|
| + continue
|
| + if client.getDefaultComponentByPosition(idx) == client[idx]:
|
| + continue
|
| + comps.append(client[idx])
|
| + comps.sort(key=lambda x: isinstance(x, univ.Choice) and \
|
| + x.getMinTagSet() or x.getTagSet())
|
| + for c in comps:
|
| + substrate += encodeFun(c, defMode, maxChunkSize)
|
| + else:
|
| + # SetOf
|
| + compSubs = []
|
| + while idx > 0:
|
| + idx = idx - 1
|
| + compSubs.append(
|
| + encodeFun(client[idx], defMode, maxChunkSize)
|
| + )
|
| + compSubs.sort() # perhaps padding's not needed
|
| + substrate = null
|
| + for compSub in compSubs:
|
| + substrate += compSub
|
| + return substrate, 1
|
| +
|
| +tagMap = encoder.tagMap.copy()
|
| +tagMap.update({
|
| + univ.Boolean.tagSet: BooleanEncoder(),
|
| + univ.BitString.tagSet: BitStringEncoder(),
|
| + univ.OctetString.tagSet: OctetStringEncoder(),
|
| + univ.Real.tagSet: RealEncoder(),
|
| + useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(),
|
| + useful.UTCTime.tagSet: UTCTimeEncoder(),
|
| + univ.SetOf().tagSet: SetOfEncoder() # conflcts with Set
|
| +})
|
| +
|
| +typeMap = encoder.typeMap.copy()
|
| +typeMap.update({
|
| + univ.Set.typeId: SetOfEncoder(),
|
| + univ.SetOf.typeId: SetOfEncoder()
|
| +})
|
| +
|
| +class Encoder(encoder.Encoder):
|
| + def __call__(self, client, defMode=False, maxChunkSize=0):
|
| + return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
|
| +
|
| +encode = Encoder(tagMap, typeMap)
|
| +
|
| +# EncoderFactory queries class instance and builds a map of tags -> encoders
|
|
|