Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / generic_container / container_list.c
1 /*
2  * Copyright 2008 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include "native_client/src/trusted/generic_container/container_list.h"
8
9 #include "native_client/src/include/portability.h"
10
11 static struct NaClContainerVtbl const  kNaClContainerListVtbl = {
12   NaClContainerListInsert,
13   NaClContainerListFind,
14   NaClContainerListDtor,
15   sizeof(struct NaClContainerListIter),
16   NaClContainerListIterCtor,
17 };
18
19
20 /*
21  * functor_obj is the comparison functor, and is the first argument to
22  * cmp_fn as the "self" (or more commonly "this") argument.  arguably
23  * we should create an explicit object with a vtable containing the
24  * single comparison function pointer, but this is so simple that that
25  * seems overkill.
26  */
27 int NaClContainerListCtor(struct NaClContainerList  *self,
28                           struct NaClCmpFunctor     *cmp_functor) {
29   self->cmp_functor = cmp_functor;
30   self->head = 0;
31
32   self->base.vtbl = &kNaClContainerListVtbl;
33   return 1;
34 }
35
36
37 int NaClContainerListIterAtEnd(struct NaClContainerIter *vself) {
38   struct NaClContainerListIter  *self = (struct NaClContainerListIter *) vself;
39
40   return *self->cur == 0;
41 }
42
43
44 void *NaClContainerListIterStar(struct NaClContainerIter *vself) {
45   struct NaClContainerListIter  *self = (struct NaClContainerListIter *) vself;
46
47   return (*self->cur)->datum;
48 }
49
50
51 void NaClContainerListIterIncr(struct NaClContainerIter  *vself) {
52   struct NaClContainerListIter  *self = (struct NaClContainerListIter *) vself;
53
54   self->cur = &(*self->cur)->next;
55 }
56
57
58 void NaClContainerListIterErase(struct NaClContainerIter  *vself) {
59   struct NaClContainerListIter  *self = (struct NaClContainerListIter *) vself;
60   struct NaClItemList           *doomed = *self->cur;
61   struct NaClItemList           *next = (*self->cur)->next;
62
63   *self->cur = next;
64   free(doomed->datum);
65   free(doomed);
66 }
67
68
69 void *NaClContainerListIterExtract(struct NaClContainerIter  *vself) {
70   struct NaClContainerListIter  *self = (struct NaClContainerListIter *) vself;
71   struct NaClItemList           *doomed = *self->cur;
72   struct NaClItemList           *next = (*self->cur)->next;
73   void                          *datum;
74
75   *self->cur = next;
76   datum = doomed->datum;
77   free(doomed);
78   return datum;
79 }
80
81 static struct NaClContainerIterVtbl const   kNaClContainerListIterVtbl = {
82   NaClContainerListIterAtEnd,
83   NaClContainerListIterStar,
84   NaClContainerListIterIncr,
85   NaClContainerListIterErase,
86   NaClContainerListIterExtract,
87 };
88
89
90 int NaClContainerListInsert(struct NaClContainer  *vself,
91                             void                  *obj) {
92   struct NaClContainerList    *self = (struct NaClContainerList *) vself;
93   struct NaClItemList         *new_entry = malloc(sizeof *new_entry);
94   struct NaClItemList         **ipp;
95   struct NaClItemList         *ip;
96
97   if (!new_entry)
98     return 0;
99
100   new_entry->datum = obj;
101
102   for (ipp = &self->head; 0 != (ip = *ipp); ipp = &ip->next) {
103     if ((*self->cmp_functor->vtbl->OrderCmp)(self->cmp_functor,
104                                              obj, ip->datum) >= 0) {
105       break;
106     }
107   }
108
109   new_entry->next = ip;
110   *ipp = new_entry;
111   return 1;
112 }
113
114
115 struct NaClContainerIter  *NaClContainerListFind(
116     struct NaClContainer      *vself,
117     void                      *key,
118     struct NaClContainerIter  *vout) {
119   struct NaClContainerList        *self = (struct NaClContainerList *) vself;
120   struct NaClItemList             **ipp;
121   struct NaClItemList             *ip;
122   struct NaClContainerListIter    *out = (struct NaClContainerListIter *) vout;
123
124   for (ipp = &self->head; (ip = *ipp) != 0; ipp = &ip->next) {
125     if ((*self->cmp_functor->vtbl->OrderCmp)(self->cmp_functor,
126                                              key, ip->datum) == 0) {
127       break;
128     }
129   }
130   out->cur = ipp;
131
132   vout->vtbl = &kNaClContainerListIterVtbl;
133   return vout;
134 }
135
136
137 void NaClContainerListDtor(struct NaClContainer  *vself) {
138   struct NaClContainerList    *self = (struct NaClContainerList *) vself;
139   struct NaClItemList         *cur, *next;
140
141   for (cur = self->head; cur; cur = next) {
142     next = cur->next;
143     free(cur->datum);
144     free(cur);
145   }
146 }
147
148
149 int NaClContainerListIterCtor(struct NaClContainer      *vself,
150                               struct NaClContainerIter  *viter) {
151   struct NaClContainerList      *self = (struct NaClContainerList *) vself;
152   struct NaClContainerListIter  *iter = (struct NaClContainerListIter *) viter;
153
154   iter->cur = &self->head;
155
156   viter->vtbl = &kNaClContainerListIterVtbl;
157   return 1;
158 }