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