aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py')
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py358
1 files changed, 0 insertions, 358 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py
deleted file mode 100755
index edae9c61..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# -*- test-case-name: twisted.test.test_banana -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Banana -- s-exp based protocol.
-
-Future Plans: This module is almost entirely stable. The same caveat applies
-to it as applies to L{twisted.spread.jelly}, however. Read its future plans
-for more details.
-
-@author: Glyph Lefkowitz
-"""
-
-import copy, cStringIO, struct
-
-from twisted.internet import protocol
-from twisted.persisted import styles
-from twisted.python import log
-
-class BananaError(Exception):
- pass
-
-def int2b128(integer, stream):
- if integer == 0:
- stream(chr(0))
- return
- assert integer > 0, "can only encode positive integers"
- while integer:
- stream(chr(integer & 0x7f))
- integer = integer >> 7
-
-
-def b1282int(st):
- """
- Convert an integer represented as a base 128 string into an C{int} or
- C{long}.
-
- @param st: The integer encoded in a string.
- @type st: C{str}
-
- @return: The integer value extracted from the string.
- @rtype: C{int} or C{long}
- """
- e = 1
- i = 0
- for char in st:
- n = ord(char)
- i += (n * e)
- e <<= 7
- return i
-
-
-# delimiter characters.
-LIST = chr(0x80)
-INT = chr(0x81)
-STRING = chr(0x82)
-NEG = chr(0x83)
-FLOAT = chr(0x84)
-# "optional" -- these might be refused by a low-level implementation.
-LONGINT = chr(0x85)
-LONGNEG = chr(0x86)
-# really optional; this is is part of the 'pb' vocabulary
-VOCAB = chr(0x87)
-
-HIGH_BIT_SET = chr(0x80)
-
-def setPrefixLimit(limit):
- """
- Set the limit on the prefix length for all Banana connections
- established after this call.
-
- The prefix length limit determines how many bytes of prefix a banana
- decoder will allow before rejecting a potential object as too large.
-
- @type limit: C{int}
- @param limit: The number of bytes of prefix for banana to allow when
- decoding.
- """
- global _PREFIX_LIMIT
- _PREFIX_LIMIT = limit
-setPrefixLimit(64)
-
-SIZE_LIMIT = 640 * 1024 # 640k is all you'll ever need :-)
-
-class Banana(protocol.Protocol, styles.Ephemeral):
- knownDialects = ["pb", "none"]
-
- prefixLimit = None
- sizeLimit = SIZE_LIMIT
-
- def setPrefixLimit(self, limit):
- """
- Set the prefix limit for decoding done by this protocol instance.
-
- @see: L{setPrefixLimit}
- """
- self.prefixLimit = limit
- self._smallestLongInt = -2 ** (limit * 7) + 1
- self._smallestInt = -2 ** 31
- self._largestInt = 2 ** 31 - 1
- self._largestLongInt = 2 ** (limit * 7) - 1
-
-
- def connectionReady(self):
- """Surrogate for connectionMade
- Called after protocol negotiation.
- """
-
- def _selectDialect(self, dialect):
- self.currentDialect = dialect
- self.connectionReady()
-
- def callExpressionReceived(self, obj):
- if self.currentDialect:
- self.expressionReceived(obj)
- else:
- # this is the first message we've received
- if self.isClient:
- # if I'm a client I have to respond
- for serverVer in obj:
- if serverVer in self.knownDialects:
- self.sendEncoded(serverVer)
- self._selectDialect(serverVer)
- break
- else:
- # I can't speak any of those dialects.
- log.msg("The client doesn't speak any of the protocols "
- "offered by the server: disconnecting.")
- self.transport.loseConnection()
- else:
- if obj in self.knownDialects:
- self._selectDialect(obj)
- else:
- # the client just selected a protocol that I did not suggest.
- log.msg("The client selected a protocol the server didn't "
- "suggest and doesn't know: disconnecting.")
- self.transport.loseConnection()
-
-
- def connectionMade(self):
- self.setPrefixLimit(_PREFIX_LIMIT)
- self.currentDialect = None
- if not self.isClient:
- self.sendEncoded(self.knownDialects)
-
-
- def gotItem(self, item):
- l = self.listStack
- if l:
- l[-1][1].append(item)
- else:
- self.callExpressionReceived(item)
-
- buffer = ''
-
- def dataReceived(self, chunk):
- buffer = self.buffer + chunk
- listStack = self.listStack
- gotItem = self.gotItem
- while buffer:
- assert self.buffer != buffer, "This ain't right: %s %s" % (repr(self.buffer), repr(buffer))
- self.buffer = buffer
- pos = 0
- for ch in buffer:
- if ch >= HIGH_BIT_SET:
- break
- pos = pos + 1
- else:
- if pos > self.prefixLimit:
- raise BananaError("Security precaution: more than %d bytes of prefix" % (self.prefixLimit,))
- return
- num = buffer[:pos]
- typebyte = buffer[pos]
- rest = buffer[pos+1:]
- if len(num) > self.prefixLimit:
- raise BananaError("Security precaution: longer than %d bytes worth of prefix" % (self.prefixLimit,))
- if typebyte == LIST:
- num = b1282int(num)
- if num > SIZE_LIMIT:
- raise BananaError("Security precaution: List too long.")
- listStack.append((num, []))
- buffer = rest
- elif typebyte == STRING:
- num = b1282int(num)
- if num > SIZE_LIMIT:
- raise BananaError("Security precaution: String too long.")
- if len(rest) >= num:
- buffer = rest[num:]
- gotItem(rest[:num])
- else:
- return
- elif typebyte == INT:
- buffer = rest
- num = b1282int(num)
- gotItem(num)
- elif typebyte == LONGINT:
- buffer = rest
- num = b1282int(num)
- gotItem(num)
- elif typebyte == LONGNEG:
- buffer = rest
- num = b1282int(num)
- gotItem(-num)
- elif typebyte == NEG:
- buffer = rest
- num = -b1282int(num)
- gotItem(num)
- elif typebyte == VOCAB:
- buffer = rest
- num = b1282int(num)
- gotItem(self.incomingVocabulary[num])
- elif typebyte == FLOAT:
- if len(rest) >= 8:
- buffer = rest[8:]
- gotItem(struct.unpack("!d", rest[:8])[0])
- else:
- return
- else:
- raise NotImplementedError(("Invalid Type Byte %r" % (typebyte,)))
- while listStack and (len(listStack[-1][1]) == listStack[-1][0]):
- item = listStack.pop()[1]
- gotItem(item)
- self.buffer = ''
-
-
- def expressionReceived(self, lst):
- """Called when an expression (list, string, or int) is received.
- """
- raise NotImplementedError()
-
-
- outgoingVocabulary = {
- # Jelly Data Types
- 'None' : 1,
- 'class' : 2,
- 'dereference' : 3,
- 'reference' : 4,
- 'dictionary' : 5,
- 'function' : 6,
- 'instance' : 7,
- 'list' : 8,
- 'module' : 9,
- 'persistent' : 10,
- 'tuple' : 11,
- 'unpersistable' : 12,
-
- # PB Data Types
- 'copy' : 13,
- 'cache' : 14,
- 'cached' : 15,
- 'remote' : 16,
- 'local' : 17,
- 'lcache' : 18,
-
- # PB Protocol Messages
- 'version' : 19,
- 'login' : 20,
- 'password' : 21,
- 'challenge' : 22,
- 'logged_in' : 23,
- 'not_logged_in' : 24,
- 'cachemessage' : 25,
- 'message' : 26,
- 'answer' : 27,
- 'error' : 28,
- 'decref' : 29,
- 'decache' : 30,
- 'uncache' : 31,
- }
-
- incomingVocabulary = {}
- for k, v in outgoingVocabulary.items():
- incomingVocabulary[v] = k
-
- def __init__(self, isClient=1):
- self.listStack = []
- self.outgoingSymbols = copy.copy(self.outgoingVocabulary)
- self.outgoingSymbolCount = 0
- self.isClient = isClient
-
- def sendEncoded(self, obj):
- io = cStringIO.StringIO()
- self._encode(obj, io.write)
- value = io.getvalue()
- self.transport.write(value)
-
- def _encode(self, obj, write):
- if isinstance(obj, (list, tuple)):
- if len(obj) > SIZE_LIMIT:
- raise BananaError(
- "list/tuple is too long to send (%d)" % (len(obj),))
- int2b128(len(obj), write)
- write(LIST)
- for elem in obj:
- self._encode(elem, write)
- elif isinstance(obj, (int, long)):
- if obj < self._smallestLongInt or obj > self._largestLongInt:
- raise BananaError(
- "int/long is too large to send (%d)" % (obj,))
- if obj < self._smallestInt:
- int2b128(-obj, write)
- write(LONGNEG)
- elif obj < 0:
- int2b128(-obj, write)
- write(NEG)
- elif obj <= self._largestInt:
- int2b128(obj, write)
- write(INT)
- else:
- int2b128(obj, write)
- write(LONGINT)
- elif isinstance(obj, float):
- write(FLOAT)
- write(struct.pack("!d", obj))
- elif isinstance(obj, str):
- # TODO: an API for extending banana...
- if self.currentDialect == "pb" and obj in self.outgoingSymbols:
- symbolID = self.outgoingSymbols[obj]
- int2b128(symbolID, write)
- write(VOCAB)
- else:
- if len(obj) > SIZE_LIMIT:
- raise BananaError(
- "string is too long to send (%d)" % (len(obj),))
- int2b128(len(obj), write)
- write(STRING)
- write(obj)
- else:
- raise BananaError("could not send object: %r" % (obj,))
-
-
-# For use from the interactive interpreter
-_i = Banana()
-_i.connectionMade()
-_i._selectDialect("none")
-
-
-def encode(lst):
- """Encode a list s-expression."""
- io = cStringIO.StringIO()
- _i.transport = io
- _i.sendEncoded(lst)
- return io.getvalue()
-
-
-def decode(st):
- """
- Decode a banana-encoded string.
- """
- l = []
- _i.expressionReceived = l.append
- try:
- _i.dataReceived(st)
- finally:
- _i.buffer = ''
- del _i.expressionReceived
- return l[0]