~gdesklets-desklet-team/gdesklets/0.36

« back to all changes in this revision

Viewing changes to utils/xdr.py

  • Committer: Robert Pastierovic
  • Date: 2007-10-07 10:08:42 UTC
  • Revision ID: pastierovic@gmail.com-20071007100842-fdvp2vzmqgh1j87k
merged 0.3x branch and basic documentation and some other changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
This module implements a simple tuple transmission protocol. It's kept simple
 
3
to be implementable in other languages as well.
 
4
 
 
5
The protocol can only transmit lists of strings, which it splits up into chunks.
 
6
A chunk consists of a LENGTH byte, the actual PAYLOAD, and a STATUS byte.
 
7
 
 
8
A single string is split up into several chunks if it exceeds the maximum length
 
9
which can be specified by the LENGTH byte (255), otherwise a string is one
 
10
chunk.
 
11
 
 
12
The STATUS byte after every chunk tells if the chunk is
 
13
 
 
14
 - continued in the next chunk (CONT)
 
15
 - the last chunk of a string (NEXT)
 
16
 - the last chunk in the transmission (END)
 
17
 
 
18
In order to handle empty lists without getting too complicated, all lists are
 
19
extended by an arbitrary first element which just gets ignored.
 
20
 
 
21
 
 
22
Example:
 
23
 
 
24
  ["Hello", "World!"] is transmitted as:
 
25
 
 
26
  01  00 01   05   48 65 6C 6C 6F 01   06  57 6F 72 6C 64 21 02
 
27
 
 
28
  (1) ?  NEXT (5)  H  e  l  l  o  NEXT (6) W  o  r  l  d  !  END
 
29
"""
 
30
 
 
31
 
 
32
class XDRError(RuntimeError):
 
33
    pass
 
34
 
 
35
 
 
36
_SEND_ERROR = "--SEND ERROR--"
 
37
 
 
38
 
 
39
_CONT = chr(0)
 
40
_NEXT = chr(1)
 
41
_END  = chr(2)
 
42
 
 
43
 
 
44
def send(s, *args):
 
45
 
 
46
    args = ["\0"] + list(args)
 
47
    while (args):
 
48
        a = args.pop(0)
 
49
 
 
50
        chunks = [ a[i:i + 0xff] for i in range(0, len(a), 0xff) ]
 
51
        while (chunks):
 
52
            c = chunks.pop(0)
 
53
            s.send(chr(len(c)))
 
54
            s.send(c)
 
55
            if (chunks): s.send(_CONT)
 
56
 
 
57
        if (args): s.send(_NEXT)
 
58
 
 
59
    s.send(_END)
 
60
 
 
61
 
 
62
def send_error(s):
 
63
 
 
64
    send(s, _SEND_ERROR)
 
65
 
 
66
 
 
67
def recv(s):
 
68
 
 
69
    args = []
 
70
    chunk = ""
 
71
    while (True):
 
72
        try:
 
73
            length = ord(s.recv(1))
 
74
        except:
 
75
            raise XDRError
 
76
 
 
77
        if (length): chunk += s.recv(length)
 
78
 
 
79
        flag = s.recv(1)
 
80
        if (flag == _CONT): continue
 
81
 
 
82
        args.append(chunk)
 
83
        chunk = ""
 
84
 
 
85
        if (flag == _END): break
 
86
    #end while
 
87
 
 
88
    return args[1:]