[Pcsclite-cvs-commit] r6057 - in /trunk/PCSC/src: simclist.c simclist.h

rousseau at users.alioth.debian.org rousseau at users.alioth.debian.org
Fri Oct 21 09:16:55 UTC 2011


Author: rousseau
Date: Fri Oct 21 09:16:54 2011
New Revision: 6057

URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=6057
Log:
Upgrade from simclist 1.5 to 1.6

Modified:
    trunk/PCSC/src/simclist.c
    trunk/PCSC/src/simclist.h

Modified: trunk/PCSC/src/simclist.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/simclist.c?rev=6057&op=diff
==============================================================================
--- trunk/PCSC/src/simclist.c (original)
+++ trunk/PCSC/src/simclist.c Fri Oct 21 09:16:54 2011
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008,2009,2010 Mij <mij at bitchx.it>
+ * Copyright (c) 2007,2008,2009,2010,2011 Mij <mij at bitchx.it>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,25 +19,58 @@
  * SimCList library. See http://mij.oltrelinux.com/devel/simclist
  */
 
-/* SimCList implementation, version 1.5 */
+/* SimCList implementation, version 1.6 */
 
 #include <stdlib.h>
 #include <string.h>
-#include <errno.h>      /* for setting errno */
+#include <errno.h>          /* for setting errno */
 #include <sys/types.h>
-#include <sys/uio.h>    /* for READ_ERRCHECK() and write() */
-#include <fcntl.h>      /* for open() etc */
-#include <arpa/inet.h>  /* for htons() */
-#include <unistd.h>
-#include <time.h>       /* for time() for random seed */
-#include <sys/time.h>   /* for gettimeofday() */
-#include <sys/stat.h>   /* for open()'s access modes S_IRUSR etc */
+#ifndef _WIN32
+    /* not in Windows! */
+#   include <unistd.h>
+#   include <stdint.h>
+#endif
+#ifndef SIMCLIST_NO_DUMPRESTORE
+    /* includes for dump/restore */
+#   include <time.h>
+#   include <sys/uio.h>     /* for READ_ERRCHECK() and write() */
+#   include <fcntl.h>       /* for open() etc */
+#   ifndef _WIN32
+#       include <arpa/inet.h>  /* for htons() on UNIX */
+#   else
+#       include <winsock2.h>  /* for htons() on Windows */
+#   endif
+#endif
+
+/* disable asserts */
+#ifndef SIMCLIST_DEBUG
+#define NDEBUG
+#endif
+
+#include <assert.h>
+
+
+#include <sys/stat.h>       /* for open()'s access modes S_IRUSR etc */
 #include <limits.h>
-#include <stdint.h>
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+/* provide gettimeofday() missing in Windows */
+int gettimeofday(struct timeval *tp, void *tzp) {
+    DWORD t;
+
+    /* XSI says: "If tzp is not a null pointer, the behavior is unspecified" */
+    assert(tzp == NULL);
+
+    t = timeGetTime();
+    tp->tv_sec = t / 1000;
+    tp->tv_usec = t % 1000;
+    return 0;
+}
+#endif
 
 
 /* work around lack of inttypes.h support in broken Microsoft Visual Studio compilers */
-#if !defined(WIN32) || !defined(_MSC_VER)
+#if !defined(_WIN32) || !defined(_MSC_VER)
 #   include <inttypes.h>   /* (u)int*_t */
 #else
 #   include <basetsd.h>
@@ -50,10 +83,22 @@
 typedef LONG32  int32_t;
 typedef INT64   int64_t;
 #endif
- 
-
-
+
+
+/* define some commodity macros for Dump/Restore functionality */
 #ifndef SIMCLIST_NO_DUMPRESTORE
