def SendUserMessage(self, message, userId, hint=''): if userId is None: userId = u'' q = CUQueue().SaveObject(message, hint) bytes = (c_ubyte * q.GetSize()).from_buffer(q._m_bytes_) return scl.SendUserMessage(self._m_p.Handle, userId, bytes, q.GetSize())
def SendResult(self, q, reqId=0): if reqId == 0: reqId = self.CurrentRequestID if q is None: q = CUQueue() buffer = (c_ubyte * q.GetSize()).from_buffer(q._m_bytes_, q._m_position_) return scl.SendReturnData(self.Handle, reqId, q.GetSize(), buffer)
def Publish(self, message, groups, hint=''): if groups is None: groups = () size = len(groups) arr = (c_uint * size)(*groups) q = CUQueue().SaveObject(message, hint) bytes = (c_ubyte * q.GetSize()).from_buffer(q._m_bytes_) return scl.Speak(self._m_p.Handle, bytes, q.GetSize(), arr, size)
def __init__(self, serviceId=0): super(CCachedBaseHandler, self).__init__(serviceId) self._csCache = threading.Lock() self._mapRowset = {} self._indexRowset = 0 self._Blob = CUQueue() self._vData = [] self._ms = tagManagementSystem.msUnknown self._mapHandler = {}
def SendResultIndex(self, reqIndex, q, reqId): if reqId == 0: reqId = self.CurrentRequestID if isinstance(q, CScopeUQueue): q = q.UQueue if q is None: q = CUQueue() buffer = (c_ubyte * q.GetSize()).from_buffer(q._m_bytes_, q._m_position_) return scl.SendReturnDataIndex(self.Handle, reqIndex, reqId, q.GetSize(), buffer)
def Enqueue(self, reqId, q): if isinstance(q, CScopeUQueue): q = q.UQueue elif q is None: q = CUQueue() bytes = (c_ubyte * q.Size).from_buffer(q._m_bytes_, q._m_position_) return scl.Enqueue(self._m_qHandle_, reqId, bytes, q.Size)
def Upload(self, source, remotePath): remotePath = remotePath.strip() self._m_ash.ResultReturned = None with self._lock_: if not self._m_s is None: raise Exception('A stream during transaction') if not hasattr(source, 'read'): raise ValueError('A readable source stream required') self._res = '' def callBack(ar): self._res = ar.LoadString() ok = self._m_ash.SendRequest(ssh.idStartUploading, CUQueue().SaveString(remotePath), callBack) and self._m_ash.WaitAll() if not self._res is None and len(self._res) > 0: self._m_s = None return self._res elif self._res is None: self._res = '' if not ok and not self._m_ash.AttachedClientSocket.Sendable: return self._m_ash.AttachedClientSocket.ErrorMsg with self._lock_: if not self._m_s is None: raise Exception('A stream during transaction') self._m_s = source if not self.Progress is None: self.Progress(self, self._m_s.tell()) if self._SendDataFromClientToServer() == 0: def dc(ar): with self._lock_: if not self.Progress is None and not self._m_s is None: self.Progress(self, self._m_s.tell()) self._m_s = None if not self._m_ash.SendRequest(ssh.idUploadCompleted, None, dc): self._m_s = None if not self._m_ash.AttachedClientSocket.Sendable: return self._m_ash.AttachedClientSocket.ErrorMsg return self._res
def Download(self, receiver, remotePath): remotePath = remotePath.strip() with self._lock_: if not self._m_s is None: raise Exception('A stream during transaction') if not hasattr(receiver, 'write'): raise ValueError('A writable target stream required') self._m_s = receiver self._m_ash.ResultReturned = self._DataFromServerToClient self._res = '' def callBack(ar): self._m_nDownloadFileSize = ar.LoadULong() self._res = ar.LoadString() ok = self._m_ash.SendRequest(ssh.idStartDownloading, CUQueue().SaveString(remotePath), callBack) and self._m_ash.WaitAll() with self._lock_: if not self._res is None and len(self._res) > 0: self._m_s = None return self._res elif self._res is None: self._res = '' if not ok and not self._m_ash.AttachedClientSocket.Sendable: self._m_s = None return self._m_ash.AttachedClientSocket.ErrorMsg if not self.Progress is None: self.Progress(self, self._m_s.tell()) def dc(ar): with self._lock_: if not self.Progress is None: self.Progress(self, self._m_s.tell()) self._m_s = None self._m_ash.ResultReturned = None if not self._m_ash.SendRequest(ssh.idDownloadCompleted, None, dc): self._m_s = None return self._m_ash.AttachedClientSocket.ErrorMsg return self._res
def _SendDataFromClientToServer(self): if self._m_ash.AttachedClientSocket.BytesInSendingBuffer > ssh.STREAM_CHUNK_SIZE: return 0 if self._m_s is None: return 0 send = 0 bytes = ssh.Read(self._m_s) read = len(bytes) while read > 0: def callBack(ar): self._SendDataFromClientToServer() ok = self._m_ash.SendRequest(ssh.idWriteDataFromClientToServer, CUQueue(bytearray(bytes)), callBack) if not ok: self._m_s = None return send if not self.Progress is None: self.Progress(self, self._m_s.tell()) send += read if self._m_ash.AttachedClientSocket.BytesInSendingBuffer > 10 * ssh.STREAM_CHUNK_SIZE: break bytes = ssh.Read(self._m_s) read = len(bytes) if read == 0: def dc(ar): with self._lock_: if not self.Progress is None: self.Progress(self, self._m_s.tell()) self._m_s = None if not self._m_ash.SendRequest(ssh.idUploadCompleted, None, dc): self._m_s = None return send
def Enqueue(self, reqId, q): if q is None: q = CUQueue() bytes = (c_ubyte * q.Size).from_buffer(q._m_bytes_, q._m_position_) return scl.Enqueue(self._m_qHandle_, reqId, bytes, q.Size)
from msstruct import CMyStruct from spa import CUQueue from decimal import Decimal import uuid, time msOriginal = CMyStruct.MakeOne() q = CUQueue() msOriginal.SaveTo(q) ms = CMyStruct() ms.LoadFrom(q) with CUQueue() as q: q.SaveInt(123).SaveInt(-1) n = q.LoadInt() assert (n == 123) n = q.LoadInt() assert (n == -1) assert (q.Size == 0) q.SaveInt(234).SaveAString('test me') n = q.LoadInt() assert (n == 234) s = q.LoadAString() assert (s == 'test me') assert (q.Size == 0) us = u'test' q.SaveString(us).SaveString(None) s = q.LoadString() assert (s == u'test') s = q.LoadString()
class CCachedBaseHandler(CAsyncServiceHandler): ONE_MEGA_BYTES = 0x100000 BLOB_LENGTH_NOT_AVAILABLE = 0xffffffe0 def __init__(self, serviceId=0): super(CCachedBaseHandler, self).__init__(serviceId) self._csCache = threading.Lock() self._mapRowset = {} self._indexRowset = 0 self._Blob = CUQueue() self._vData = [] self._ms = tagManagementSystem.msUnknown self._mapHandler = {} @property def DBManagementSystem(self): with self._csCache: return self._ms def CleanCallbacks(self): with self._csCache: self._mapRowset = {} self._mapHandler = {} return super(CCachedBaseHandler, self).CleanCallbacks() def OnMergeTo(self, dbTo): with dbTo._csDB: with self._csDB: dbTo._mapRowset.update(self._mapRowset) self._mapRowset = {} dbTo._mapHandler.update(self._mapHandler) self._mapHandler = {} def GetCachedTables(self, defaultDb, handler, row, rh, flags=DB_CONSTS.ENABLE_TABLE_UPDATE_MESSAGES): q = CScopeUQueue.Lock() index = self.GetCallIndex(); with self._csCache: self._mapRowset[index] = Pair(rh, row) self._mapHandler[index] = handler q.SaveString(defaultDb).SaveUInt(flags).SaveULong(index) ok = self.SendRequest(DB_CONSTS.idGetCachedTables, q, None) CScopeUQueue.Unlock(q) if not ok: with self._csCache: self._mapHandler.pop(index) self._mapRowset.pop(index) return ok def OnResultReturned(self, reqId, mc): if reqId == DB_CONSTS.idRowsetHeader: self._Blob.SetSize(0) if self._Blob.MaxBufferSize > CCachedBaseHandler.ONE_MEGA_BYTES: self._Blob.Realloc(CCachedBaseHandler.ONE_MEGA_BYTES) self._vData = [] vColInfo = CDBColumnInfoArray() vColInfo.LoadFrom(mc) header = None with self._csCache: self._indexRowset = mc.LoadULong() if len(vColInfo.list) > 0: if self._indexRowset in self._mapRowset: header = self._mapRowset.get(self._indexRowset).first if not header is None: header(vColInfo) elif reqId == DB_CONSTS.idBeginRows: self._Blob.SetSize(0) self._vData = [] if mc.GetSize() > 0: with self._csCache: self._indexRowset = mc.LoadULong() elif reqId == DB_CONSTS.idTransferring: while mc.GetSize() > 0: vt = mc.LoadObject() self._vData.append(vt) elif reqId == DB_CONSTS.idEndRows: if mc.GetSize() > 0 or len(self._vData) > 0: while mc.GetSize() > 0: vt = mc.LoadObject() self._vData.append(vt) row = None with self._csCache: if self._indexRowset in self._mapRowset: row = self._mapRowset.get(self._indexRowset).second if not row is None: row(self._vData) self._vData = [] elif reqId == DB_CONSTS.idStartBLOB: if mc.GetSize() > 0: self._Blob.SetSize(0) length = mc.LoadUInt() if length != -1 and length > self._Blob.MaxBufferSize: self._Blob.Realloc(length) self._Blob.Push(mc.GetBuffer(), mc.GetSize()) mc.SetSize(0) elif reqId == DB_CONSTS.idChunk: if mc.GetSize() > 0: self._Blob.Push(mc.GetBuffer(), mc.GetSize()) mc.SetSize(0) elif reqId == DB_CONSTS.idEndBLOB: if mc.GetSize() > 0 or self._Blob.GetSize() > 0: self._Blob.Push(mc.GetBuffer(), mc.GetSize()) mc.SetSize(0) content_len = self._Blob.PeakUInt(2) if content_len >= CCachedBaseHandler.BLOB_LENGTH_NOT_AVAILABLE: content_len = self._Blob.GetSize() - 6 #sizeof(VARTYPE) + sizeof(unsigned int) self._Blob.ResetUInt(content_len, 2) vt = self._Blob.LoadObject() self._vData.append(vt) elif reqId == DB_CONSTS.idGetCachedTables: self._ms = mc.LoadInt() res = mc.LoadInt() err_msg = mc.LoadString() r = None with self._csCache: if self._indexRowset in self._mapHandler: r = self._mapHandler.get(self._indexRowset) self._mapHandler.pop(self._indexRowset) if self._indexRowset in self._mapRowset: self._mapRowset.pop(self._indexRowset) if r: r(res, err_msg) else: super(CCachedBaseHandler, self).OnResultReturned(reqId, mc)
def sayHello(self): fName = self.UQueue.LoadString() lName = self.UQueue.LoadString() res = u'Hello ' + fName + ' ' + lName print(res) return CUQueue().SaveString(res)
def MakeRequest(self, reqId, q): if q is None: q = CUQueue() buffer = (c_ubyte * q.GetSize()).from_buffer(q._m_bytes_, q._m_position_) return scl.MakeRequest(self.Handle, reqId, buffer, q.GetSize())
from msstruct import CMyStruct from spa import CUQueue, CScopeUQueue from decimal import Decimal import uuid from datetime import datetime msOrig = CMyStruct.MakeOne() print(msOrig) with CScopeUQueue() as sb: sb.Save(msOrig) res = sb.LoadByClass(CMyStruct) print(res) with CUQueue() as q: q.Empty() q.SaveInt(123).SaveInt(-1) n = q.LoadInt() assert (n == 123) n = q.LoadInt() assert (n == -1) assert (q.Size == 0) q.SaveInt(234).SaveAString('test me') n = q.LoadInt() assert (n == 234) s = q.LoadAString() assert (s == 'test me') assert (q.Size == 0) us = u'test' q.SaveString(us).SaveString(None)
def echo(self): ms = CMyStruct() ms.LoadFrom(self.UQueue) q = CUQueue() ms.SaveTo(q) return q
def OnResultReturned(self, reqId, mc): if reqId == CStreamingFile.idDownload: res = mc.LoadInt() errMsg = mc.LoadString() dl = None with self._csFile: if len(self._vContext): context = self._vContext[0] context.ErrCode = res context.ErrMsg = errMsg dl = context.Download if dl: dl(self, res, errMsg) with self._csFile: if len(self._vContext): self._vContext.popleft()._CloseFile() self.OnPostProcessing(0, 0) elif reqId == CStreamingFile.idStartDownloading: with self._csFile: fileSize = mc.LoadULong() localFile = mc.LoadString() remoteFile = mc.LoadString() flags = mc.LoadUInt() initSize = mc.LoadLong() if len(self._vContext) == 0: ctx = CContext(False, flags) ctx.LocalFile = localFile; ctx.FilePath = remoteFile; OpenLocalWrite(ctx); ctx.InitSize = initSize; self._vContext.append(ctx) front = self._vContext[0] front.FileSize = fileSize initSize = 0 if front.InitSize > 0: initSize = front.InitSize if front.File.tell() > initSize: front.File.flush() front.File.seek(initSize) front.File.truncate(initSize) elif reqId == CStreamingFile.idDownloading: downloaded = 0 trans = None with self._csFile: if len(self._vContext): context = self._vContext[0] trans = context.Transferring context.File.write(mc.GetBuffer()) initSize = 0 if context.InitSize > 0: initSize = context.InitSize downloaded = context.File.tell() - initSize mc.SetSize(0) if trans: trans(self, downloaded) elif reqId == CStreamingFile.idUploadBackup: pass elif reqId == CStreamingFile.idUpload: cs = self.AttachedClientSocket res = mc.LoadInt() errMsg = mc.LoadString() ctx = CContext(False, 0) if res or errMsg: ctx.ErrCode = res ctx.ErrMsg = errMsg with self._csFile: if len(self._vContext) > 0: context = self._vContext[0] if mc.GetSize() > 0: context.InitSize = mc.LoadLong() context.ErrCode = res context.ErrMsg = errMsg ctx = context else: with self._csFile: if len(self._vContext) > 0: context = self._vContext[0] if mc.GetSize() > 0: context.InitSize = mc.LoadLong() context.QueueOk = cs.ClientQueue.StartJob() queue_enabled = cs.ClientQueue.Available if queue_enabled: with CScopeUQueue() as q: q.SaveString(context.FilePath).SaveUInt(context.Flags).SaveULong(context.FileSize).SaveLong(context.InitSize) self.SendRequest(CStreamingFile.idUploadBackup, q, None, context.Discarded, None) ret = bytearray(context.File.read(CStreamingFile.STREAM_CHUNK_SIZE)) while len(ret) == CStreamingFile.STREAM_CHUNK_SIZE: if not self.SendRequest(CStreamingFile.idUploading, CUQueue(ret), None, context.Discarded, None): context.ErrCode = cs.ErrorCode context.ErrMsg = cs.ErrorMessage ctx = context break ret = bytearray(context.File.read(CStreamingFile.STREAM_CHUNK_SIZE)) if len(ret) < CStreamingFile.STREAM_CHUNK_SIZE: break if not queue_enabled: sent_buffer_size = cs.BytesInSendingBuffer if sent_buffer_size >= 40 * CStreamingFile.STREAM_CHUNK_SIZE: break if ctx.ErrCode or ctx.ErrMsg: pass elif len(ret) > 0: if not self.SendRequest(CStreamingFile.idUploading, CUQueue(ret), None, context.Discarded, None): context.ErrCode = cs.ErrorCode context.ErrMsg = cs.ErrorMessage ctx = context if not (ctx.ErrCode or ctx.ErrMsg) and len(ret) < CStreamingFile.STREAM_CHUNK_SIZE: context.Sent = True if not self.SendRequest(CStreamingFile.idUploadCompleted, None, None, context.Discarded, None): context.ErrCode = cs.ErrorCode context.ErrMsg = cs.ErrorMessage ctx = context if context.QueueOk: cs.ClientQueue.EndJob() if ctx.ErrCode or ctx.ErrMsg: ctx._CloseFile() if ctx.Download: ctx.Download(self, ctx.ErrCode, ctx.ErrMsg) with self._csFile: self._vContext.popleft() if ctx.QueueOk: cs.ClientQueue.AbortJob() self.OnPostProcessing(0, 0) elif reqId == CStreamingFile.idUploading: cs = self.AttachedClientSocket ctx = CContext(False, 0) trans = None uploaded = mc.LoadLong() with self._csFile: if len(self._vContext) > 0: context = self._vContext[0] trans = context.Transferring if uploaded < 0: context._CloseFile() elif not context.Sent: ret = bytearray(context.File.read(CStreamingFile.STREAM_CHUNK_SIZE)) if len(ret) > 0: if not self.SendRequest(CStreamingFile.idUploading, CUQueue(ret), None, context.Discarded, None): context.ErrCode = cs.ErrorCode context.ErrMsg = cs.ErrorMessage ctx = context if not (ctx.ErrCode or ctx.ErrMsg) and len(ret) < CStreamingFile.STREAM_CHUNK_SIZE: context.Sent = True if not self.SendRequest(CStreamingFile.idUploadCompleted, None, None, context.Discarded, None): context.ErrCode = cs.ErrorCode context.ErrMsg = cs.ErrorMessage ctx = context if ctx.ErrCode or ctx.ErrMsg: ctx._CloseFile() if ctx.Download: ctx.Download(self, ctx.ErrCode, ctx.ErrMsg) with self._csFile: self._vContext.popleft() self.OnPostProcessing(0, 0) elif trans: trans(self, uploaded) elif reqId == CStreamingFile.idUploadCompleted: upl = None with self._csFile: if len(self._vContext): context = self._vContext[0] if context.File: upl = context.Download else: context.Sent = False context.QueueOk = False if upl: upl(self, 0, '') with self._csFile: if len(self._vContext): context = self._vContext[0] if context.File: context._CloseFile() self._vContext.popleft() self.OnPostProcessing(0, 0) else: super(CStreamingFile, self).OnResultReturned(reqId, mc)
def _Transfer(self): index = 0 rh = None se = None cs = self.AttachedClientSocket if not cs.Sendable: return False sent_buffer_size = cs.BytesInSendingBuffer if sent_buffer_size > 3 * CStreamingFile.STREAM_CHUNK_SIZE: return True while index < len(self._vContext): context = self._vContext[index] if context.Sent: index += 1 continue if context.Uploading and context.Tried and not context.File: if index == 0: if context.Download: context.Download( self, CStreamingFile.CANNOT_OPEN_LOCAL_FILE_FOR_READING, context.ErrMsg) self._vContext.popleft() else: index += 1 continue if context.Uploading: if not context.Tried: context.Tried = True try: context.File = open(context.LocalFile, 'rb') context.File.seek(0, io.SEEK_END) context.FileSize = context.File.tell() context.File.seek(0, io.SEEK_SET) cq = self.AttachedClientSocket.ClientQueue if cq.Available: cq.StartJob() with CScopeUQueue() as q: q.SaveString(context.FilePath).SaveUInt( context.Flags).SaveULong(context.FileSize) if not self.SendRequest(CStreamingFile.idUpload, q, rh, context.Discarded, se): return False except IOError as e: context.ErrMsg = e.strerror context.File = None if not context.File: if index == 0: if context.Download: context.Download( self, CStreamingFile. CANNOT_OPEN_LOCAL_FILE_FOR_READING, context.ErrMsg) self._vContext.popleft() else: index += 1 continue else: ret = bytearray( context.File.read(CStreamingFile.STREAM_CHUNK_SIZE)) while len(ret) > 0: if not self.SendRequest(CStreamingFile.idUploading, CUQueue(ret), rh, context.Discarded, se): return False sent_buffer_size = cs.BytesInSendingBuffer if len(ret) < CStreamingFile.STREAM_CHUNK_SIZE: break if sent_buffer_size >= 5 * CStreamingFile.STREAM_CHUNK_SIZE: break ret = bytearray( context.File.read( CStreamingFile.STREAM_CHUNK_SIZE)) if len(ret) < CStreamingFile.STREAM_CHUNK_SIZE: context.Sent = True if not self.SendRequest( CStreamingFile.idUploadCompleted, None, rh, context.Discarded, se): return False cq = self.AttachedClientSocket.ClientQueue if cq.Available: cq.EndJob() if sent_buffer_size >= 4 * CStreamingFile.STREAM_CHUNK_SIZE: break else: with CScopeUQueue() as q: q.SaveString(context.FilePath).SaveUInt(context.Flags) if not self.SendRequest(CStreamingFile.idDownload, q, rh, context.Discarded, se): return False context.Sent = True context.Tried = True sent_buffer_size = cs.BytesInSendingBuffer if sent_buffer_size > 3 * CStreamingFile.STREAM_CHUNK_SIZE: return True index += 1 return True