10cf9001e404ceaa149612c84c504ab2bc53b0bd
[oweals/gnunet.git] / src / psycutil / psyc_env.c
1 /*
2  * This file is part of GNUnet.
3  * Copyright (C) 2013 GNUnet e.V.
4  *
5  * GNUnet is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Affero General Public License as published
7  * by the Free Software Foundation, either version 3 of the License,
8  * or (at your option) any later version.
9  *
10  * GNUnet is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /**
20  * @author Gabor X Toth
21  *
22  * @file
23  * Library providing operations for the @e environment of
24  * PSYC and Social messages.
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_psyc_env.h"
30
31 /**
32  * Environment for a message.
33  *
34  * Contains modifiers.
35  */
36 struct GNUNET_PSYC_Environment
37 {
38   struct GNUNET_PSYC_Modifier *mod_head;
39   struct GNUNET_PSYC_Modifier *mod_tail;
40   size_t mod_count;
41 };
42
43
44 /**
45  * Create an environment.
46  *
47  * @return A newly allocated environment.
48  */
49 struct GNUNET_PSYC_Environment *
50 GNUNET_PSYC_env_create ()
51 {
52   return GNUNET_new (struct GNUNET_PSYC_Environment);
53 }
54
55
56 /**
57  * Add a modifier to the environment.
58  *
59  * @param env The environment.
60  * @param oper Operation to perform.
61  * @param name Name of the variable.
62  * @param value Value of the variable.
63  * @param value_size Size of @a value.
64  */
65 void
66 GNUNET_PSYC_env_add (struct GNUNET_PSYC_Environment *env,
67                      enum GNUNET_PSYC_Operator oper, const char *name,
68                      const void *value, size_t value_size)
69 {
70   struct GNUNET_PSYC_Modifier *mod = GNUNET_new (struct GNUNET_PSYC_Modifier);
71   mod->oper = oper;
72   mod->name = name;
73   mod->value = value;
74   mod->value_size = value_size;
75   GNUNET_CONTAINER_DLL_insert_tail (env->mod_head, env->mod_tail, mod);
76   env->mod_count++;
77 }
78
79
80 /**
81  * Get the first modifier of the environment.
82  */
83 struct GNUNET_PSYC_Modifier *
84 GNUNET_PSYC_env_head (const struct GNUNET_PSYC_Environment *env)
85 {
86   return env->mod_head;
87 }
88
89
90 /**
91  * Get the last modifier of the environment.
92  */
93 struct GNUNET_PSYC_Modifier *
94 GNUNET_PSYC_env_tail (const struct GNUNET_PSYC_Environment *env)
95 {
96   return env->mod_tail;
97 }
98
99
100 /**
101  * Remove a modifier from the environment.
102  */
103 void
104 GNUNET_PSYC_env_remove (struct GNUNET_PSYC_Environment *env,
105                         struct GNUNET_PSYC_Modifier *mod)
106 {
107   GNUNET_CONTAINER_DLL_remove (env->mod_head, env->mod_tail, mod);
108 }
109
110
111 /**
112  * Get the modifier at the beginning of an environment and remove it.
113  *
114  * @param env
115  * @param oper
116  * @param name
117  * @param value
118  * @param value_size
119  *
120  * @return
121  */
122 int
123 GNUNET_PSYC_env_shift (struct GNUNET_PSYC_Environment *env,
124                        enum GNUNET_PSYC_Operator *oper, const char **name,
125                        const void **value, size_t *value_size)
126 {
127   if (NULL == env->mod_head)
128     return GNUNET_NO;
129
130   struct GNUNET_PSYC_Modifier *mod = env->mod_head;
131   *oper = mod->oper;
132   *name = mod->name;
133   *value = mod->value;
134   *value_size = mod->value_size;
135
136   GNUNET_CONTAINER_DLL_remove (env->mod_head, env->mod_tail, mod);
137   GNUNET_free (mod);
138   env->mod_count--;
139
140   return GNUNET_YES;
141 }
142
143
144 /**
145  * Iterate through all modifiers in the environment.
146  *
147  * @param env The environment.
148  * @param it Iterator.
149  * @param it_cls Closure for iterator.
150  */
151 void
152 GNUNET_PSYC_env_iterate (const struct GNUNET_PSYC_Environment *env,
153                          GNUNET_PSYC_Iterator it, void *it_cls)
154 {
155   struct GNUNET_PSYC_Modifier *mod;
156   for (mod = env->mod_head; NULL != mod; mod = mod->next)
157     it (it_cls, mod->oper, mod->name, mod->value, mod->value_size);
158 }
159
160
161 /**
162  * Get the number of modifiers in the environment.
163  *
164  * @param env The environment.
165  *
166  * @return Number of modifiers.
167  */
168 size_t
169 GNUNET_PSYC_env_get_count (const struct GNUNET_PSYC_Environment *env)
170 {
171   return env->mod_count;
172 }
173
174
175 /**
176  * Destroy an environment.
177  *
178  * @param env The environment to destroy.
179  */
180 void
181 GNUNET_PSYC_env_destroy (struct GNUNET_PSYC_Environment *env)
182 {
183   struct GNUNET_PSYC_Modifier *mod, *prev = NULL;
184   for (mod = env->mod_head; NULL != mod; mod = mod->next)
185   {
186     if (NULL != prev)
187       GNUNET_free (prev);
188     prev = mod;
189   }
190   if (NULL != prev)
191     GNUNET_free (prev);
192
193   GNUNET_free (env);
194 }