~glyph/+junk/amphacks

4 by Glyph Lefkowitz
medium-sized box support
1
"""
5 by Glyph Lefkowitz
Describe the 'mediumbox' example a little.
2
An argument type for sending medium-sized strings (more than 64k, but small
3
enough that they still fit into memory and don't require streaming).
4
"""
5
6
from itertools import count
4 by Glyph Lefkowitz
medium-sized box support
7
from cStringIO import StringIO
8
9
from twisted.protocols.amp import Argument
10
11
CHUNK_MAX = 0xffff
12
13
class BigString(Argument):
14
    def fromBox(self, name, strings, objects, proto):
15
        value = StringIO()
16
        value.write(strings.get(name))
17
        for counter in count(2):
18
            chunk = strings.get("%s.%d" % (name, counter))
19
            if chunk is None:
20
                break
21
            value.write(chunk)
22
        objects[name] = value.getvalue()
23
24
25
    def toBox(self, name, strings, objects, proto):
26
        value = StringIO(objects[name])
27
        firstChunk = value.read(CHUNK_MAX)
28
        strings[name] = firstChunk
29
        counter = 2
30
        while True:
31
            nextChunk = value.read(CHUNK_MAX)
32
            if not nextChunk:
33
                break
34
            strings["%s.%d" % (name, counter)] = nextChunk
35
            counter += 1
36
37
from twisted.protocols.amp import AMP, Command
38
class Send(Command):
39
    arguments = [('big', BigString())]
40
41
class Example(AMP):
42
    @Send.responder
43
    def gotBig(self, big):
44
        print 'Got a big input', len(big)
45
        f = file("OUTPUT", "wb")
46
        f.write(big)
47
        f.close()
48
        return {}
49
50
def main(argv):
51
    from twisted.internet import reactor
52
    from twisted.internet.protocol import Factory, ClientCreator
53
    if argv[1] == 'client':
54
        filename = argv[2]
55
        def connected(result):
56
            result.callRemote(Send, big=file(filename).read())
57
        ClientCreator(reactor, AMP).connectTCP("localhost", 4321).addCallback(
58
            connected)
59
        reactor.run()
60
    elif argv[1] == 'server':
61
        f = Factory()
62
        f.protocol = Example
63
        reactor.listenTCP(4321, f)
64
        reactor.run()
65
    else:
66
        print "Specify 'client' or 'server'."
67
if __name__ == '__main__':
68
    from sys import argv as arguments
69
    main(arguments)
70
71