gloox  1.1-svn
util.cpp
1 /*
2  Copyright (c) 2006-2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 #include "util.h"
14 #include "gloox.h"
15 
16 namespace gloox
17 {
18 
19  namespace util
20  {
21 
22  int internalLog2( unsigned int n )
23  {
24  int pos = 0;
25  if ( n >= 1<<16 ) { n >>= 16; pos += 16; }
26  if ( n >= 1<< 8 ) { n >>= 8; pos += 8; }
27  if ( n >= 1<< 4 ) { n >>= 4; pos += 4; }
28  if ( n >= 1<< 2 ) { n >>= 2; pos += 2; }
29  if ( n >= 1<< 1 ) { pos += 1; }
30  return ( (n == 0) ? (-1) : pos );
31  }
32 
33  unsigned _lookup( const std::string& str, const char* values[], unsigned size, int def )
34  {
35  unsigned i = 0;
36  for( ; i < size && str != values[i]; ++i )
37  ;
38  return ( i == size && def >= 0 ) ? (unsigned)def : i;
39  }
40 
41  const std::string _lookup( unsigned code, const char* values[], unsigned size, const std::string& def )
42  {
43  return code < size ? std::string( values[code] ) : def;
44  }
45 
46  unsigned _lookup2( const std::string& str, const char* values[],
47  unsigned size, int def )
48  {
49  return 1 << _lookup( str, values, size, def <= 0 ? def : (int)internalLog2( def ) );
50  }
51 
52  const std::string _lookup2( unsigned code, const char* values[], unsigned size, const std::string& def )
53  {
54  const unsigned i = (unsigned)internalLog2( code );
55  return i < size ? std::string( values[i] ) : def;
56  }
57 
58  static const char escape_chars[] = { '&', '<', '>', '\'', '"' };
59 
60  static const std::string escape_seqs[] = { "amp;", "lt;", "gt;", "apos;", "quot;" };
61 
62  static const unsigned escape_size = 5;
63 
64  const std::string escape( std::string what )
65  {
66  for( size_t val, i = 0; i < what.length(); ++i )
67  {
68  for( val = 0; val < escape_size; ++val )
69  {
70  if( what[i] == escape_chars[val] )
71  {
72  what[i] = '&';
73  what.insert( i+1, escape_seqs[val] );
74  i += escape_seqs[val].length();
75  break;
76  }
77  }
78  }
79  return what;
80  }
81 
82  bool checkValidXMLChars( const std::string& data )
83  {
84  if( data.empty() )
85  return true;
86 
87  std::string::const_iterator it = data.begin();
88  for( ; it != data.end()
89  && ( (unsigned char)(*it) == 0x09
90  || (unsigned char)(*it) == 0x0a
91  || (unsigned char)(*it) == 0x0d
92  || ( (unsigned char)(*it) >= 0x20
93  && (unsigned char)(*it) != 0xc0
94  && (unsigned char)(*it) != 0xc1
95  && (unsigned char)(*it) < 0xf5 ) ); ++it )
96  ;
97 
98  return ( it == data.end() );
99  }
100 
101  void replaceAll( std::string& target, const std::string& find, const std::string& replace )
102  {
103  std::string::size_type findSize = find.size();
104  std::string::size_type replaceSize = replace.size();
105 
106  if( findSize == 0 )
107  return;
108 
109  std::string::size_type index = target.find( find, 0 );
110 
111  while( index != std::string::npos )
112  {
113  target.replace( index, findSize, replace );
114  index = target.find( find, index+replaceSize );
115  }
116  }
117 
118  }
119 
120 }
121