blob: 86cf86060e2712521106273fb2561e68d698cefe [file] [log] [blame]
#!/usr/bin/python
# -*- coding: utf-8 -*-
from ctypes import *
xpack_path = 'cpack.dat'
cpack_fields = [
"scust_no",
"scust_no2",
"sholder_ac_no",
"sholder_ac_no2",
"sholder_type",
"sholder_type2",
"sname",
"sname2",
"sall_name",
"smarket_code",
"smarket_code2",
"sdate0",
"sdate1",
"sdate2",
"sdate3",
"stime0",
"stime1",
"stime2",
"stime3",
"lvol0",
"lvol1",
"lvol2",
"lvol3",
"lvol4",
"lvol5",
"lvol6",
"lvol7",
"lvol8",
"lvol9",
"lvol10",
"lvol11",
"lvol12",
"damt0",
"damt1",
"damt2",
"damt3",
"damt4",
"damt5",
"damt6",
"damt7",
"damt8",
"damt9",
"damt10",
"damt11",
"damt12",
"damt13",
"damt14",
"damt15",
"damt16",
"damt17",
"damt18",
"damt19",
"damt20",
"damt21",
"damt22",
"damt23",
"damt24",
"damt25",
"damt26",
"damt27",
"damt28",
"damt29",
"damt30",
"damt31",
"damt32",
"damt33",
"sstock_code",
"sstock_code2",
"scust_type",
"scust_type2",
"sstat_type",
"sstat_type2",
"sroom_no",
"sroom_no2",
"sopen_emp",
"sclose_emp",
"schange_emp",
"scheck_emp",
"semp",
"snation_code",
"lcert_code",
"stx_pwd",
"stx_pwd2",
"swithdraw_pwd",
"swithdraw_pwd2",
"semp_pwd",
"semp_pwd2",
"sbank_pwd",
"sbank_pwd2",
"scust_auth",
"scust_auth2",
"scust_limit",
"scust_limit2",
"lsafe_level",
"lsafe_level2",
"spost_code",
"spost_code2",
"sphone",
"sphone2",
"sphone3",
"spager",
"semail",
"semail2",
"snote",
"snote2",
"scert_no",
"scert_no2",
"scert_addr",
"sstatus0",
"sstatus1",
"sstatus2",
"sstatus3",
"sstatus4",
"lwithdraw_flag",
"saddr",
"saddr2",
"sserial0",
"sserial1",
"sserial2",
"sserial3",
"sserial4",
"scurrency_type",
"scurrency_type2",
"sbranch_code0",
"sbranch_code1",
"sbranch_code2",
"usset0",
"usset1",
"usset2",
"usset3",
"usset4",
"usset5",
"usset6",
"sstation0",
"sstation1",
"sbank_acc",
"sbank_acc2",
"lbank_acc_type",
"lbank_acc_type2",
"smain_flag",
"smain_flag2",
"sbank_code",
"sbank_code2",
"semp_no",
"semp_no2",
"drate0",
"drate1",
"lserial0",
"lserial1",
"sbankname",
"sbankname2",
"scard0",
"scard1",
"sorder0",
"sorder1",
"sorder2",
"scusttypes",
"ssectypes",
"vsmess",
"vsvarstr0",
"vsvarstr1",
"vsvarstr2",
"vsvarstr3"
]
class pyBccclt:
drtp_no = -1
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
pyBccclt.bccclt_dll.SetDebugSwitch(debug)
r = pyBccclt.bccclt_dll.BCCCLTInit(1)
if not r:
raise RuntimeError(u"初始化连接失败")
no = pyBccclt.bccclt_dll.AddDrtpNode(ip, port)
pyBccclt.drtp_no = no
if pyBccclt.drtp_no < 0:
raise RuntimeError(u'初始化通讯平台连接失败')
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.decode('gbk')
def reset(self):
self.request_row = 0
self.error_code = c_int(0)
self.error_msg = create_string_buffer('\000' * 1024)
self.return_code = c_int(0)
self.record_count = 0
self.record = None
self.timeout = 5000
self.response_row = 0
self.raw_resp = None
pyBccclt.bccclt_dll.ResetPackHandle(self.handle)
def close(self):
if self.handle != None:
pyBccclt.bccclt_dll.DeleteXpackHandle(self.handle)
self.handle = None
def callsvr(self, func, request, timeout=1000):
self.reset()
self.timeout = timeout
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 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)
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 = pyBccclt.bccclt_dll.GetRetCode(self.handle, byref(self.return_code))
if not r:
raise RuntimeError(u'取返回码错误')
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 pyBccclt.bccclt_dll.HaveNextPack(self.handle):
return False
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:
raise RuntimeError(u'取后续数据返回错误,ret=%d' % self.get_retcode())
cnt = c_int(0)
pyBccclt.bccclt_dll.GetRecordCount(self.handle, byref(cnt))
self.record_count = cnt.value
# print "next count: %d" % self.record_count
if self.response_row < self.record_count:
return True
return False
def convert_ascii(self, data):
i = 0
datalen = len(data)
result = []
while i < datalen:
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.append(chr(t1))
i += 2
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 = 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' or f[0] == 'v':
v = create_string_buffer('\000' * 512)
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 = 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 = 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)
self.record[f] = data
else:
raise ValueError(u'字段类型错误 %s' % f)
self.response_row += 1
#print "fetch one record , " ,self.record
return self.record
def fetch_record(self, fields):
while self.has_more_record():
ret = self.next_record(fields)
yield ret
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