+/* write() decorated with error checking logic */
+#define WRITE_ERRCHECK(fd, msgbuf, msglen)      do {                                                    \
+                                                    if (write(fd, msgbuf, msglen) < 0) return -1;       \
+                                                } while (0);
+/* READ_ERRCHECK() decorated with error checking logic */
+#define READ_ERRCHECK(fd, msgbuf, msglen)      do {                                                     \
+                                                    if (read(fd, msgbuf, msglen) != msglen) {           \
+                                                        /*errno = EPROTO;*/                             \
+                                                        return -1;                                      \
+                                                    }                                                   \
+                                                } while (0);
+
 /* convert 64bit integers from host to network format */
 #define hton64(x)       (\
         htons(1) == 1 ?                                         \
@@ -77,13 +122,6 @@
 #ifndef EPROTO
 #define EPROTO  EIO
 #endif
-
-/* disable asserts */
-#ifndef SIMCLIST_DEBUG
-#define NDEBUG
-#endif
-
-#include <assert.h>
 
 #ifdef SIMCLIST_WITH_THREADS
 /* limit (approx) to the number of threads running
@@ -140,7 +178,8 @@
 /* header for a list dump */
 struct list_dump_header_s {
     uint16_t ver;               /* version */
-    int64_t timestamp;          /* dump timestamp */
+    int32_t timestamp_sec;      /* dump timestamp, seconds since UNIX Epoch */
+    int32_t timestamp_usec;     /* dump timestamp, microseconds since timestamp_sec */
     int32_t rndterm;            /* random value terminator -- terminates the data sequence */
 
     uint32_t totlistlen;        /* sum of every element' size, bytes */
@@ -166,11 +205,11 @@
 #endif
 
 /* do not inline, this is recursive */
-static void list_sort_quicksort(list_t *restrict l, int versus, 
+static void list_sort_quicksort(list_t *restrict l, int versus,
         unsigned int first, struct list_entry_s *fel,
         unsigned int last, struct list_entry_s *lel);
 
-static inline void list_sort_selectionsort(list_t *restrict l, int versus, 
+static inline void list_sort_selectionsort(list_t *restrict l, int versus,
         unsigned int first, struct list_entry_s *fel,
         unsigned int last, struct list_entry_s *lel);
 
@@ -178,22 +217,10 @@
 
 static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart);
 
-/* write() decorated with error checking logic */
-#define WRITE_ERRCHECK(fd, msgbuf, msglen)      do {                                                    \
-                                                    if (write(fd, msgbuf, msglen) < 0) return -1;       \
-                                                } while (0);
-/* READ_ERRCHECK() decorated with error checking logic */
-#define READ_ERRCHECK(fd, msgbuf, msglen)      do {                                                     \
-                                                    if (read(fd, msgbuf, msglen) != msglen) {           \
-                                                        /*errno = EPROTO;*/                             \
-                                                        return -1;                                      \
-                                                    }                                                   \
-                                                } while (0);
-
 /*
  * Random Number Generator
- * 
- * The user is expected to seed the RNG (ie call srand()) if 
+ *
+ * The user is expected to seed the RNG (ie call srand()) if
  * SIMCLIST_SYSTEM_RNG is defined.
  *
  * Otherwise, a self-contained RNG based on LCG is used; see
@@ -216,12 +243,12 @@
 static unsigned random_seed = 0;
 
 /* use local RNG */
-static inline void seed_random() {
+static inline void seed_random(void) {
     if (random_seed == 0)
         random_seed = (unsigned)getpid() ^ (unsigned)time(NULL);
 }
 
-static inline long get_random() {
+static inline long get_random(void) {
     random_seed = (1664525 * random_seed + 1013904223);
     return random_seed;
 }
@@ -297,7 +324,7 @@
     l->attrs.unserializer = NULL;
 
     assert(list_attrOk(l));
-    
+
     return 0;
 }
 
@@ -308,7 +335,7 @@
     l->attrs.comparator = comparator_fun;
 
     assert(list_attrOk(l));
-    
+
     return 0;
 }
 
@@ -392,7 +419,7 @@
 
     if (l->attrs.comparator == NULL || l->numels == 0)
         return NULL;
