libisdn
asn1_list.h
Go to the documentation of this file.
00001 
00005 #ifndef __ASN1_LIST_H__
00006 #define __ASN1_LIST_H__
00007 
00008 static inline struct asn1_list *asn1_get_last(const struct asn1_list *elem)
00009 {
00010         if (!elem || !elem->head) return NULL;
00011         return (elem->head->prev != elem->head) ? elem->head->prev : NULL;
00012 }
00013 
00014 static inline struct asn1_list *asn1_get_first(const struct asn1_list *elem)
00015 {
00016         if (!elem || !elem->head) return NULL;
00017         return (elem->head->next != elem->head) ? elem->head->next : NULL;
00018 }
00019 
00020 static inline struct asn1_list *asn1_get_next(const struct asn1_list *elem)
00021 {
00022         return (elem->next != elem->head) ? elem->next : NULL;
00023 }
00024 
00025 static inline struct asn1_list *asn1_get_prev(const struct asn1_list *elem)
00026 {
00027         return (elem->prev != elem->head) ? elem->prev : NULL;
00028 }
00029 
00030 static inline int asn1_append(struct asn1_list *elem, struct asn1_list *e)
00031 {
00032         struct asn1_list *p = NULL;
00033 
00034         if (!elem || !elem->head || !e)
00035                 return -1;
00036 
00037         p = elem->head->prev;
00038         p->next = e;
00039         e->prev = p;
00040         e->next = p->head;
00041         p->head->prev = e;
00042         e->head = p->head;
00043         return 0;
00044 }
00045 
00046 static inline int asn1_prepend(struct asn1_list *elem, struct asn1_list *e)
00047 {
00048         struct asn1_list *p = NULL;
00049 
00050         if (!elem || !elem->head || !e)
00051                 return -1;
00052 
00053         p = elem->head->next;
00054         p->prev = e;
00055         e->next = p;
00056         e->prev = p->head;
00057         p->head->next = e;
00058         e->head = p->head;
00059         return 0;
00060 }
00061 
00062 static inline int asn1_insert_after(struct asn1_list *elem, struct asn1_list *e)
00063 {
00064         if (!elem || !e) return -1;
00065 
00066         e->next = elem->next;
00067         e->prev = elem;
00068         elem->next->prev = e;
00069         elem->next = e;
00070         e->head = elem->head;
00071         return 0;
00072 }
00073 
00074 static inline int asn1_insert_before(struct asn1_list *elem, struct asn1_list *e)
00075 {
00076         if (!elem || !e) return -1;
00077 
00078         e->prev = elem->prev;
00079         e->next = elem;
00080         elem->prev->next = e;
00081         elem->prev = e;
00082         e->head = elem->head;
00083         return 0;
00084 }
00085 
00086 static inline int asn1_is_first(const struct asn1_list *elem)
00087 {
00088         return (elem->prev == elem->head);
00089 }
00090 
00091 static inline int asn1_is_last(const struct asn1_list *elem)
00092 {
00093         return (elem->next == elem->head);
00094 }
00095 
00096 static inline int asn1_is_head(const struct asn1_list *elem)
00097 {
00098         return (!elem->head || elem->head == elem);
00099 }
00100 
00101 static inline int asn1_count(const struct asn1_list *head)
00102 {
00103         int count = 0;
00104 
00105         for (struct asn1_list *elem = (struct asn1_list *)head; elem->next != head; elem = elem->next) count++;
00106         return count;
00107 }
00108 
00109 static inline struct asn1_list *asn1_get_head(const struct asn1_list *elem)
00110 {
00111         return (struct asn1_list *)elem->head;
00112 }
00113 
00114 static inline int asn1_remove(const struct asn1_list *elem)
00115 {
00116         if (elem->head == elem)
00117                 return -1;
00118         if (elem->prev)
00119                 elem->prev->next = elem->next;
00120         if (elem->next)
00121                 elem->next->prev = elem->prev;
00122         return 0;
00123 }
00124 
00125 #define ASN1_INIT_HEAD(x)       do { \
00126                 struct asn1_list *__p = (x);    \
00127                 __p->head = (x);                \
00128                 __p->prev = (x);                \
00129                 __p->next = (x);                \
00130         } while(0);
00131 
00132 #define ASN1_INIT_LIST(x)       do { \
00133                 struct asn1_list *__p = (x);    \
00134                 __p->head = NULL;               \
00135                 __p->prev = NULL;               \
00136                 __p->next = NULL;               \
00137         } while(0);
00138 
00139 
00140 static inline struct asn1_list *asn1_get_children(const struct asn1_complex *elem)
00141 {
00142         return (struct asn1_list *)&elem->children;
00143 }
00144 
00145 static inline struct asn1_list *asn1_get_first_child(const struct asn1_complex *elem)
00146 {
00147         return asn1_get_first(&elem->children);
00148 }
00149 
00150 static inline struct asn1_list *asn1_get_last_child(const struct asn1_complex *elem)
00151 {
00152         return asn1_get_last(&elem->children);
00153 }
00154 
00155 static inline int asn1_has_children(const struct asn1_complex *elem)
00156 {
00157         return !!(asn1_get_next(&elem->children));
00158 }
00159 
00160 static inline struct asn1_list *asn1_get_parent(const struct asn1_list *elem)
00161 {
00162         struct asn1_complex *p = (struct asn1_complex *)container_of(elem->head, struct asn1_complex, children);
00163         return (struct asn1_list *)&p->siblings;
00164 }
00165 
00166 /*****************************************************************************************
00167  * High-level list functions (object level)
00168  *****************************************************************************************/
00169 
00174 #define ASN1_OBJECT(x)  \
00175         ((struct asn1_object *)(x))
00176 
00182 static inline struct asn1_object *asn1_obj_get_first_sibling(const struct asn1_object *obj)
00183 {
00184         struct asn1_list *elem = NULL;
00185         if ((elem = asn1_get_first(&obj->siblings)) == NULL)
00186                 return NULL;
00187         return container_of(elem, struct asn1_object, siblings);
00188 }
00189 
00195 static inline struct asn1_object *asn1_obj_get_last_sibling(const struct asn1_object *obj)
00196 {
00197         struct asn1_list *elem = NULL;
00198         if ((elem = asn1_get_last(&obj->siblings)) == NULL)
00199                 return NULL;
00200         return container_of(elem, struct asn1_object, siblings);
00201 }
00202 
00208 static inline struct asn1_object *asn1_obj_get_first_child(const struct asn1_object *obj)
00209 {
00210         struct asn1_complex *complex = NULL;
00211         struct asn1_list *elem = NULL;
00212         if (!obj->hdr.asn_complex)
00213                 return NULL;
00214         complex = (struct asn1_complex *)obj;
00215         if ((elem = asn1_get_first(&complex->children)) == NULL)
00216                 return NULL;
00217         return container_of(elem, struct asn1_object, siblings);
00218 }
00219 
00225 static inline struct asn1_object *asn1_obj_get_last_child(const struct asn1_object *obj)
00226 {
00227         struct asn1_complex *complex = NULL;
00228         struct asn1_list *elem = NULL;
00229         if (!obj->hdr.asn_complex)
00230                 return NULL;
00231         complex = (struct asn1_complex *)obj;
00232         if ((elem = asn1_get_last(&complex->children)) == NULL)
00233                 return NULL;
00234         return container_of(elem, struct asn1_object, siblings);
00235 }
00236 
00242 static inline struct asn1_object *asn1_obj_get_next(const struct asn1_object *obj)
00243 {
00244         struct asn1_list *elem = NULL;
00245         if ((elem = asn1_get_next(&obj->siblings)) == NULL)
00246                 return NULL;
00247         return container_of(elem, struct asn1_object, siblings);
00248 }
00249 
00255 static inline struct asn1_object *asn1_obj_get_prev(const struct asn1_object *obj)
00256 {
00257         struct asn1_list *elem = NULL;
00258         if ((elem = asn1_get_prev(&obj->siblings)) == NULL)
00259                 return NULL;
00260         return container_of(elem, struct asn1_object, siblings);
00261 }
00262 
00268 static inline struct asn1_object *asn1_obj_get_parent(const struct asn1_object *obj)
00269 {
00270         struct asn1_complex *parent = NULL;
00271         if (obj->siblings.head == NULL)
00272                 return NULL;
00273         parent = container_of(obj->siblings.head, struct asn1_complex, children);
00274         if (!parent->hdr.asn_complex)
00275                 return NULL;
00276         return (struct asn1_object *)parent;
00277 }
00278 
00279 #endif /* __ASN1_LIST_H__  */