2 * Copyright (C) 2015-2019 "IoT.bzh"
3 * Author "Fulup Ar Foll"
4 * Author: José Bollo <jose.bollo@iot.bzh>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
27 #include "afb-token.h"
30 * structure for recording a token
34 /** link to the next token of the list */
35 struct afb_token *next;
37 /** reference of the token */
40 /** local numeric id of the token */
43 /** string value of the token */
49 struct afb_token *first;
50 pthread_mutex_t mutex;
54 static struct tokenset tokenset = {
56 .mutex = PTHREAD_MUTEX_INITIALIZER,
60 static struct afb_token *searchid(uint16_t id)
62 struct afb_token *r = tokenset.first;
63 while (r && r->id != id)
69 * Get a token for the given value
71 * @param token address to return the pointer to the gotten token
72 * @param tokenstring string value of the token to get
73 * @return 0 in case of success or a -errno like negative code
75 int afb_token_get(struct afb_token **token, const char *tokenstring)
78 struct afb_token *tok;
81 /* get length of the token string */
82 length = + strlen(tokenstring);
85 pthread_mutex_lock(&tokenset.mutex);
87 /* search the token */
89 while (tok && memcmp(tokenstring, tok->text, length))
95 tok = afb_token_addref(tok);
98 /* not found, create */
99 tok = malloc(length + sizeof *tok);
101 /* creation failed */
104 while(!++tokenset.idgen || searchid(tokenset.idgen));
105 tok->next = tokenset.first;
106 tokenset.first = tok;
107 tok->id = tokenset.idgen;
109 memcpy(tok->text, tokenstring, length);
113 pthread_mutex_unlock(&tokenset.mutex);
119 * Add a reference count to the given token
121 * @param token the token to reference
122 * @return the token with the reference added
124 struct afb_token *afb_token_addref(struct afb_token *token)
127 __atomic_add_fetch(&token->refcount, 1, __ATOMIC_RELAXED);
132 * Remove a reference to the given token and clean the memory if needed
134 * @param token the token that is unreferenced
136 void afb_token_unref(struct afb_token *token)
138 struct afb_token **pt;
139 if (token && !__atomic_sub_fetch(&token->refcount, 1, __ATOMIC_RELAXED)) {
140 pthread_mutex_lock(&tokenset.mutex);
141 pt = &tokenset.first;
142 while (*pt && *pt != token)
145 pthread_mutex_unlock(&tokenset.mutex);
151 * Check whether the token is valid or not
153 * @param token the token to check
154 * @return a boolean value: 0 if not valid, 1 if valid
156 int afb_token_check(struct afb_token *token)
163 * Get the string value of the token
165 * @param token the token whose string value is queried
166 * @return the string value of the token
168 const char *afb_token_string(const struct afb_token *token)
174 * Get the "local" numeric id of the token
176 * @param token the token whose id is queried
177 * @return the numeric id of the token
179 uint16_t afb_token_id(const struct afb_token *token)