irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

irods_serialization.cpp
Go to the documentation of this file.
1 #include <string>
2 #include <sstream>
3 #include <vector>
4 #include <set>
5 #include <boost/regex.hpp>
7 #include "irods_exception.hpp"
8 #include "rodsErrorTable.h"
9 
10 namespace irods {
11  static const char default_escape_char = '\\';
12  static const char default_delimiter_char = ';';
13  static const std::string default_special_characters = std::string( 1, default_escape_char ) + default_delimiter_char;
14 
16  const char escape_char ) {
17  std::stringstream str;
18  switch ( escape_char ) {
19  case '\0':
20  break;
21  case '$':
22  case '(':
23  case ')':
24  case '?':
25  case ':':
26  case '\\':
27  str << '\\' << escape_char;
28  break;
29  default:
30  str << escape_char;
31  }
32  str << "$&";
33  return str.str();
34  }
35 
36  boost::regex character_set_regex(
37  const std::set<char>& character_set ) {
38  std::stringstream str;
39  str << '[';
40  for ( std::set<char>::const_iterator iter = character_set.begin(); iter != character_set.end(); ++iter ) {
41  switch ( *iter ) {
42  case ']':
43  case '^':
44  case '-':
45  case '\\':
46  str << '\\' << *iter;
47  break;
48  default:
49  str << *iter;
50  }
51  }
52  str << ']';
53  return boost::regex( str.str() );
54  }
55 
56  boost::regex character_set_regex(
57  const std::string& character_set ) {
58  std::set<char> set;
59  for ( std::string::const_iterator iter = character_set.begin(); iter != character_set.end(); iter++ ) {
60  set.insert( *iter );
61  }
62  return character_set_regex( set );
63  }
64 
65  std::vector<std::string> escape_strings(
66  const std::vector<std::string>& strs,
67  const boost::regex& special_character_set_regex,
68  const char escape_char ) {
69  std::vector<std::string> escaped_strs;
70  if ( escape_char ) {
71  if ( !boost::regex_match( std::string( 1, escape_char ), special_character_set_regex ) ) {
72  THROW( SYS_BAD_INPUT, "Regular expression passed to escape_string must match against the escape character." );
73  }
74  for ( std::vector<std::string>::const_iterator iter = strs.begin(); iter != strs.end(); ++iter ) {
75  escaped_strs.push_back( boost::regex_replace( *iter, special_character_set_regex, get_format_string_for_escape( escape_char ) ) );
76  }
77  }
78  else {
79  for ( std::vector<std::string>::const_iterator iter = strs.begin(); iter != strs.end(); ++iter ) {
80  escaped_strs.push_back( *iter );
81  }
82  }
83  return escaped_strs;
84  }
85 
86  std::vector<std::string> escape_strings(
87  const std::vector<std::string>& strs,
88  const std::set<char>& special_character_set,
89  const char escape_char ) {
90  return escape_strings( strs, character_set_regex( special_character_set ), escape_char );
91  }
92 
93  std::vector<std::string> escape_strings(
94  const std::vector<std::string>& strs,
95  const std::string& special_character_set,
96  const char escape_char ) {
97  return escape_strings( strs, character_set_regex( special_character_set ), escape_char );
98  }
99 
100  std::vector<std::string> escape_strings(
101  const std::vector<std::string>& strs,
102  const boost::regex& special_character_set_regex ) {
103  return escape_strings( strs, special_character_set_regex, default_escape_char );
104  }
105 
106  std::vector<std::string> escape_strings(
107  const std::vector<std::string>& strs,
108  const std::set<char>& special_character_set ) {
109  return escape_strings( strs, character_set_regex( special_character_set ) );
110  }
111 
112  std::vector<std::string> escape_strings(
113  const std::vector<std::string>& strs,
114  const std::string& special_character_set ) {
115  return escape_strings( strs, character_set_regex( special_character_set ) );
116  }
117 
118  std::vector<std::string> escape_strings(
119  const std::vector<std::string>& strs ) {
121  }
122 
123  std::string escape_string(
124  const std::string& str,
125  const boost::regex& special_character_set_regex,
126  const char escape_char ) {
127  std::vector<std::string> v;
128  v.push_back( str );
129  return escape_strings( v, special_character_set_regex, escape_char )[0];
130  }
131 
132  std::string escape_string(
133  const std::string& str,
134  const std::set<char>& special_character_set,
135  const char escape_char ) {
136  return escape_string( str, character_set_regex( special_character_set ), escape_char );
137  }
138 
139  std::string escape_string(
140  const std::string& str,
141  const std::string& special_character_set,
142  const char escape_char ) {
143  return escape_string( str, character_set_regex( special_character_set ), escape_char );
144  }
145 
146  std::string escape_string(
147  const std::string& str,
148  const boost::regex& special_character_set_regex ) {
149  return escape_string( str, special_character_set_regex, default_escape_char );
150  }
151 
152  std::string escape_string(
153  const std::string& str,
154  const std::set<char>& special_character_set ) {
155  return escape_string( str, character_set_regex( special_character_set ) );
156  }
157 
158  std::string escape_string(
159  const std::string& str,
160  const std::string& special_character_set ) {
161  return escape_string( str, character_set_regex( special_character_set ) );
162  }
163 
164  std::string escape_string(
165  const std::string& str ) {
167  }
168 
169  std::string join( std::vector<std::string>& strs, const std::string& separator ) {
170  std::stringstream joined;
171  for ( std::vector<std::string>::const_iterator iter = strs.begin(); iter != strs.end(); ) {
172  joined << *iter;
173  ++iter;
174  if ( iter != strs.end() ) {
175  joined << separator;
176  }
177  }
178  return joined.str();
179  }
180 
181  std::string join( std::vector<std::string>& strs, const char separator ) {
182  return join( strs, std::string( 1, separator ) );
183  }
184 
185  std::string serialize_list(
186  const std::vector<std::string>& list,
187  const boost::regex& special_character_set_regex,
188  const char delimiter_char,
189  const char escape_char ) {
190  if ( escape_char && !boost::regex_match( std::string( 1, delimiter_char ), special_character_set_regex ) ) {
191  THROW( SYS_BAD_INPUT, "Regular expression passed to serialize_list must match against the delimiter character." );
192  }
193  std::vector<std::string> escaped_strings = escape_strings( list, special_character_set_regex, escape_char );
194  return join( escaped_strings, delimiter_char );
195  }
196 
197  std::string serialize_list(
198  const std::vector<std::string>& list,
199  const std::set<char>& special_character_set,
200  const char delimiter_char,
201  const char escape_char ) {
202  return serialize_list( list, character_set_regex( special_character_set ), delimiter_char, escape_char );
203  }
204 
205  std::string serialize_list(
206  const std::vector<std::string>& list,
207  const std::string& special_character_set,
208  const char delimiter_char,
209  const char escape_char ) {
210  return serialize_list( list, character_set_regex( special_character_set ), delimiter_char, escape_char );
211  }
212 
213  std::string serialize_list(
214  const std::vector<std::string>& list,
215  const boost::regex& special_character_set_regex,
216  const char delimiter_char ) {
217  return serialize_list( list, special_character_set_regex, delimiter_char, default_escape_char );
218  }
219 
220  std::string serialize_list(
221  const std::vector<std::string>& list,
222  const std::set<char>& special_character_set,
223  const char delimiter_char ) {
224  return serialize_list( list, character_set_regex( special_character_set ), delimiter_char );
225  }
226 
227  std::string serialize_list(
228  const std::vector<std::string>& list,
229  const std::string& special_character_set,
230  const char delimiter_char ) {
231  return serialize_list( list, character_set_regex( special_character_set ), delimiter_char );
232  }
233 
234  std::string serialize_list(
235  const std::vector<std::string>& list,
236  const boost::regex& special_character_set_regex ) {
237  return serialize_list( list, special_character_set_regex, default_delimiter_char );
238  }
239 
240  std::string serialize_list(
241  const std::vector<std::string>& list,
242  const std::set<char>& special_character_set ) {
243  return serialize_list( list, character_set_regex( special_character_set ) );
244  }
245 
246  std::string serialize_list(
247  const std::vector<std::string>& list,
248  const std::string& special_character_set ) {
249  return serialize_list( list, character_set_regex( special_character_set ) );
250  }
251 
252  std::string serialize_list(
253  const std::vector<std::string>& list ) {
255  }
256 
257  std::vector<std::string> deserialize_list(
258  const std::string& list,
259  const std::string& delimiters,
260  const char escape_char ) {
261  std::vector<std::string> deserialized_list;
262  std::stringstream current_string;
263  const char delimiter_char = delimiters[0];
264  const std::string remaining_delimiters = delimiters.size() ? delimiters.substr( 1 ) : "" ;
265  for ( std::string::const_iterator iter = list.begin(); iter != list.end(); ++iter ) {
266  if ( *iter == escape_char ) {
267  ++iter;
268  if ( iter == list.end() ) {
269  break;
270  }
271  if ( remaining_delimiters.size() && ( *iter == escape_char || remaining_delimiters.find( *iter ) != std::string::npos ) ) {
272  current_string << escape_char;
273  }
274  }
275  else if ( *iter == delimiter_char ) {
276  deserialized_list.push_back( current_string.str() );
277  current_string.str( "" );
278  continue;
279  }
280  current_string << *iter;
281  }
282  if ( !current_string.str().empty() ) {
283  deserialized_list.push_back( current_string.str() );
284  }
285 
286  return deserialized_list;
287  }
288 
289  std::vector<std::string> deserialize_list(
290  const std::string& list,
291  const char delimiter_char,
292  const char escape_char ) {
293  return deserialize_list( list, std::string( 1, delimiter_char ), escape_char );
294  }
295 
296  std::vector<std::string> deserialize_list(
297  const std::string& list,
298  const std::string& delimiters ) {
299  return deserialize_list( list, delimiters, '\\' );
300  }
301 
302  std::vector<std::string> deserialize_list(
303  const std::string& list,
304  const char delimiter_char ) {
305  return deserialize_list( list, delimiter_char, '\\' );
306  }
307 
308  std::vector<std::string> deserialize_list(
309  const std::string& list ) {
310  return deserialize_list( list, ";", '\\' );
311  }
312 
313  std::vector<std::string> deserialize_metadata( const std::string& metadata ) {
314  std::vector<std::string> deserialized_metadata = deserialize_list( metadata );
315  if ( deserialized_metadata.size() % 3 == 2 ) {
316  deserialized_metadata.push_back( "" );
317  }
318  else if ( deserialized_metadata.size() % 3 != 0 ) {
319  THROW( SYS_BAD_INPUT, "Metadata strings must consist of triplets of semicolon-separated tokens" );
320  }
321 
322  return deserialized_metadata;
323  }
324 
325  std::string serialize_metadata( const std::vector<std::string>& metadata ) {
326  if ( metadata.size() % 3 != 0 ) {
327  THROW( SYS_BAD_INPUT, "Metadata must exist in triplets" );
328  }
329  return serialize_list( metadata );
330  }
331 
332  std::vector<std::vector<std::string> > deserialize_acl( const std::string& acl ) {
333  std::vector<std::string> shallow_deserialized_acl = deserialize_list( acl, "; ", '\\' );
334  std::vector<std::vector<std::string> > deserialized_acl;
335  for ( std::vector<std::string>::const_iterator iter = shallow_deserialized_acl.begin(); iter != shallow_deserialized_acl.end(); ++iter ) {
336  std::vector<std::string> current_acl = deserialize_list( *iter, " ", '\\' );
337  if ( current_acl.size() != 2 ) {
338  THROW( SYS_BAD_INPUT, "ACLs must be a space-separated tuple of \"user permission\"" );
339  }
340  deserialized_acl.push_back( current_acl );
341  }
342 
343  return deserialized_acl;
344  }
345 
346  std::string serialize_acl( const std::vector<std::vector<std::string> >& acl ) {
347  std::vector<std::string> shallow_serialized_acl;
348  for ( std::vector<std::vector<std::string> >::const_iterator iter = acl.begin(); iter != acl.end(); ++iter ) {
349  if ( iter->size() != 2 ) {
350  THROW( SYS_BAD_INPUT, "ACLs must be a tuple of user and permission" );
351  }
352  shallow_serialized_acl.push_back( serialize_list( *iter, boost::regex( "[\\\\ ;]" ), ' ', '\\' ) );
353  }
354  return join( shallow_serialized_acl, ';' );
355  }
356 }
357 
358 extern "C" {
359  char* serialize_list_c( const char** list, size_t list_len ) {
360  std::vector<std::string> list_strings;
361  for ( size_t i = 0; i < list_len; i++ ) {
362  list_strings.push_back( list[i] );
363  }
364  return strdup( irods::serialize_list( list_strings ).c_str() );
365  }
366 
367  char* serialize_metadata_c( const char** metadata, size_t metadata_len ) {
368  std::vector<std::string> metadata_strings;
369  for ( size_t i = 0; i < metadata_len; i++ ) {
370  metadata_strings.push_back( metadata[i] );
371  }
372  try {
373  return strdup( irods::serialize_metadata( metadata_strings ).c_str() );
374  }
375  catch ( const irods::exception& ) {
376  return NULL;
377  }
378  }
379 
380  char* serialize_acl_c( const char** acl, size_t acl_len ) {
381  std::vector<std::vector<std::string> > acl_strings;
382  for ( size_t i = 0; i < acl_len; i++ ) {
383  if ( !( i & 1 ) ) {
384  std::vector<std::string> v;
385  v.push_back( acl[i] );
386  acl_strings.push_back( v );
387  }
388  else {
389  acl_strings.back().push_back( acl[i] );
390  }
391  }
392  try {
393  return strdup( irods::serialize_acl( acl_strings ).c_str() );
394  }
395  catch ( const irods::exception& ) {
396  return NULL;
397  }
398  }
399 }
NULL
#define NULL
Definition: rodsDef.h:70
THROW
#define THROW(_code, _msg)
Definition: irods_exception.hpp:68
irods::default_delimiter_char
static const char default_delimiter_char
Definition: irods_serialization.cpp:12
irods::escape_strings
std::vector< std::string > escape_strings(const std::vector< std::string > &strs, const boost::regex &special_character_set_regex, const char escape_char)
Definition: irods_serialization.cpp:65
irods_exception.hpp
irods::serialize_list
std::string serialize_list(const std::vector< std::string > &list, const boost::regex &special_character_set_regex, const char delimiter_char, const char escape_char)
Definition: irods_serialization.cpp:185
irods::character_set_regex
boost::regex character_set_regex(const std::set< char > &character_set)
Definition: irods_serialization.cpp:36
irods::deserialize_acl
std::vector< std::vector< std::string > > deserialize_acl(const std::string &acl)
Definition: irods_serialization.cpp:332
irods::default_special_characters
static const std::string default_special_characters
Definition: irods_serialization.cpp:13
irods::default_escape_char
static const char default_escape_char
Definition: irods_serialization.cpp:11
irods_serialization.hpp
serialize_acl_c
char * serialize_acl_c(const char **acl, size_t acl_len)
Definition: irods_serialization.cpp:380
irods::deserialize_metadata
std::vector< std::string > deserialize_metadata(const std::string &metadata)
Definition: irods_serialization.cpp:313
irods::deserialize_list
std::vector< std::string > deserialize_list(const std::string &list, const std::string &delimiters, const char escape_char)
Definition: irods_serialization.cpp:257
irods
Definition: apiHandler.hpp:35
serialize_metadata_c
char * serialize_metadata_c(const char **metadata, size_t metadata_len)
Definition: irods_serialization.cpp:367
irods::escape_string
std::string escape_string(const std::string &_string, const std::string &_escape_token, const std::set< std::string > &_special_tokens)
Definition: irods_kvp_string_parser.cpp:185
irods::serialize_acl
std::string serialize_acl(const std::vector< std::vector< std::string > > &acl)
Definition: irods_serialization.cpp:346
irods::get_format_string_for_escape
std::string get_format_string_for_escape(const char escape_char)
Definition: irods_serialization.cpp:15
irods::join
std::string join(std::vector< std::string > &strs, const std::string &separator)
Definition: irods_serialization.cpp:169
serialize_list_c
char * serialize_list_c(const char **list, size_t list_len)
Definition: irods_serialization.cpp:359
irods::exception
Definition: irods_exception.hpp:15
rodsErrorTable.h
irods::serialize_metadata
std::string serialize_metadata(const std::vector< std::string > &metadata)
Definition: irods_serialization.cpp:325
list
Definition: irods_list.h:13
SYS_BAD_INPUT
@ SYS_BAD_INPUT
Definition: rodsErrorTable.h:215