修改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