gloox  1.0
util.cpp
00001 /*
00002   Copyright (c) 2006-2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 #include "util.h"
00014 #include "gloox.h"
00015 
00016 namespace gloox
00017 {
00018 
00019   namespace util
00020   {
00021 
00022     int internalLog2( unsigned int n )
00023     {
00024       int pos = 0;
00025       if ( n >= 1<<16 ) { n >>= 16; pos += 16; }
00026       if ( n >= 1<< 8 ) { n >>=  8; pos +=  8; }
00027       if ( n >= 1<< 4 ) { n >>=  4; pos +=  4; }
00028       if ( n >= 1<< 2 ) { n >>=  2; pos +=  2; }
00029       if ( n >= 1<< 1 ) {           pos +=  1; }
00030       return ( (n == 0) ? (-1) : pos );
00031     }
00032 
00033     unsigned _lookup( const std::string& str, const char* values[], unsigned size, int def )
00034     {
00035       unsigned i = 0;
00036       for( ; i < size && str != values[i]; ++i )
00037         ;
00038       return ( i == size && def >= 0 ) ? (unsigned)def : i;
00039     }
00040 
00041     const std::string _lookup( unsigned code, const char* values[], unsigned size, const std::string& def )
00042     {
00043       return code < size ? std::string( values[code] ) : def;
00044     }
00045 
00046     unsigned _lookup2( const std::string& str, const char* values[],
00047                        unsigned size, int def )
00048     {
00049       return 1 << _lookup( str, values, size, def <= 0 ? def : (int)internalLog2( def ) );
00050     }
00051 
00052     const std::string _lookup2( unsigned code, const char* values[], unsigned size, const std::string& def )
00053     {
00054       const unsigned i = (unsigned)internalLog2( code );
00055       return i < size ? std::string( values[i] ) : def;
00056     }
00057 
00058     static const char escape_chars[] = { '&', '<', '>', '\'', '"' };
00059 
00060     static const std::string escape_seqs[] = { "amp;", "lt;", "gt;", "apos;", "quot;" };
00061 
00062     static const unsigned escape_size = 5;
00063 
00064     const std::string escape( std::string what )
00065     {
00066       for( size_t val, i = 0; i < what.length(); ++i )
00067       {
00068         for( val = 0; val < escape_size; ++val )
00069         {
00070           if( what[i] == escape_chars[val] )
00071           {
00072             what[i] = '&';
00073             what.insert( i+1, escape_seqs[val] );
00074             i += escape_seqs[val].length();
00075             break;
00076           }
00077         }
00078       }
00079       return what;
00080     }
00081 
00082     bool checkValidXMLChars( const std::string& data )
00083     {
00084       if( data.empty() )
00085         return true;
00086 
00087       std::string::const_iterator it = data.begin();
00088       for( ; it != data.end()
00089              && ( (unsigned char)(*it) == 0x09
00090                   || (unsigned char)(*it) == 0x0a
00091                   || (unsigned char)(*it) == 0x0d
00092                   || ( (unsigned char)(*it) >= 0x20
00093                      && (unsigned char)(*it) != 0xc0
00094                      && (unsigned char)(*it) != 0xc1
00095                      && (unsigned char)(*it) < 0xf5 ) ); ++it )
00096         ;
00097 
00098       return ( it == data.end() );
00099     }
00100 
00101     void replaceAll( std::string& target, const std::string& find, const std::string& replace )
00102     {
00103       std::string::size_type findSize = find.size();
00104       std::string::size_type replaceSize = replace.size();
00105 
00106       if( findSize == 0 )
00107         return;
00108 
00109       std::string::size_type index = target.find( find, 0 );
00110 
00111       while( index != std::string::npos )
00112       {
00113         target.replace( index, findSize, replace );
00114         index = target.find( find, index+replaceSize );
00115       }
00116     }
00117 
00118   }
00119 
00120 }
00121