| # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| # for details. All rights reserved. Use of this source code is governed by a | |
| # BSD-style license that can be found in the LICENSE file. | |
| ''' | |
| This Encoder shares a lot in common with protobufs. It uses variable length | |
| ints and size-encoded strings and binary values. Other than being hugely | |
| stripped down, the major conceptual difference is that this encoding | |
| is UTF8 "safe". This means that it generates a form that should be passed | |
| on the wire as UTF8 and then can be very efficiently decoded by JS in the | |
| browser which natively handles these kinds of strings. To stay efficient in | |
| this range, all numeric data is encoded in only 7 bits. | |
| ''' | |
| import base64 | |
| class Encoder: | |
| def __init__(self): | |
| self.data = [] | |
| def writeInt(self, value): | |
| '''Uses a 7-bit per byte encoding to stay UTF-8 "safe".''' | |
| bits = value & 0x3f | |
| value >>= 6 | |
| while value: | |
| self.data.append(chr(0x40 | bits)) | |
| bits = value & 0x3f | |
| value >>= 6 | |
| self.data.append(chr(bits)) | |
| def writeBool(self, b): | |
| self.data.append(('F', 'T')[b]) | |
| def writeString(self, s): | |
| if not s: s = '' | |
| self.writeInt(len(s)) | |
| self.data.append(s) | |
| def writeBinary(self, s): | |
| '''Encode binary data using base64. This is less efficient than a 7-bit | |
| encoding would be; however, it can be decoded much faster on most | |
| browsers due to native support for the format.''' | |
| v = base64.b64encode(s) | |
| self.writeInt(len(v)) | |
| self.data.append(v) | |
| def writeList(self, l): | |
| self.writeInt(len(l)) | |
| for i in l: | |
| i.encode(self) | |
| def writeRaw(self, s): | |
| self.data.append(s) | |
| def finish(self): | |
| d = ''.join(self.data) | |
| return _encVarInt(len(d)) + d | |
| def getRaw(self): | |
| return ''.join(self.data) |