diff -r 261778de26ff -r 620f9b141567 thirdparty/google_appengine/google/net/proto/ProtocolBuffer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thirdparty/google_appengine/google/net/proto/ProtocolBuffer.py Tue Aug 26 21:49:54 2008 +0000 @@ -0,0 +1,481 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +import struct +import array +import string +import re +from google.pyglib.gexcept import AbstractMethod +import httplib + +__all__ = ['ProtocolMessage', 'Encoder', 'Decoder', + 'ProtocolBufferDecodeError', + 'ProtocolBufferEncodeError', + 'ProtocolBufferReturnError'] + +URL_RE = re.compile('^(https?)://([^/]+)(/.*)$') + +class ProtocolMessage: + + + def __init__(self, contents=None): + raise AbstractMethod + + def Clear(self): + raise AbstractMethod + + def IsInitialized(self, debug_strs=None): + raise AbstractMethod + + def Encode(self): + try: + return self._CEncode() + except AbstractMethod: + e = Encoder() + self.Output(e) + return e.buffer().tostring() + + def _CEncode(self): + raise AbstractMethod + + def ParseFromString(self, s): + self.Clear() + self.MergeFromString(s) + return + + def MergeFromString(self, s): + try: + self._CMergeFromString(s) + dbg = [] + if not self.IsInitialized(dbg): + raise ProtocolBufferDecodeError, '\n\t'.join(dbg) + except AbstractMethod: + a = array.array('B') + a.fromstring(s) + d = Decoder(a, 0, len(a)) + self.Merge(d) + return + + def _CMergeFromString(self, s): + raise AbstractMethod + + def __getstate__(self): + return self.Encode() + + def __setstate__(self, contents_): + self.__init__(contents=contents_) + + def sendCommand(self, server, url, response, follow_redirects=1, + secure=0, keyfile=None, certfile=None): + data = self.Encode() + if secure: + if keyfile and certfile: + conn = httplib.HTTPSConnection(server, key_file=keyfile, + cert_file=certfile) + else: + conn = httplib.HTTPSConnection(server) + else: + conn = httplib.HTTPConnection(server) + conn.putrequest("POST", url) + conn.putheader("Content-Length", "%d" %len(data)) + conn.endheaders() + conn.send(data) + resp = conn.getresponse() + if follow_redirects > 0 and resp.status == 302: + m = URL_RE.match(resp.getheader('Location')) + if m: + protocol, server, url = m.groups() + return self.sendCommand(server, url, response, + follow_redirects=follow_redirects - 1, + secure=(protocol == 'https'), + keyfile=keyfile, + certfile=certfile) + if resp.status != 200: + raise ProtocolBufferReturnError(resp.status) + if response is not None: + response.ParseFromString(resp.read()) + return response + + def sendSecureCommand(self, server, keyfile, certfile, url, response, + follow_redirects=1): + return self.sendCommand(server, url, response, + follow_redirects=follow_redirects, + secure=1, keyfile=keyfile, certfile=certfile) + + def __str__(self, prefix="", printElemNumber=0): + raise AbstractMethod + + def ToASCII(self): + return self._CToASCII(ProtocolMessage._SYMBOLIC_FULL_ASCII) + + def ToCompactASCII(self): + return self._CToASCII(ProtocolMessage._NUMERIC_ASCII) + + def ToShortASCII(self): + return self._CToASCII(ProtocolMessage._SYMBOLIC_SHORT_ASCII) + + _NUMERIC_ASCII = 0 + _SYMBOLIC_SHORT_ASCII = 1 + _SYMBOLIC_FULL_ASCII = 2 + + def _CToASCII(self, output_format): + raise AbstractMethod + + def ParseASCII(self, ascii_string): + raise AbstractMethod + + def ParseASCIIIgnoreUnknown(self, ascii_string): + raise AbstractMethod + + + def Output(self, e): + dbg = [] + if not self.IsInitialized(dbg): + raise ProtocolBufferEncodeError, '\n\t'.join(dbg) + self.OutputUnchecked(e) + return + + def OutputUnchecked(self, e): + raise AbstractMethod + + def Parse(self, d): + self.Clear() + self.Merge(d) + return + + def Merge(self, d): + self.TryMerge(d) + dbg = [] + if not self.IsInitialized(dbg): + raise ProtocolBufferDecodeError, '\n\t'.join(dbg) + return + + def TryMerge(self, d): + raise AbstractMethod + + def CopyFrom(self, pb): + if (pb == self): return + self.Clear() + self.MergeFrom(pb) + + def MergeFrom(self, pb): + raise AbstractMethod + + + def lengthVarInt32(self, n): + return self.lengthVarInt64(n) + + def lengthVarInt64(self, n): + if n < 0: + return 10 + result = 0 + while 1: + result += 1 + n >>= 7 + if n == 0: + break + return result + + def lengthString(self, n): + return self.lengthVarInt32(n) + n + + def DebugFormat(self, value): + return "%s" % value + def DebugFormatInt32(self, value): + if (value <= -2000000000 or value >= 2000000000): + return self.DebugFormatFixed32(value) + return "%d" % value + def DebugFormatInt64(self, value): + if (value <= -2000000000 or value >= 2000000000): + return self.DebugFormatFixed64(value) + return "%d" % value + def DebugFormatString(self, value): + def escape(c): + o = ord(c) + if o == 10: return r"\n" + if o == 39: return r"\'" + + if o == 34: return r'\"' + if o == 92: return r"\\" + + if o >= 127 or o < 32: return "\\%03o" % o + return c + return '"' + "".join([escape(c) for c in value]) + '"' + def DebugFormatFloat(self, value): + return "%ff" % value + def DebugFormatFixed32(self, value): + if (value < 0): value += (1L<<32) + return "0x%x" % value + def DebugFormatFixed64(self, value): + if (value < 0): value += (1L<<64) + return "0x%x" % value + def DebugFormatBool(self, value): + if value: + return "true" + else: + return "false" + +class Encoder: + + NUMERIC = 0 + DOUBLE = 1 + STRING = 2 + STARTGROUP = 3 + ENDGROUP = 4 + FLOAT = 5 + MAX_TYPE = 6 + + def __init__(self): + self.buf = array.array('B') + return + + def buffer(self): + return self.buf + + def put8(self, v): + if v < 0 or v >= (1<<8): raise ProtocolBufferEncodeError, "u8 too big" + self.buf.append(v & 255) + return + + def put16(self, v): + if v < 0 or v >= (1<<16): raise ProtocolBufferEncodeError, "u16 too big" + self.buf.append((v >> 0) & 255) + self.buf.append((v >> 8) & 255) + return + + def put32(self, v): + if v < 0 or v >= (1L<<32): raise ProtocolBufferEncodeError, "u32 too big" + self.buf.append((v >> 0) & 255) + self.buf.append((v >> 8) & 255) + self.buf.append((v >> 16) & 255) + self.buf.append((v >> 24) & 255) + return + + def put64(self, v): + if v < 0 or v >= (1L<<64): raise ProtocolBufferEncodeError, "u64 too big" + self.buf.append((v >> 0) & 255) + self.buf.append((v >> 8) & 255) + self.buf.append((v >> 16) & 255) + self.buf.append((v >> 24) & 255) + self.buf.append((v >> 32) & 255) + self.buf.append((v >> 40) & 255) + self.buf.append((v >> 48) & 255) + self.buf.append((v >> 56) & 255) + return + + def putVarInt32(self, v): + if v >= (1L << 31) or v < -(1L << 31): + raise ProtocolBufferEncodeError, "int32 too big" + self.putVarInt64(v) + return + + def putVarInt64(self, v): + if v >= (1L << 63) or v < -(1L << 63): + raise ProtocolBufferEncodeError, "int64 too big" + if v < 0: + v += (1L << 64) + self.putVarUint64(v) + return + + def putVarUint64(self, v): + if v < 0 or v >= (1L << 64): + raise ProtocolBufferEncodeError, "uint64 too big" + while 1: + bits = v & 127 + v >>= 7 + if (v != 0): + bits |= 128 + self.buf.append(bits) + if v == 0: + break + return + + + def putFloat(self, v): + a = array.array('B') + a.fromstring(struct.pack("f", v)) + self.buf.extend(a) + return + + def putDouble(self, v): + a = array.array('B') + a.fromstring(struct.pack("d", v)) + self.buf.extend(a) + return + + def putBoolean(self, v): + if v: + self.buf.append(1) + else: + self.buf.append(0) + return + + def putPrefixedString(self, v): + self.putVarInt32(len(v)) + a = array.array('B') + a.fromstring(v) + self.buf.extend(a) + return + + def putRawString(self, v): + a = array.array('B') + a.fromstring(v) + self.buf.extend(a) + + +class Decoder: + def __init__(self, buf, idx, limit): + self.buf = buf + self.idx = idx + self.limit = limit + return + + def avail(self): + return self.limit - self.idx + + def buffer(self): + return self.buf + + def pos(self): + return self.idx + + def skip(self, n): + if self.idx + n > self.limit: raise ProtocolBufferDecodeError, "truncated" + self.idx += n + return + + def skipData(self, tag): + t = tag & 7 + if t == Encoder.NUMERIC: + self.getVarInt64() + elif t == Encoder.DOUBLE: + self.skip(8) + elif t == Encoder.STRING: + n = self.getVarInt32() + self.skip(n) + elif t == Encoder.STARTGROUP: + while 1: + t = self.getVarInt32() + if (t & 7) == Encoder.ENDGROUP: + break + else: + self.skipData(t) + if (t - Encoder.ENDGROUP) != (tag - Encoder.STARTGROUP): + raise ProtocolBufferDecodeError, "corrupted" + elif t == Encoder.ENDGROUP: + raise ProtocolBufferDecodeError, "corrupted" + elif t == Encoder.FLOAT: + self.skip(4) + else: + raise ProtocolBufferDecodeError, "corrupted" + + def get8(self): + if self.idx >= self.limit: raise ProtocolBufferDecodeError, "truncated" + c = self.buf[self.idx] + self.idx += 1 + return c + + def get16(self): + if self.idx + 2 > self.limit: raise ProtocolBufferDecodeError, "truncated" + c = self.buf[self.idx] + d = self.buf[self.idx + 1] + self.idx += 2 + return (d << 8) | c + + def get32(self): + if self.idx + 4 > self.limit: raise ProtocolBufferDecodeError, "truncated" + c = self.buf[self.idx] + d = self.buf[self.idx + 1] + e = self.buf[self.idx + 2] + f = long(self.buf[self.idx + 3]) + self.idx += 4 + return (f << 24) | (e << 16) | (d << 8) | c + + def get64(self): + if self.idx + 8 > self.limit: raise ProtocolBufferDecodeError, "truncated" + c = self.buf[self.idx] + d = self.buf[self.idx + 1] + e = self.buf[self.idx + 2] + f = long(self.buf[self.idx + 3]) + g = long(self.buf[self.idx + 4]) + h = long(self.buf[self.idx + 5]) + i = long(self.buf[self.idx + 6]) + j = long(self.buf[self.idx + 7]) + self.idx += 8 + return ((j << 56) | (i << 48) | (h << 40) | (g << 32) | (f << 24) + | (e << 16) | (d << 8) | c) + + def getVarInt32(self): + v = self.getVarInt64() + if v >= (1L << 31) or v < -(1L << 31): + raise ProtocolBufferDecodeError, "corrupted" + return v + + def getVarInt64(self): + result = self.getVarUint64() + if result >= (1L << 63): + result -= (1L << 64) + return result + + def getVarUint64(self): + result = long(0) + shift = 0 + while 1: + if shift >= 64: raise ProtocolBufferDecodeError, "corrupted" + b = self.get8() + result |= (long(b & 127) << shift) + shift += 7 + if (b & 128) == 0: + if result >= (1L << 64): raise ProtocolBufferDecodeError, "corrupted" + return result + return result + + def getFloat(self): + if self.idx + 4 > self.limit: raise ProtocolBufferDecodeError, "truncated" + a = self.buf[self.idx:self.idx+4] + self.idx += 4 + return struct.unpack("f", a)[0] + + def getDouble(self): + if self.idx + 8 > self.limit: raise ProtocolBufferDecodeError, "truncated" + a = self.buf[self.idx:self.idx+8] + self.idx += 8 + return struct.unpack("d", a)[0] + + def getBoolean(self): + b = self.get8() + if b != 0 and b != 1: raise ProtocolBufferDecodeError, "corrupted" + return b + + def getPrefixedString(self): + length = self.getVarInt32() + if self.idx + length > self.limit: + raise ProtocolBufferDecodeError, "truncated" + r = self.buf[self.idx : self.idx + length] + self.idx += length + return r.tostring() + + def getRawString(self): + r = self.buf[self.idx:self.limit] + self.idx = self.limit + return r.tostring() + + +class ProtocolBufferDecodeError(Exception): pass +class ProtocolBufferEncodeError(Exception): pass +class ProtocolBufferReturnError(Exception): pass