| 185 | |
| 186 | class BitStringEncoder(AbstractItemEncoder): |
| 187 | def encodeValue(self, value, asn1Spec, encodeFun, **options): |
| 188 | if asn1Spec is not None: |
| 189 | # TODO: try to avoid ASN.1 schema instantiation |
| 190 | value = asn1Spec.clone(value) |
| 191 | |
| 192 | valueLength = len(value) |
| 193 | if valueLength % 8: |
| 194 | alignedValue = value << (8 - valueLength % 8) |
| 195 | else: |
| 196 | alignedValue = value |
| 197 | |
| 198 | maxChunkSize = options.get('maxChunkSize', 0) |
| 199 | if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8: |
| 200 | substrate = alignedValue.asOctets() |
| 201 | return bytes((len(substrate) * 8 - valueLength,)) + substrate, False, True |
| 202 | |
| 203 | if LOG: |
| 204 | LOG('encoding into up to %s-octet chunks' % maxChunkSize) |
| 205 | |
| 206 | baseTag = value.tagSet.baseTag |
| 207 | |
| 208 | # strip off explicit tags |
| 209 | if baseTag: |
| 210 | tagSet = tag.TagSet(baseTag, baseTag) |
| 211 | |
| 212 | else: |
| 213 | tagSet = tag.TagSet() |
| 214 | |
| 215 | alignedValue = alignedValue.clone(tagSet=tagSet) |
| 216 | |
| 217 | stop = 0 |
| 218 | substrate = b'' |
| 219 | while stop < valueLength: |
| 220 | start = stop |
| 221 | stop = min(start + maxChunkSize * 8, valueLength) |
| 222 | substrate += encodeFun(alignedValue[start:stop], asn1Spec, **options) |
| 223 | |
| 224 | return substrate, True, True |
| 225 | |
| 226 | |
| 227 | class OctetStringEncoder(AbstractItemEncoder): |