| # 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) |