-    
+
     curminmax = l->head_sentinel->next->data;
     for (s = l->head_sentinel->next->next; s != l->tail_sentinel; s = s->next) {
         if (l->attrs.comparator(curminmax, s->data) * versus > 0)
@@ -411,11 +438,7 @@
     /* accept 1 slot overflow for fetching head and tail sentinels */
     if (posstart < -1 || posstart > (int)l->numels) return NULL;
 
-
-    if (0 == l->numels)
-        x = 0;
-    else
-        x = (float)(posstart+1) / l->numels;
+    x = (float)(posstart+1) / l->numels;
     if (x <= 0.25) {
         /* first quarter: get to posstart from head */
         for (i = -1, ptr = l->head_sentinel; i < posstart; ptr = ptr->next, i++);
@@ -436,7 +459,7 @@
 void *list_extract_at(list_t *restrict l, unsigned int pos) {
     struct list_entry_s *tmp;
     void *data;
-    
+
     if (l->iter_active || pos >= l->numels) return NULL;
 
     tmp = list_findpos(l, pos);
@@ -445,7 +468,7 @@
     tmp->data = NULL;   /* save data from list_drop_elem() free() */
     list_drop_elem(l, tmp, pos);
     l->numels--;
-    
+
     assert(list_repOk(l));
 
     return data;
@@ -453,9 +476,9 @@
 
 int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) {
     struct list_entry_s *lent, *succ, *prec;
-    
+
     if (l->iter_active || pos > l->numels) return -1;
-    
+
     /* this code optimizes malloc() with a free-list */
     if (l->spareelsnum > 0) {
         lent = l->spareels[l->spareelsnum-1];
@@ -478,7 +501,7 @@
     /* actually append element */
     prec = list_findpos(l, pos-1);
     succ = prec->next;
-    
+
     prec->next = lent;
     lent->prev = prec;
     lent->next = succ;
@@ -536,16 +559,17 @@
 
 int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) {
     struct list_entry_s *lastvalid, *tmp, *tmp2;
-    unsigned int i;
+    unsigned int numdel, midposafter, i;
     int movedx;
-    unsigned int numdel, midposafter;
 
     if (l->iter_active || posend < posstart || posend >= l->numels) return -1;
+
+    numdel = posend - posstart + 1;
+    if (numdel == l->numels) return list_clear(l);
 
     tmp = list_findpos(l, posstart);    /* first el to be deleted */
     lastvalid = tmp->prev;              /* last valid element */
 
-    numdel = posend - posstart + 1;
     midposafter = (l->numels-1-numdel)/2;
 
     midposafter = midposafter < posstart ? midposafter : midposafter+numdel;
@@ -593,14 +617,18 @@
 
     assert(list_repOk(l));
 
-    return 0;
+    return numdel;
 }
 
 int list_clear(list_t *restrict l) {
     struct list_entry_s *s;
+    unsigned int numels;
+
+    /* will be returned */
+    numels = l->numels;
 
     if (l->iter_active) return -1;
-    
+
     if (l->attrs.copy_data) {        /* also free user data */
         /* spare a loop conditional with two loops: spareing elems and freeing elems */
         for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
@@ -635,7 +663,7 @@
 
     assert(list_repOk(l));
 
-    return 0;
+    return numels;
 }
 
 unsigned int list_size(const list_t *restrict l) {
@@ -649,7 +677,7 @@
 int list_locate(const list_t *restrict l, const void *data) {
     struct list_entry_s *el;
     int pos = 0;
-    
+
     if (l->attrs.comparator != NULL) {
         /* use comparator */
         for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) {
@@ -719,7 +747,7 @@
     }
     el->next = dest->tail_sentinel;
     dest->tail_sentinel->prev = el;
-    
+
     /* fix mid pointer */
     err = l2->numels - l1->numels;
     if ((err+1)/2 > 0) {        /* correct pos RIGHT (err-1)/2 moves */
@@ -729,7 +757,7 @@
         err = -err/2;
         for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev;
     }
- 
+
     assert(!(list_repOk(l1) && list_repOk(l2)) || list_repOk(dest));
 
     return 0;
@@ -763,7 +791,7 @@
 }
 #endif
 
-static inline void list_sort_selectionsort(list_t *restrict l, int versus, 
+static inline void list_sort_selectionsort(list_t *restrict l, int versus,
         unsigned int first, struct list_entry_s *fel,
         unsigned int last, struct list_entry_s *lel) {
     struct list_entry_s *cursor, *toswap, *firstunsorted;
@@ -771,7 +799,7 @@
 
     if (last <= first) /* <= 1-element lists are always sorted */
         return;
-    
+
     for (firstunsorted = fel; firstunsorted != lel; firstunsorted = firstunsorted->next) {
         /* find min or max in the remainder of the list */
         for (toswap = firstunsorted, cursor = firstunsorted->next; cursor != lel->next; cursor = cursor->next)
@@ -784,7 +812,7 @@
     }
 }
 
-static void list_sort_quicksort(list_t *restrict l, int versus, 
+static void list_sort_quicksort(list_t *restrict l, int versus,
         unsigned int first, struct list_entry_s *fel,
         unsigned int last, struct list_entry_s *lel) {
     unsigned int pivotid;
@@ -800,12 +828,12 @@
 
     if (last <= first)      /* <= 1-element lists are always sorted */
         return;
-    
+
     if (last - first+1 <= SIMCLIST_MINQUICKSORTELS) {
         list_sort_selectionsort(l, versus, first, fel, last, lel);
         return;
     }
-    
+
     /* base of iteration: one element list */
     if (! (last > first)) return;
 
@@ -942,7 +970,7 @@
 int list_hash(const list_t *restrict l, list_hash_t *restrict hash) {
     struct list_entry_s *x;
     list_hash_t tmphash;
-    
+
     assert(hash != NULL);
 
     tmphash = l->numels * 2 + 100;
@@ -966,7 +994,7 @@
         /* hash each element with the user-given function */
         for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
             tmphash += tmphash ^ l->attrs.hasher(x->data);
-            tmphash +=* hash % l->numels;
+            tmphash += tmphash % l->numels;
         }
     }
 
@@ -990,9 +1018,11 @@
         return -1;
     }
 
-    /* timestamp */
-    READ_ERRCHECK(fd, & info->timestamp, sizeof(info->timestamp));
-    info->timestamp = hton64(info->timestamp);
+    /* timestamp.tv_sec and timestamp.tv_usec */
+    READ_ERRCHECK(fd, & info->timestamp.tv_sec, sizeof(info->timestamp.tv_sec));
+    info->timestamp.tv_sec = ntohl(info->timestamp.tv_sec);
+    READ_ERRCHECK(fd, & info->timestamp.tv_usec, sizeof(info->timestamp.tv_usec));
+    info->timestamp.tv_usec = ntohl(info->timestamp.tv_usec);
 
     /* list terminator (to check thereafter) */
     READ_ERRCHECK(fd, & terminator_head, sizeof(terminator_head));
@@ -1065,13 +1095,13 @@
     /****       DUMP FORMAT      ****
 
     [ ver   timestamp   |  totlen   numels  elemlen     hash    |   DATA ]
-    
+
     where DATA can be:
     @ for constant-size list (element size is constant; elemlen > 0)
     [ elem    elem    ...    elem ]
     @ for other lists (element size dictated by element_meter each time; elemlen <= 0)
     [ size elem     size elem       ...     size elem ]
-    
+
     all integers are encoded in NETWORK BYTE FORMAT
     *****/
 
@@ -1082,8 +1112,8 @@
 
     /* timestamp */
     gettimeofday(&timeofday, NULL);
-    header.timestamp = (int64_t)timeofday.tv_sec * 1000000 + (int64_t)timeofday.tv_usec;
-    header.timestamp = hton64(header.timestamp);
+    header.timestamp_sec = htonl(timeofday.tv_sec);
+    header.timestamp_usec = htonl(timeofday.tv_usec);
 
     header.rndterm = htonl((int32_t)get_random());
 
@@ -1113,7 +1143,7 @@
     /* write CONTENT */
     if (l->numels > 0) {
         /* SPECULATE that the list has constant element size */
-        
+
         if (l->attrs.serializer != NULL) {  /* user user-specified serializer */
             /* get preliminary length of serialized element in header.elemlen */
             ser_buf = l->attrs.serializer(l->head_sentinel->next->data, & header.elemlen);
@@ -1180,13 +1210,14 @@
     lseek(fd, 0, SEEK_SET);
 
     WRITE_ERRCHECK(fd, & header.ver, sizeof(header.ver));                        /* version */
-    WRITE_ERRCHECK(fd, & header.timestamp, sizeof(header.timestamp));            /* timestamp */
+    WRITE_ERRCHECK(fd, & header.timestamp_sec, sizeof(header.timestamp_sec));    /* timestamp seconds */
+    WRITE_ERRCHECK(fd, & header.timestamp_usec, sizeof(header.timestamp_usec));  /* timestamp microseconds */
     WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm));                /* random terminator */
 
     WRITE_ERRCHECK(fd, & header.totlistlen, sizeof(header.totlistlen));          /* total length of elements */
     WRITE_ERRCHECK(fd, & header.numels, sizeof(header.numels));                  /* number of elements */
     WRITE_ERRCHECK(fd, & header.elemlen, sizeof(header.elemlen));                /* size of each element, or 0 for independent */
-    WRITE_ERRCHECK(fd, & header.listhash, sizeof(header.listhash));             /* list hash, or 0 for "ignore" */
+    WRITE_ERRCHECK(fd, & header.listhash, sizeof(header.listhash));              /* list hash, or 0 for "ignore" */
 
 
     /* possibly store total written length in "len" */
@@ -1206,7 +1237,7 @@
     memset(& header, 0, sizeof(header));
 
     /* read header */
-    
+
     /* version */
     READ_ERRCHECK(fd, &header.ver, sizeof(header.ver));
     header.ver = ntohs(header.ver);
@@ -1216,7 +1247,10 @@
     }
 
     /* timestamp */
-    READ_ERRCHECK(fd, & header.timestamp, sizeof(header.timestamp));
+    READ_ERRCHECK(fd, & header.timestamp_sec, sizeof(header.timestamp_sec));
+    header.timestamp_sec = ntohl(header.timestamp_sec);
+    READ_ERRCHECK(fd, & header.timestamp_usec, sizeof(header.timestamp_usec));
+    header.timestamp_usec = ntohl(header.timestamp_usec);
 
     /* list terminator */
     READ_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm));
@@ -1242,7 +1276,7 @@
 
     /* read content */
     totreadlen = totmemorylen = 0;
-    if (header.elemlen > 0) {   
+    if (header.elemlen > 0) {
         /* elements have constant size = header.elemlen */
         if (l->attrs.unserializer != NULL) {
             /* use unserializer */
@@ -1319,29 +1353,34 @@
 }
 
 int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) {
-    int fd;
-    size_t sizetoret;
-
-    fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+    int fd, oflag, mode;
+
+#ifndef _WIN32
+    oflag = O_RDWR | O_CREAT | O_TRUNC;
+    mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+#else
+    oflag = _O_RDWR | _O_CREAT | _O_TRUNC;
+    mode = _S_IRUSR | _S_IWUSR | _S_IRGRP | _S_IROTH;
+#endif
+    fd = open(filename, oflag, mode);
     if (fd < 0) return -1;
 
-    sizetoret = list_dump_filedescriptor(l, fd, len);
+    list_dump_filedescriptor(l, fd, len);
     close(fd);
 
-    return sizetoret;
+    return 0;
 }
 
 int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) {
     int fd;
-    size_t totdata;
 
     fd = open(filename, O_RDONLY, 0);
     if (fd < 0) return -1;
 
-    totdata = list_restore_filedescriptor(l, fd, len);
+    list_restore_filedescriptor(l, fd, len);
     close(fd);
 
-    return totdata;
+    return 0;
 }
 #endif /* ifndef SIMCLIST_NO_DUMPRESTORE */
 
@@ -1357,7 +1396,7 @@
     } else {                /* now even */
         if (pos < l->numels/2) l->mid = l->mid->next;
     }
-    
+
     tmp->prev->next = tmp->next;
     tmp->next->prev = tmp->prev;
 
@@ -1375,7 +1414,7 @@
 }
 
 /* ready-made comparators and meters */
-#define SIMCLIST_NUMBER_COMPARATOR(type)     int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); } 
+#define SIMCLIST_NUMBER_COMPARATOR(type)     int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); }
 
 SIMCLIST_NUMBER_COMPARATOR(int8_t)
 SIMCLIST_NUMBER_COMPARATOR(int16_t)
@@ -1456,7 +1495,7 @@
             /* spare elements checks */
             l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS
          );
