@@ -21,6 +21,12 @@ import datetime
2121
2222import sys
2323
24+ cdef extern from * :
25+ ctypedef char * const_char_ptr " const char*"
26+
27+ from cpython.mem cimport PyMem_Malloc, PyMem_Free
28+ from cpython.version cimport PY_MAJOR_VERSION
29+
2430from libc.stdlib cimport *
2531cdef extern from " stdlib.h" nogil:
2632 void * memset(void * str , int c, size_t n)
@@ -35,6 +41,8 @@ cdef extern from "Python.h":
3541
3642cdef extern from " string.h" :
3743 int strnlen(char * s, int maxlen)
44+ char * strcpy(char * , char * )
45+
3846
3947cdef extern from " paradox.h" :
4048 ctypedef enum fieldtype_t:
@@ -116,13 +124,27 @@ cdef extern from "paradox.h":
116124 ctypedef struct pxpindex_t
117125 ctypedef struct pxstream_t
118126
127+
128+ ctypedef struct Pxval_str:
129+ char * val
130+ int len
131+ ctypedef union Pxval_value:
132+ long lval
133+ double dval
134+ Pxval_str str
135+ ctypedef struct pxval_t:
136+ char isnull
137+ int type
138+ Pxval_value value
139+
140+
119141 pxdoc_t * PX_new()
120- pxdoc_t* PX_new2(void (* errorhandler)(pxdoc_t * p, int type , char * msg, void * data),
121- void * (* allocproc)(pxdoc_t * p, size_t size, char * caller),
122- void * (* reallocproc)(pxdoc_t * p, void * mem, size_t size, char * caller),
142+ pxdoc_t* PX_new2(void (* errorhandler)(pxdoc_t * p, int type , const_char_ptr msg, void * data),
143+ void * (* allocproc)(pxdoc_t * p, size_t size, const_char_ptr caller),
144+ void * (* reallocproc)(pxdoc_t * p, void * mem, size_t size, const_char_ptr caller),
123145 void (* freeproc)(pxdoc_t * p, void * mem))
124146 char * PX_strdup(pxdoc_t * pxdoc, char * str )
125- int PX_open_file(pxdoc_t * pxdoc, char * filename)
147+ int PX_open_file(pxdoc_t * pxdoc, const_char_ptr filename)
126148 int PX_create_file(pxdoc_t * pxdoc, pxfield_t * px_fields, unsigned int numfields, char * filename, int type )
127149 int PX_read_primary_index(pxdoc_t * pindex)
128150 int PX_add_primary_index(pxdoc_t * pxdoc, pxdoc_t * pindex)
@@ -163,14 +185,15 @@ cdef class PXDoc:
163185 """
164186
165187 cdef pxdoc_t * doc
166- cdef char * filename
188+ cdef bytes filename
167189 cdef char isopen
168190
169191 def __init__ (self , filename ):
170192 """
171193 Create a PXDoc instance, associated to the given external filename.
172194 """
173-
195+ if PY_MAJOR_VERSION >= 3 or isinstance (filename, unicode ):
196+ filename = filename.encode(' utf8' )
174197 self .filename = filename
175198 self .doc = PX_new2(& errorhandler, NULL , NULL , NULL )
176199 self .isopen = 0
@@ -179,8 +202,7 @@ cdef class PXDoc:
179202 """
180203 Open the data file.
181204 """
182-
183- if PX_open_file(self .doc, self .filename)< 0 :
205+ if PX_open_file(self .doc, self .filename) < 0 :
184206 raise Exception (" Couldn't open `%s `" % self .filename)
185207 self .isopen = 1
186208
@@ -357,7 +379,7 @@ cdef class Table(PXDoc):
357379 Get number of fields in the table.
358380 """
359381
360- return self .record.getFieldsCount( )
382+ return len ( self .record)
361383
362384 def readRecord (self , recno = None ):
363385 """
@@ -376,17 +398,36 @@ cdef class Table(PXDoc):
376398 """
377399
378400 if not recno:
379- recno = self .current_recno+ 1
401+ recno = self .current_recno + 1
380402 else :
381403 self .current_recno = recno
382404
383- if recno>= self .doc.px_head.px_numrecords:
405+ if recno >= self .doc.px_head.px_numrecords:
384406 return False
385407
386408 self .current_recno = recno
387409
388410 return self .record.read(recno)
389411
412+ def __iter__ (self ):
413+ return self
414+
415+ def __next__ (self ):
416+ ok = self .readRecord()
417+ if not ok:
418+ self .current_recno = - 1
419+ raise StopIteration ()
420+ return self .record
421+
422+ def __getitem__ (self , key ):
423+ if key >= self .doc.px_head.px_numrecords:
424+ raise IndexError ()
425+ self .record.read(key)
426+ return self .record
427+
428+ def __len__ (self ):
429+ return self .doc.px_head.px_numrecords
430+
390431 def append (self , values ):
391432 cdef char * b
392433 l = len (self .fields)
@@ -629,6 +670,7 @@ cdef class Record:
629670 """
630671
631672 cdef void * data
673+ cdef int current_fieldno
632674 cdef Table table
633675 cdef public fields
634676
@@ -643,15 +685,17 @@ cdef class Record:
643685 self .data = table.doc.malloc(table.doc,
644686 table.doc.px_head.px_recordsize,
645687 " Memory for record" )
688+ self .current_fieldno = - 1
689+
646690 self .table = table
647691 self .fields = []
648692 offset = 0
649- for i in range (self .getFieldsCount( )):
693+ for i in range (len ( self )):
650694 field = RecordField(self , i, offset)
651695 self .fields.append(field)
652- offset = offset + table.doc.px_head.px_fields[i].px_flen
696+ offset = offset + table.doc.px_head.px_fields[i].px_flen
653697
654- def getFieldsCount (self ):
698+ def __len__ (self ):
655699 """
656700 Get number of fields in the record.
657701 """
@@ -667,3 +711,18 @@ cdef class Record:
667711 self .table.filename))
668712 return True
669713
714+ def __iter__ (self ):
715+ return self
716+
717+ def __next__ (self ):
718+ fieldno = self .current_fieldno + 1
719+ try :
720+ field = self .fields[fieldno]
721+ self .current_fieldno = fieldno
722+ return field
723+ except IndexError :
724+ self .current_fieldno = - 1
725+ raise StopIteration ()
726+
727+ def __getitem__ (self , key ):
728+ return self .fields[key]
0 commit comments