Simple data structures / objects in plain C Snapshot
|
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