修改bccclt取后续数据包的bug
diff --git a/tcutils/pybccclt.py b/tcutils/pybccclt.py
index 2c35317..86cf860 100644
--- a/tcutils/pybccclt.py
+++ b/tcutils/pybccclt.py
@@ -1,8 +1,8 @@
+#!/usr/bin/python
# -*- coding: utf-8 -*-
from ctypes import *
-bccclt_dll = None
xpack_path = 'cpack.dat'
cpack_fields = [
@@ -167,44 +167,46 @@
"vsmess",
"vsvarstr0",
"vsvarstr1",
-"vsvarstr2"
+"vsvarstr2",
+"vsvarstr3"
]
-def load_bccclt():
- global bccclt_dll
- bccclt_dll = cdll.LoadLibrary('bccclt.dll')
-
-
-load_bccclt()
class pyBccclt:
drtp_no = -1
-
- def setup(ip,port,xpack='cpack.dat',debug=0):
+ bccclt_dll = None
+
+ @staticmethod
+ def load_bccclt():
+ pyBccclt.bccclt_dll = cdll.LoadLibrary('bccclt.dll')
+
+ @staticmethod
+ def setup(ip, port, xpack='cpack.dat', debug=0):
''' 初始化 '''
+ if not pyBccclt.bccclt_dll:
+ pyBccclt.load_bccclt()
global xpack_path
xpack_path = xpack
- bccclt_dll.SetDebugSwitch( debug )
- r = bccclt_dll.BCCCLTInit(1)
+ pyBccclt.bccclt_dll.SetDebugSwitch(debug)
+ r = pyBccclt.bccclt_dll.BCCCLTInit(1)
if not r:
raise RuntimeError(u"初始化连接失败")
- no = bccclt_dll.AddDrtpNode(ip,port)
+ no = pyBccclt.bccclt_dll.AddDrtpNode(ip, port)
pyBccclt.drtp_no = no
if pyBccclt.drtp_no < 0:
raise RuntimeError(u'初始化通讯平台连接失败')
-
-
-
- setup = staticmethod(setup)
-
- def __init__(self,mainfunc):
- self.handle = bccclt_dll.NewXpackHandle( xpack_path )
- self.mainfunc = mainfunc
+
+ def __init__(self, mainfunc):
+ self.handle = pyBccclt.bccclt_dll.NewXpackHandle(xpack_path)
+ if isinstance(mainfunc, str) or isinstance(mainfunc, unicode):
+ self.mainfunc = int(mainfunc)
+ else:
+ self.mainfunc = mainfunc
self.reset()
-
+
def get_errormsg(self):
- return self.error_msg.value
-
+ return self.error_msg.value.decode('gbk')
+
def reset(self):
self.request_row = 0
self.error_code = c_int(0)
@@ -214,123 +216,131 @@
self.record = None
self.timeout = 5000
self.response_row = 0
- bccclt_dll.ResetPackHandle(self.handle)
-
+ self.raw_resp = None
+ pyBccclt.bccclt_dll.ResetPackHandle(self.handle)
+
def close(self):
- if self.handle <> None:
- bccclt_dll.DeleteXpackHandle( self.handle )
+ if self.handle != None:
+ pyBccclt.bccclt_dll.DeleteXpackHandle(self.handle)
self.handle = None
-
- def callsvr(self,func,request,timeout = 1000):
+
+ def callsvr(self, func, request, timeout=1000):
self.reset()
self.timeout = timeout
- for k,v in request.iteritems():
- if k not in cpack_fields:
- raise ValueError(u"字段 %s 不存在" % k)
-
- if isinstance(v,int):
- bccclt_dll.SetIntFieldByName(self.handle,self.request_row,k,v)
- elif isinstance(v,float):
- bccclt_dll.SetDoubleFieldByName(self.handle,self.request_row,k,v)
- elif isinstance(v,str):
- bccclt_dll.SetStringFieldByName(self.handle,self.request_row,k,v)
- else:
- raise ValueError(u"字段 %s 数据类型错误" % k)
-
- bccclt_dll.SetRequestType(self.handle,func)
+ if request:
+ for k, v in request.iteritems():
+ if k not in cpack_fields:
+ raise ValueError(u"字段 %s 不存在" % k)
+ if isinstance(v, int):
+ pyBccclt.bccclt_dll.SetIntFieldByName(self.handle, self.request_row, k, v)
+ elif isinstance(v, float):
+ pyBccclt.bccclt_dll.SetDoubleFieldByName(self.handle, self.request_row, k, v)
+ elif isinstance(v, str):
+ pyBccclt.bccclt_dll.SetStringFieldByName(self.handle, self.request_row, k, v)
+ else:
+ raise ValueError(u"字段 %s 数据类型错误" % k)
+
+ pyBccclt.bccclt_dll.SetRequestType(self.handle, func)
#print "CallRequest %d:%d" % (self.mainfunc,func)
- if not bccclt_dll.CallRequest(self.handle,pyBccclt.drtp_no,0,self.mainfunc,timeout,byref(self.error_code),self.error_msg):
+ if not pyBccclt.bccclt_dll.CallRequest(self.handle, pyBccclt.drtp_no, 0,
+ self.mainfunc, timeout, byref(self.error_code), self.error_msg):
#print "CallRequest error "
return False
-
+
self.get_return_error()
-
cnt = c_int(0)
- bccclt_dll.GetRecordCount(self.handle,byref(cnt))
+ pyBccclt.bccclt_dll.GetRecordCount(self.handle, byref(cnt))
self.record_count = cnt.value
return True
-
+
def get_retcode(self):
return self.return_code.value
-
+
def get_return_error(self):
- r = bccclt_dll.GetRetCode(self.handle,byref(self.return_code))
+ r = pyBccclt.bccclt_dll.GetRetCode(self.handle, byref(self.return_code))
if not r:
raise RuntimeError(u'取返回码错误')
- if self.get_retcode() <> 0:
- bccclt_dll.GetStringFieldByName(self.handle,0,"vsmess",self.error_msg)
+ if self.get_retcode() != 0:
+ pyBccclt.bccclt_dll.GetStringFieldByName(self.handle, 0, "vsmess", self.error_msg)
return self.return_code.value
-
+
def has_more_record(self):
#print "resp:%d, record: %d" % (self.response_row , self.record_count)
if self.response_row < self.record_count:
return True
- elif not bccclt_dll.HaveNextPack( self.handle ):
+ elif not pyBccclt.bccclt_dll.HaveNextPack(self.handle):
return False
- elif not bccclt_dll.CallNext(self.handle,self.timeout,byref(self.error_code),self.error_msg):
+ elif not pyBccclt.bccclt_dll.CallNext(self.handle, self.timeout,
+ byref(self.error_code), self.error_msg):
raise RuntimeError(u'获取后续数据包异常')
else:
self.response_row = 0
self.record_count = 0
self.get_return_error()
- if self.get_retcode() <> 0:
+ if self.get_retcode() != 0:
raise RuntimeError(u'取后续数据返回错误,ret=%d' % self.get_retcode())
cnt = c_int(0)
- bccclt_dll.GetRecordCount(self.handle,byref(cnt))
+ pyBccclt.bccclt_dll.GetRecordCount(self.handle, byref(cnt))
self.record_count = cnt.value
- if self.response_row < self.record_count:
+ # print "next count: %d" % self.record_count
+ if self.response_row < self.record_count:
return True
return False
-
- def convert_ascii(self,data):
+
+ def convert_ascii(self, data):
i = 0
datalen = len(data)
- result = ''
+ result = []
while i < datalen:
- t = data[i:i+2]
- t1 = int(t,16) & 0xFF
+ t = data[i: i + 2]
+ t1 = int(t, 16) & 0xFF
+ if t1 == 0:
+ break
if (t1 < ord('0') or t1 > ord('9')) and (t1 < ord('A') or t1 > ord('F')):
- raise ValueError("Value is non-hexdicimal %s:%d" % (chr(t1),t1))
- result += chr(t1)
+ raise ValueError("Value is non-hexdicimal %s:%d" % (chr(t1), t1))
+ result.append(chr(t1))
i += 2
- return result
-
- def next_record(self,fields):
+ return "".join(result)
+
+ def next_record(self, fields):
if self.response_row >= self.record_count:
raise ValueError(u'无可用记录')
-
+
self.record = {}
for f in fields:
#print "获取字段 ",f
if f not in cpack_fields:
raise ValueError(u"字段 %s 不存在" % f)
-
+
ctype_field = create_string_buffer(f)
if f[0] == 'l':
v = c_int(0)
- r = bccclt_dll.GetIntFieldByName(self.handle,self.response_row,ctype_field,byref(v))
+ r = pyBccclt.bccclt_dll.GetIntFieldByName(self.handle, self.response_row,
+ ctype_field, byref(v))
if not r:
raise ValueError(u"字段 %s 未返回" % f)
self.record[f] = v.value
- elif f[0] == 's':
+ elif f[0] == 's' or f[0] == 'v':
v = create_string_buffer('\000' * 512)
- r = bccclt_dll.GetStringFieldByName(self.handle,self.response_row,ctype_field,v,511)
+ r = pyBccclt.bccclt_dll.GetStringFieldByName(self.handle, self.response_row, ctype_field, v)
if not r:
raise ValueError(u"字段 %s 未返回" % f)
#print "%s: %s" % (f,v.value)
self.record[f] = v.value
elif f[0] == 'd':
v = c_double(0.0)
- r = bccclt_dll.GetDoubleFieldByName(self.handle,self.response_row,ctype_field,byref(v))
+ r = pyBccclt.bccclt_dll.GetDoubleFieldByName(self.handle, self.response_row,
+ ctype_field, byref(v))
if not r:
raise ValueError(u"字段 %s 未返回" % f)
self.record[f] = v.value
elif f[0] == 'u':
v = create_string_buffer('\000' * 1024)
- r = bccclt_dll.GetStringFieldByName(self.handle,self.response_row,ctype_field,v,1023)
+ r = pyBccclt.bccclt_dll.GetStringFieldByName(self.handle, self.response_row,
+ ctype_field, v)
if not r:
raise ValueError(u"字段 %s 未返回" % f)
-
+
data = v.value
data = data[2:]
data = self.convert_ascii(data)
@@ -340,13 +350,31 @@
self.response_row += 1
#print "fetch one record , " ,self.record
return self.record
-
- def fetch_record(self,fields):
+
+ def fetch_record(self, fields):
while self.has_more_record():
ret = self.next_record(fields)
yield ret
-
-
-
-
-
\ No newline at end of file
+
+ def send_raw_data(self, data, requesttype, timeout):
+ if isinstance(data, unicode):
+ data = data.encode('gbk')
+ pyBccclt.bccclt_dll.SetRawRecord(self.handle, 0, data, len(data))
+ pyBccclt.bccclt_dll.SetRequestType(self.handle, requesttype)
+ r = pyBccclt.bccclt_dll.CallRequest(self.handle, pyBccclt.drtp_no, 0,
+ self.mainfunc, timeout, byref(self.error_code), self.error_msg)
+ if not r:
+ return False
+ if self.raw_resp is None:
+ self.raw_resp = create_string_buffer(8196)
+ else:
+ memset(self.raw_resp, 0, sizeof(self.raw_resp))
+ r = pyBccclt.bccclt_dll.GetRawRecord(self.handle, 0, self.raw_resp, 8196)
+ if not r:
+ return False
+ return True
+
+ def raw_data(self):
+ if self.raw_resp is None:
+ raise ValueError(u"response is None")
+ return self.raw_resp.value