-fix records
[oweals/gnunet.git] / src / identity-provider / identity_attribute.c
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2010-2015 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  * @file identity-provider/identity_attribute.c
23  * @brief helper library to manage identity attributes
24  * @author Martin Schanzenbach
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "identity_attribute.h"
29
30 /**
31  * Create a new attribute.
32  *
33  * @param name the attribute name
34  * @param type the attribute type
35  * @param data the attribute value
36  * @param data_size the attribute value size
37  * @return the new attribute
38  */
39 struct GNUNET_IDENTITY_PROVIDER_Attribute *
40 attribute_new (const char* attr_name,
41                uint32_t attr_type,
42                const void* data,
43                size_t data_size)
44 {
45   struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
46   char *write_ptr;
47
48   attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute) +
49                         strlen (attr_name) + 1 +
50                         data_size);
51   attr->attribute_type = attr_type;
52   attr->data_size = data_size;
53   write_ptr = (char*)&attr[1];
54   GNUNET_memcpy (write_ptr,
55                  attr_name,
56                  strlen (attr_name) + 1);
57   attr->name = write_ptr;
58   write_ptr += strlen (attr->name) + 1;
59   GNUNET_memcpy (write_ptr,
60                  data,
61                  data_size);
62   attr->data = write_ptr;
63   return attr;
64 }
65
66 size_t
67 attribute_list_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
68 {
69   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
70   size_t len = 0;
71   for (le = attrs->list_head; NULL != le; le = le->next)
72     len += attribute_serialize_get_size (le->attribute);
73   return len; 
74 }
75
76 size_t
77 attribute_list_serialize (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
78                           char *result)
79 {
80   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
81   size_t len;
82   size_t total_len;
83   char* write_ptr;
84
85   write_ptr = result;
86   total_len = 0;
87   for (le = attrs->list_head; NULL != le; le = le->next)
88   {
89     len = attribute_serialize (le->attribute,
90                                write_ptr);
91     total_len += len;
92     write_ptr += len;
93   }
94   return total_len;
95 }
96
97 struct GNUNET_IDENTITY_PROVIDER_AttributeList *
98 attribute_list_deserialize (const char* data,
99                        size_t data_size)
100 {
101   struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
102   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
103   size_t attr_len;
104   const char* read_ptr;
105
106   if (data_size < sizeof (struct Attribute))
107     return NULL;
108   
109   attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
110   read_ptr = data;
111   while (((data + data_size) - read_ptr) >= sizeof (struct Attribute))
112   {
113
114     le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
115     le->attribute = attribute_deserialize (read_ptr,
116                                            data_size - (read_ptr - data));
117     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
118                 "Deserialized attribute %s\n", le->attribute->name);
119     GNUNET_CONTAINER_DLL_insert (attrs->list_head,
120                                  attrs->list_tail,
121                                  le);
122     attr_len = attribute_serialize_get_size (le->attribute);
123     read_ptr += attr_len;
124   }
125   return attrs;
126 }
127
128 void
129 attribute_list_destroy (struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
130 {
131   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
132   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *tmp_le;
133
134   for (le = attrs->list_head; NULL != le;)
135   {
136     GNUNET_free (le->attribute);
137     tmp_le = le;
138     le = le->next;
139     GNUNET_free (tmp_le);
140   }
141   GNUNET_free (attrs);
142
143 }
144
145 size_t
146 attribute_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
147 {
148   return sizeof (struct Attribute) 
149     + strlen (attr->name)
150     + attr->data_size; //TODO get data_size from plugin
151 }
152
153 size_t
154 attribute_serialize (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
155                      char *result)
156 {
157   size_t data_len_ser;
158   size_t name_len;
159   struct Attribute *attr_ser;
160   char* write_ptr;
161
162   attr_ser = (struct Attribute*)result;
163   attr_ser->attribute_type = htons (attr->attribute_type);
164   name_len = strlen (attr->name);
165   attr_ser->name_len = htons (name_len);
166   write_ptr = (char*)&attr_ser[1];
167   GNUNET_memcpy (write_ptr, attr->name, name_len);
168   write_ptr += name_len;
169   //TODO plugin-ize
170   //data_len_ser = plugin->serialize_attribute_value (attr,
171   //                                                  &attr_ser[1]);
172   data_len_ser = attr->data_size;
173   GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
174   attr_ser->data_size = htons (data_len_ser);
175
176   return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
177 }
178
179 struct GNUNET_IDENTITY_PROVIDER_Attribute *
180 attribute_deserialize (const char* data,
181                        size_t data_size)
182 {
183   struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
184   struct Attribute *attr_ser;
185   size_t data_len;
186   size_t name_len;
187   char* write_ptr;
188
189   if (data_size < sizeof (struct Attribute))
190     return NULL;
191
192   attr_ser = (struct Attribute*)data;
193   //TODO use plugin. 
194   data_len = ntohs (attr_ser->data_size);
195   name_len = ntohs (attr_ser->name_len);
196   attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute)
197                         + data_len + name_len + 1);
198   attr->attribute_type = ntohs (attr_ser->attribute_type);
199   attr->data_size = ntohs (attr_ser->data_size);
200
201   write_ptr =  (char*)&attr[1];
202   GNUNET_memcpy (write_ptr,
203                  &attr_ser[1],
204                  name_len);
205   write_ptr[name_len] = '\0';
206   attr->name = write_ptr;
207
208   write_ptr += name_len + 1;
209   GNUNET_memcpy (write_ptr,
210                  (char*)&attr_ser[1] + name_len,
211                  attr->data_size);
212   attr->data = write_ptr;
213   return attr;
214
215 }
216
217 /* end of identity_attribute.c */