source: geniuswebcore/geniusweb/partystdio/StdInOutConnectionEnd.py@ 78

Last change on this file since 78 was 73, checked in by Bart Vastenhouw, 3 years ago

Fix for IssueValue hashcode.

File size: 2.0 KB
RevLine 
[73]1import json
2import sys
3from typing import Optional
4
5from pyson.ObjectMapper import ObjectMapper
6from tudelft.utilities.listener.DefaultListenable import DefaultListenable
7from tudelft.utilities.listener.Listener import Listener
8
9from geniusweb.actions.Action import Action
10from geniusweb.connection.ConnectionEnd import ConnectionEnd
11from geniusweb.inform.Inform import Inform
12
13
14class StdInOutConnectionEnd(DefaultListenable[Inform],ConnectionEnd[Inform, Action]):
15 '''
16 A connectionend for a party that forwards stdin to the party,
17 and pushes outdata from the party back into the stream.
18 '''
19 def __init__(self):
20 super().__init__()
21 self._pyson = ObjectMapper()
22
23
24 def send(self,act:Action ):
25 data=json.dumps(self._pyson.toJson(act))
26 sys.stdout.buffer.write(len(data).to_bytes(4,'little'))
27 sys.stdout.buffer.write(bytes(data, 'utf-8'))
28 sys.stdout.buffer.flush()
29
30 def run(self, receiver: Listener[Inform]):
31 '''
32 @param receiver the listener for the information
33 runs until the input breaks.
34 returns only after termination
35 @raise exception if the read or the receiver throws:
36 '''
37 # blocking read
38 while True:
39 data=self.readblock()
40 if not data:
41 break
42
43 obj=self._pyson.parse(json.loads(data.decode("utf-8")),Inform)
44 receiver.notifyChange(obj)
45 # FIXME receiver.terminate?
46
47 def readblock(self)->Optional[bytearray]:
48 '''
49 @return next block of data from stdin, or None if stream closed.
50 '''
51 sizedata=sys.stdin.buffer.raw.read(4) #type:ignore
52 if len(sizedata)<4:
53 return None
54 remaining=int.from_bytes(sizedata, byteorder='little',signed=True)
55 if remaining>20000000:
56 raise ValueError("Received bad block:"+str(remaining))
57 #sys.stderr.write("remaining: "+str(remaining))
58
59 data=bytearray()
60 while remaining>0:
61 newdata=sys.stdin.buffer.raw.read(remaining) #type:ignore
62 if len(newdata)==0:
63 # FIXME receiver.terminate ?
64 return None
65 data.extend(bytearray(newdata))
66 remaining=remaining-len(newdata)
67 return data
68
Note: See TracBrowser for help on using the repository browser.