1
2
3
4
5
6
7
8
9
10
11 import logging, os
12 from ctypes import CDLL, CFUNCTYPE, POINTER, Structure, byref, cast, \
13 string_at, c_void_p, c_int, c_ulong, c_bool, c_size_t, c_char_p
14
15
16 import dlinklist as dll
20 """
21 Many methods in the API return a status value, this class provides an
22 enumeration of the status valid return values.
23 """
24 NORMAL = 0
25 MEM_ERROR = 1
26 ZERO_INFO = 2
27 NULL_LIST = 3
28 NOT_FOUND = 4
29 OPEN_ERROR = 5
30 WRITE_ERROR = 6
31 READ_ERROR = 7
32 NOT_MODIFIED = 8
33 NULL_FUNCTION = 9
34 CONTINUE = 10
35 _ERRORS = None
36 __MESSAGES = {
37 0: "Normal operation",
38 1: "malloc error",
39 2: "sizeof(Info) is zero",
40 3: "List is NULL",
41 4: "Record not found",
42 5: "Cannot open file",
43 6: "File write error",
44 7: "File read error",
45 8: "Unmodified list",
46 9: "NULL function pointer",
47 10: "Continue process--internal use only",
48 }
49
50 @classmethod
52 """
53 Return a tuple consisting of the text name of the status return value
54 and the description of the status. If the return value is invalid the
55 number of the value is returned and the phrase 'Unknown error'.
56
57 @param num: The numeric value from the C{Return} class.
58 @type num: C{int}
59 @return: A tuple consisting of the text C{Return} value and the
60 description.
61 @rtype: C{(str} or C{int, str)}
62 """
63 return (self._ERRORS.get(num, num),
64 self.__MESSAGES.get(num, "Unknown error"))
65
66 Return._ERRORS = dict([(v,k) for k,v in Return.__dict__.items()
67 if not k.startswith("_")])
71 """
72 Provides an enumeration of the search origin values.
73 """
74 ORIGIN_DEFAULT = 0
75 HEAD = 1
76 CURRENT = 2
77 TAIL = 3
78 _ORIGINS = None
79 __MESSAGES = {
80 0: "Use current origin setting",
81 1: "Set origin to head pointer",
82 2: "Set origin to current pointer",
83 3: "Set origin to tail pointer",
84 }
85
86 @classmethod
88 """
89 Return a tuple consisting of the text name of the search origin value
90 and the description of the status. If the search origin value is
91 invalid the number of the value is returned and the phrase
92 'Unknown error'.
93
94 @param num: The numeric value from the C{SrchOrigin} class.
95 @type num: C{int}
96 @return: A tuple consisting of the text C{SrchOrigin} value and the
97 description.
98 @rtype: C{(str} or C{int, str)}
99 """
100 return (self._ORIGINS.get(num, num),
101 self.__MESSAGES.get(num, "Unknown search origin"))
102
103 SrchOrigin._ORIGINS = dict([(v,k) for k,v in SrchOrigin.__dict__.items()
104 if not k.startswith("_")])
108 """
109 Provides an enumeration of the search direction values.
110 """
111 DIRECTION_DEFAULT = 0
112 DOWN = 1
113 UP = 2
114 _DIRS = None
115 __MESSAGES = {
116 0: "Use current direction setting",
117 1: "Set direction to down",
118 2: "Set direction to up",
119 }
120
121 @classmethod
123 """
124 Return a tuple consisting of the text name of the search direction value
125 and the description of the status. If the search direction value is
126 invalid the number of the value is returned and the phrase
127 'Unknown error'.
128
129 @param num: The numeric value from the C{SrchDir} class.
130 @type num: C{int}
131 @return: A tuple consisting of the text C{SrchDir} value and the
132 description.
133 @rtype: C{(str} or C{int, str)}
134 """
135 return (self._DIRS.get(num, num),
136 self.__MESSAGES.get(num, "Unknown search direction"))
137
138 SrchDir._DIRS = dict([(v,k) for k,v in SrchDir.__dict__.items()
139 if not k.startswith("_")])
143 """
144 Provides an enumeration of the insert direction values.
145 """
146 INSERT_DEFAULT = 0
147 ABOVE = 1
148 BELOW = 2
149 _DIRS = None
150 __MESSAGES = {
151 0: "Use current insert setting",
152 1: "Insert new record ABOVE current record",
153 2: "Insert new record BELOW current record",
154 }
155
156 @classmethod
158 """
159 Return a tuple consisting of the text name of the insert direction value
160 and the description of the status. If the insert direction value is
161 invalid the number of the value is returned and the phrase
162 'Unknown error'.
163
164 @param num: The numeric value from the C{InsertDir} class.
165 @type num: C{int}
166 @return: A tuple consisting of the text C{InsertDir} value and the
167 description.
168 @rtype: C{(str} or C{int, str)}
169 """
170 return (self._DIRS.get(num, num),
171 self.__MESSAGES.get(num, "Unknown search direction"))
172
173 InsertDir._DIRS = dict([(v,k) for k,v in InsertDir.__dict__.items()
174 if not k.startswith("_")])
175
176
177 -class Node(Structure):
178 """
179 This class holds the link list pointers and the Info structure pointer.
180 """
181 _fields_ = [
182 ('info', c_void_p),
183 ]
184 Node._fields_.append(('next', POINTER(Node)))
185 Node._fields_.append(('prior', POINTER(Node)))
186
187
188 -class List(Structure):
189 """
190 This is the top level control structure which keeps track of the Node
191 structure pointers and various variables used in the API.
192 """
193 _fields_ = (
194 ('head', POINTER(Node)),
195 ('tail', POINTER(Node)),
196 ('current', POINTER(Node)),
197 ('saved', POINTER(Node)),
198 ('infosize', c_int),
199 ('listsize', c_ulong),
200 ('current_index', c_ulong),
201 ('save_index', c_ulong),
202 ('modified', c_bool),
203 ('search_origin', c_int),
204 ('search_dir', c_int),
205 )
206
207
208 -class Info(Structure):
210
213 """
214 This class is returned by the getSearchModes() method and contains the
215 current search origin and direction modes from the Controller List class.
216 """
217 _fields_ = (
218 ('search_origin', c_int),
219 ('search_dir', c_int),
220 )
221
224 """
225 This class provides thin wrappers around the functions in my doubly linklist
226 C library.
227
228 1. Initialization Methods
229 - C{create()} -- Creates and initializes the link list. This method
230 both creates and initializes the list and should be used in
231 preference to the next two methods except in rare cases.
232 - C{createList()} -- List creation method.
233 - C{initialize()} -- List initialization method.
234 - C{destroyList()} -- List removal method.
235
236 2. Status and State Methods
237 - C{version()} -- Get the version information and a list of
238 contributers to this project.
239 - C{isListEmpty()} -- Check if the list is empty.
240 - C{isListFull()} -- Check if the list is full.
241 - C{getNumberOfRecords()} -- Get the number of records in the link
242 list.
243 - C{setSearchModes()} -- Sets the search C{origin} and C{dir} modes.
244 - C{getSearchModes()} -- Get the search modes, a tuple of origin and
245 direction.
246 - C{getCurrentIndex()} -- Get the current index value.
247
248 3. Pointer Manipulation Methods
249 - C{currentPointerToHead()} -- Moves the current pointer to the head
250 of the list.
251 - C{currentPointerToTail()} -- Moves the current pointer to the tail
252 of the list.
253 - C{incrementCurrentPointer()} -- Moves the current pointer to the
254 next C{Node}.
255 - C{decrementCurrentPointer()} -- Moves the current pointer to the
256 prior C{Node}.
257 - C{storeCurrentPointer()} -- Store the current pointer in the control
258 C{List} class.
259 - C{restoreCurrentPointer()} -- Restore the current pointer from the
260 control C{List} class.
261
262 4. List Update Methods
263 - C{addRecord()} -- Adds a record to the link list.
264 - C{insertRecord()} -- Inserts a record relative to the current
265 pointer.
266 - C{swapRecord()} -- Swaps current record up or down one position in
267 the list.
268 - C{updateCurrentRecord()} -- Updates the current record.
269 - C{deleteCurrentRecord()} -- Delete a record from the list.
270 - C{deleteAllNodes()} -- Deletes all the C{Info} and their C{Node}
271 objects from the list then reinitializes the control C{List}.
272
273 5. Search and Retrieval Methods
274 - C{findRecord()} -- Find a C{record} in the list with search criteria
275 passed into C{match}.
276 - C{findNthRecord()} -- Return the Nth record in the list based on
277 the setting of origin and direction values in the control C{List}.
278 - C{getCurrentRecord()} -- Return the current record.
279 - C{getPriorRecord()} -- Return the prior record relative to the current
280 pointer.
281 - C{getNextRecord()} -- Return the next record relative to the current
282 pointer.
283
284 6. Input/Output Methods
285 - C{saveList()} -- Save list to disk.
286 - C{loadList()} -- Load list from disk.
287
288 7. Miscellaneous Helper Methods
289 - C{compare()} -- A basic compare function. You may need to write
290 your own.
291 - C{checkInfoType()} -- Utility method to check that the C{Info}
292 object is valid.
293 """
294 __LIBRARY = ("../src/libdll.so", dll._RES_PATH, "../libdll.so",)
295
296 - def __init__(self, logname="", disableLogging=False):
297 """
298 The constructor creates logging and instantiates the library object.
299
300 @keyword logname: The logging name used in your application, defaults
301 to the root logger.
302 @type logname: C{str}
303 @keyword disableLogging: Turns logging on or off. The default C{False}
304 turns logging on, and C{True} turns logging
305 off.
306 @type disableLogging: C{bool}
307 @raise LibraryNotFoundException: If the C{C} library cannot be found.
308 """
309 if not logname: logging.basicConfig()
310 self._log = logging.getLogger(logname)
311 self._log.setLevel(logging.DEBUG)
312 if disableLogging: logging.disable(100)
313 self._lib = None
314
315 for path in self.__LIBRARY:
316 try:
317 self._lib = CDLL(path)
318 break
319 except:
320 pass
321
322 if not self._lib:
323 lib = os.path.split(self.__LIBRARY[0])[1]
324 msg = "Could not load library: %s"
325 self._log.critical(msg, lib)
326 raise dll.LibraryNotFoundException(msg % lib)
327
328 self._list_p = None
329
330
331
332
333
335 """
336 Creates and initializes the link list. This method should be used
337 instead of the C{createList} and C{initialize} methods unless you need
338 to reuse the C{List} class.
339
340 @param infoSize: The size of the user defined C{Info} class.
341 @type infoSize: C{int}
342 @return: A pointer to the top level C{List} class. This return value
343 can be disregarded in most situations as it is not needed for
344 normal use.
345 @rtype: C{ctypes POINTER}
346 @raise APIException: If a low level error occurred in the C{C} code.
347 @raise FunctionException: If the status return value is not
348 C{Return.NORMAL}.
349 """
350 list_p = self.createList()
351 self.initialize(infoSize)
352 return list_p
353
355 """
356 Creates the C{List} object in memory.
357
358 The C{C} function doc string::
359
360 List *DLL_CreateList(List **list);
361
362 Arguments: list -- Pointer to a pointer to a name of a structure to
363 create.
364 Returns : Pointer to created structure NULL if unsuccessful}
365
366 @return: A pointer to the top level C{List} class. This return value
367 can be disregarded in most situations as it is not needed for
368 normal use.
369 @rtype: C{ctypes POINTER}
370 @raise APIException: If a low level error occurred in the C{C} code.
371 """
372 try:
373 createList = self._lib.DLL_CreateList
374 createList.argtypes = (POINTER(POINTER(List)),)
375 createList.restype = POINTER(List)
376 control = POINTER(List)()
377 list_p = createList(byref(control))
378 except Exception, e:
379 self._log.critical("Unknown error: %s", str(e))
380 raise dll.APIException(e)
381
382 self._log.debug("List address: %s", hex(cast(list_p, c_void_p).value))
383 self._list_p = list_p
384 return list_p
385
387 """
388 Initializes the C{List} class with the user's C{Info} class size
389 parameters.
390
391 The C{C} function doc string::
392
393 DLL_Return DLL_InitializeList(List *list, size_t infosize);
394
395 Arguments: list -- Pointer to type List
396 infosize -- Size of user Info
397 Returns : DLL_NORMAL -- Initialization was done successfully
398 DLL_ZERO_INFO -- sizeof(Info) is zero
399 DLL_NULL_LIST -- Info is NULL
400
401 @param infoSize: The size of the user defined C{Info} class.
402 @type infoSize: C{int}
403 @return: C{None}
404 @raise APIException: If a low level error occurred in the C{C} code.
405 @raise FunctionException: If the status return value is not
406 C{Return.NORMAL}.
407 """
408 try:
409 initList = self._lib.DLL_InitializeList
410 initList.argtypes = (POINTER(List), c_size_t)
411 retval = initList(self._list_p, c_size_t(infoSize))
412 except Exception, e:
413 self._log.critical("Unknown error: %s", str(e))
414 raise dll.APIException(e)
415
416 if retval != Return.NORMAL:
417 msg = "Return.%s: %s" % Return.getMessage(retval)
418 raise dll.FunctionException(msg, retval=retval)
419
421 """
422 Deallocates the memory of all C{Nodes} and the C{Info} objects then
423 deallocates the memory used by the C{List} object.
424
425 The C{C} function doc string::
426
427 void DLL_DestroyList(List **list);
428
429 Arguments: list -- Pointer to a pointer to a name of a structure to
430 destroy.
431 Returns : void
432
433 @return: C{None}
434 @raise APIException: If a low level error occurred in the C{C} code.
435 """
436 try:
437 destroyList = self._lib.DLL_DestroyList
438 destroyList.argtypes = (POINTER(POINTER(List)),)
439 destroyList.restype = None
440 destroyList(byref(self._list_p))
441 except Exception, e:
442 self._log.critical("Unknown error: %s", str(e))
443 raise dll.APIException(e)
444
445
446
447
448
450 """
451 Get the version information and a list of contributors to this project.
452
453 The C{C} function doc string::
454
455 DLL_Version() : Returns a pointer to version information
456
457 Arguments: void
458
459 Return : char * -- Pointer to version info
460
461 @return: A printable string.
462 @rtype: C{str}
463 @raise APIException: If a low level error occurred in the C{C} code.
464 """
465 try:
466 version = string_at(self._lib.DLL_Version())
467 except Exception, e:
468 self._log.critical("Unknown error: %s", str(e))
469 raise dll.APIException(e)
470
471 return version
472
474 """
475 Check if the list is empty.
476
477 The C{C} function doc string::
478
479 DLL_Boolean DLL_IsListEmpty(List *list);
480
481 Arguments: list -- Pointer to type List
482 Returns : DLL_TRUE -- List is empty
483 DLL_FALSE -- List has items in it
484
485 @return: If the list is empty return C{True} else return C{False}.
486 @rtype: C{bool}
487 @raise APIException: If a low level error occurred in the C{C} code.
488 """
489 try:
490 isListEmpty = self._lib.DLL_IsListEmpty
491 isListEmpty.argtypes = (POINTER(List),)
492 retval = isListEmpty(self._list_p)
493 except Exception, e:
494 self._log.critical("Unknown error: %s", str(e))
495 raise dll.APIException(e)
496
497 return retval
498
500 """
501 Check if the list is full, meaning memory is exhausted.
502
503 The C{C} function doc string::
504
505 DLL_Boolean DLL_IsListFull(List *list);
506
507 Arguments: list -- Pointer to type List
508 Returns : DLL_TRUE -- List is full (memory dependent)
509 DLL_FALSE -- List is empty or partially full
510
511 @return: If the list is full return C{True} else return C{False}.
512 @rtype: C{bool}
513 @raise APIException: If a low level error occurred in the C{C} code.
514 """
515 try:
516 isListFull = self._lib.DLL_IsListFull
517 isListFull.argtypes = (POINTER(List),)
518 retval = isListFull(self._list_p)
519 except Exception, e:
520 self._log.critical("Unknown error: %s", str(e))
521 raise dll.APIException(e)
522
523 return retval
524
526 """
527 Get the number of records in the link list.
528
529 The C{C} function doc string::
530
531 unsigned long DLL_GetNumberOfRecords(List *list);
532
533 Arguments: list -- Pointer to type List
534 Returns : Number of records in list
535
536 @return: The number of records in the link list.
537 @rtype: C{int}
538 @raise APIException: If a low level error occurred in the C{C} code.
539 """
540 try:
541 getNumberOfRecords = self._lib.DLL_GetNumberOfRecords
542 getNumberOfRecords.argtypes = (POINTER(List),)
543 retval = getNumberOfRecords(self._list_p)
544 except Exception, e:
545 self._log.critical("Unknown error: %s", str(e))
546 raise dll.APIException(e)
547
548 return retval
549
551 """
552 Sets the search C{origin} and C{dir} modes and returns the previously
553 set modes.
554
555 The C{C} function doc string::
556
557 DLL_Return DLL_SetSearchModes(List *list, DLL_SrchOrigin origin,
558 DLL_SrchDir dir);
559
560 Arguments: list -- Pointer to type List
561 origin -- Indicates the start search pointer to
562 use
563 dir -- Indicates the direction to search in
564 Returns : DLL_NORMAL -- Values assigned were accepted
565 DLL_NOT_MODIFIED -- Values were not assigned--invalid type
566 (previous values are still in place)
567
568 @param origin: A value from the C{SrchOrigin} class.
569 @type origin: C{int}
570 @param dir: A value from the C{SrchDir} class.
571 @type dir: C{int}
572 @return: The previously set modes: C{(origin, direction)}
573 @rtype: C{tuple}
574 @raise APIException: If a low level error occurred in the C{C} code.
575 @raise FunctionException: If the status return value is not
576 C{Return.NORMAL}.
577 """
578 modes = self.getSearchModes()
579
580 try:
581 setSearchModes = self._lib.DLL_SetSearchModes
582 setSearchModes.argtypes = (POINTER(List), c_int, c_int)
583 retval = setSearchModes(self._list_p, origin, dir)
584 except Exception, e:
585 self._log.critical("Unknown error: %s", str(e))
586 raise dll.APIException(e)
587
588 if retval != Return.NORMAL:
589 msg = "Return.%s: %s" % Return.getMessage(retval)
590 raise dll.FunctionException(msg, retval=retval)
591
592 return modes
593
595 """
596 Get the search modes, a tuple of origin and direction.
597
598 The C{C} function doc string::
599
600 DLL_SearchModes DLL_GetSearchModes(List *list, DLL_SearchModes *ssp);
601
602 Arguments: list -- Pointer to type List
603 ssp -- Save structure pointer
604 Returns : Pointer to type DLL_SearchModes
605
606 @return: The search modes in a tuple C{(origin, direction)}.
607 @rtype: C{tuple}
608 @raise APIException: If a low level error occurred in the C{C} code.
609 """
610 try:
611 setSearchModes = self._lib.DLL_GetSearchModes
612 setSearchModes.argtypes = (POINTER(List), POINTER(SearchModes))
613 setSearchModes.restype = POINTER(SearchModes)
614 sm = SearchModes()
615 modes_p = setSearchModes(self._list_p, byref(sm))
616 modes = modes_p.contents
617 except Exception, e:
618 self._log.critical("Unknown error: %s", str(e))
619 raise dll.APIException(e)
620
621 return modes.search_origin, modes.search_dir
622
624 """
625 Get the current index value.
626
627 The C{C} function doc string::
628
629 unsigned long DLL_GetCurrentIndex(List *list);
630
631 Arguments: list -- Pointer to type List
632 Returns : Current record's index
633
634 @return: The index where the first C{Node} is 1.
635 @rtype: C{int}
636 @raise APIException: If a low level error occurred in the C{C} code.
637 """
638 try:
639 getCurrentIndex = self._lib.DLL_GetCurrentIndex
640 getCurrentIndex.argtypes = (POINTER(List),)
641 getCurrentIndex.restype = c_ulong
642 retval = getCurrentIndex(self._list_p)
643 except Exception, e:
644 self._log.critical("Unknown error: %s", str(e))
645 raise dll.APIException(e)
646
647 return retval
648
649
650
651
652
654 """
655 Moves the current pointer to the head of the list.
656
657 The C{C} function doc string::
658
659 DLL_Return DLL_CurrentPointerToHead(List *list);
660
661 Arguments: list -- Pointer to type List
662 Returns : DLL_NORMAL -- Record found
663 DLL_NULL_LIST -- Empty list
664
665 @return: C{None}
666 @raise APIException: If a low level error occurred in the C{C} code.
667 @raise FunctionException: If the status return value is not
668 C{Return.NORMAL}.
669 """
670 try:
671 currentPointerToHead = self._lib.DLL_CurrentPointerToHead
672 currentPointerToHead.argtypes = (POINTER(List),)
673 retval = currentPointerToHead(self._list_p)
674 except Exception, e:
675 self._log.critical("Unknown error: %s", str(e))
676 raise dll.APIException(e)
677
678 if retval != Return.NORMAL:
679 msg = "Return.%s: %s" % Return.getMessage(retval)
680 raise dll.FunctionException(msg, retval=retval)
681
683 """
684 Moves the current pointer to the tail of the list.
685
686 The C{C} function doc string::
687
688 DLL_Return DLL_CurrentPointerToTail(List *list);
689
690 Arguments: list -- Pointer to type List
691 Returns : DLL_NORMAL -- Record found
692 DLL_NULL_LIST -- Empty list
693
694 @return: C{None}
695 @raise APIException: If a low level error occurred in the C{C} code.
696 @raise FunctionException: If the status return value is not
697 C{Return.NORMAL}.
698 """
699 try:
700 currentPointerToTail = self._lib.DLL_CurrentPointerToTail
701 currentPointerToTail.argtypes = (POINTER(List),)
702 retval = currentPointerToTail(self._list_p)
703 except Exception, e:
704 self._log.critical("Unknown error: %s", str(e))
705 raise dll.APIException(e)
706
707 if retval != Return.NORMAL:
708 msg = "Return.%s: %s" % Return.getMessage(retval)
709 raise dll.FunctionException(msg, retval=retval)
710
712 """
713 Moves the current pointer to the next C{Node}.
714
715 The C{C} function doc string::
716
717 DLL_Return DLL_IncrementCurrentPointer(List *list);
718
719 Arguments: list -- Pointer to type List
720 Returns : DLL_NORMAL -- Record found
721 DLL_NULL_LIST -- Empty list
722 DLL_NOT_FOUND -- Record not found
723
724 @return: C{None}
725 @raise APIException: If a low level error occurred in the C{C} code.
726 @raise FunctionException: If the status return value is not
727 C{Return.NORMAL}.
728 """
729 try:
730 incrementCurrentPointer = self._lib.DLL_IncrementCurrentPointer
731 incrementCurrentPointer.argtypes = (POINTER(List),)
732 retval = incrementCurrentPointer(self._list_p)
733 except Exception, e:
734 self._log.critical("Unknown error: %s", str(e))
735 raise dll.APIException(e)
736
737 if retval != Return.NORMAL:
738 msg = "Return.%s: %s" % Return.getMessage(retval)
739 raise dll.FunctionException(msg, retval=retval)
740
742 """
743 Moves the current pointer to the prior C{Node}.
744
745 The C{C} function doc string::
746
747 DLL_Return DLL_DecrementCurrentPointer(List *list);
748
749 Arguments: list -- Pointer to type List
750 Returns : DLL_NORMAL -- Record found
751 DLL_NULL_LIST -- Empty list
752 DLL_NOT_FOUND -- Record not found
753
754 @return: C{None}
755 @raise APIException: If a low level error occurred in the C{C} code.
756 @raise FunctionException: If the status return value is not
757 C{Return.NORMAL}.
758 """
759 try:
760 decrementCurrentPointer = self._lib.DLL_DecrementCurrentPointer
761 decrementCurrentPointer.argtypes = (POINTER(List),)
762 retval = decrementCurrentPointer(self._list_p)
763 except Exception, e:
764 self._log.critical("Unknown error: %s", str(e))
765 raise dll.APIException(e)
766
767 if retval != Return.NORMAL:
768 msg = "Return.%s: %s" % Return.getMessage(retval)
769 raise dll.FunctionException(msg, retval=retval)
770
772 """
773 Store the current pointer in the control C{List} class.
774
775 The C{C} function doc string::
776
777 DLL_Return DLL_StoreCurrentPointer(List *list);
778
779 Arguments: list -- Pointer to type List
780 Returns : DLL_NORMAL -- Record found
781 DLL_NOT_FOUND -- Record not found
782
783 @return: C{None}
784 @raise APIException: If a low level error occurred in the C{C} code.
785 @raise FunctionException: If the status return value is not
786 C{Return.NORMAL}.
787 """
788 try:
789 storeCurrentPointer = self._lib.DLL_StoreCurrentPointer
790 storeCurrentPointer.argtypes = (POINTER(List),)
791 retval = storeCurrentPointer(self._list_p)
792 except Exception, e:
793 self._log.critical("Unknown error: %s", str(e))
794 raise dll.APIException(e)
795
796 if retval != Return.NORMAL:
797 msg = "Return.%s: %s" % Return.getMessage(retval)
798 raise dll.FunctionException(msg, retval=retval)
799
801 """
802 Restore the current pointer from the control C{List} class.
803
804 The C{C} function doc string::
805
806 DLL_Return DLL_restoreCurrentPointer(List *list);
807
808 Arguments: list -- Pointer to type List
809 Returns : DLL_NORMAL -- Record found
810 DLL_NOT_FOUND -- Record not found
811
812 @return: C{None}
813 @raise APIException: If a low level error occurred in the C{C} code.
814 @raise FunctionException: If the status return value is not
815 C{Return.NORMAL}.
816 """
817 try:
818 restoreCurrentPointer = self._lib.DLL_RestoreCurrentPointer
819 restoreCurrentPointer.argtypes = (POINTER(List),)
820 retval = restoreCurrentPointer(self._list_p)
821 except Exception, e:
822 self._log.critical("Unknown error: %s", str(e))
823 raise dll.APIException(e)
824
825 if retval != Return.NORMAL:
826 msg = "Return.%s: %s" % Return.getMessage(retval)
827 raise dll.FunctionException(msg, retval=retval)
828
829
830
831
832
834 """
835 Adds a record to the link list. If C{pFun} is C{None} new records will
836 be added at the end of the list. If the C{pFun} is a comparison function
837 the added record's position in the list will be determined by this
838 function.
839
840 The C{C} function doc string::
841
842 DLL_Return DLL_AddRecord(List *list, Info *info,
843 int (*pFun)(Info *, Info *));
844
845 Arguments: list -- Pointer to type List
846 info -- Pointer to record to add
847 pFun -- Pointer to search function
848 Returns : DLL_NORMAL -- Node was added successfully
849 DLL_MEM_ERROR -- Memory allocation failed
850
851 @param info: The C{Info} class instantiated object.
852 @type info: C{Info} is defined internally as C{c_void_p}
853 @keyword pFun: A C{CFUNCTYPE} object for comparing data in the user
854 C{Info} class. The default is C{None}.
855 @type pFun: C{ctypes CFUNCTYPE}
856 @return: C{None}
857 @raise APIException: If a low level error occurred in the C{C} code.
858 @raise FunctionException: If status return value is not
859 C{Return.NORMAL}.
860 """
861 try:
862 addRecord = self._lib.DLL_AddRecord
863 addRecord.argtypes = (POINTER(List), c_void_p, c_void_p,)
864 retval = addRecord(self._list_p, cast(byref(info), c_void_p), pFun)
865 except Exception, e:
866 self._log.critical("Unknown error: %s", str(e))
867 raise dll.APIException(e)
868
869 if retval != Return.NORMAL:
870 msg = "Return.%s: %s" % Return.getMessage(retval)
871 raise dll.FunctionException(msg, retval=retval)
872
874 """
875 Inserts a record relative to the current pointer and is determined by
876 the C{dir}. If C{dir} is C{InsertDir.ABOVE} the record will be
877 inserted toward the head of the list, if C{InsertDir.BELOW} the
878 record will be inserted toward the tail of the list.
879
880 The C{C} function doc string::
881
882 DLL_Return DLL_InsertRecord(List *list, Info *info,
883 DLL_InsertDir dir);
884
885 Arguments: list -- Pointer to type List
886 info -- Record to add
887 dir -- Direction to insert, can be DLL_ABOVE
888 (toward head) or DLL_BELOW (toward
889 tail)
890 Returns : DLL_NORMAL -- Node was added successfully
891 DLL_MEM_ERROR -- Memory allocation failed
892 DLL_NOT_MODIFIED -- Insert direction is invalid
893 (not DLL_ABOVE or DLL_BELOW)
894
895 @param info: The C{Info} class instantiated object.
896 @type info: C{Info} is defined internally as C{c_void_p}
897 @param dir: A value from the C{InsertDir} class.
898 @type dir: C{int}
899 @return: C{None}
900 @raise APIException: If a low level error occurred in the C{C} code.
901 @raise FunctionException: If status return value is not
902 C{Return.NORMAL}.
903 """
904 try:
905 insertRecord = self._lib.DLL_InsertRecord
906 insertRecord.argtypes = (POINTER(List), c_void_p, c_int)
907 retval = insertRecord(self._list_p, cast(byref(info), c_void_p),
908 dir)
909 except Exception, e:
910 self._log.critical("Unknown error: %s", str(e))
911 raise dll.APIException(e)
912
913 if retval != Return.NORMAL:
914 msg = "Return.%s: %s" % Return.getMessage(retval)
915 raise dll.FunctionException(msg, retval=retval)
916
918 """
919 Swaps current record up or down one position in the list. The swapped
920 record will still be current after completion. If C{dir} is
921 C{InsertDir.ABOVE} the record will be swapped toward the head of the
922 list, if C{InsertDir.BELOW} the record will be swapped toward the tail
923 of the list.
924
925 The C{C} function doc string::
926
927 DLL_Return DLL_SwapRecord(List *list, DLL_InsertDir dir);
928
929 Arguments: list -- Pointer to type List
930 dir -- Direction to swap, can be DLL_ABOVE
931 (toward head) or DLL_BELOW (toward
932 tail)
933 Returns : DLL_NORMAL -- Node was swapped successfully
934 DLL_NULL_LIST -- list->current is NULL
935 DLL_NOT_MODIFIED -- Swap direction not DLL_ABOVE or
936 DLL_BELOW
937 DLL_NOT_FOUND -- Current record is already at end of
938 list indicated by dir.
939
940 @param dir: A value from the C{InsertDir} class.
941 @type dir: C{int}
942 @return: C{None}
943 @raise APIException: If a low level error occurred in the C{C} code.
944 @raise FunctionException: If status return value is not
945 C{Return.NORMAL}.
946 """
947 try:
948 swapRecord = self._lib.DLL_SwapRecord
949 swapRecord.argtypes = (POINTER(List), c_int)
950 retval = swapRecord(self._list_p, dir)
951 except Exception, e:
952 self._log.critical("Unknown error: %s", str(e))
953 raise dll.APIException(e)
954
955 if retval != Return.NORMAL:
956 msg = "Return.%s: %s" % Return.getMessage(retval)
957 raise dll.FunctionException(msg, retval=retval)
958
960 """
961 Updates the current record. The entire record is over written.
962
963 The C{C} function doc string::
964
965 DLL_Return DLL_UpdateCurrentRecord(List *list, Info *record);
966
967 Arguments: list -- Pointer to type List
968 record -- Pointer to an Info structure in list
969 Returns : DLL_NORMAL -- Record updated
970 DLL_NULL_LIST -- Empty list
971
972 @param record: An C{Info} object with new data.
973 @type record: C{Info} is defined internally as C{c_void_p}
974 @return: C{None}
975 @raise APIException: If a low level error occurred in the C{C} code.
976 @raise FunctionException: If the status return value is not
977 C{Return.NORMAL}.
978 """
979 try:
980 updateCurrentRecord = self._lib.DLL_UpdateCurrentRecord
981 updateCurrentRecord.argtypes = (POINTER(List), c_void_p,)
982 retval = updateCurrentRecord(self._list_p, cast(byref(record),
983 c_void_p))
984 except Exception, e:
985 self._log.critical("Unknown error: %s", str(e))
986 raise dll.APIException(e)
987
988 if retval != Return.NORMAL:
989 msg = "Return.%s: %s" % Return.getMessage(retval)
990 raise dll.FunctionException(msg, retval=retval)
991
993 """
994 Delete a record from the list. This removes the C{Node} and C{Info}
995 objects.
996
997 The C{C} function doc string::
998
999 DLL_Return DLL_DeleteCurrentRecord(List *list);
1000
1001 Arguments: list -- Pointer to type List
1002 Returns : DLL_NORMAL -- Record deleted
1003 DLL_NULL_LIST -- List is empty
1004
1005 @return: C{None}
1006 @raise APIException: If a low level error occurred in the C{C} code.
1007 @raise FunctionException: If the status return value is not
1008 C{Return.NORMAL}.
1009 """
1010 try:
1011 deleteCurrentRecord = self._lib.DLL_DeleteCurrentRecord
1012 deleteCurrentRecord.argtypes = (POINTER(List),)
1013 retval = deleteCurrentRecord(self._list_p)
1014 except Exception, e:
1015 self._log.critical("Unknown error: %s", str(e))
1016 raise dll.APIException(e)
1017
1018 if retval != Return.NORMAL:
1019 msg = "Return.%s: %s" % Return.getMessage(retval)
1020 raise dll.FunctionException(msg, retval=retval)
1021
1023 """
1024 Deletes all the C{Info} and their C{Node} objects from the list then
1025 reinitializes the control C{List} for continued use.
1026
1027 The C{C} function doc string::
1028
1029 DLL_Return DLL_DeleteEntireList(List *list);
1030
1031 Arguments: list -- Pointer to type List
1032 Returns : DLL_NORMAL -- List deleted
1033 DLL_NULL_LIST -- List is empty
1034
1035 @return: C{None}
1036 @raise APIException: If a low level error occurred in the C{C} code.
1037 @raise FunctionException: If the status return value is not
1038 C{Return.NORMAL}.
1039 """
1040 try:
1041 deleteEntireList = self._lib.DLL_DeleteEntireList
1042 deleteEntireList.argtypes = (POINTER(List),)
1043 retval = deleteEntireList(self._list_p)
1044 except Exception, e:
1045 self._log.critical("Unknown error: %s", str(e))
1046 raise dll.APIException(e)
1047
1048 if retval != Return.NORMAL:
1049 msg = "Return.%s: %s" % Return.getMessage(retval)
1050 raise dll.FunctionException(msg, retval=retval)
1051
1052
1053
1054
1055
1057 """
1058 Find a C{record} in the list with search criteria passed into C{match}.
1059 If the C{pFun} is a comparison function the found record will be
1060 determined by this function. Return the found record.
1061
1062 The C{C} function doc string::
1063
1064 DLL_Return DLL_FindRecord(List *list, Info *record, Info *match,
1065 int (*pFun)(Info *, Info *));
1066
1067 Arguments: list -- Pointer to type List
1068 record -- Pointer to an Info structure in list
1069 match -- Pointer to an Info structure to match
1070 to Node in list
1071 pFun -- Pointer to search function
1072 Returns : DLL_NORMAL -- Record found
1073 DLL_NULL_LIST -- Empty list
1074 DLL_NOT_FOUND -- Record not found
1075 DLL_NULL_FUNCTION -- pFun is NULL
1076
1077 @param record: An C{Info} object that will have the retrieved data.
1078 @type record: C{Info} is defined internally as C{c_void_p}
1079 @param match: An C{Info} object with the search criteria.
1080 @type match: C{Info} is defined internally as C{c_void_p}
1081 @keyword pFun: A C{CFUNCTYPE} object for comparing data in the user
1082 C{Info} class. The default is C{None}.
1083 @type pFun: C{ctypes CFUNCTYPE}
1084 @return: The found record.
1085 @rtype: C{Info}
1086 @raise APIException: If a low level error occurred in the C{C} code.
1087 @raise FunctionException: If the status return value is not
1088 C{Return.NORMAL}.
1089 """
1090 try:
1091 findRecord = self._lib.DLL_FindRecord
1092 findRecord.argtypes = (POINTER(List), c_void_p, c_void_p, c_void_p,)
1093 retval = findRecord(self._list_p, cast(byref(record), c_void_p),
1094 cast(byref(match), c_void_p), pFun)
1095 except Exception, e:
1096 self._log.critical("Unknown error: %s", str(e))
1097 raise dll.APIException(e)
1098
1099 if retval != Return.NORMAL:
1100 msg = "Return.%s: %s" % Return.getMessage(retval)
1101 raise dll.FunctionException(msg, retval=retval)
1102
1103 return record
1104
1106 """
1107 Returns the Nth record in the list based on the setting of origin and
1108 direction values in the control C{List}. Return the found record.
1109
1110 The C{C} function doc string::
1111
1112 DLL_Return DLL_FindNthRecord(List *list, Info *record,
1113 unsigned long skip);
1114
1115 Arguments: list -- Pointer to type List
1116 record -- Record to hold return data
1117 skip -- Number of records to skip
1118 (Always a positive number)
1119 Returns : DLL_NORMAL -- Node was found successfully
1120 DLL_NULL_LIST -- list->current is NULL
1121 DLL_NOT_FOUND -- Index value is too large or wrong dir
1122 value (current record index remains
1123 unchanged)
1124
1125 @param record: An C{Info} object that will have the retrieved data.
1126 @type record: C{Info} is defined internally as C{c_void_p}
1127 @param skip: The number of records to skip over while doing the search.
1128 @type skip: C{int}
1129 @return: The found record.
1130 @rtype: C{Info}
1131 @raise APIException: If a low level error occurred in the C{C} code.
1132 @raise FunctionException: If the status return value is not
1133 C{Return.NORMAL}.
1134 """
1135 try:
1136 findNthRecord = self._lib.DLL_FindNthRecord
1137 findNthRecord.argtypes = (POINTER(List), c_void_p, c_ulong,)
1138 retval = findNthRecord(self._list_p, cast(byref(record), c_void_p),
1139 skip)
1140 except Exception, e:
1141 self._log.critical("Unknown error: %s", str(e))
1142 raise dll.APIException(e)
1143
1144 if retval != Return.NORMAL:
1145 msg = "Return.%s: %s" % Return.getMessage(retval)
1146 raise dll.FunctionException(msg, retval=retval)
1147
1148 return record
1149
1151 """
1152 Return the current record.
1153
1154 The C{C} function doc string::
1155
1156 DLL_Return DLL_GetCurrentRecord(List *list, Info *record);
1157
1158 Arguments: list -- Pointer to type List
1159 record -- Pointer to an Info structure
1160 Returns : DLL_NORMAL -- Record returned
1161 DLL_NULL_LIST -- List is empty
1162
1163 @param record: An C{Info} object that will have the retrieved data.
1164 @type record: C{Info} is defined internally as C{c_void_p}
1165 @return: The current record.
1166 @rtype: C{Info}
1167 @raise APIException: If a low level error occurred in the C{C} code.
1168 @raise FunctionException: If the status return value is not
1169 C{Return.NORMAL}.
1170 """
1171 try:
1172 getCurrentRecord = self._lib.DLL_GetCurrentRecord
1173 getCurrentRecord.argtypes = (POINTER(List), c_void_p,)
1174 retval = getCurrentRecord(self._list_p,
1175 cast(byref(record), c_void_p))
1176 except Exception, e:
1177 self._log.critical("Unknown error: %s", str(e))
1178 raise dll.APIException(e)
1179
1180 if retval != Return.NORMAL:
1181 msg = "Return.%s: %s" % Return.getMessage(retval)
1182 raise dll.FunctionException(msg, retval=retval)
1183
1184 return record
1185
1187 """
1188 Return the prior record relative to the current pointer.
1189
1190 The C{C} function doc string::
1191
1192 DLL_Return DLL_GetPriorRecord(List *list, Info *record);
1193
1194 Arguments: list -- Pointer to type List
1195 record -- Pointer to an Info structure
1196 Returns : DLL_NORMAL -- Record returned
1197 DLL_NULL_LIST -- List is empty
1198 DLL_NOT_FOUND -- Beginning of list
1199
1200 @param record: An C{Info} object that will have the retrieved data.
1201 @type record: C{Info} is defined internally as C{c_void_p}
1202 @return: The prior record.
1203 @rtype: C{Info}
1204 @raise APIException: If a low level error occurred in the C{C} code.
1205 @raise FunctionException: If the status return value is not
1206 C{Return.NORMAL}.
1207 """
1208 try:
1209 getPriorRecord = self._lib.DLL_GetPriorRecord
1210 getPriorRecord.argtypes = (POINTER(List), c_void_p,)
1211 retval = getPriorRecord(self._list_p, cast(byref(record), c_void_p))
1212 except Exception, e:
1213 self._log.critical("Unknown error: %s", str(e))
1214 raise dll.APIException(e)
1215
1216 if retval != Return.NORMAL:
1217 msg = "Return.%s: %s" % Return.getMessage(retval)
1218 raise dll.FunctionException(msg, retval=retval)
1219
1220 return record
1221
1223 """
1224 Return the next record relative to the current pointer.
1225
1226 The C{C} function doc string::
1227
1228 DLL_Return DLL_GetNextRecord(List *list, Info *record);
1229
1230 Arguments: list -- Pointer to type List
1231 record -- Pointer to an Info structure
1232 Returns : DLL_NORMAL -- Record returned
1233 DLL_NULL_LIST -- List is empty
1234 DLL_NOT_FOUND -- End of list
1235
1236 @param record: An C{Info} object that will have the retrieved data.
1237 @type record: C{Info} is defined internally as C{c_void_p}
1238 @return: The next record.
1239 @rtype: C{Info}
1240 @raise APIException: If a low level error occurred in the C{C} code.
1241 @raise FunctionException: If the status return value is not
1242 C{Return.NORMAL}.
1243 """
1244 try:
1245 getNextRecord = self._lib.DLL_GetNextRecord
1246 getNextRecord.argtypes = (POINTER(List), c_void_p,)
1247 retval = getNextRecord(self._list_p, cast(byref(record), c_void_p))
1248 except Exception, e:
1249 self._log.critical("Unknown error: %s", str(e))
1250 raise dll.APIException(e)
1251
1252 if retval != Return.NORMAL:
1253 msg = "Return.%s: %s" % Return.getMessage(retval)
1254 raise dll.FunctionException(msg, retval=retval)
1255
1256 return record
1257
1258
1259
1260
1261
1263 """
1264 Save list to disk. The file is saved in binary format because the fields
1265 in the C{Info} class are save in their entirety causing C{NULL} bytes
1266 to be padded after text. It should be trivial to pad the fields with
1267 spaces before calling this method thus eliminating any binary data
1268 in text files.
1269
1270 The C{C} function doc string::
1271
1272 DLL_Return DLL_SaveList(List *list, const char *path);
1273
1274 Arguments: list -- Pointer to type List
1275 path -- Pointer to path and filename
1276 Return : DLL_NORMAL -- File written successfully
1277 DLL_NULL_LIST -- List is empty
1278 DLL_OPEN_ERROR -- File open error
1279 DLL_WRITE_ERROR -- File write error
1280 DLL_NOT_MODIFIED -- Unmodified list no save was done
1281
1282 @param path: The full path to the data file.
1283 @type path: C{str}
1284 @return: C{None}
1285 @raise APIException: If a low level error occurred in the C{C} code.
1286 @raise FunctionException: If the status return value is not
1287 C{Return.NORMAL}.
1288 """
1289 try:
1290 saveList = self._lib.DLL_SaveList
1291 saveList.argtypes = (POINTER(List), c_char_p,)
1292 retval = saveList(self._list_p, c_char_p(path))
1293 except Exception, e:
1294 self._log.critical("Unknown error: %s", str(e))
1295 raise dll.APIException(e)
1296
1297 if retval != Return.NORMAL:
1298 msg = "Return.%s: %s" % Return.getMessage(retval)
1299 raise dll.FunctionException(msg, retval=retval)
1300
1302 """
1303 Load list from disk. When using the C{pFun} keyword argument the
1304 function passed will sort the incoming data.
1305
1306 The C{C} function doc string::
1307
1308 DLL_Return DLL_LoadList(List *list, const char *path,
1309 int (*pFun)(Info *, Info *));
1310
1311 Arguments: list -- Pointer to type List
1312 path -- Pointer to path and filename
1313 pFun -- Pointer to search function
1314 Return : DLL_NORMAL -- File written successfully
1315 DLL_MEM_ERROR -- Memory allocation failed
1316 DLL_OPEN_ERROR -- File open error
1317 DLL_READ_ERROR -- File read error
1318
1319 @param path: The full path to the data file.
1320 @type path: C{str}
1321 @keyword pFun: A C{CFUNCTYPE} object for comparing data in the user
1322 C{Info} class. The default is C{None}.
1323 @type pFun: C{ctypes CFUNCTYPE}
1324 @return: C{None}
1325 @raise APIException: If a low level error occurred in the C{C} code.
1326 @raise FunctionException: If the status return value is not
1327 C{Return.NORMAL}.
1328 """
1329 try:
1330 loadList = self._lib.DLL_LoadList
1331 loadList.argtypes = (POINTER(List), c_char_p, c_void_p,)
1332 retval = loadList(self._list_p, c_char_p(path), pFun)
1333 except Exception, e:
1334 self._log.critical("Unknown error: %s", str(e))
1335 raise dll.APIException(e)
1336
1337 if retval != Return.NORMAL:
1338 msg = "Return.%s: %s" % Return.getMessage(retval)
1339 raise dll.FunctionException(msg, retval=retval)
1340
1341
1342
1343
1344
1346 """
1347 A basic compare function. You may need to write your own.
1348
1349 @return: Function pointer.
1350 @rtype: C{ctypes POINTER}
1351 """
1352
1353
1354 cmpPrototype = CFUNCTYPE(c_int, c_char_p, c_char_p)
1355 return cmpPrototype(cmp)
1356
1358 """
1359 Utility method to check that the C{Info} object is valid.
1360
1361 @param info: An instance of an C{Info} class.
1362 @type info: C{Info}
1363 @raise APIException: If a low level error occurred in the C{C} code.
1364 """
1365 if not isinstance(info, Structure):
1366 msg = "Invalid Info type is not a subclass of ctypes Structure."
1367 raise dll.APIException(msg)
1368