thirdparty/google_appengine/google/net/proto/ProtocolBuffer.py
changeset 109 620f9b141567
child 828 f5fd65cc3bf3
--- /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