1 /*
2  * Copyright (C) 2020-2021 Bareos GmbH & Co. KG
3  * Copyright (C) 2010 SCALITY SA. All rights reserved.
4  * http://www.scality.com
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY SCALITY SA ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL SCALITY SA OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and documentation
30  * are those of the authors and should not be interpreted as representing
31  * official policies, either expressed or implied, of SCALITY SA.
32  *
33  * https://github.com/scality/Droplet
34  */
35 #include "dropletp.h"
36 
37 /** @file */
38 
39 /**
40  *
41  *
42  * @param blob
43  * @param key
44  * @param data
45  * @param datalen
46  *
47  * @return
48  */
dpl_ntinydb_set(dpl_sbuf_t * blob,const char * key,const char * data,int datalen)49 dpl_status_t dpl_ntinydb_set(dpl_sbuf_t* blob,
50                              const char* key,
51                              const char* data,
52                              int datalen)
53 {
54   char flag;
55   int keylen, ret;
56   uint32_t len;
57 
58   flag = 0;
59   ret = dpl_sbuf_add(blob, &flag, 1);
60   if (-1 == ret) return DPL_FAILURE;
61 
62   keylen = strlen(key);
63   len = htonl(keylen);
64 
65   ret = dpl_sbuf_add(blob, (char*)&len, sizeof(len));
66   if (-1 == ret) return DPL_FAILURE;
67 
68   ret = dpl_sbuf_add(blob, key, keylen);
69   if (-1 == ret) return DPL_FAILURE;
70 
71   len = htonl(datalen);
72   ret = dpl_sbuf_add(blob, (char*)&len, sizeof(len));
73   if (-1 == ret) return DPL_FAILURE;
74 
75   ret = dpl_sbuf_add(blob, data, datalen);
76   if (-1 == ret) return DPL_FAILURE;
77 
78   // printf("ntinydb_set '%s' '%.*s'\n", key, datalen, data);
79 
80   dpl_sbuf_print(stdout, blob);
81 
82   return DPL_SUCCESS;
83 }
84 
dpl_ntinydb_get(const char * blob_buf,int blob_len,const char * key,const char ** data_returned,int * datalen_returned)85 dpl_status_t dpl_ntinydb_get(const char* blob_buf,
86                              int blob_len,
87                              const char* key,
88                              const char** data_returned,
89                              int* datalen_returned)
90 {
91   int i, keylenref, keylen, datalen, match;
92   __attribute__((unused)) char flag;
93   uint32_t len;
94 
95   keylenref = strlen(key);
96 
97   match = 0;
98   i = 0;
99   while (1) {
100     // fprintf(stderr, "%d\n", blob_buf[i]);
101 
102     if ((i + 1) < blob_len)
103       flag = blob_buf[i];
104     else
105       break;
106 
107     i++;
108 
109     if ((i + sizeof(len)) < blob_len)
110       memcpy(&len, blob_buf + i, sizeof(len));
111     else
112       break;
113 
114     i += sizeof(len);
115 
116     keylen = ntohl(len);
117 
118     if (keylen == keylenref) {
119       // fprintf(stderr, "%.*s\n", keylen, blob_buf + i);
120 
121       if (!memcmp(key, blob_buf + i, keylenref)) match = 1;
122     }
123 
124     i += keylen;
125 
126     if ((i + sizeof(len)) < blob_len)
127       memcpy(&len, blob_buf + i, sizeof(len));
128     else
129       break;
130 
131     i += sizeof(len);
132 
133     datalen = ntohl(len);
134 
135     if (1 == match) {
136       // fprintf(stderr, "match datalen=%d\n", datalen);
137 
138       *data_returned = blob_buf + i;
139       *datalen_returned = datalen;
140 
141       return DPL_SUCCESS;
142     }
143 
144     i += datalen;
145   }
146 
147   return DPL_FAILURE;
148 }
149 
dpl_ntinydb_list(const char * blob_buf,int blob_len,dpl_ntinydb_func_t cb_func,void * cb_arg)150 dpl_status_t dpl_ntinydb_list(const char* blob_buf,
151                               int blob_len,
152                               dpl_ntinydb_func_t cb_func,
153                               void* cb_arg)
154 {
155   int i, keylen, datalen;
156   __attribute__((unused)) int match;
157   __attribute__((unused)) char flag;
158   uint32_t len;
159 
160   match = 0;
161   i = 0;
162   while (1) {
163     // fprintf(stderr, "%d\n", blob_buf[i]);
164 
165     if ((i + 1) < blob_len)
166       flag = blob_buf[i];
167     else
168       break;
169 
170     i++;
171 
172     if ((i + sizeof(len)) < blob_len)
173       memcpy(&len, blob_buf + i, sizeof(len));
174     else
175       break;
176 
177     i += sizeof(len);
178 
179     keylen = ntohl(len);
180 
181     if (NULL != cb_func) {
182       int ret;
183 
184       ret = cb_func(blob_buf + i, keylen, cb_arg);
185       if (0 != ret) return DPL_FAILURE;
186     }
187 
188     i += keylen;
189 
190     if ((i + sizeof(len)) < blob_len)
191       memcpy(&len, blob_buf + i, sizeof(len));
192     else
193       break;
194 
195     i += sizeof(len);
196 
197     datalen = ntohl(len);
198 
199     i += datalen;
200   }
201 
202   return DPL_SUCCESS;
203 }
204