]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/src/Util/include/JM/jm_string_set.h
Add FMILibrary-2.0.3 to org.simantics.fmil.core\native.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / src / Util / include / JM / jm_string_set.h
1 /*
2     Copyright (C) 2012 Modelon AB
3
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the BSD style license.
6
7      This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10     FMILIB_License.txt file for more details.
11
12     You should have received a copy of the FMILIB_License.txt file
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14 */
15
16 #ifndef JM_STRING_SET_H
17 #define JM_STRING_SET_H
18
19 #include <string.h>
20 #include <stdio.h>
21
22 #include "jm_types.h"
23 #include "jm_vector.h"
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 /** \file jm_string_set.h Definition of ::jm_string_set and supporting functions
28         *
29         * \addtogroup jm_utils
30         * @{
31         *    \addtogroup jm_string_set_group
32         * @}
33         */
34
35         /** \addtogroup jm_string_set_group A set of strings
36          @{
37         */
38
39 /** 
40         \brief Set of string is based on a vector       
41
42 */
43 typedef struct jm_vector_jm_string jm_string_set; /* equivalent to "typedef jm_vector(jm_string) jm_string_set" which Doxygen does not understand */
44
45 /**
46 \brief Find a string in a set.
47
48 \param s A string set.
49 \param str Search string.
50 \return If found returns a pointer to the string saved in the set. If not found returns NULL.
51 */
52 static jm_string jm_string_set_find(jm_string_set* s, jm_string str) {
53     jm_string* found = jm_vector_bsearch(jm_string)(s,&str,jm_compare_string);
54     if(found) return *found;
55     return 0;
56 }
57
58 /**
59 \brief Find index of a string in a set.
60
61 \param s A string set.
62 \param str Search string.
63 \return If found returns the index to the string saved in the set. If not found returns the insertion index of the string.
64 */
65 static size_t jm_string_set_find_index(jm_string_set* s, jm_string str) {
66     size_t len = jm_vector_get_size(jm_string)(s);
67     size_t first = 0;
68     size_t mid = 0;
69     size_t last = len - 1;
70     if(len == 0) {
71         return 0;
72     }
73     while (first <= last) {
74         mid = (last + first)/2;
75         if (strcmp(jm_vector_get_item(jm_string)(s,mid), str) == 0) {
76             return mid;
77         } else if (strcmp(jm_vector_get_item(jm_string)(s,mid), str) > 0) {
78             if (mid == 0) return first;
79             last = mid - 1;
80         } else if (strcmp(jm_vector_get_item(jm_string)(s,mid), str) < 0) {
81             first = mid + 1;
82         }
83     }
84     return first;
85 }
86
87 /**
88 *  \brief Put an element in the set if it is not there yet.
89 *
90 *  @param s A string set.
91 *  \param str String to put.
92 *  @return A pointer to the inserted (or found) element or zero pointer if failed.
93 */
94 static jm_string jm_string_set_put(jm_string_set* s, jm_string str) {
95     jm_string* pnewstr;
96     char* newstr = 0;
97     size_t len = strlen(str) + 1;
98     size_t idx = jm_string_set_find_index(s, str);
99
100     if (idx != jm_vector_get_size(jm_string)(s)) {
101         if (strcmp(jm_vector_get_item(jm_string)(s, idx), str) != 0) {
102             pnewstr = jm_vector_insert(jm_string)(s, idx, str);
103         } else {
104             return jm_vector_get_item(jm_string)(s, idx);
105         }
106     } else {
107         pnewstr = jm_vector_push_back(jm_string)(s, str);
108     }
109     if(pnewstr) *pnewstr = newstr = s->callbacks->malloc(len);
110     if(!pnewstr || !newstr) return 0;
111     memcpy(newstr, str, len);
112     return *pnewstr;
113 }
114
115 /** @}
116         */
117
118 #ifdef __cplusplus
119 }
120 #endif
121
122 #endif /* JM_STRING_SET_H */