|
xorp
|
00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- 00002 // vim:set sts=4 ts=8: 00003 00004 // Copyright (c) 2001-2011 XORP, Inc and Others 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU Lesser General Public License, Version 00008 // 2.1, June 1999 as published by the Free Software Foundation. 00009 // Redistribution and/or modification of this program under the terms of 00010 // any other version of the GNU Lesser General Public License is not 00011 // permitted. 00012 // 00013 // This program is distributed in the hope that it will be useful, but 00014 // WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details, 00016 // see the GNU Lesser General Public License, Version 2.1, a copy of 00017 // which can be found in the XORP LICENSE.lgpl file. 00018 // 00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA; 00020 // http://xorp.net 00021 00022 #ifndef __LIBXORP_UTILS_HH__ 00023 #define __LIBXORP_UTILS_HH__ 00024 00025 00026 #include "utility.h" 00027 00028 // 00029 // Set of utilities 00030 // 00031 00032 #define PATH_CURDIR "." 00033 #define PATH_PARENT ".." 00034 00035 #define NT_PATH_DELIMITER_CHAR '\\' 00036 #define NT_PATH_DELIMITER_STRING "\\" 00037 #define NT_PATH_ENV_DELIMITER_CHAR ';' 00038 #define NT_PATH_ENV_DELIMITER_STRING ";" 00039 #define NT_PATH_DRIVE_DELIMITER_CH ':' 00040 #define NT_EXECUTABLE_SUFFIX ".exe" 00041 00042 // NT specific 00043 #define NT_PATH_UNC_PREFIX "\\\\" 00044 #define NT_PATH_DRIVE_SUFFIX ":" 00045 00046 #define UNIX_PATH_DELIMITER_CHAR '/' 00047 #define UNIX_PATH_DELIMITER_STRING "/" 00048 #define UNIX_PATH_ENV_DELIMITER_CHAR ':' 00049 #define UNIX_PATH_ENV_DELIMITER_STRING ":" 00050 #define UNIX_EXECUTABLE_SUFFIX "" 00051 00052 #ifdef HOST_OS_WINDOWS 00053 #define PATH_DELIMITER_CHAR NT_PATH_DELIMITER_CHAR 00054 #define PATH_DELIMITER_STRING NT_PATH_DELIMITER_STRING 00055 #define PATH_ENV_DELIMITER_CHAR NT_PATH_ENV_DELIMITER_CHAR 00056 #define PATH_ENV_DELIMITER_STRING NT_PATH_ENV_DELIMITER_STRING 00057 #define EXECUTABLE_SUFFIX NT_EXECUTABLE_SUFFIX 00058 #else // ! HOST_OS_WINDOWS 00059 #define PATH_DELIMITER_CHAR UNIX_PATH_DELIMITER_CHAR 00060 #define PATH_DELIMITER_STRING UNIX_PATH_DELIMITER_STRING 00061 #define PATH_ENV_DELIMITER_CHAR UNIX_PATH_ENV_DELIMITER_CHAR 00062 #define PATH_ENV_DELIMITER_STRING UNIX_PATH_ENV_DELIMITER_STRING 00063 #define EXECUTABLE_SUFFIX UNIX_EXECUTABLE_SUFFIX 00064 #endif // ! HOST_OS_WINDOWS 00065 00066 00073 inline string 00074 unix_path_to_native(const string& unixpath) 00075 { 00076 #ifdef HOST_OS_WINDOWS 00077 string nativepath = unixpath; 00078 string::size_type n = 0; 00079 while (string::npos != (n = nativepath.find(UNIX_PATH_DELIMITER_CHAR, n))) { 00080 nativepath[n] = NT_PATH_DELIMITER_CHAR; 00081 } 00082 return (nativepath); 00083 #else // ! HOST_OS_WINDOWS 00084 return string(unixpath); 00085 #endif // ! HOST_OS_WINDOWS 00086 } 00087 00097 inline bool 00098 is_absolute_path(const string& path, bool homeok = false) 00099 { 00100 if (path.empty()) 00101 return false; 00102 00103 #ifdef HOST_OS_WINDOWS 00104 if ((path.find(NT_PATH_UNC_PREFIX) == 0) || 00105 ((path.size() >= 2) && isalpha(path[0]) && path[1] == ':')) 00106 return true; 00107 return false; 00108 UNUSED(homeok); 00109 #else // ! HOST_OS_WINDOWS 00110 if (path[0] == '/') 00111 return true; 00112 if (homeok && path[0] == '~') 00113 return true; 00114 return false; 00115 #endif // ! HOST_OS_WINDOWS 00116 } 00117 00126 list<string> split(const string& s, char sep); 00127 00134 string strip_empty_spaces(const string& s); 00135 00142 bool has_empty_space(const string& s); 00143 00149 const char* xorp_basename(const char* argv0); 00150 00156 template<class T> void 00157 delete_pointers_list(list<T *>& delete_list) 00158 { 00159 list<T *> tmp_list; 00160 00161 // Swap the elements, so the original container never contains 00162 // entries that point to deleted elements. 00163 swap(tmp_list, delete_list); 00164 00165 for (typename list<T *>::iterator iter = tmp_list.begin(); 00166 iter != tmp_list.end(); 00167 ++iter) { 00168 T *elem = (*iter); 00169 delete elem; 00170 } 00171 tmp_list.clear(); 00172 } 00173 00179 template<class T> void 00180 delete_pointers_vector(vector<T *>& delete_vector) 00181 { 00182 vector<T *> tmp_vector; 00183 // Swap the elements, so the original container never contains 00184 // entries that point to deleted elements. 00185 swap(tmp_vector, delete_vector); 00186 00187 for (typename vector<T *>::iterator iter = tmp_vector.begin(); 00188 iter != tmp_vector.end(); 00189 ++iter) { 00190 T *elem = (*iter); 00191 delete elem; 00192 } 00193 tmp_vector.clear(); 00194 } 00195 00235 FILE* xorp_make_temporary_file(const string& tmp_dir, 00236 const string& filename_template, 00237 string& final_filename, 00238 string& errmsg); 00239 00240 #ifdef HOST_OS_WINDOWS 00241 00262 void win_quote_args(const list<string>& args, string& cmdline); 00263 #endif // HOST_OS_WINDOWS 00264 00279 inline uint32_t 00280 xorp_bit_count_uint32(uint32_t x) 00281 { 00282 // 00283 // 32-bit recursive reduction using SWAR... 00284 // but first step is mapping 2-bit values 00285 // into sum of 2 1-bit values in sneaky way. 00286 // 00287 x -= ((x >> 1) & 0x55555555); 00288 x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); 00289 x = (((x >> 4) + x) & 0x0f0f0f0f); 00290 x += (x >> 8); 00291 x += (x >> 16); 00292 x &= 0x0000003f; 00293 00294 return (x); 00295 } 00296 00306 inline uint32_t 00307 xorp_leading_zero_count_uint32(uint32_t x) 00308 { 00309 x |= (x >> 1); 00310 x |= (x >> 2); 00311 x |= (x >> 4); 00312 x |= (x >> 8); 00313 x |= (x >> 16); 00314 00315 return (32 - xorp_bit_count_uint32(x)); 00316 } 00317 00337 template <typename A> 00338 class AlignData { 00339 public: 00345 AlignData(const vector<uint8_t>& buffer) { 00346 if (_data_is_copied) { 00347 _data = malloc(sizeof(uint8_t) * buffer.size()); 00348 memcpy(_data, &buffer[0], sizeof(uint8_t) * buffer.size()); 00349 _const_data = _data; 00350 } else { 00351 _data = NULL; 00352 _const_data = &buffer[0]; 00353 } 00354 _payload = reinterpret_cast<const A*>(_const_data); 00355 } 00356 00360 ~AlignData() { 00361 if (_data != NULL) 00362 free(_data); 00363 } 00364 00370 const A* payload() const { return (_payload); } 00371 00383 const A* payload_by_offset(size_t offset) const { 00384 const void* offset_data; 00385 offset_data = reinterpret_cast<const uint8_t*>(_const_data) + offset; 00386 return (reinterpret_cast<const A*>(offset_data)); 00387 } 00388 00389 private: 00390 // Damn..code assumes data is not coppied, see: 00391 // NetlinkSocket::force_recvmsg_flgs 00392 // Will just have to assume that alignment is OK till we can clean this up. --Ben 00393 static const bool _data_is_copied = false; 00394 00395 void* _data; 00396 const void* _const_data; 00397 const A* _payload; 00398 }; 00399 00400 #endif // __LIBXORP_UTILS_HH__