Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS system source for the DUNE DAQ project.
3 : // Fork baseline commit: system-00-00-20 (2020-09-25).
4 : // Renamed since fork: yes (from src/StringMemoryArea.cxx to src/StringMemoryArea.cpp).
5 :
6 : /*
7 : * StringMemoryArea.cxx
8 : * OksSystem
9 : *
10 : * Created by Matthias Wiesmann on 17.02.05.
11 : * Copyright 2005 CERN. All rights reserved.
12 : *
13 : */
14 :
15 : #include "ers/ers.hpp"
16 : #include <sstream>
17 :
18 : #include "okssystem/StringMemoryArea.hpp"
19 :
20 : const char OksSystem::StringMemoryArea::STRING_SEPARATOR = (char)3;
21 : const char OksSystem::StringMemoryArea::MAP_ENTRY_SEPARATOR = (char)4;
22 :
23 : /** Inserts a string at the end of the string region
24 : * \param str the string to insert
25 : * \return the offset in the string region of the string
26 : */
27 :
28 : OksSystem::StringMemoryArea::offset_t
29 0 : OksSystem::StringMemoryArea::add(const char* str)
30 : {
31 0 : ERS_PRECONDITION(str);
32 0 : const size_t l = strlen(str);
33 0 : const offset_t offset = last_string();
34 0 : const offset_t start = offset + 1;
35 0 : const offset_t end = start + l;
36 :
37 0 : ERS_RANGE_CHECK(1, end, string_area_size());
38 0 : char* data = string_area_write();
39 0 : char* current = &data[start];
40 0 : strcpy(current, str);
41 0 : last_string(end);
42 0 : return start;
43 : } // add
44 :
45 : /** Clears a string in the string region
46 : * \param offset the offset of the start of the string
47 : * \return the lenght of the cleared string
48 : */
49 :
50 : size_t
51 0 : OksSystem::StringMemoryArea::clear(offset_t offset)
52 : {
53 0 : char* data = string_area_write();
54 0 : size_t count = 0;
55 0 : while (data[count + offset]) {
56 0 : data[count + offset] = '\0';
57 0 : count++;
58 : } // while
59 0 : return count;
60 : } // clear_string
61 :
62 : /** Finds a string in the string area
63 : * \param offset the starting offset of the string
64 : * \return pointer to string
65 : * \note the actual characters are in the shared area
66 : */
67 :
68 : const char*
69 0 : OksSystem::StringMemoryArea::get_string(offset_t offset) const
70 : {
71 0 : if (offset == 0)
72 : return 0;
73 0 : ERS_RANGE_CHECK(1, offset, string_area_size());
74 0 : const char* str = string_area_read();
75 0 : if (str == NULL) {
76 : return 0;
77 : }
78 0 : return &(str[offset]);
79 : } // get_string
80 :
81 : /** Inserts a string in the string area.
82 : * \param offset offset of the existing string to replace - 0 means no offset defined
83 : * \param str the string to insert
84 : * \return the actual offset where the string was inserted
85 : * \note An existing string is replaced only if the next string can fit in the space.
86 : * if not, the old string is zeroed and the new string inserted at the end of the area.
87 : * This can lead to fragmentation, so you should avoid replacing strings.
88 : */
89 :
90 : OksSystem::StringMemoryArea::offset_t
91 0 : OksSystem::StringMemoryArea::insert(offset_t offset, const char* str)
92 : {
93 0 : ERS_PRECONDITION(str);
94 0 : if (offset == 0)
95 0 : return add(str);
96 0 : ERS_RANGE_CHECK(1, offset, string_area_size());
97 0 : size_t available = clear(offset);
98 0 : if (available >= strlen(str)) {
99 0 : char* data = string_area_write();
100 0 : char* dest = &data[offset];
101 0 : strcpy(dest, str);
102 0 : return offset;
103 : } // if
104 0 : return add(str);
105 : } // insert_string
106 :
107 : /** Inserts a string into memory
108 : * This version updates the memory reference
109 : * \param address of the offset of the string
110 : * \param str the string to insert
111 : */
112 :
113 : void
114 0 : OksSystem::StringMemoryArea::insert(offset_t* offset, const char* str)
115 : {
116 0 : ERS_PRECONDITION(offset);
117 0 : const offset_t n_offset = insert(*offset, str);
118 0 : *offset = n_offset;
119 0 : } // insert
120 :
121 : /** Extracts a vector of string from memory
122 : * \param offset offset of the vector
123 : * \return a vector of strings
124 : */
125 :
126 : OksSystem::StringMemoryArea::str_vector
127 0 : OksSystem::StringMemoryArea::get_vector(offset_t offset) const
128 : {
129 :
130 0 : OksSystem::StringMemoryArea::str_vector vector;
131 0 : const char* str = get_string(offset);
132 :
133 0 : if (str != 0) {
134 :
135 0 : const std::string text(str);
136 :
137 0 : std::string::size_type start_p = 0;
138 0 : std::string::size_type end_p = 0;
139 :
140 0 : while (start_p < text.size()) {
141 0 : end_p = text.find(STRING_SEPARATOR, start_p);
142 0 : if (end_p == std::string::npos) {
143 0 : end_p = text.length();
144 : }
145 0 : std::string extract = text.substr(start_p, end_p - start_p);
146 0 : if (extract.size() > 0) {
147 0 : vector.push_back(extract);
148 : }
149 0 : start_p = end_p + 1;
150 0 : } // while
151 :
152 0 : } // if
153 :
154 0 : return vector;
155 :
156 0 : } // get_vector
157 :
158 : /** Inserts a vector in the string area
159 : * \param offset the offset of the string
160 : * \param vect the vector to insert
161 : * \note the strings should not contain the caracter STRING_SEPARATOR (03)
162 : */
163 :
164 : OksSystem::StringMemoryArea::offset_t
165 0 : OksSystem::StringMemoryArea::insert(offset_t offset, const str_vector& vect)
166 : {
167 : // ERS_RANGE_CHECK(0, offset, string_area_size());
168 0 : str_vector::const_iterator pos;
169 0 : std::ostringstream stream;
170 0 : for (pos = vect.begin(); pos != vect.end(); pos++) {
171 0 : if (vect.begin() != pos) {
172 0 : stream << STRING_SEPARATOR;
173 : } // if first
174 0 : stream << (*pos);
175 : } // for
176 0 : return insert(offset, stream.str().c_str());
177 0 : } // insert
178 :
179 : /** Inserts a vector into memory
180 : * This version updates the memory reference
181 : * \param address of the offset of the string
182 : * \param str the string to insert
183 : * \note the strings should not contain the caracter STRING_SEPARATOR (03)
184 : */
185 :
186 : void
187 0 : OksSystem::StringMemoryArea::insert(offset_t* offset, const str_vector& vect)
188 : {
189 0 : ERS_PRECONDITION(offset);
190 0 : const offset_t n_offset = insert(*offset, vect);
191 0 : *offset = n_offset;
192 0 : } // insert
193 :
194 : /** Reads a string map from memory
195 : * \param offset offset of the map in memory
196 : * \return a map of strings
197 : */
198 :
199 : OksSystem::StringMemoryArea::str_map
200 0 : OksSystem::StringMemoryArea::get_map(offset_t offset) const
201 : {
202 :
203 0 : ERS_RANGE_CHECK(1, offset, string_area_size());
204 0 : OksSystem::StringMemoryArea::str_map map;
205 0 : const char* str = get_string(offset);
206 :
207 0 : if (str != 0) {
208 :
209 0 : const std::string text(str);
210 0 : std::string::size_type start_p = 0;
211 0 : std::string::size_type end_p = 0;
212 :
213 0 : while (start_p < text.size()) {
214 0 : end_p = text.find(MAP_ENTRY_SEPARATOR, start_p);
215 0 : if (end_p == std::string::npos) {
216 0 : end_p = text.length();
217 : }
218 0 : const std::string entry(text.substr(start_p, end_p - start_p));
219 0 : const std::string::size_type entrySize = entry.size();
220 0 : if (entrySize > 0) {
221 0 : const std::string::size_type separator_p = entry.find(STRING_SEPARATOR);
222 0 : if (separator_p != std::string::npos) {
223 0 : if ((separator_p + 1) < entrySize) {
224 0 : map[entry.substr(0, separator_p)] = entry.substr(separator_p + 1);
225 : } else {
226 0 : map[entry.substr(0, separator_p)] = "";
227 : }
228 : }
229 : }
230 0 : start_p = end_p + 1;
231 0 : } // while
232 :
233 0 : } // if
234 :
235 0 : return map;
236 :
237 0 : } // get_map
238 :
239 : /** Inserts a map into memory
240 : * \param offset current offset of the map
241 : * \param map the map to insert
242 : * \return the new offset of the map
243 : * \note the strings should not contain the caracter STRING_SEPARATOR (03)
244 : */
245 :
246 : OksSystem::StringMemoryArea::offset_t
247 0 : OksSystem::StringMemoryArea::insert(offset_t offset, const str_map& map)
248 : {
249 : // ERS_RANGE_CHECK(0, offset, string_area_size());
250 0 : str_map::const_iterator pos;
251 0 : std::ostringstream stream;
252 0 : for (pos = map.begin(); pos != map.end(); pos++) {
253 0 : if (map.begin() != pos) {
254 0 : stream << MAP_ENTRY_SEPARATOR;
255 : } // if first
256 0 : stream << (pos->first);
257 0 : stream << STRING_SEPARATOR;
258 0 : stream << (pos->second);
259 : } // for
260 0 : return insert(offset, stream.str().c_str());
261 0 : } // insert
262 :
263 : /** Inserts a vector into memory
264 : * This version updates the memory reference
265 : * \param address of the offset of the string
266 : * \param str the string to insert
267 : * \note the strings should not contain the caracter STRING_SEPARATOR (03)
268 : */
269 :
270 : void
271 0 : OksSystem::StringMemoryArea::insert(offset_t* offset, const str_map& map)
272 : {
273 0 : ERS_PRECONDITION(offset);
274 0 : const offset_t n_offset = insert(*offset, map);
275 0 : *offset = n_offset;
276 0 : } // insert
|