-rps: open channel when inserting peer in view
[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
6  * it under the terms of the GNU General Public License as published
7  * by the Free Software Foundation; either version 3, or (at your
8  * 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  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with GNUnet; see the file COPYING.  If not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * @author Gabor X Toth
23  *
24  * @file
25  * Library providing operations for the @e environment of
26  * PSYC and Social messages.
27  */
28
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_psyc_env.h"
32
33 /**
34  * Environment for a message.
35  *
36  * Contains modifiers.
37  */
38 struct GNUNET_PSYC_Environment
39 {
40   struct GNUNET_PSYC_Modifier *mod_head;
41   struct GNUNET_PSYC_Modifier *mod_tail;
42   size_t mod_count;
43 };
44
45
46 /**
47  * Create an environment.
48  *
49  * @return A newly allocated environment.
50  */
51 struct GNUNET_PSYC_Environment *
52 GNUNET_PSYC_env_create ()
53 {
54   return GNUNET_new (struct GNUNET_PSYC_Environment);
55 }
56
57
58 /**
59  * Add a modifier to the environment.
60  *
61  * @param env The environment.
62  * @param oper Operation to perform.
63  * @param name Name of the variable.
64  * @param value Value of the variable.
65  * @param value_size Size of @a value.
66  */
67 void
68 GNUNET_PSYC_env_add (struct GNUNET_PSYC_Environment *env,
69                      enum GNUNET_PSYC_Operator oper, const char *name,
70                      const void *value, size_t value_size)
71 {
72   struct GNUNET_PSYC_Modifier *mod = GNUNET_new (struct GNUNET_PSYC_Modifier);
73   mod->oper = oper;
74   mod->name = name;
75   mod->value = value;
76   mod->value_size = value_size;
77   GNUNET_CONTAINER_DLL_insert_tail (env->mod_head, env->mod_tail, mod);
78   env->mod_count++;
79 }
80
81
82 /**
83  * Get the first modifier of the environment.
84  */
85 struct GNUNET_PSYC_Modifier *
86 GNUNET_PSYC_env_head (const struct GNUNET_PSYC_Environment *env)
87 {
88   return env->mod_head;
89 }
90
91
92 /**
93  * Get the last modifier of the environment.
94  */
95 struct GNUNET_PSYC_Modifier *
96 GNUNET_PSYC_env_tail (const struct GNUNET_PSYC_Environment *env)
97 {
98   return env->mod_tail;
99 }
100
101
102 /**
103  * Remove a modifier from the environment.
104  */
105 void
106 GNUNET_PSYC_env_remove (struct GNUNET_PSYC_Environment *env,
107                         struct GNUNET_PSYC_Modifier *mod)
108 {
109   GNUNET_CONTAINER_DLL_remove (env->mod_head, env->mod_tail, mod);
110 }
111
112
113 /**
114  * Get the modifier at the beginning of an environment and remove it.
115  *
116  * @param env
117  * @param oper
118  * @param name
119  * @param value
120  * @param value_size
121  *
122  * @return
123  */
124 int
125 GNUNET_PSYC_env_shift (struct GNUNET_PSYC_Environment *env,
126                        enum GNUNET_PSYC_Operator *oper, const char **name,
127                        const void **value, size_t *value_size)
128 {
129   if (NULL == env->mod_head)
130     return GNUNET_NO;
131
132   struct GNUNET_PSYC_Modifier *mod = env->mod_head;
133   *oper = mod->oper;
134   *name = mod->name;
135   *value = mod->value;
136   *value_size = mod->value_size;
137
138   GNUNET_CONTAINER_DLL_remove (env->mod_head, env->mod_tail, mod);
139   GNUNET_free (mod);
140   env->mod_count--;
141
142   return GNUNET_YES;
143 }
144
145
146 /**
147  * Iterate through all modifiers in the environment.
148  *
149  * @param env The environment.
150  * @param it Iterator.
151  * @param it_cls Closure for iterator.
152  */
153 void
154 GNUNET_PSYC_env_iterate (const struct GNUNET_PSYC_Environment *env,
155                          GNUNET_PSYC_Iterator it, void *it_cls)
156 {
157   struct GNUNET_PSYC_Modifier *mod;
158   for (mod = env->mod_head; NULL != mod; mod = mod->next)
159     it (it_cls, mod->oper, mod->name, mod->value, mod->value_size);
160 }
161
162
163 /**
164  * Get the number of modifiers in the environment.
165  *
166  * @param env The environment.
167  *
168  * @return Number of modifiers.
169  */
170 size_t
171 GNUNET_PSYC_env_get_count (const struct GNUNET_PSYC_Environment *env)
172 {
173   return env->mod_count;
174 }
175
176
177 /**
178  * Destroy an environment.
179  *
180  * @param env The environment to destroy.
181  */
182 void
183 GNUNET_PSYC_env_destroy (struct GNUNET_PSYC_Environment *env)
184 {
185   struct GNUNET_PSYC_Modifier *mod, *prev = NULL;
186   for (mod = env->mod_head; NULL != mod; mod = mod->next)
187   {
188     if (NULL != prev)
189       GNUNET_free (prev);
190     prev = mod;
191   }
192   if (NULL != prev)
193     GNUNET_free (prev);
194
195   GNUNET_free (env);
196 }