RPS API: Fix whitespaces
[oweals/gnunet.git] / src / rps / rps-test_util.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C)
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  * @file rps/rps-test_util.c
21  * @brief Some utils faciliating the view into the internals for the sampler
22  *        needed for evaluation
23  *
24  * @author Julius Bünger
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "rps-test_util.h"
30
31 #include <inttypes.h>
32
33 #define LOG(kind, ...) GNUNET_log_from(kind,"rps-test_util",__VA_ARGS__)
34
35 #define B2B_PAT "%c%c%c%c%c%c%c%c"
36 #define B2B(byte)  \
37   (byte & 0x80 ? '1' : '0'), \
38   (byte & 0x40 ? '1' : '0'), \
39   (byte & 0x20 ? '1' : '0'), \
40   (byte & 0x10 ? '1' : '0'), \
41   (byte & 0x08 ? '1' : '0'), \
42   (byte & 0x04 ? '1' : '0'), \
43   (byte & 0x02 ? '1' : '0'), \
44   (byte & 0x01 ? '1' : '0')
45
46 #ifdef TO_FILE
47
48
49 /**
50  * @brief buffer for storing the unaligned bits for the next write
51  */
52 static char buf_unaligned;
53
54 /**
55  * @brief number of bits in unaligned buffer
56  */
57 static unsigned num_bits_buf_unaligned;
58
59
60 void
61 to_file_raw (const char *file_name, const char *buf, size_t size_buf)
62 {
63   struct GNUNET_DISK_FileHandle *f;
64   size_t size_written;
65
66   if (NULL == (f = GNUNET_DISK_file_open (file_name,
67                                           GNUNET_DISK_OPEN_APPEND |
68                                           GNUNET_DISK_OPEN_WRITE |
69                                           GNUNET_DISK_OPEN_CREATE,
70                                           GNUNET_DISK_PERM_USER_READ |
71                                           GNUNET_DISK_PERM_USER_WRITE |
72                                           GNUNET_DISK_PERM_GROUP_READ |
73                                           GNUNET_DISK_PERM_OTHER_READ)))
74   {
75     LOG (GNUNET_ERROR_TYPE_WARNING,
76          "Not able to open file %s\n",
77          file_name);
78     return;
79   }
80
81   size_written = GNUNET_DISK_file_write (f, buf, size_buf);
82   if (size_buf != size_written)
83   {
84     LOG (GNUNET_ERROR_TYPE_WARNING,
85          "Unable to write to file! (Size: %u, size_written: %u)\n",
86          size_buf,
87          size_written);
88
89     if (GNUNET_YES != GNUNET_DISK_file_close (f))
90       LOG (GNUNET_ERROR_TYPE_WARNING,
91            "Unable to close file\n");
92
93     return;
94   }
95   LOG (GNUNET_ERROR_TYPE_WARNING,
96        "Wrote %u bytes raw.\n",
97        size_written);
98   if (GNUNET_YES != GNUNET_DISK_file_close (f))
99     LOG (GNUNET_ERROR_TYPE_WARNING,
100          "Unable to close file\n");
101 }
102
103 void
104 to_file_raw_unaligned (const char *file_name,
105                        const char *buf,
106                        size_t size_buf,
107                        unsigned bits_needed)
108 {
109   // TODO endianness!
110   GNUNET_assert (size_buf >= (bits_needed/8));
111   //if (0 == num_bits_buf_unaligned)
112   //{
113   //  if (0 == (bits_needed % 8))
114   //  {
115   //    to_file_raw (file_name, buf, size_buf);
116   //    return;
117   //  }
118   //  to_file_raw (file_name, buf, size_buf - 1);
119   //  buf_unaligned = buf[size_buf - 1];
120   //  num_bits_buf_unaligned = bits_needed % 8;
121   //  return;
122   //}
123   LOG (GNUNET_ERROR_TYPE_DEBUG,
124        "Was asked to write %u bits\n", bits_needed);
125
126   char buf_write[size_buf + 1];
127   const unsigned bytes_iter = (0 != bits_needed % 8?
128                                (bits_needed/8)+1:
129                                bits_needed/8);
130   // TODO what if no iteration happens?
131   unsigned size_buf_write = 0;
132   LOG (GNUNET_ERROR_TYPE_DEBUG,
133       "num_bits_buf_unaligned: %u\n",
134        num_bits_buf_unaligned);
135   LOG (GNUNET_ERROR_TYPE_DEBUG,
136       "ua args: size_buf: %u, bits_needed: %u -> iter: %u\n",
137        size_buf,
138        bits_needed,
139        bytes_iter);
140   buf_write[0] = buf_unaligned;
141   /* Iterate over input bytes */
142   for (unsigned i = 0; i < bytes_iter; i++)
143   {
144     /* Number of bits needed in this iteration - 8 for all except last iter */
145     unsigned num_bits_needed_iter;
146     /* Mask for bits to actually use */
147     unsigned mask_bits_needed_iter;
148     char byte_input;
149     /* Number of bits needed to align unaligned byte */
150     unsigned num_bits_to_align;
151     /* Number of bits that are to be moved */
152     unsigned num_bits_to_move;
153     /* Mask for bytes to be moved */
154     char mask_input_to_move;
155     /* Masked bits to be moved */
156     char bits_to_move;
157     /* The amount of bits needed to fit the bits to shift to the nearest spot */
158     unsigned distance_shift_bits;
159     /* Shifted bits on the move */
160     char bits_moving;
161     /* (unaligned) byte being filled with bits */
162     char byte_to_fill;
163     /* mask for needed bits of the input byte that have not been moved */
164     char mask_input_leftover;
165     /* needed bits of the input byte that have not been moved */
166     char byte_input_leftover;
167     unsigned num_bits_leftover;
168     //unsigned num_bits_discard;
169     char byte_unaligned_new;
170
171     if ( (bits_needed - (i * 8)) <= 8)
172     {
173       /* last iteration */
174       num_bits_needed_iter = bits_needed - (i * 8);
175     }
176     else
177     {
178       num_bits_needed_iter = 8;
179     }
180     LOG (GNUNET_ERROR_TYPE_DEBUG,
181         "number of bits needed in this iteration: %u\n",
182          num_bits_needed_iter);
183     mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
184     LOG (GNUNET_ERROR_TYPE_DEBUG,
185         "mask needed bits (current iter): "B2B_PAT"\n",
186          B2B(mask_bits_needed_iter));
187     LOG (GNUNET_ERROR_TYPE_DEBUG,
188         "Unaligned byte: "B2B_PAT" (%u bits)\n",
189          B2B(buf_unaligned),
190          num_bits_buf_unaligned);
191     byte_input = buf[i];
192     LOG (GNUNET_ERROR_TYPE_DEBUG,
193         "next whole input byte: "B2B_PAT"\n",
194          B2B(byte_input));
195     byte_input &= mask_bits_needed_iter;
196     num_bits_to_align = 8 - num_bits_buf_unaligned;
197     LOG (GNUNET_ERROR_TYPE_DEBUG,
198         "input byte, needed bits: "B2B_PAT"\n",
199          B2B(byte_input));
200     LOG (GNUNET_ERROR_TYPE_DEBUG,
201         "number of bits needed to align unaligned bit: %u\n",
202          num_bits_to_align);
203     num_bits_to_move  = GNUNET_MIN (num_bits_to_align, num_bits_needed_iter);
204     LOG (GNUNET_ERROR_TYPE_DEBUG,
205         "number of bits of new byte to move: %u\n",
206          num_bits_to_move);
207     mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
208     LOG (GNUNET_ERROR_TYPE_DEBUG,
209         "mask of bits of new byte to take for moving: "B2B_PAT"\n",
210          B2B(mask_input_to_move));
211     bits_to_move = byte_input & mask_input_to_move;
212     LOG (GNUNET_ERROR_TYPE_DEBUG,
213         "masked bits of new byte to take for moving: "B2B_PAT"\n",
214          B2B(bits_to_move));
215     distance_shift_bits = num_bits_buf_unaligned;
216     LOG (GNUNET_ERROR_TYPE_DEBUG,
217         "distance needed to shift bits to their correct spot: %u\n",
218          distance_shift_bits);
219     bits_moving = bits_to_move << distance_shift_bits;
220     LOG (GNUNET_ERROR_TYPE_DEBUG,
221         "shifted, masked bits of new byte being moved: "B2B_PAT"\n",
222          B2B(bits_moving));
223     byte_to_fill = buf_unaligned | bits_moving;
224     LOG (GNUNET_ERROR_TYPE_DEBUG,
225         "byte being filled: "B2B_PAT"\n",
226          B2B(byte_to_fill));
227     LOG (GNUNET_ERROR_TYPE_DEBUG,
228         "pending bytes: %u\n",
229          num_bits_buf_unaligned + num_bits_needed_iter);
230     if (num_bits_buf_unaligned + num_bits_needed_iter >= 8)
231     {
232       /* buf_unaligned was aligned by filling
233        * -> can be written to storage */
234       buf_write[i] = byte_to_fill;
235       size_buf_write++;
236
237       /* store the leftover, unaligned bits in buffer */
238       mask_input_leftover = mask_bits_needed_iter & (~ mask_input_to_move);
239       LOG (GNUNET_ERROR_TYPE_DEBUG,
240           "mask of leftover bits of new byte: "B2B_PAT"\n",
241            B2B(mask_input_leftover));
242       byte_input_leftover = byte_input & mask_input_leftover;
243       LOG (GNUNET_ERROR_TYPE_DEBUG,
244           "masked, leftover bits of new byte: "B2B_PAT"\n",
245            B2B(byte_input_leftover));
246       num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
247       LOG (GNUNET_ERROR_TYPE_DEBUG,
248           "number of unaligned bits left: %u\n",
249            num_bits_leftover);
250       //num_bits_discard = 8 - num_bits_needed_iter;
251       byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
252       LOG (GNUNET_ERROR_TYPE_DEBUG,
253           "new unaligned byte: "B2B_PAT"\n",
254            B2B(byte_unaligned_new));
255       buf_unaligned = byte_unaligned_new;
256       num_bits_buf_unaligned = num_bits_leftover % 8;
257     }
258     else
259     {
260       /* unaligned buffer still unaligned but 'fuller' */
261       buf_unaligned = byte_to_fill;
262       num_bits_buf_unaligned = (num_bits_buf_unaligned + bits_needed) % 8;
263     }
264   }
265   to_file_raw (file_name, buf_write, size_buf_write);
266   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
267 }
268
269 char *
270 auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key)
271 {
272   int size;
273   size_t name_buf_size;
274   char *end;
275   char *buf;
276   char *name_buf;
277   size_t keylen = (sizeof (struct GNUNET_CRYPTO_AuthKey)) * 8;
278
279   name_buf_size = 512 * sizeof (char);
280   name_buf = GNUNET_malloc (name_buf_size);
281
282   if (keylen % 5 > 0)
283     keylen += 5 - keylen % 5;
284   keylen /= 5;
285   buf = GNUNET_malloc (keylen + 1);
286
287   end = GNUNET_STRINGS_data_to_string (&(auth_key.key),
288       sizeof (struct GNUNET_CRYPTO_AuthKey),
289       buf,
290       keylen);
291
292   if (NULL == end)
293   {
294     GNUNET_free (buf);
295     GNUNET_break (0);
296   }
297   else
298   {
299     *end = '\0';
300   }
301
302   size = GNUNET_snprintf (name_buf, name_buf_size, "sampler_el-%s", buf);
303   if (0 > size)
304     LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n");
305
306   GNUNET_free (buf);
307
308   return name_buf;
309 }
310
311
312
313 char *
314 create_file (const char *name)
315 {
316   int size;
317   size_t name_buf_size;
318   char *name_buf;
319   char *prefix;
320   char *file_name;
321
322   prefix = "/tmp/rps/";
323   name_buf_size = (strlen (prefix) + strlen (name) + 2) * sizeof (char);
324   name_buf = GNUNET_malloc (name_buf_size);
325
326   size = GNUNET_snprintf (name_buf, name_buf_size, "%s%s", prefix, name);
327   if (0 > size)
328     LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n");
329
330   if (GNUNET_YES != GNUNET_DISK_directory_create (prefix))
331   {
332     LOG (GNUNET_ERROR_TYPE_WARNING,
333          "Could not create directory %s.\n",
334          prefix);
335   }
336
337   if (NULL == strstr (name, "sampler_el"))
338   {/* only append random string to sampler */
339     if (NULL == (file_name = GNUNET_DISK_mktemp (name_buf)))
340       LOG (GNUNET_ERROR_TYPE_WARNING, "Could not create file\n");
341
342     GNUNET_free (name_buf);
343     return file_name;
344   }
345
346   return name_buf;
347 }
348
349 #endif /* TO_FILE */
350
351
352 struct GNUNET_CRYPTO_AuthKey
353 string_to_auth_key (const char *str)
354 {
355   struct GNUNET_CRYPTO_AuthKey auth_key;
356
357   if (GNUNET_OK !=
358       GNUNET_STRINGS_string_to_data (str,
359                                      strlen (str),
360                                      &auth_key.key,
361                                      sizeof (struct GNUNET_CRYPTO_AuthKey)))
362   {
363     LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to convert string to data\n");
364   }
365
366   return auth_key;
367 }
368
369
370 /**
371  * @brief Try to ensure that `/tmp/rps` exists.
372  *
373  * @return #GNUNET_YES on success
374  *         #GNUNET_SYSERR on failure
375  */
376 static int ensure_folder_exist (void)
377 {
378   if (GNUNET_NO == GNUNET_DISK_directory_test ("/tmp/rps/", GNUNET_NO))
379   {
380     GNUNET_DISK_directory_create ("/tmp/rps");
381   }
382   if (GNUNET_YES != GNUNET_DISK_directory_test ("/tmp/rps/", GNUNET_NO))
383   {
384     return GNUNET_SYSERR;
385   }
386   return GNUNET_YES;
387 }
388
389 char *
390 store_prefix_file_name (const struct GNUNET_PeerIdentity *peer,
391     const char *prefix)
392 {
393   int len_file_name;
394   int out_size;
395   char *file_name;
396   const char *pid_long;
397
398   if (GNUNET_SYSERR == ensure_folder_exist()) return NULL;
399   pid_long = GNUNET_i2s_full (peer);
400   len_file_name = (strlen (prefix) +
401                    strlen (pid_long) +
402                    11)
403                      * sizeof (char);
404   file_name = GNUNET_malloc (len_file_name);
405   out_size = GNUNET_snprintf (file_name,
406                               len_file_name,
407                               "/tmp/rps/%s-%s",
408                               prefix,
409                               pid_long);
410   if (len_file_name < out_size ||
411       0 > out_size)
412   {
413     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
414                "Failed to write string to buffer (size: %i, out_size: %i)\n",
415                len_file_name,
416                out_size);
417   }
418   return file_name;
419 }
420
421 /* end of gnunet-service-rps.c */