11 import contextlib |
11 import contextlib |
12 import json |
12 import json |
13 import os |
13 import os |
14 import struct |
14 import struct |
15 import sys |
15 import sys |
16 |
16 import time |
17 from zlib import adler32 |
17 import zlib |
18 |
18 |
19 from PyQt6.QtCore import QProcess, QThread, QTimer, pyqtSignal |
19 from PyQt6.QtCore import QProcess, QThread, QTimer, pyqtSignal |
20 from PyQt6.QtNetwork import QHostAddress, QTcpServer |
20 from PyQt6.QtNetwork import QHostAddress, QTcpServer |
21 from PyQt6.QtWidgets import QApplication |
21 from PyQt6.QtWidgets import QApplication |
22 |
22 |
173 self.__processQueue() |
173 self.__processQueue() |
174 else: |
174 else: |
175 packedData = json.dumps([fx, fn, data]) |
175 packedData = json.dumps([fx, fn, data]) |
176 packedData = bytes(packedData, "utf-8") |
176 packedData = bytes(packedData, "utf-8") |
177 header = struct.pack( |
177 header = struct.pack( |
178 b"!II", len(packedData), adler32(packedData) & 0xFFFFFFFF |
178 b"!II", len(packedData), zlib.adler32(packedData) & 0xFFFFFFFF |
179 ) |
179 ) |
180 connection.write(header) |
180 connection.write(header) |
181 connection.write(b"JOB ") # 6 character message type |
181 connection.write(b"JOB ") # 6 character message type |
182 connection.write(packedData) |
182 connection.write(packedData) |
183 |
183 |
187 |
187 |
188 @param lang language of the incoming connection |
188 @param lang language of the incoming connection |
189 @type str |
189 @type str |
190 @exception RuntimeError raised if hashes don't match |
190 @exception RuntimeError raised if hashes don't match |
191 """ |
191 """ |
|
192 headerSize = struct.calcsize(b"!II") |
|
193 |
192 data = "" |
194 data = "" |
193 fx = "" |
195 fx = "" |
194 |
196 |
195 connection = self.connections[lang] |
197 connection = self.connections[lang] |
196 while connection.bytesAvailable(): |
198 while connection and connection.bytesAvailable(): |
197 header = connection.read(struct.calcsize(b"!II")) |
199 now = time.monotonic() |
|
200 while connection.bytesAvailable() < headerSize: |
|
201 connection.waitForReadyRead(50) |
|
202 if time.monotonic() - now > 2.0: # 2 seconds timeout |
|
203 return |
|
204 header = connection.read(headerSize) |
198 length, datahash = struct.unpack(b"!II", header) |
205 length, datahash = struct.unpack(b"!II", header) |
199 |
206 |
200 packedData = b"" |
207 packedData = b"" |
|
208 now = time.monotonic() |
201 while len(packedData) < length: |
209 while len(packedData) < length: |
202 maxSize = length - len(packedData) |
210 maxSize = length - len(packedData) |
203 if connection.bytesAvailable() < maxSize: |
211 if connection.bytesAvailable() < maxSize: |
204 connection.waitForReadyRead(50) |
212 connection.waitForReadyRead(50) |
205 packedData += connection.read(maxSize) |
213 newData = connection.read(maxSize) |
206 |
214 if newData: |
207 if adler32(packedData) & 0xFFFFFFFF != datahash: |
215 packedData += newData |
|
216 else: |
|
217 if time.monotonic() - now > 2.0: # 2 seconds timeout |
|
218 break |
|
219 |
|
220 if zlib.adler32(packedData) & 0xFFFFFFFF != datahash: |
208 raise RuntimeError("Hashes not equal") |
221 raise RuntimeError("Hashes not equal") |
209 packedData = packedData.decode("utf-8") |
222 packedData = packedData.decode("utf-8") |
210 # "check" if is's a tuple of 3 values |
223 # "check" if is's a tuple of 3 values |
211 fx, fn, data = json.loads(packedData) |
224 fx, fn, data = json.loads(packedData) |
212 |
225 |