blob: 2c35317fb8733ea721157e16a7a389de99ddf4e6 [file] [log] [blame]
# -*- coding: utf-8 -*-
from ctypes import *
bccclt_dll = None
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"
]
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):
''' 初始化 '''
global xpack_path
xpack_path = xpack
bccclt_dll.SetDebugSwitch( debug )
r = bccclt_dll.BCCCLTInit(1)
if not r:
raise RuntimeError(u"初始化连接失败")
no = 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
self.reset()
def get_errormsg(self):
return self.error_msg.value
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
bccclt_dll.ResetPackHandle(self.handle)
def close(self):
if self.handle <> None:
bccclt_dll.DeleteXpackHandle( self.handle )
self.handle = None
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)
#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):
#print "CallRequest error "
return False
self.get_return_error()
cnt = c_int(0)
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))
if not r:
raise RuntimeError(u'取返回码错误')
if self.get_retcode() <> 0:
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 ):
return False
elif not 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)
bccclt_dll.GetRecordCount(self.handle,byref(cnt))
self.record_count = cnt.value
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 < 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)
i += 2
return 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))
if not r:
raise ValueError(u"字段 %s 未返回" % f)
self.record[f] = v.value
elif f[0] == 's':
v = create_string_buffer('\000' * 512)
r = bccclt_dll.GetStringFieldByName(self.handle,self.response_row,ctype_field,v,511)
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))
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)
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