-    
+
     if (!ok) return 0;
 
     if (l->numels >= 1) {

Modified: trunk/PCSC/src/simclist.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/simclist.h?rev=6057&op=diff
==============================================================================
--- trunk/PCSC/src/simclist.h (original)
+++ trunk/PCSC/src/simclist.h Fri Oct 21 09:16:54 2011
@@ -31,6 +31,15 @@
 #include <errno.h>
 #include <sys/types.h>
 
+#ifndef SIMCLIST_NO_DUMPRESTORE
+#   ifndef _WIN32
+#       include <sys/time.h>    /* list_dump_info_t's struct timeval */
+#   else
+#       include <time.h>
+#   endif
+#endif
+
+
 /* Be friend of both C90 and C99 compilers */
 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
     /* "inline" and "restrict" are keywords */
@@ -49,13 +58,13 @@
 
 #ifndef SIMCLIST_NO_DUMPRESTORE
 typedef struct {
-    uint16_t version;       /* dump version */
-    int64_t timestamp;      /* when the list has been dumped, microseconds from UNIX epoch */
+    uint16_t version;           /* dump version */
+    struct timeval timestamp;   /* when the list has been dumped, seconds since UNIX epoch */
     uint32_t list_size;
     uint32_t list_numels;
-    list_hash_t list_hash;       /* hash of the list when dumped, or 0 if invalid */
+    list_hash_t list_hash;      /* hash of the list when dumped, or 0 if invalid */
     uint32_t dumpsize;
-    int consistent;         /* 1 if the dump is verified complete/consistent; 0 otherwise */
+    int consistent;             /* 1 if the dump is verified complete/consistent; 0 otherwise */
 } list_dump_info_t;
 #endif
 
@@ -458,7 +467,7 @@
  * @param l     list to operate
  * @param posstart  [0,size-1] position index of the first element to be deleted
  * @param posend    [posstart,size-1] position of the last element to be deleted
- * @return      the number of elements successfully removed
+ * @return      the number of elements successfully removed on success, <0 on error
  */
 int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
 
@@ -471,7 +480,7 @@
  * @see list_size()
  *
  * @param l     list to operate
- * @return      the number of elements in the list before cleaning
+ * @return      the number of elements removed on success, <0 on error
  */
 int list_clear(list_t *restrict l);
 
@@ -578,7 +587,7 @@
  *
  * @param l     list to operate
  * @param versus positive: order small to big; negative: order big to small
- * @return      0: sorting went OK      non-0: errors happened
+ * @return      0 iff sorting was successful
  *
  * @see list_attributes_comparator()
  */




More information about the Pcsclite-cvs-commit mailing list