2013-02-04 21:48:05 +04:00
/* -------------------------------------------------------------------------- */
2020-04-30 16:00:02 +03:00
/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
2013-02-04 21:48:05 +04:00
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
2013-02-12 15:15:09 +04:00
# ifndef _NEBULA_UTIL_H_
# define _NEBULA_UTIL_H_
2013-02-04 21:48:05 +04:00
# include <string>
2014-10-10 18:53:57 +04:00
# include <sstream>
2013-11-15 15:58:53 +04:00
# include <vector>
2014-10-10 18:53:57 +04:00
# include <set>
2016-03-10 18:28:33 +03:00
# include <algorithm>
2019-08-16 12:11:31 +03:00
# include <random>
2013-02-04 21:48:05 +04:00
2016-07-29 18:50:52 +03:00
# include <openssl/crypto.h>
2013-02-04 21:48:05 +04:00
namespace one_util
{
2013-02-09 00:58:34 +04:00
std : : string & toupper ( std : : string & st ) ;
2013-02-04 21:48:05 +04:00
2013-02-09 00:58:34 +04:00
std : : string & tolower ( std : : string & st ) ;
2013-02-04 21:48:05 +04:00
2013-02-09 00:50:40 +04:00
std : : string log_time ( time_t the_time ) ;
2013-02-04 21:48:05 +04:00
2013-02-09 00:58:34 +04:00
std : : string log_time ( ) ;
2013-02-09 19:38:54 +04:00
2017-09-11 12:39:44 +03:00
/**
* Escape XML entity and character references
* @ param in the string to be escaped
* @ return a string copy
*/
std : : string xml_escape ( const std : : string & in ) ;
2013-02-09 19:38:54 +04:00
/**
* sha1 digest
* @ param in the string to be hashed
* @ return sha1 hash of str
*/
std : : string sha1_digest ( const std : : string & in ) ;
2019-03-01 14:30:24 +03:00
/**
* sha256 digest
* @ param in the string to be hashed
* @ return sha256 hash of str
*/
std : : string sha256_digest ( const std : : string & in ) ;
2013-02-09 19:38:54 +04:00
2013-07-05 03:31:30 +04:00
/**
* AES256 encryption
* @ param in the string to encrypt
* @ param password to encrypt data
2019-09-03 17:31:51 +03:00
* @ return a pointer to the encrypted string ( must be freed ) or nullptr in case of
2013-07-05 03:31:30 +04:00
* error
*/
2019-09-03 17:31:51 +03:00
std : : string * aes256cbc_encrypt ( const std : : string & in , const std : : string & password ) ;
/**
* AES256 decryption
* @ param in the base64 string to decrypt
* @ param password to decrypt data
* @ return a pointer to the decrypted string ( must be freed ) or nullptr in case of
* error
*/
std : : string * aes256cbc_decrypt ( const std : : string & in , const std : : string & password ) ;
2013-06-27 17:49:23 +04:00
/**
* Creates a random number , using time ( 0 ) as seed , and performs an sha1 hash
* @ return a new random password
*/
std : : string random_password ( ) ;
2013-11-15 15:58:53 +04:00
2019-08-16 12:11:31 +03:00
/**
* Returns random number , default range is < 0 , Type Max Value > , specialization for integer types
* @ param min - minimal potentially generated number , defaults to 0
* @ param max - maximal potentially generated number , defaults to type max value
* @ return number between min , max
*/
template < typename Integer , typename std : : enable_if < std : : is_integral < Integer > : : value > : : type * = nullptr >
Integer random ( Integer min = 0 , Integer max = std : : numeric_limits < Integer > : : max ( ) )
{
2019-08-16 12:19:11 +03:00
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER ;
2019-08-16 12:11:31 +03:00
static std : : random_device rd ;
2019-08-16 12:19:11 +03:00
static std : : mt19937_64 rng ( rd ( ) ) ;
2019-08-16 12:11:31 +03:00
std : : uniform_int_distribution < Integer > distribution ( min , max ) ;
2019-08-16 12:19:11 +03:00
pthread_mutex_lock ( & mutex ) ;
Integer i = distribution ( rng ) ;
pthread_mutex_unlock ( & mutex ) ;
return i ;
2019-08-16 12:11:31 +03:00
}
/**
* Returns random number , default range is < 0 , Type Max Value > , specialization for floating types
* @ param min - minimal potentially generated number , defaults to 0
* @ param max - maximal potentially generated number , defaults to type max value
* @ return number between min , max
*/
template < typename Floating , typename std : : enable_if < std : : is_floating_point < Floating > : : value > : : type * = nullptr >
Floating random ( Floating min = 0 , Floating max = std : : numeric_limits < Floating > : : max ( ) )
{
2019-08-16 12:19:11 +03:00
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER ;
2019-08-16 12:11:31 +03:00
static std : : random_device rd ;
2019-08-16 12:19:11 +03:00
static std : : mt19937_64 rng ( rd ( ) ) ;
2019-08-16 12:11:31 +03:00
std : : uniform_real_distribution < Floating > distribution ( min , max ) ;
2019-08-16 12:19:11 +03:00
pthread_mutex_lock ( & mutex ) ;
Floating f = distribution ( rng ) ;
pthread_mutex_unlock ( & mutex ) ;
return f ;
2019-08-16 12:11:31 +03:00
}
2013-11-15 15:58:53 +04:00
/**
* Splits a string , using the given delimiter
*
* @ param st string to split
* @ param delim delimiter character
* @ param clean_empty true to clean empty split parts .
* Example for st " a::b:c "
* clean_empty true will return [ " a " , " b " , " c " ]
* clean_empty fase will return [ " a " , " " , " b " , " c " ]
*
* @ return a vector containing the resulting substrings
*/
2019-07-01 18:52:47 +03:00
template < class T >
void split ( const std : : string & st , char delim , std : : vector < T > & parts )
{
std : : string part ;
std : : stringstream ss ( st ) ;
while ( getline ( ss , part , delim ) )
{
if ( part . empty ( ) )
{
continue ;
}
std : : istringstream iss ( part ) ;
T part_t ;
iss > > part_t ;
if ( iss . fail ( ) )
{
continue ;
}
parts . push_back ( part_t ) ;
}
}
std : : vector < std : : string > split ( const std : : string & st , char delim ,
2019-09-03 17:31:51 +03:00
bool clean_empty = true ) ;
2014-09-09 20:13:52 +04:00
/**
2014-10-10 18:53:57 +04:00
* Splits a string , using the given delimiter
*
* @ param st string to split
* @ param delim delimiter character
* @ param result where the result will be saved
*/
template < class T >
2017-01-03 22:03:03 +03:00
void split_unique ( const std : : string & st , char delim , std : : set < T > & result )
2014-10-10 18:53:57 +04:00
{
T elem ;
std : : vector < std : : string > : : const_iterator it ;
2017-01-03 22:03:03 +03:00
std : : vector < std : : string > strings = split ( st , delim , true ) ;
2014-10-10 18:53:57 +04:00
for ( it = strings . begin ( ) ; it ! = strings . end ( ) ; it + + )
{
std : : istringstream iss ( * it ) ;
iss > > elem ;
if ( iss . fail ( ) )
{
continue ;
}
result . insert ( elem ) ;
}
}
2017-01-03 22:03:03 +03:00
/**
* Explicit specialization for strings
*/
template < >
void split_unique ( const std : : string & st , char delim ,
std : : set < std : : string > & result ) ;
2014-10-10 18:53:57 +04:00
/**
* Joins the given element with the delimiter
2014-09-09 20:13:52 +04:00
*
2014-10-10 18:53:57 +04:00
* @ param first iterator
* @ param last iterator
2014-09-09 20:13:52 +04:00
* @ param delim delimiter character
* @ return the joined strings
*/
2014-10-10 18:53:57 +04:00
template < class Iterator >
std : : string join ( Iterator first , Iterator last , char delim )
{
std : : ostringstream oss ;
2019-09-03 17:31:51 +03:00
for ( Iterator it = first ; it ! = last ; it + + )
2014-10-10 18:53:57 +04:00
{
if ( it ! = first )
{
oss < < delim ;
}
oss < < * it ;
}
return oss . str ( ) ;
}
2014-12-10 19:28:52 +03:00
2016-03-10 18:28:33 +03:00
/**
* Joins the given element with the delimiter
*
* @ param values set of values
* @ param delim delimiter character
* @ return the joined strings
*/
template < class T >
2020-03-04 18:05:57 +03:00
std : : string join ( const std : : set < T > & values , char delim )
2016-03-10 18:28:33 +03:00
{
return join ( values . begin ( ) , values . end ( ) , delim ) ;
}
2014-11-06 19:41:20 +03:00
/**
* Creates a string from the given float , using fixed notation . If the
* number has any decimals , they will be truncated to 2.
*
* @ param num
* @ return
*/
std : : string float_to_str ( const float & num ) ;
2014-12-28 12:40:58 +03:00
2015-12-01 18:09:31 +03:00
/**
* Returns a scaped version of a value in the from " <op><val><cl> "
* @ param v the value to be escaped
* @ param op the opening escape string
* @ param cl the closing escape string
*/
template < typename ValueType > inline
std : : string escape ( const ValueType & v , const char * op , const char * cl )
{
std : : ostringstream oss ;
oss < < op < < v < < cl ;
return oss . str ( ) ;
}
template < typename ValueType > inline
std : : string escape_xml ( const ValueType & v )
{
return escape ( v , " <![CDATA[ " , " ]]> " ) ;
}
template < typename ValueType > inline
std : : string escape_xml_attr ( const ValueType & v )
{
return escape ( v , " ' " , " ' " ) ;
}
2019-01-30 02:10:18 +03:00
void escape_json ( const std : : string & str , std : : ostringstream & s ) ;
void escape_token ( const std : : string & str , std : : ostringstream & s ) ;
2014-12-28 12:40:58 +03:00
/**
* Checks if a strings matches a regular expression
*
* @ param pattern PCRE extended pattern
* @ param subject the string to test
* @ return 0 on match , another value otherwise
*/
int regex_match ( const char * pattern , const char * subject ) ;
2015-11-20 17:44:37 +03:00
/**
* Trim an string using the isspace function
* @ param the string
* @ return trimed string
*/
std : : string trim ( const std : : string & str ) ;
2016-01-20 14:03:19 +03:00
/**
* Returns a copy of st with the all occurrences of " find " substituted
* for " replacement "
* @ param st string input
2016-01-30 15:55:13 +03:00
* @ param sfind string to search for
2016-01-20 14:03:19 +03:00
* @ param replacement string to replace occurrences with
* @ return a string copy
*/
2016-01-30 15:55:13 +03:00
std : : string gsub ( const std : : string & st , const std : : string & sfind ,
const std : : string & replacement ) ;
2016-03-10 18:28:33 +03:00
template < class T >
2019-01-30 02:10:18 +03:00
std : : set < T > set_intersection ( const std : : set < T > & first , const std : : set < T >
& second )
2016-03-10 18:28:33 +03:00
{
std : : set < T > output ;
std : : set_intersection (
first . begin ( ) , first . end ( ) , second . begin ( ) , second . end ( ) ,
std : : inserter ( output , output . begin ( ) ) ) ;
return output ;
}
2016-04-05 13:47:21 +03:00
2019-09-03 17:31:51 +03:00
} // namespace one_util
2013-02-04 21:48:05 +04:00
2013-02-12 15:15:09 +04:00
# endif /* _NEBULA_UTIL_H_ */