Simple data structures / objects in plain C Snapshot
dlistunr.c
Go to the documentation of this file.
00001 #include <cutils/dlistunr.h>
00002 
00003 M_INLINE DLISTUNR_entry *DLISTUNR_new_list_entry( size_t datasize)
00004 {
00005         DLISTUNR_entry *entry;
00006 
00007         entry = malloc(  sizeof(DLISTUNR_entry) + datasize );
00008         if (!entry) {
00009                 return 0;
00010         }
00011         entry->elmcount = 0;
00012         return entry;
00013 }
00014 
00015 
00016 M_INLINE void *DLISTUNR_insert_entry(DLISTUNR_entry *entry, size_t pos, size_t elmmaxcount, size_t elmsize)
00017 {
00018         if (!entry) {
00019                 return 0;
00020         }
00021 
00022         if (entry->elmcount >= elmmaxcount || entry->elmcount == (size_t) -1) {
00023                 return 0;
00024         }
00025 
00026         pos ++;
00027 
00028         if (pos < entry->elmcount) {    
00029                 memmove(entry->buffer + (pos + 1) * elmsize,
00030                             entry->buffer +  pos * elmsize, 
00031                                 (entry->elmcount - pos) * elmsize);
00032                 
00033         } 
00034         
00035         entry->elmcount ++ ;
00036         return entry->buffer + (pos * elmsize);
00037 }
00038 
00039 M_INLINE void *DLISTUNR_insert_newnode(DLISTUNR *list,
00040                                                                                                   DLISTUNR_position insert_pos)
00041 {
00042         DLISTUNR_entry *newnode;
00043 
00044         newnode = DLISTUNR_new_list_entry( list->elmsize * list->elmmaxcount);
00045         if (!newnode) {
00046                 return 0;
00047         }
00048         
00049         DRING_insert_after( (DRING *) insert_pos.entry, (DRING *) newnode );
00050 
00051         newnode->elmcount = 1;
00052         return newnode->buffer;
00053 }
00054 
00055 
00056 
00057 int DLISTUNR_insert_after(DLISTUNR *list, DLISTUNR_position pos, void *data, size_t size)
00058 {
00059         size_t elmsize = list->elmsize;
00060         size_t elmmaxcount = list->elmmaxcount;
00061         DLISTUNR_position insert_pos = pos;
00062         DLISTUNR_entry *next;
00063         void *newnodepos;
00064 
00065         if (size != list->elmsize) {
00066                 return -1;
00067         }
00068 
00069         if (!insert_pos.entry) {
00070                 insert_pos.entry = (DLISTUNR_entry *) list->root.ring.prev;
00071         }
00072 
00073         if ((newnodepos = DLISTUNR_insert_entry(
00074                                                                 insert_pos.entry, 
00075                                                                 insert_pos.index, 
00076                                                                 elmmaxcount, 
00077                                                                 elmsize)) == 0) {
00078                 
00079                 next = (DLISTUNR_entry *) insert_pos.entry->ring.next;
00080                  
00081                 if ((newnodepos = DLISTUNR_insert_entry(next, (size_t) -1, elmmaxcount, elmsize)) == 0){
00082 
00083                         if ((newnodepos = DLISTUNR_insert_newnode(list, insert_pos)) == 0) {
00084                                 return -1;
00085                         }
00086                         list->entrycount ++;
00087                         next = (DLISTUNR_entry *) insert_pos.entry->ring.next;
00088 
00089                 } 
00090                         
00091                 if (insert_pos.entry->elmcount != (size_t) -1 && 
00092                         insert_pos.index < (insert_pos.entry->elmcount - 1) ) {
00093 
00094                         /* bad bad */
00095                         insert_pos.index ++;
00096 
00097                         /* move elements from prev node to new node */
00098                         memcpy(next->buffer, 
00099                                    insert_pos.entry->buffer + (list->elmmaxcount - 1) * elmsize,
00100                                    elmsize);
00101 
00102                         /* move elements in current node */             
00103                         memmove(insert_pos.entry->buffer + (insert_pos.index + 1) * elmsize,
00104                                         insert_pos.entry->buffer + insert_pos.index  * elmsize,
00105                                         (insert_pos.entry->elmcount - insert_pos.index - 1) * elmsize);
00106                 
00107                         /* copy new node into insert_pos.index */
00108                         newnodepos = insert_pos.entry->buffer + insert_pos.index  * elmsize;
00109                 }
00110         } 
00111         
00112         memcpy(newnodepos, data, elmsize);
00113         list->elmcount ++;
00114         return 0;
00115 }
00116 
00117 
00118 int DLISTUNR_unlink(DLISTUNR *list, DLISTUNR_position pos)
00119 {
00120         DLISTUNR_entry *entry;
00121         size_t elmsize = list->elmsize;
00122 
00123         if (DLISTUNR_check_position(pos)) {
00124                 return -1;
00125         }
00126         entry = pos.entry;
00127 
00128         if (entry->elmcount == (size_t) -1) {
00129                 return -1;
00130         }
00131 
00132         if (entry->elmcount != 1) {
00133                 if (pos.index < (entry->elmcount-1)) {
00134                         memmove(entry->buffer + pos.index * elmsize,
00135                                         entry->buffer + (pos.index + 1) * elmsize, 
00136                                         (entry->elmcount - pos.index - 1) * elmsize );
00137                 }
00138                 entry->elmcount --;
00139         } else {
00140                 DRING_unlink((DRING *)pos.entry);
00141                 free( pos.entry);
00142                 list->entrycount --;
00143         }
00144 
00145         list->elmcount --;
00146         return 0;
00147 }
00148 
00149