update to new tars-version

This commit is contained in:
ruanshudong 2020-03-15 17:40:18 +08:00
parent b868046b6b
commit 22b483e618
34 changed files with 2175 additions and 1244 deletions

View File

@ -5,9 +5,9 @@ project(tars2node)
set(CMAKE_VERBOSE_MAKEFILE off)
# version
set(TARS_VERSION "1.1.0")
set(TARS_VERSION "1.2.0")
set(PARSER_VERSION "${TARS_VERSION}")
set(GENERATOR_VERSION "20190529")
set(GENERATOR_VERSION "20200315")
# namespace
set(IDL_NAMESPACE Tars)
@ -20,9 +20,39 @@ set(STREAM_MODULE_PATH "@tars/stream")
set(IDL_TYPE "Tars")
set(PROTOCOL_NAME "Tup")
# flag
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O2 -Wall -Wno-sign-compare -Wno-unused-result -static")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O2 -Wall -static")
IF (APPLE)
link_libraries(iconv)
ENDIF(APPLE)
set(PLATFORM)
IF (UNIX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++11 -Wno-deprecated -fno-strict-aliasing -Wno-overloaded-virtual")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-builtin-macro-redefined -D__FILE__='\"$(notdir $(abspath $<))\"'")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -Wall -g")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -Wall -fno-strict-aliasing")
set(PLATFORM "linux")
IF(APPLE)
set(PLATFORM "mac")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
ENDIF(APPLE)
ELSEIF (WIN32)
set(PLATFORM "window")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4101 /wd4244 /wd4996 /wd4091 /wd4503 /wd4819 /wd4200 /wd4800 /wd4267 /wd4834 /wd4267")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj " )
ELSE ()
MESSAGE(STATUS "================ ERROR: This platform is unsupported!!! ================")
ENDIF (UNIX)
#
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PLATFORM}/bin)
# define
add_definitions(-DTARS_VERSION="${TARS_VERSION}")

BIN
build/mac/bin/tars2node Executable file

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -438,7 +438,7 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
sstr << estr.str() << endl;
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + IDL_TYPE + ".js";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, sstr.str());
return true;

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -238,6 +238,6 @@ void CodeGenerator::generateDTS(const ContextPtr &pPtr)
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + IDL_TYPE + ".d.ts";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, sstr.str());
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -544,7 +544,7 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(cPtr->getFileName())) + "Proxy.js";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, sstr.str());
return true;

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -147,6 +147,6 @@ void CodeGenerator::generateDTSProxy(const ContextPtr &cPtr)
sstr << estr.str() << endl;
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(cPtr->getFileName())) + "Proxy.d.ts";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, sstr.str());
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -509,7 +509,7 @@ bool CodeGenerator::generateTSProxy(const ContextPtr &cPtr)
sstr << estr.str() << endl;
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(cPtr->getFileName())) + "Proxy.ts";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, sstr.str());
return true;

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -382,7 +382,7 @@ bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + ".js";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, str.str());
return true;

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -153,6 +153,6 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + ".d.ts";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, str.str());
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -118,6 +118,6 @@ void CodeGenerator::generateJSServerImp(const ContextPtr &cPtr)
str << generateJSServerImp(cPtr, namespaces[i]);
}
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, str.str());
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -397,7 +397,7 @@ bool CodeGenerator::generateTSServer(const ContextPtr &pPtr)
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + ".ts";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, str.str());
return true;

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -105,6 +105,6 @@ void CodeGenerator::generateTSServerImp(const ContextPtr &cPtr)
str << endl;
str << estr.str();
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, str.str());
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -441,6 +441,6 @@ void CodeGenerator::generateTS(const ContextPtr &pPtr)
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + IDL_TYPE + ".ts";
TC_File::makeDirRecursive(_sToPath, 0755);
TC_File::makeDirRecursive(_sToPath);
makeUTF8File(sFileName, sstr.str());
}

View File

@ -121,6 +121,7 @@ int main(int argc, char* argv[])
#undef ALLOW_USE_RESERVED_NAMESPACE_BASE
#undef ALLOW_USE_RESERVED_NAMESPACE_V
g_parse->setTars(option.hasParam("with-tars"));
g_parse->setUseCurrentPath(option.hasParam("relative"));
CodeGenerator generator;

View File

@ -1,199 +0,0 @@
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* 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.
*/
#ifndef __TC_ATOMIC_H
#define __TC_ATOMIC_H
#include <stdint.h>
namespace tars
{
/////////////////////////////////////////////////
/**
* @file tc_atomic.h
* @brief .
*/
__BEGIN_DECLS
#define TARS_LOCK "lock ; "
typedef struct { volatile int counter; } tars_atomic_t;
#define tars_atomic_read(v) ((v)->counter)
#define tars_atomic_set(v,i) (((v)->counter) = (i))
__END_DECLS
/**
* @brief ,int做原子操作
*/
class TC_Atomic
{
public:
/**
*
*/
typedef int atomic_type;
/**
* @brief ,0
*/
TC_Atomic(atomic_type at = 0)
{
set(at);
}
TC_Atomic& operator++()
{
inc();
return *this;
}
TC_Atomic& operator--()
{
dec();
return *this;
}
operator atomic_type() const
{
return get();
}
TC_Atomic& operator+=(atomic_type n)
{
add(n);
return *this;
}
TC_Atomic& operator-=(atomic_type n)
{
sub(n);
return *this;
}
TC_Atomic& operator=(atomic_type n)
{
set(n);
return *this;
}
/**
* @brief
*
* @return int
*/
atomic_type get() const { return _value.counter; }
/**
* @brief
* @param i
*
* @return int
*/
atomic_type add(atomic_type i) { return add_and_return(i); }
/**
* @brief
* @param i
*
* @return int
*/
atomic_type sub(atomic_type i) { return add_and_return(-i); }
/**
* @brief 1
*
* @return int
*/
atomic_type inc() { return add(1); }
/**
* @brief 1
*/
atomic_type dec() { return sub(1); }
/**
* @brief 1
*
* @return void
*/
void inc_fast()
{
__asm__ __volatile__(
TARS_LOCK "incl %0"
:"=m" (_value.counter)
:"m" (_value.counter));
}
/**
* @brief 1
* Atomically decrements @_value by 1 and returns true if the
* result is 0, or false for all other
*/
bool dec_and_test()
{
unsigned char c;
__asm__ __volatile__(
TARS_LOCK "decl %0; sete %1"
:"=m" (_value.counter), "=qm" (c)
:"m" (_value.counter) : "memory");
return c != 0;
}
/**
* @brief
*/
atomic_type set(atomic_type i)
{
_value.counter = i;
return i;
}
protected:
/**
* @brief
*/
int add_and_return(int i)
{
/* Modern 486+ processor */
int __i = i;
__asm__ __volatile__(
TARS_LOCK "xaddl %0, %1;"
:"=r"(i)
:"m"(_value.counter), "0"(i));
return i + __i;
}
protected:
/**
*
*/
tars_atomic_t _value;
};
}
#endif

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -17,17 +17,13 @@
#ifndef __TC_AUTOPTR_H
#define __TC_AUTOPTR_H
#include "util/tc_atomic.h"
#include "util/tc_ex.h"
// #include "util/tc_atomic.h"
#include <atomic>
#include <typeinfo>
namespace tars
{
///////////////////////////////////////////////////////
/**
* @file tc_autoptr.h
* @brief (, ).
*/
//////////////////////////////////////////////////////
/**
* @brief
@ -35,7 +31,7 @@ namespace tars
struct TC_AutoPtrNull_Exception : public TC_Exception
{
TC_AutoPtrNull_Exception(const string &buffer) : TC_Exception(buffer){};
~TC_AutoPtrNull_Exception() throw(){};
~TC_AutoPtrNull_Exception() {};
};
/**
@ -43,22 +39,17 @@ struct TC_AutoPtrNull_Exception : public TC_Exception
*
*
*
* TC_Atomic实现
*/
template<class T>
class TC_HandleBaseT
class TC_HandleBase
{
public:
/** 原子计数类型*/
typedef T atomic_type;
/**
* @brief .
*
* @return TC_HandleBase&
*/
TC_HandleBaseT& operator=(const TC_HandleBaseT&)
TC_HandleBase& operator=(const TC_HandleBase&)
{
return *this;
}
@ -66,14 +57,14 @@ public:
/**
* @brief
*/
void incRef() { _atomic.inc_fast(); }
void incRef() { ++_atomic; }
/**
* @brief , ==0, ,
*/
void decRef()
{
if(_atomic.dec_and_test() && !_bNoDelete)
if((--_atomic) == 0 && !_bNoDelete)
{
_bNoDelete = true;
delete this;
@ -85,7 +76,7 @@ public:
*
* @return int
*/
int getRef() const { return _atomic.get(); }
int getRef() const { return _atomic; }
/**
* @brief .
@ -99,21 +90,21 @@ protected:
/**
* @brief
*/
TC_HandleBaseT() : _atomic(0), _bNoDelete(false)
TC_HandleBase() : _atomic(0), _bNoDelete(false)
{
}
/**
* @brief
*/
TC_HandleBaseT(const TC_HandleBaseT&) : _atomic(0), _bNoDelete(false)
TC_HandleBase(const TC_HandleBase&) : _atomic(0), _bNoDelete(false)
{
}
/**
* @brief
*/
virtual ~TC_HandleBaseT()
virtual ~TC_HandleBase()
{
}
@ -122,7 +113,7 @@ protected:
/**
*
*/
atomic_type _atomic;
std::atomic<int> _atomic;
/**
*
@ -130,34 +121,6 @@ protected:
bool _bNoDelete;
};
template<>
inline void TC_HandleBaseT<int>::incRef()
{
//__sync_fetch_and_add(&_atomic,1);
++_atomic;
}
template<>
inline void TC_HandleBaseT<int>::decRef()
{
//int c = __sync_fetch_and_sub(&_atomic, 1);
//if(c == 1 && !_bNoDelete)
if(--_atomic == 0 && !_bNoDelete)
{
_bNoDelete = true;
delete this;
}
}
template<>
inline int TC_HandleBaseT<int>::getRef() const
{
//return __sync_fetch_and_sub(const_cast<volatile int*>(&_atomic), 0);
return _atomic;
}
typedef TC_HandleBaseT<TC_Atomic> TC_HandleBase;
/**
* @brief .
*
@ -425,7 +388,7 @@ public:
template<typename T> inline void
TC_AutoPtr<T>::throwNullHandleException() const
{
throw TC_AutoPtrNull_Exception("autoptr null handle error");
throw TC_AutoPtrNull_Exception("autoptr null handle error![" + string(typeid(T).name()) +"]");
}
/**
@ -443,14 +406,9 @@ inline bool operator==(const TC_AutoPtr<T>& lhs, const TC_AutoPtr<U>& rhs)
{
T* l = lhs.get();
U* r = rhs.get();
if(l && r)
{
return *l == *r;
}
else
{
return !l && !r;
}
// 改为直接比较指针,而不是比较值
return (l == r);
}
/**
@ -468,14 +426,9 @@ inline bool operator!=(const TC_AutoPtr<T>& lhs, const TC_AutoPtr<U>& rhs)
{
T* l = lhs.get();
U* r = rhs.get();
if(l && r)
{
return *l != *r;
}
else
{
return l || r;
}
// 改为直接比较指针,而不是比较值
return (l != r);
}
/**
@ -495,7 +448,9 @@ inline bool operator<(const TC_AutoPtr<T>& lhs, const TC_AutoPtr<U>& rhs)
U* r = rhs.get();
if(l && r)
{
return *l < *r;
//return *l < *r;
// 改为直接比较指针,而不是比较值
return (l < r);
}
else
{

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -17,13 +17,10 @@
#ifndef __TC_COMMON_H
#define __TC_COMMON_H
#ifndef __USE_XOPEN
#define __USE_XOPEN
#endif
#include "util/tc_platform.h"
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
@ -38,6 +35,7 @@
#include <stdexcept>
#include <algorithm>
#include <map>
#include <unordered_map>
#include <stack>
#include <vector>
@ -68,6 +66,58 @@ class TC_Common
{
public:
static const float _EPSILON_FLOAT;
static const double _EPSILON_DOUBLE;
/**
* @brief sleep
*/
static void sleep(uint32_t sec);
static void msleep(uint32_t ms);
/**
* @brief ,double 6float默认6位精度
*/
static bool equal(double x, double y, double epsilon = _EPSILON_DOUBLE);
static bool equal(double x, double y, float epsilon );
static bool equal(float x, float y, float epsilon = _EPSILON_FLOAT);
static bool equal(float x, float y, double epsilon );
/**
* @brief vector double
*/
static bool equal(const vector<double> & vx, const vector<double>& vy, double epsilon = _EPSILON_DOUBLE);
static bool equal(const vector<double>& vx, const vector<double>& vy, float epsilon );
static bool equal(const vector<float>& vx, const vector<float> & vy, float epsilon = _EPSILON_FLOAT);
static bool equal(const vector<float>& vx, const vector<float>& vy, double epsilon );
/**
* @brief map中如果key或者value为double/float字段
*/
template<typename V, typename E>
static bool equal(const V& x, const V& y, E eps);
template<typename K, typename V, typename D, typename A , typename E=double>
static bool equal(const map<K, V, D, A>& mx , const map<K, V, D, A>& my, E epsilon = _EPSILON_DOUBLE);
/**
* , ()
* @param s
* @param c
* @param n
* @return
*/
static string outfill(const string& s, char pad = ' ', size_t n = 50, bool rightPad=true)
{
if(n <= s.length())
return s;
if(rightPad)
return (s + string((n - s.length()), pad));
return (string((n - s.length()), pad) + s);
}
/**
* @brief .
*
@ -149,6 +199,15 @@ public:
*/
static int strgmt2tm(const string &sString, struct tm &stTm);
/**
* @brief .
*
* @param sString
* @param sFormat
* @return time_t
*/
static time_t str2time(const string &sString, const string &sFormat = "%Y%m%d%H%M%S");
/**
* @brief .
*
@ -167,6 +226,29 @@ public:
*/
static string tm2str(const time_t &t, const string &sFormat = "%Y%m%d%H%M%S");
/**
* @brief tm.
*
* @param t
*/
static void tm2time(const time_t &t, struct tm &tt);
/**
* @brief time_t转换成tm(localtime_r, !!!)
*
* @param t
* @param sFormat
* @return string
*/
static void tm2tm(const time_t &t, struct tm &stTm);
/**
* @brief
*
* @param t
*/
static int gettimeofday(struct timeval &tv);
/**
* @brief
* @param sFormat
@ -266,7 +348,12 @@ public:
* @return
*/
template<typename T>
static string tostr(const T &t);
inline static string tostr(const T &t)
{
ostringstream sBuffer;
sBuffer << t;
return sBuffer.str();
}
/**
* @brief vector转换成string.
@ -295,6 +382,15 @@ public:
template<typename K, typename V, typename D, typename A>
static string tostr(const multimap<K, V, D, A> &t);
/**
* @brief map输出为字符串.
*
* @param map<K, V, D, A> map对象
* @return string
*/
template<typename K, typename V, typename D, typename P, typename A>
static string tostr(const unordered_map<K, V, D, P, A> &t);
/**
* @brief pair map等关系容器可以直接用tostr来输出
* @param pair<F, S> pair对象
@ -400,6 +496,8 @@ public:
*/
static bool isPrimeNumber(size_t n);
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
/**
* @brief daemon
*/
@ -410,6 +508,15 @@ public:
*/
static void ignorePipe();
/**
* @brief 16
* @param p
* @param len
*/
static void getRandomHexChars(char* p, unsigned int len);
#endif
/**
* @brief string类型转成一个字节 .
*
@ -427,11 +534,11 @@ public:
static size_t toSize(const string &s, size_t iDefaultSize);
/**
* @brief 16
* @param p
* @param len
* @brief .
* @return string
*/
static void getRandomHexChars(char* p, unsigned int len);
static string getHostName();
};
namespace p
@ -475,10 +582,14 @@ namespace p
{
short operator()(const string &sStr)
{
if(!sStr.empty())
{
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return (short) ::strtol(sStr.c_str(), NULL, 16);
}
else {
return atoi(sStr.c_str());
}
}
return 0;
}
};
@ -488,9 +599,13 @@ namespace p
{
unsigned short operator()(const string &sStr)
{
if(!sStr.empty())
{
return strtoul(sStr.c_str(), NULL, 10);
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return (unsigned short) ::strtoul(sStr.c_str(), NULL, 16);
}
else {
return (unsigned short) strtoul(sStr.c_str(), NULL, 10);
}
}
return 0;
}
@ -501,10 +616,14 @@ namespace p
{
int operator()(const string &sStr)
{
if(!sStr.empty())
{
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return ::strtol(sStr.c_str(), NULL, 16);
}
else {
return atoi(sStr.c_str());
}
}
return 0;
}
};
@ -514,10 +633,14 @@ namespace p
{
unsigned int operator()(const string &sStr)
{
if(!sStr.empty())
{
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return ::strtoul(sStr.c_str(), NULL, 16);
}
else {
return strtoul(sStr.c_str(), NULL, 10);
}
}
return 0;
}
};
@ -527,10 +650,14 @@ namespace p
{
long operator()(const string &sStr)
{
if(!sStr.empty())
{
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return ::strtol(sStr.c_str(), NULL, 16);
}
else {
return atol(sStr.c_str());
}
}
return 0;
}
};
@ -540,10 +667,14 @@ namespace p
{
long long operator()(const string &sStr)
{
if(!sStr.empty())
{
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return ::strtoll(sStr.c_str(), NULL, 16);
}
else {
return atoll(sStr.c_str());
}
}
return 0;
}
};
@ -553,10 +684,14 @@ namespace p
{
unsigned long operator()(const string &sStr)
{
if(!sStr.empty())
{
if (!sStr.empty()) {
if (sStr.find("0x") == 0) {
return ::strtoul(sStr.c_str(), NULL, 16);
}
else {
return strtoul(sStr.c_str(), NULL, 10);
}
}
return 0;
}
};
@ -568,7 +703,7 @@ namespace p
{
if(!sStr.empty())
{
return atof(sStr.c_str());
return (float) atof(sStr.c_str());
}
return 0;
}
@ -637,7 +772,6 @@ T TC_Common::strto(const string &sStr, const string &sDefault)
return strto<T>(s);
}
template<typename T>
vector<T> TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmpty)
{
@ -646,42 +780,32 @@ vector<T> TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmp
string::size_type pos = 0;
string::size_type pos1 = 0;
while(true)
{
while (true) {
string s;
pos1 = sStr.find_first_of(sSep, pos);
if(pos1 == string::npos)
{
if(pos + 1 <= sStr.length())
{
if (pos1 == string::npos) {
if (pos + 1 <= sStr.length()) {
s = sStr.substr(pos);
}
}
else if(pos1 == pos)
{
else if (pos1 == pos) {
s = "";
}
else
{
else {
s = sStr.substr(pos, pos1 - pos);
pos = pos1;
}
if(withEmpty)
{
vt.push_back(strto<T>(s));
if (withEmpty) {
vt.push_back(std::move(strto<T>(s)));
}
else
{
if(!s.empty())
{
T tmp = strto<T>(s);
vt.push_back(tmp);
else {
if (!s.empty()) {
vt.push_back(std::move(strto<T>(s)));
}
}
if(pos1 == string::npos)
{
if (pos1 == string::npos) {
break;
}
@ -690,13 +814,48 @@ vector<T> TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmp
return vt;
}
template<typename T>
string TC_Common::tostr(const T &t)
{
ostringstream sBuffer;
sBuffer << t;
return sBuffer.str();
}
template<>
string TC_Common::tostr<bool>(const bool &t);
template<>
string TC_Common::tostr<char>(const char &t);
template<>
string TC_Common::tostr<unsigned char>(const unsigned char &t);
template<>
string TC_Common::tostr<short>(const short &t);
template<>
string TC_Common::tostr<unsigned short>(const unsigned short &t);
template<>
string TC_Common::tostr<int>(const int &t);
template<>
string TC_Common::tostr<unsigned int>(const unsigned int &t);
template<>
string TC_Common::tostr<long>(const long &t);
template<>
string TC_Common::tostr<long long>(const long long &t);
template<>
string TC_Common::tostr<unsigned long>(const unsigned long &t);
template<>
string TC_Common::tostr<float>(const float &t);
template<>
string TC_Common::tostr<double>(const double &t);
template<>
string TC_Common::tostr<long double>(const long double &t);
template<>
string TC_Common::tostr<std::string>(const std::string &t);
template<typename T>
string TC_Common::tostr(const vector<T> &t)
@ -744,6 +903,22 @@ string TC_Common::tostr(const multimap<K, V, D, A> &t)
return sBuffer;
}
template<typename K, typename V, typename D, typename P, typename A>
string TC_Common::tostr(const unordered_map<K, V, D, P, A> &t)
{
string sBuffer;
typename unordered_map<K, V, D, P, A>::const_iterator it = t.begin();
while (it != t.end()) {
sBuffer += " [";
sBuffer += tostr(it->first);
sBuffer += "]=[";
sBuffer += tostr(it->second);
sBuffer += "] ";
++it;
}
return sBuffer;
}
template<typename F, typename S>
string TC_Common::tostr(const pair<F, S> &itPair)
{
@ -780,6 +955,63 @@ string TC_Common::tostr(InputIter iFirst, InputIter iLast, const string &sSep)
return sBuffer;
}
template<typename V,typename E>
bool TC_Common::equal(const V& x, const V& y,E eps)
{
return x == y;
}
template<typename K, typename V, typename D, typename A, typename E>
bool TC_Common::equal(const map<K, V, D, A>& mx, const map<K, V, D, A>& my, E epsilon)
{
auto first1= mx.begin();
auto last1 = mx.end();
auto first2 = my.begin();
auto last2 = my.end();
if (distance(first1, last1) != distance(first2, last2))
{
return false;
}
bool doubleKey = (std::is_same<K, double>::value || std::is_same<K, float>::value);
bool doubleValue = (std::is_same<V, double>::value || std::is_same<V, float>::value);
for (; first2 != last2; ++first1, ++first2)
{
if (doubleKey )
{
if (!TC_Common::equal(first1->first ,first2->first, epsilon) )
{
return false;
}
}
else
{
if (first1->first != first2->first)
{
return false;
}
}
if (doubleValue)
{
if (!TC_Common::equal(first1->second, first2->second, epsilon))
{
return false;
}
}
else
{
if ( first1->second != first2->second)
{
return false;
}
}
}
return true;
}
}
#endif

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -54,17 +54,6 @@ struct TC_Encoder_Exception : public TC_Exception
class TC_Encoder
{
public:
/**
* @brief gbk utf8.
*
* @param sOut buffer
* @param iMaxOutLen buffer最大的长度/sOut的长度
* @param sIn buffer
* @param iInLen buffer长度
* @throws TC_Encoder_Exception
* @return
*/
static void gbk2utf8(char *sOut, int &iMaxOutLen, const char *sIn, int iInLen);
/**
* @brief gbk utf8.
@ -85,17 +74,6 @@ public:
*/
static void gbk2utf8(const string &sIn, vector<string> &vtStr);
/**
* @brief utf8 gbk.
*
* @param sOut buffer
* @param iMaxOutLen buffer最大的长度/sOut的长度
* @param sIn buffer
* @param iInLen buffer长度
* @throws TC_Encoder_Exception
* @return
*/
static void utf82gbk(char *sOut, int &iMaxOutLen, const char *sIn, int iInLen);
/**
* @brief utf8 gbk.
@ -133,6 +111,20 @@ public:
* @return str
*/
static string transFrom(const string& str, char f = '\n', char t = '\r', char u = '\0');
protected:
/**
* @brief utf8 gbk.
*
* @param sOut buffer
* @param iMaxOutLen buffer最大的长度/sOut的长度
* @param sIn buffer
* @param iInLen buffer长度
* @throws TC_Encoder_Exception
* @return
*/
static void utf82gbk(char *sOut, int &iMaxOutLen, const char *sIn, int iInLen);
};
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -18,6 +18,8 @@
#define __TC_EX_H
#include <stdexcept>
#include <string>
using namespace std;
namespace tars
@ -36,9 +38,8 @@ class TC_Exception : public exception
{
public:
/**
* @brief errno的构造函数
*
*
* @brief errno的构造函数
* @param err, (linux版本, errno获取错误码, windows版本, GetLastError())
*
* @param buffer
*/
@ -50,7 +51,7 @@ public:
*
*
* @param buffer
* @param err , strerror获取错误信息
* @param errno :errno, windows版本 :GetLastError()
*/
TC_Exception(const string &buffer, int err);
@ -73,22 +74,46 @@ public:
*/
int getErrCode() { return _code; }
/**
* @brief (linux是errno, windows是GetLastError())
*
* @return 0
*/
static string parseError(int err);
/**
* @brief (linux是errno, windows是GetLastError)
*
* @return 0
*/
static int getSystemCode();
private:
void getBacktrace();
private:
/**
*
*/
string _buffer;
/**
*
*/
int _code;
/**
*
*/
string _buffer;
};
//为了避免windows平台GetLastError()获取不对的问题, 因为抛异常, throw TC_Exception("xxxx", TC_Exception::getSystemCode())时
//回调用系统函数分配内存, 导致错误码被改写, 因此专门定义宏来抛出异常
//先获取到错误码, 再throw
#define TARS_THROW_EXCEPTION(EX_CLASS, buffer) throw EX_CLASS(buffer)
#define TARS_THROW_EXCEPTION_SYSCODE(EX_CLASS, buffer) \
{ \
int ret = TC_Exception::getSystemCode(); \
throw EX_CLASS(buffer, ret); \
}
}
#endif

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -17,16 +17,25 @@
#ifndef __TC_FILE_H_
#define __TC_FILE_H_
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fnmatch.h>
#include "util/tc_platform.h"
#include "util/tc_port.h"
#include <iostream>
#include <fstream>
#include "util/tc_ex.h"
#include "util/tc_common.h"
#if TARGET_PLATFORM_LINUX ||TARGET_PLATFORM_IOS
#define FILE_SEP "/"
#else
#define FILE_SEP "\\"
#endif
namespace tars
{
/////////////////////////////////////////////////
@ -103,37 +112,18 @@ public:
* @brief , , .
*
* @param sFullPath
* @param iFlag , S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP| S_IXGRP | S_IROTH | S_IXOTH
* @return bool true- false-
*/
static bool makeDir(const string &sDirectoryPath, mode_t iFlag = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
static bool makeDir(const string &sDirectoryPath);
/**
*@brief , , .
*
* @param sFullPath
* @param iFlag , S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
* @return true-false-
*/
static bool makeDirRecursive(const string &sDirectoryPath, mode_t iFlag = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
/**
* @brief .
*
* @param sFullFileName
* @param canExecutable true表示可执行, false代表不可之行
* @return 0,
*/
static int setExecutable(const string &sFullFileName, bool canExecutable);
/**
* @brief .
*
* @param sFullFileName
* @return true-, false-
*/
static bool canExecutable(const string &sFullFileName);
static bool makeDirRecursive(const string &sDirectoryPath);
/**
* @brief .
@ -144,6 +134,15 @@ public:
*/
static int removeFile(const string &sFullFileName, bool bRecursive);
/**
* @brief .
*
* @param sSrcFullFileName
* @param sDstFullFileName
* @return 0-errno查看失败的原因
*/
static int renameFile(const string &sSrcFullFileName, const string &sDstFullFileName);
/**
* @brief string
* ,
@ -151,13 +150,7 @@ public:
* @return
*/
static string load2str(const string &sFullFileName);
/**
* @brief vector<char>
* ,
* @param sFullFileName
*/
static void load2str(const string &sFullFileName, vector<char> &buffer);
static bool load2str(const string &sFullFileName, vector<char> &data);
/**
* @brief .
@ -178,6 +171,23 @@ public:
*/
static int save2file(const string &sFullFileName, const char *sFileData, size_t length);
/**
* @brief .
*
* @param sFullFileName
* @param canExecutable true表示可执行, false代表不可之行
* @return 0,
*/
static int setExecutable(const string &sFullFileName, bool canExecutable);
/**
* @brief .
*
* @param sFullFileName
* @return true-, false-
*/
static bool canExecutable(const string &sFullFileName);
/**
* @brief .
*
@ -246,6 +256,7 @@ public:
*/
static string extractUrlFilePath(const string &sUrl);
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
/**
* @brief .
*
@ -263,6 +274,7 @@ public:
* @return
*/
static size_t scanDir(const string &sFilePath, vector<string> &vtMatchFiles, FILE_SELECT f = NULL, int iMaxSize = 0);
#endif
/**
* @brief , .
@ -283,7 +295,15 @@ public:
* @return
*/
static void copyFile(const string &sExistFile, const string &sNewFile, bool bRemove = false);
};
/**
* @brief windows盘符开头.
* @return
*/
static bool startWindowsPanfu(const string & sPath);
private:
static bool isPanfu(const string & sPath);
};
}
#endif // TC_FILE_H

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -54,13 +54,21 @@ public:
*/
void decode(int argc, char *argv[]);
/**
* @brief (decode的区别是: , argv[0])
*
* @param command
*
*/
void decode(const char *command);
/**
* @brief --.
*
* @param sName
* @return bool truefalse
*/
bool hasParam(const string &sName);
bool hasParam(const string &sName) const;
/**
* @brief -- ,
@ -68,7 +76,21 @@ public:
* @param sName
* @return string
*/
string getValue(const string &sName);
string getValue(const string &sName) const;
/**
* @brief --.
*
* @return map<string,string> map类型的标识和参数值的对应关系
*/
const map<string, string>& getMulti() const;
/**
* @brief , abc,
* defvector中
* @return vector<string> vector
*/
const vector<string>& getSingle() const;
/**
* @brief --.

View File

@ -0,0 +1,46 @@
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* 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.
*/
#ifndef _TC_PLATFORM_H_
#define _TC_PLATFORM_H_
#if defined _WIN32 || defined _WIN64
#define TARGET_PLATFORM_WINDOWS 1
#elif __APPLE__
#define TARGET_PLATFORM_IOS 1
#elif defined ANDROID
#define TARGET_PLATFORM_ANDROID 1
#define TARGET_PLATFORM_LINUX 1
#elif __linux__
#define TARGET_PLATFORM_LINUX 1
#else
#error Unsupported platform.
#endif
#if TARGET_PLATFORM_WINDOWS
#include <winsock2.h>
#include <windows.h>
#else
#include <unistd.h>
#endif
#endif

View File

@ -0,0 +1,69 @@
#ifndef __TC_PORT_H
#define __TC_PORT_H
#include "util/tc_platform.h"
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
#include <unistd.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <sys/types.h>
#else
#include <direct.h>
#include <io.h>
typedef unsigned short mode_t;
#define S_IFREG _S_IFREG //表示为普通文件为了跨平台一律使用S_IFREG
#define S_IFDIR _S_IFDIR //表示为目录为了跨平台一律使用S_IFDIR
#endif
#include <stdio.h>
#include <string>
namespace tars
{
class TC_Port
{
public:
static int strcasecmp(const char *s1, const char *s2);
static int strncasecmp(const char *s1, const char *s2, size_t n);
static void localtime_r(const time_t *clock, struct tm *result);
static void gmtime_r(const time_t *clock, struct tm *result);
static time_t timegm(struct tm *timeptr);
static int gettimeofday(struct timeval &tv);
static int chmod(const char *path, mode_t mode);
static FILE * fopen(const char * path, const char * mode);
#if TARGET_PLATFORM_WINDOWS
typedef struct _stat stat_t;
#else
typedef struct stat stat_t;
#endif
static int lstat(const char * path, stat_t * buf);
static int mkdir(const char *path);
static int rmdir(const char *path);
static int closeSocket(int fd);
static int64_t getpid();
};
}
#endif

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -15,13 +15,103 @@
*/
#include "util/tc_common.h"
#include "util/tc_port.h"
#include <chrono>
#include <thread>
#if TARGET_PLATFORM_WINDOWS
#include <sys/timeb.h>
#pragma comment(lib, "ws2_32.lib")
#include "util/tc_strptime.h"
#endif
// #if TARGET_PLATFORM_WINDOWS || TARGET_PLATFORM_IOS
// #define HOST_NAME_MAX 64
// #endif
#include <signal.h>
#include <sys/time.h>
#include <string.h>
#include <cmath>
namespace tars
{
const float TC_Common::_EPSILON_FLOAT = 0.000001f;
const double TC_Common::_EPSILON_DOUBLE = 0.000001;
void TC_Common::sleep(uint32_t sec)
{
std::this_thread::sleep_for(std::chrono::seconds(sec));
}
void TC_Common::msleep(uint32_t ms)
{
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
bool TC_Common::equal(double x, double y, double epsilon)
{
return fabs(x - y) < epsilon;
}
bool TC_Common::equal(double x, double y, float epsilon)
{
return equal(x ,y,(double)epsilon);
}
bool TC_Common::equal(float x, float y, float epsilon)
{
return fabsf(x - y) < epsilon;
}
bool TC_Common::equal(float x, float y, double epsilon)
{
return equal(x, y, float(epsilon));
}
bool TC_Common::equal(const vector<double>& vx, const vector<double>& vy, double epsilon)
{
if (vx.size() != vy.size())
{
return false;
}
for (size_t i = 0; i < vx.size(); i ++)
{
if (!equal(vx[i],vy[i],epsilon))
{
return false;
}
}
return true;
}
bool TC_Common::equal(const vector<double>& vx, const vector<double>& vy, float epsilon)
{
return equal(vx, vy, double(epsilon));
}
bool TC_Common::equal(const vector<float>& vx, const vector<float>& vy, float epsilon)
{
if (vx.size() != vy.size())
{
return false;
}
for (size_t i = 0; i < vx.size(); i++)
{
if (!equal(vx[i], vy[i], epsilon))
{
return false;
}
}
return true;
}
bool TC_Common::equal(const vector<float>& vx, const vector<float>& vy, double epsilon)
{
return equal(vx, vy, float(epsilon));
}
template <>
string TC_Common::tostr<bool>(const bool &t)
{
@ -108,9 +198,8 @@ string TC_Common::tostr<unsigned long>(const unsigned long &t)
template <>
string TC_Common::tostr<float>(const float &t)
{
char buf[32];
snprintf(buf, 32, "%.5f", t);
string s(buf);
//C++11 to_string默认保留后面6位小数
string s = std::to_string(t);
//去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
bool bFlag = false;
@ -142,10 +231,8 @@ string TC_Common::tostr<float>(const float &t)
template <>
string TC_Common::tostr<double>(const double &t)
{
char buf[32];
snprintf(buf, 32, "%.5f", t);
string s(buf);
//C++11 to_string默认保留后面6位小数
string s = std::to_string(t);
//去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
bool bFlag = false;
int pos = int(s.size() - 1);
@ -364,12 +451,53 @@ bool TC_Common::isdigit(const string &sInput)
return true;
}
//用于计算时区差异!
class TimezoneHelper
{
public:
TimezoneHelper()
{
struct tm timeinfo;
time_t secs, local_secs, gmt_secs;
time(&secs);
//带时区时间
TC_Port::localtime_r(&secs, &timeinfo);
local_secs = ::mktime(&timeinfo);
//不带时区时间
TC_Port::gmtime_r(&secs, &timeinfo);
gmt_secs = ::mktime(&timeinfo);
timezone_diff_secs = local_secs - gmt_secs;
}
static int64_t timezone_diff_secs;
};
int64_t TimezoneHelper::timezone_diff_secs = 0;
int TC_Common::str2tm(const string &sString, const string &sFormat, struct tm &stTm)
{
char *p = strptime(sString.c_str(), sFormat.c_str(), &stTm);
return (p != NULL) ? 0 : -1;
}
time_t TC_Common::str2time(const string &sString, const string &sFormat)
{
struct tm stTm;
if (0 == str2tm(sString, sFormat, stTm))
{
//注意这里没有直接用mktime, mktime会访问时区文件, 会巨慢!
static TimezoneHelper helper;
return TC_Port::timegm(&stTm) - TimezoneHelper::timezone_diff_secs;
}
return 0;
}
int TC_Common::strgmt2tm(const string &sString, struct tm &stTm)
{
return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm);
@ -384,14 +512,39 @@ string TC_Common::tm2str(const struct tm &stTm, const string &sFormat)
return string(sTimeString);
}
int TC_Common::gettimeofday(struct timeval &tv)
{
return TC_Port::gettimeofday(tv);
}
void TC_Common::tm2time(const time_t &t, struct tm &tt)
{
//加快速度, 否则会比较慢, 不用localtime_r(会访问时区文件, 较慢)
static TimezoneHelper helper;
time_t localt = t + TimezoneHelper::timezone_diff_secs;
TC_Port::gmtime_r(&localt, &tt);
}
string TC_Common::tm2str(const time_t &t, const string &sFormat)
{
struct tm tt;
localtime_r(&t, &tt);
tm2time(t, tt);
return tm2str(tt, sFormat);
}
void TC_Common::tm2tm(const time_t &t, struct tm &tt)
{
static TimezoneHelper helper;
time_t localt = t + TimezoneHelper::timezone_diff_secs;
TC_Port::gmtime_r(&localt, &tt);
}
string TC_Common::now2str(const string &sFormat)
{
time_t t = time(NULL);
@ -407,7 +560,8 @@ string TC_Common::now2GMTstr()
string TC_Common::tm2GMTstr(const time_t &t)
{
struct tm tt;
gmtime_r(&t, &tt);
TC_Port::gmtime_r(&t, &tt);
return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT");
}
@ -430,7 +584,7 @@ int64_t TC_Common::now2ms()
{
struct timeval tv;
gettimeofday(&tv, 0);
TC_Common::gettimeofday(tv);
return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000;
}
@ -439,7 +593,7 @@ int64_t TC_Common::now2us()
{
struct timeval tv;
gettimeofday(&tv, 0);
TC_Common::gettimeofday(tv);
return tv.tv_sec * (int64_t)1000000 + tv.tv_usec;
}
@ -480,7 +634,7 @@ string TC_Common::bin2str(const string &sBinData, const string &sSep, size_t lin
int TC_Common::str2bin(const char *psAsciiData, unsigned char *sBinData, int iBinSize)
{
int iAsciiLength = strlen(psAsciiData);
int iAsciiLength = (int)strlen(psAsciiData);
int iRealLength = (iAsciiLength/2 > iBinSize)?iBinSize:(iAsciiLength/2);
for (int i = 0 ; i < iRealLength ; i++)
@ -494,9 +648,9 @@ string TC_Common::str2bin(const string &sString, const string &sSep, size_t line
{
const char *psAsciiData = sString.c_str();
int iAsciiLength = sString.length();
size_t iAsciiLength = sString.length();
string sBinData;
for (int i = 0 ; i < iAsciiLength ; i++)
for (size_t i = 0 ; i < iAsciiLength ; i++)
{
sBinData += x2c(psAsciiData + i);
i++;
@ -634,6 +788,7 @@ bool TC_Common::matchPeriod(const string& s, const vector<string>& pat)
return false;
}
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
void TC_Common::daemon()
{
pid_t pid;
@ -677,6 +832,7 @@ void TC_Common::ignorePipe()
sigemptyset(&sig.sa_mask);
sigaction(SIGPIPE,&sig,NULL);
}
#endif
bool TC_Common::isPrimeNumber(size_t n)
{
@ -735,6 +891,25 @@ size_t TC_Common::toSize(const string &s, size_t iDefaultSize)
return iDefaultSize;
}
string TC_Common::getHostName()
{
string hostName;
char buff[256] = { 0 };
int ret = ::gethostname(buff, sizeof(buff));
if (0 == ret)
{
hostName = string(buff);
}
else
{
// 获取不到host 则直接传空串。
}
return hostName;
}
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
// Generate the randome string, a SHA1-sized random number
void TC_Common::getRandomHexChars(char* p, unsigned int len)
{
@ -753,5 +928,8 @@ void TC_Common::getRandomHexChars(char* p, unsigned int len)
}
#endif
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -13,70 +13,138 @@
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
#include "util/tc_platform.h"
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
#include <iconv.h>
#include <errno.h>
#endif
#include <string.h>
#include "util/tc_encoder.h"
#include <iostream>
namespace tars
{
void TC_Encoder::gbk2utf8(char *sOut, int &iMaxOutLen, const char *sIn, int iInLen)
{
char * pIn = (char*)sIn;
char * pEnd = pIn+iInLen;
char * pOut = sOut;
size_t iLeftLen;
size_t iGbkLen;
iconv_t cd;
#if TARGET_PLATFORM_WINDOWS
#include <windows.h>
if (iInLen > iMaxOutLen)
void TC_Encoder::gbk2utf8(const string &sIn, vector<string> &vtStr)
{
throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iInLen > iMaxOutLen error : ", errno);
}
string sOut;
cd = iconv_open("UTF-8","GBK");
if (cd == (iconv_t)-1)
for(string::size_type pos = 0; pos < sIn.length(); ++pos)
{
throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error : ", errno);
}
iLeftLen = iMaxOutLen;
while(pIn < pEnd)
{
if((unsigned char)(*pIn)==0x80)
{
//注意GBK的0x80转换为UTF-8时为E2 82 AC
*pOut = 0xe2; pOut++; iLeftLen--;
*pOut = 0x82; pOut++; iLeftLen--;
*pOut = 0xac; pOut++; iLeftLen--;
pIn++;
}
else if((unsigned char)(*pIn)<0x80)
if((unsigned char)sIn[pos] < 0x80)
{
//单字节(GBK: 0x00-0x7F)
*pOut = *pIn;
pIn++;pOut++;iLeftLen--;
sOut += sIn[pos];
}
else
{
//双字节
iGbkLen=2;
int iRet=iconv(cd, &pIn, (size_t *)&iGbkLen, (char **)&pOut, (size_t *)&iLeftLen);
if(iRet < 0)
{
*pOut = ' '; //转换不了替换为空格
pIn+=2; pOut++; iLeftLen--;
char pIn[128] = "\0";
strncpy(pIn, sIn.c_str() + pos, 2);
sOut = gbk2utf8(pIn);
++pos;
}
vtStr.push_back(sOut);
}
}
iconv_close(cd);
sOut[iMaxOutLen - iLeftLen] = '\0';
iMaxOutLen = iMaxOutLen - iLeftLen;
std::string TC_Encoder::gbk2utf8(const std::string &strGbk)
{
string outUtf8 = "";
int n = MultiByteToWideChar(CP_ACP, 0, strGbk.c_str(), -1, NULL, 0);
WCHAR *str1 = new WCHAR[n];
MultiByteToWideChar(CP_ACP, 0, strGbk.c_str(), -1,str1, n);
n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
char *str2 = new char[n];
WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
outUtf8 = str2;
delete[]str1;
str1 = NULL;
delete[]str2;
str2 = NULL;
return outUtf8;
}
std::string TC_Encoder::utf82gbk(const std::string &strUtf8)
{
string outGBK = "";
int n = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, NULL, 0);
WCHAR *str1 = new WCHAR[n];
MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, str1, n);
n = WideCharToMultiByte(CP_ACP, 0, str1, -1, NULL, 0, NULL, NULL);
char *str2 = new char[n];
WideCharToMultiByte(CP_ACP, 0, str1, -1, str2, n, NULL, NULL);
outGBK = str2;
delete[] str1;
str1 = NULL;
delete[] str2;
str2 = NULL;
return outGBK;
}
#else
// void TC_Encoder::gbk2utf8(char *sOut, int &iMaxOutLen, const char *sIn, int iInLen)
// {
// char * pIn = (char*)sIn;
// char * pEnd = pIn+iInLen;
// char * pOut = sOut;
// size_t iLeftLen;
// size_t iGbkLen;
// iconv_t cd;
// if (iInLen > iMaxOutLen)
// {
// throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iInLen > iMaxOutLen error : ", errno);
// }
// cd = iconv_open("UTF-8","GBK");
// if (cd == (iconv_t)-1)
// {
// throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error : ", errno);
// }
// iLeftLen = iMaxOutLen;
// while(pIn < pEnd)
// {
// if((unsigned char)(*pIn)==0x80)
// {
// //注意GBK的0x80转换为UTF-8时为E2 82 AC
// *pOut = 0xe2; pOut++; iLeftLen--;
// *pOut = 0x82; pOut++; iLeftLen--;
// *pOut = 0xac; pOut++; iLeftLen--;
// pIn++;
// }
// else if((unsigned char)(*pIn)<0x80)
// {
// //单字节(GBK: 0x00-0x7F)
// *pOut = *pIn;
// pIn++;pOut++;iLeftLen--;
// }
// else
// {
// //双字节
// iGbkLen=2;
// int iRet=iconv(cd, &pIn, (size_t *)&iGbkLen, (char **)&pOut, (size_t *)&iLeftLen);
// if(iRet < 0)
// {
// *pOut = ' '; //转换不了替换为空格
// pIn+=2; pOut++; iLeftLen--;
// }
// }
// }
// iconv_close(cd);
// sOut[iMaxOutLen - iLeftLen] = '\0';
// iMaxOutLen = iMaxOutLen - iLeftLen;
// }
string TC_Encoder::gbk2utf8(const string &sIn)
{
iconv_t cd;
@ -84,7 +152,9 @@ string TC_Encoder::gbk2utf8(const string &sIn)
cd = iconv_open("UTF-8","GBK");
if (cd == (iconv_t)-1)
{
throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error", errno);
TARS_THROW_EXCEPTION_SYSCODE(TC_Encoder_Exception, "[TC_Encoder::gbk2utf8] iconv_open error");
// throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error", TC_Exception::getSystemCode());
}
string sOut;
@ -142,7 +212,8 @@ void TC_Encoder::gbk2utf8(const string &sIn, vector<string> &vtStr)
cd = iconv_open("UTF-8","GBK");
if (cd == (iconv_t)-1)
{
throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error", errno);
TARS_THROW_EXCEPTION_SYSCODE(TC_Encoder_Exception, "[TC_Encoder::gbk2utf8] iconv_open error");
// throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error", TC_Exception::getSystemCode());
}
vtStr.clear();
@ -196,6 +267,53 @@ void TC_Encoder::gbk2utf8(const string &sIn, vector<string> &vtStr)
iconv_close(cd);
}
// string TC_Encoder::utf82gbk(const string &sIn)
// {
// if(sIn.length() == 0)
// {
// return "";
// }
// iconv_t cd;
// cd = iconv_open("GBK","UTF-8");
// if (cd == (iconv_t)-1)
// {
// throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv_open error", errno);
// }
// size_t sizeLeftLen = sIn.length() * 2 + 1;
// size_t iMaxOutLen = sizeLeftLen;
// // char *pOut = new char[iMaxOutLen];
// char pOut[255];
// // memset(pOut, iMaxOutLen, 0x00);
// const char * pIn = sIn.c_str();
// size_t sizeInLen = sIn.length();
// char *out = pOut;
// cout << sizeInLen << ", " << iMaxOutLen << endl;
// size_t ret = iconv(cd, (char**)&pIn, (size_t*)&sizeInLen, (char **)&out, (size_t*)&sizeLeftLen);
// if (ret == (size_t) - 1)
// {
// // delete[] pOut;
// iconv_close(cd);
// throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv error", errno);
// }
// iconv_close(cd);
// out[iMaxOutLen - sizeLeftLen] = '\0';
// cout << sIn << ", " << iMaxOutLen << "," << sizeLeftLen << "," << out << endl;
// string sOut;
// sOut.assign(out, (iMaxOutLen - sizeLeftLen));
// // delete[] pOut;
// return sOut;
// }
void TC_Encoder::utf82gbk(char *sOut, int &iMaxOutLen, const char *sIn, int iInLen)
{
iconv_t cd;
@ -203,7 +321,8 @@ void TC_Encoder::utf82gbk(char *sOut, int &iMaxOutLen, const char *sIn, int iInL
cd = iconv_open("GBK","UTF-8");
if (cd == (iconv_t)-1)
{
throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv_open error", errno);
TARS_THROW_EXCEPTION_SYSCODE(TC_Encoder_Exception, "[TC_Encoder::utf82gbk] iconv_open error");
// throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv_open error", TC_Exception::getSystemCode());
}
char * pIn = (char*)sIn;
@ -216,7 +335,8 @@ void TC_Encoder::utf82gbk(char *sOut, int &iMaxOutLen, const char *sIn, int iInL
{
iMaxOutLen = 0;
iconv_close(cd);
throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv error", errno);
TARS_THROW_EXCEPTION_SYSCODE(TC_Encoder_Exception, "[TC_Encoder::utf82gbk] iconv error");
// throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv error", TC_Exception::getSystemCode());
return;
}
@ -257,6 +377,8 @@ string TC_Encoder::utf82gbk(const string &sIn)
return sOut;
}
#endif
/**
* \n -> \r\0
* \r -> \r\r
@ -308,3 +430,5 @@ string TC_Encoder::transFrom(const string& str, char f /*= '\n'*/, char t /*= '\
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -15,25 +15,29 @@
*/
#include "util/tc_ex.h"
#include "util/tc_platform.h"
#if TARGET_PLATFORM_LINUX
#include <execinfo.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <cerrno>
#include <iostream>
namespace tars
{
TC_Exception::TC_Exception(const string &buffer)
:_buffer(buffer), _code(0)
: _code(0), _buffer(buffer)
{
// getBacktrace();
}
TC_Exception::TC_Exception(const string &buffer, int err)
{
_buffer = buffer + " :" + strerror(err);
_buffer = buffer + " :" + parseError(err);
_code = err;
// getBacktrace();
}
TC_Exception::~TC_Exception() throw()
@ -47,6 +51,7 @@ const char* TC_Exception::what() const throw()
void TC_Exception::getBacktrace()
{
#if TARGET_PLATFORM_LINUX
void * array[64];
int nSize = backtrace(array, 64);
char ** symbols = backtrace_symbols(array, nSize);
@ -57,6 +62,59 @@ void TC_Exception::getBacktrace()
_buffer += "\n";
}
free(symbols);
#endif
}
#if TARGET_PLATFORM_WINDOWS
static std::string Unicode2ANSI(LPCWSTR lpszSrc)
{
std::string sResult;
if (lpszSrc != NULL) {
int nANSILen = WideCharToMultiByte(CP_ACP, 0, lpszSrc, -1, NULL, 0, NULL, NULL);
char* pANSI = new char[nANSILen + 1];
if (pANSI != NULL) {
ZeroMemory(pANSI, nANSILen + 1);
WideCharToMultiByte(CP_ACP, 0, lpszSrc, -1, pANSI, nANSILen, NULL, NULL);
sResult = pANSI;
delete[] pANSI;
}
}
return sResult;
}
#endif
string TC_Exception::parseError(int err)
{
string errMsg;
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
errMsg = strerror(err);
#else
// LPTSTR lpMsgBuf;
LPSTR lpMsgBuf;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) & lpMsgBuf, 0, NULL);
// errMsg = Unicode2ANSI((LPCWSTR)lpMsgBuf);
errMsg = lpMsgBuf;
LocalFree(lpMsgBuf);
#endif
return errMsg;
}
int TC_Exception::getSystemCode()
{
#if TARGET_PLATFORM_WINDOWS
int ret = GetLastError();
return ret;
#else
return errno;
#endif
}
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -13,10 +13,17 @@
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
#include "util/tc_file.h"
#include "util/tc_port.h"
#include <set>
#include <string.h>
#if TARGET_PLATFORM_IOS
#include <sys/proc_info.h>
#include <libproc.h>
#endif
namespace tars
{
@ -39,15 +46,24 @@ bool TC_File::isAbsolute(const string &sFullFileName)
{
++i;
}
return sFullFileName[i] == '/';
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
return sFullFileName[i] == FILE_SEP[0];
#else
if (sFullFileName.length() >= i + 2)
{
if (isPanfu(sFullFileName.substr(i, 2)))
{
return true;
}
}
return false;
#endif
}
bool TC_File::isFileExist(const string &sFullFileName, mode_t iFileType)
{
struct stat f_stat;
if (lstat(sFullFileName.c_str(), &f_stat) == -1)
TC_Port::stat_t f_stat;
if (TC_Port::lstat(sFullFileName.c_str(), &f_stat) == -1)
{
return false;
}
@ -56,14 +72,12 @@ bool TC_File::isFileExist(const string &sFullFileName, mode_t iFileType)
{
return false;
}
return true;
}
bool TC_File::isFileExistEx(const string &sFullFileName, mode_t iFileType)
{
struct stat f_stat;
if (stat(sFullFileName.c_str(), &f_stat) == -1)
{
return false;
@ -77,42 +91,10 @@ bool TC_File::isFileExistEx(const string &sFullFileName, mode_t iFileType)
return true;
}
bool TC_File::makeDir(const string &sDirectoryPath, mode_t iFlag)
{
int iRetCode = mkdir(sDirectoryPath.c_str(), iFlag);
if(iRetCode < 0 && errno == EEXIST)
{
return isFileExistEx(sDirectoryPath, S_IFDIR);
}
return iRetCode == 0;
}
bool TC_File::makeDirRecursive(const string &sDirectoryPath, mode_t iFlag)
{
string simple = simplifyDirectory(sDirectoryPath);
string::size_type pos = 0;
for(; pos != string::npos; )
{
pos = simple.find("/", pos + 1);
string s;
if(pos == string::npos)
{
s = simple.substr(0, simple.size());
return makeDir(s.c_str(), iFlag);
}
else
{
s = simple.substr(0, pos);
if(!makeDir(s.c_str(), iFlag)) return false;
}
}
return true;
}
int TC_File::setExecutable(const string &sFullFileName, bool canExecutable)
{
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
struct stat f_stat;
if (stat(sFullFileName.c_str(), &f_stat) == -1)
@ -120,11 +102,29 @@ int TC_File::setExecutable(const string &sFullFileName, bool canExecutable)
return -1;
}
return chmod(sFullFileName.c_str(), canExecutable ? f_stat.st_mode | S_IXUSR : f_stat.st_mode & ~S_IXUSR);
return TC_Port::chmod(sFullFileName.c_str(), canExecutable ? f_stat.st_mode | S_IXUSR : f_stat.st_mode & ~S_IXUSR);
#else
return 0;
#endif
}
struct classcomp
{
bool operator() (const string& lhs, const string& rhs) const
{
return TC_Port::strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
}
};
bool TC_File::canExecutable(const string &sFullFileName)
{
#if TARGET_PLATFORM_WINDOWS
string ex = extractFileExt(sFullFileName);
static set<string, classcomp> ext = {"exe", "bat", "com"};
return ext.find(ex) != ext.end();
#else
struct stat f_stat;
if (stat(sFullFileName.c_str(), &f_stat) == -1)
@ -133,8 +133,107 @@ bool TC_File::canExecutable(const string &sFullFileName)
}
return f_stat.st_mode & S_IXUSR;
#endif
}
#if TARGET_PLATFORM_WINDOWS
string TC_File::getExePath()
{
char exeFullPath[MAX_PATH]; // Full path
GetModuleFileName(NULL, exeFullPath, MAX_PATH);
return exeFullPath; // Get full path of the file
}
#elif TARGET_PLATFORM_IOS
string TC_File::getExePath()
{
int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
pid_t pids[numberOfProcesses];
bzero(pids, sizeof(pids));
proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
char pathBuffer[PROC_PIDPATHINFO_MAXSIZE];
bzero(pathBuffer, PROC_PIDPATHINFO_MAXSIZE);
for (int i = 0; i < numberOfProcesses; ++i) {
if (pids[i] == 0) { continue; }
if(pids[i] == getpid())
{
proc_pidpath(pids[i], pathBuffer, sizeof(pathBuffer));
break;
}
}
return pathBuffer;
}
#else
string TC_File::getExePath()
{
string proc = "/proc/self/exe";
char buf[2048] = "\0";
int bufsize = sizeof(buf) / sizeof(char);
int count = readlink(proc.c_str(), buf, bufsize);
if ( count < 0 )
{
TARS_THROW_EXCEPTION_SYSCODE(TC_File_Exception, "[TC_File::getExePath] could not get exe path error");
// throw TC_File_Exception("[TC_File::getExePath] could not get exe path error", TC_Exception::getSystemCode());
}
count = (count >= bufsize) ? (bufsize - 1) : count;
buf[count] = '\0';
return buf;
}
#endif
bool TC_File::makeDir(const string &sDirectoryPath)
{
int iRetCode = TC_Port::mkdir(sDirectoryPath.c_str());
if(iRetCode < 0 && errno == EEXIST)
{
return isFileExistEx(sDirectoryPath, S_IFDIR);
}
return iRetCode == 0;
}
bool TC_File::makeDirRecursive(const string &sDirectoryPath)
{
string simple = simplifyDirectory(sDirectoryPath);
string::size_type pos = 0;
for(; pos != string::npos; )
{
pos = simple.find(FILE_SEP, pos + 1);
string s;
if(pos == string::npos)
{
s = simple.substr(0, simple.size());
#if TARGET_PLATFORM_WINDOWS
if (isPanfu(s))
{
return false;
}
#endif
return makeDir(s.c_str());
}
else
{
s = simple.substr(0, pos);
#if TARGET_PLATFORM_WINDOWS
if (isPanfu(s))
{
continue;
}
#endif
if(!makeDir(s.c_str())) return false;
}
}
return true;
}
int TC_File::removeFile(const string &sFullFileName, bool bRecursive)
{
string path = simplifyDirectory(sFullFileName);
@ -150,9 +249,9 @@ int TC_File::removeFile(const string &sFullFileName, bool bRecursive)
removeFile(files[i], bRecursive);
}
if(path != "/")
if(path != FILE_SEP)
{
if(::rmdir(path.c_str()) == -1)
if(TC_Port::rmdir(path.c_str()) == -1)
{
return -1;
}
@ -161,7 +260,7 @@ int TC_File::removeFile(const string &sFullFileName, bool bRecursive)
}
else
{
if(::rmdir(path.c_str()) == -1)
if(TC_Port::rmdir(path.c_str()) == -1)
{
return -1;
}
@ -178,52 +277,102 @@ int TC_File::removeFile(const string &sFullFileName, bool bRecursive)
return 0;
}
int TC_File::renameFile(const string &sSrcFullFileName, const string &sDstFullFileName)
{
return rename(sSrcFullFileName.c_str(), sDstFullFileName.c_str());
}
string TC_File::simplifyDirectory(const string& path)
{
string result = path;
#if TARGET_PLATFORM_WINDOWS
result = TC_Common::replace(result, "/", "\\");
#else
result = TC_Common::replace(result, "\\", "/");
#endif
string::size_type pos;
pos = 0;
while((pos = result.find("//", pos)) != string::npos)
while((pos = result.find(string(FILE_SEP) + FILE_SEP, pos)) != string::npos)
{
result.erase(pos, 1);
}
pos = 0;
while((pos = result.find("/./", pos)) != string::npos)
while((pos = result.find(string(FILE_SEP) + "." + FILE_SEP, pos)) != string::npos)
{
result.erase(pos, 2);
}
while(result.substr(0, 4) == "/../")
while(result.substr(0, 4) == string(FILE_SEP) + ".." + FILE_SEP)
{
result.erase(0, 3);
}
if(result == "/.")
if(result.find(string(FILE_SEP) + ".." + FILE_SEP) != string::npos)
{
bool ab = TC_File::isAbsolute(result);
vector<string> dirs = TC_Common::sepstr<string>(result, FILE_SEP);
stack<string> q;
for(size_t i = 0; i < dirs.size(); i++)
{
if(dirs[i] == ".." && !q.empty())
{
if(!TC_File::startWindowsPanfu(q.top()) && q.top() != ".." && q.top() != ".")
q.pop();
else
{
q.push(dirs[i]);
}
}
else
{
q.push(dirs[i]);
}
}
result = "";
while(!q.empty())
{
result = q.top() + FILE_SEP + result;
q.pop();
}
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
if(ab)
{
result = FILE_SEP + result;
}
#endif
}
if(result == string(FILE_SEP) + ".")
{
return result.substr(0, result.size() - 1);
}
if(result.size() >= 2 && result.substr(result.size() - 2, 2) == "/.")
if(result.size() >= 2 && result.substr(result.size() - 2, 2) == string(FILE_SEP) + ".")
{
result.erase(result.size() - 2, 2);
}
if(result == "/")
if(result == FILE_SEP)
{
return result;
}
if(result.size() >= 1 && result[result.size() - 1] == '/')
if(result.size() >= 1 && result[result.size() - 1] == FILE_SEP[0])
{
result.erase(result.size() - 1);
}
if(result == "/..")
if(result == string(FILE_SEP) + "..")
{
result = "/";
result = FILE_SEP;
}
return result;
@ -231,48 +380,30 @@ string TC_File::simplifyDirectory(const string& path)
string TC_File::load2str(const string &sFullFileName)
{
FILE* fp = fopen(sFullFileName.data(), "rb");
if (!fp)
return "";
ifstream ifs(sFullFileName.c_str());
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
string s(size, '\0');
fread((void*)s.data(), size, 1, fp);
fclose(fp);
return s;
return string(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
}
void TC_File::load2str(const string &sFullFileName, vector<char> &buffer)
bool TC_File::load2str(const string &sFullFileName, vector<char> &data)
{
buffer.clear();
FILE* fp = fopen(sFullFileName.data(), "rb");
if (!fp)
return;
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
buffer.resize(size);
fread((void*)&buffer[0], size, 1, fp);
fclose(fp);
ifstream ifs(sFullFileName.c_str());
if(ifs.is_open())
{
data.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
return true;
}
return false;
}
void TC_File::save2file(const string &sFullFileName, const string &sFileData)
{
ofstream ofs((sFullFileName).c_str());
ofs << sFileData;
ofs.close();
save2file(sFullFileName, sFileData.c_str(), sFileData.length());
}
int TC_File::save2file(const string &sFullFileName, const char *sFileData, size_t length)
{
FILE *fp = fopen(sFullFileName.c_str(), "wb");
FILE *fp = TC_Port::fopen(sFullFileName.c_str(), "wb");
if (fp == NULL)
{
return -1;
@ -288,26 +419,6 @@ int TC_File::save2file(const string &sFullFileName, const char *sFileData, size_
return -1;
}
string TC_File::getExePath()
{
string proc = "/proc/self/exe";
char buf[2048] = "\0";
int bufsize = sizeof(buf)/sizeof(char);
int count = readlink(proc.c_str(), buf,bufsize);
if ( count < 0 )
{
throw TC_File_Exception("[TC_File::getExePath] could not get exe path error", errno);
}
count = (count>=bufsize)?(bufsize-1):count;
buf[count] = '\0';
return buf;
}
string TC_File::extractFileName(const string &sFullFileName)
{
if(sFullFileName.length() <= 0)
@ -315,7 +426,7 @@ string TC_File::extractFileName(const string &sFullFileName)
return "";
}
string::size_type pos = sFullFileName.rfind('/');
string::size_type pos = sFullFileName.rfind(FILE_SEP);
if(pos == string::npos)
{
return sFullFileName;
@ -326,22 +437,28 @@ string TC_File::extractFileName(const string &sFullFileName)
string TC_File::extractFilePath(const string &sFullFileName)
{
if(sFullFileName.length() <= 0)
#if TARGET_PLATFORM_WINDOWS
string sFullFileNameTmp = TC_Common::replace(sFullFileName, "/", "\\");
#else
string sFullFileNameTmp = TC_Common::replace(sFullFileName, "\\", "/");
#endif
if (sFullFileNameTmp.length() <= 0)
{
return "./";
return string(".") + FILE_SEP;
}
string::size_type pos = 0;
for(pos = sFullFileName.length(); pos != 0 ; --pos)
for (pos = sFullFileNameTmp.length(); pos != 0; --pos)
{
if(sFullFileName[pos-1] == '/')
if (sFullFileNameTmp[pos - 1] == FILE_SEP[0])
{
return sFullFileName.substr(0, pos);
return sFullFileNameTmp.substr(0, pos);
}
}
return "./";
return string(".") + FILE_SEP;
}
string TC_File::extractFileExt(const string &sFullFileName)
@ -409,6 +526,7 @@ string TC_File::extractUrlFilePath(const string &sUrl)
return sUrl.substr(pos);
}
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
size_t TC_File::scanDir(const string &sFilePath, vector<string> &vtMatchFiles, FILE_SELECT f, int iMaxSize )
{
vtMatchFiles.clear();
@ -440,9 +558,11 @@ size_t TC_File::scanDir(const string &sFilePath, vector<string> &vtMatchFiles, F
return vtMatchFiles.size();
}
#endif
void TC_File::listDirectory(const string &path, vector<string> &files, bool bRecursive)
{
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
vector<string> tf;
scanDir(path, tf, 0, 0);
@ -451,7 +571,7 @@ void TC_File::listDirectory(const string &path, vector<string> &files, bool bRec
if(tf[i] == "." || tf[i] == "..")
continue;
string s = path + "/" + tf[i];
string s = path + FILE_SEP + tf[i];
if(isFileExist(s, S_IFDIR))
{
@ -466,6 +586,35 @@ void TC_File::listDirectory(const string &path, vector<string> &files, bool bRec
files.push_back(simplifyDirectory(s));
}
}
#elif TARGET_PLATFORM_WINDOWS
intptr_t hFile;
_finddata_t fileinfo;
if ((hFile = _findfirst(string(path + "\\*.*").c_str(), &fileinfo)) != -1)
{
do
{
string sName = fileinfo.name;
if (sName == "." || sName == "..")
continue;
string s = path + FILE_SEP + sName;
if (fileinfo.attrib & _A_SUBDIR)
{
files.push_back(simplifyDirectory(s));
if (bRecursive)
{
listDirectory(s, files, bRecursive);
}
}
else
{
files.push_back(simplifyDirectory(s));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
#endif
}
void TC_File::copyFile(const string &sExistFile, const string &sNewFile,bool bRemove)
@ -474,41 +623,67 @@ void TC_File::copyFile(const string &sExistFile, const string &sNewFile,bool bRe
{
TC_File::makeDir(sNewFile);
vector<string> tf;
TC_File::scanDir(sExistFile,tf, 0, 0);
TC_File::listDirectory(sExistFile,tf, false);
for(size_t i = 0; i <tf.size(); i++)
{
if(tf[i] == "." || tf[i] == "..")
string fileName = TC_File::extractFileName(tf[i]);
if(fileName == "." || fileName == "..")
continue;
string s = sExistFile + "/" + tf[i];
string d = sNewFile + "/" + tf[i];
string s = sExistFile + FILE_SEP + fileName;
string d = sNewFile + FILE_SEP + fileName;
copyFile(s, d,bRemove);
}
}
else
{
if(bRemove) std::remove(sNewFile.c_str());
std::ifstream fin(sExistFile.c_str());
std::ifstream fin(sExistFile.c_str(), ios::binary);
if(!fin)
{
throw TC_File_Exception("[TC_File::copyFile] error: "+sExistFile, errno);
TARS_THROW_EXCEPTION_SYSCODE(TC_File_Exception, "[TC_File::copyFile] error: "+sExistFile);
}
std::ofstream fout(sNewFile.c_str());
std::ofstream fout(sNewFile.c_str(), ios::binary);
if(!fout )
{
throw TC_File_Exception("[TC_File::copyFile] error: "+sNewFile, errno);
TARS_THROW_EXCEPTION_SYSCODE(TC_File_Exception, "[TC_File::copyFile] error: "+sNewFile);
}
struct stat f_stat;
if (stat(sExistFile.c_str(), &f_stat) == -1)
{
throw TC_File_Exception("[TC_File::copyFile] error: "+sExistFile, errno);
}
chmod(sNewFile.c_str(),f_stat.st_mode);
fout << fin.rdbuf();
fin.close();
fout.close();
TC_Port::stat_t f_stat;
if (TC_Port::lstat(sExistFile.c_str(), &f_stat) == -1)
{
TARS_THROW_EXCEPTION_SYSCODE(TC_File_Exception, "[TC_File::copyFile] error: "+sExistFile);
}
TC_Port::chmod(sNewFile.c_str(),f_stat.st_mode);
}
}
bool TC_File::startWindowsPanfu(const string & sPath)
{
if (sPath.length() < 2)
{
return false;
}
char c = sPath[0];
return isalpha(c) && (sPath[1] == ':');
}
bool TC_File::isPanfu(const string & sPath)
{
if (sPath.length() != 2)
{
return false;
}
char c = sPath[0];
return isalpha(c) && (sPath[1] == ':');
}
}

View File

@ -1,4 +1,4 @@
/**
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
@ -29,6 +29,24 @@ void TC_Option::decode(int argc, char *argv[])
{
v.push_back(argv[i]);
}
for(size_t i = 0; i < v.size(); i++)
{
if(v[i].length() > 2 && v[i].substr(0,2) == "--")
{
parse(v[i]);
}
else
{
_vSingle.push_back(v[i]);
}
}
}
void TC_Option::decode(const char *command)
{
_mParam.clear();
if(command == NULL)
return;
vector<string> v = TC_Common::sepstr<string>(command, " \t");
for(size_t i = 0; i < v.size(); i++)
{
@ -56,20 +74,31 @@ void TC_Option::parse(const string &s)
}
}
string TC_Option::getValue(const string &sName)
string TC_Option::getValue(const string &sName) const
{
if(_mParam.find(sName) != _mParam.end())
auto it = _mParam.find(sName);
if( it != _mParam.end())
{
return _mParam[sName];
return it->second;
}
return "";
}
bool TC_Option::hasParam(const string &sName)
bool TC_Option::hasParam(const string &sName) const
{
return _mParam.find(sName) != _mParam.end();
}
const vector<string>& TC_Option::getSingle() const
{
return _vSingle;
}
const map<string, string>& TC_Option::getMulti() const
{
return _mParam;
}
vector<string>& TC_Option::getSingle()
{
return _vSingle;

174
third_partly/util/src/tc_port.cpp Executable file
View File

@ -0,0 +1,174 @@
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* 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.
*/
#include "util/tc_port.h"
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
#include <limits.h>
#include <sys/time.h>
#else
#pragma comment(lib, "ws2_32.lib")
// #include <winsock.h>
#include <time.h>
#include <sys/timeb.h>
#include "util/tc_strptime.h"
#endif
namespace tars
{
int TC_Port::strcasecmp(const char *s1, const char *s2)
{
#if TARGET_PLATFORM_WINDOWS
return ::_stricmp(s1, s2);
#else
return ::strcasecmp(s1, s2);
#endif
}
int TC_Port::strncasecmp(const char *s1, const char *s2, size_t n)
{
#if TARGET_PLATFORM_WINDOWS
return ::_strnicmp(s1, s2, n);
#else
return ::strncasecmp(s1, s2, n);
#endif
}
void TC_Port::localtime_r(const time_t *clock, struct tm *result)
{
//带时区时间
#if TARGET_PLATFORM_WINDOWS
::localtime_s(result, clock);
#else
::localtime_r(clock, result);
#endif
}
void TC_Port::gmtime_r(const time_t *clock, struct tm *result)
{
#if TARGET_PLATFORM_WINDOWS
::gmtime_s(result, clock);
#else
::gmtime_r(clock, result);
#endif
}
time_t TC_Port::timegm(struct tm *timeptr)
{
#if TARGET_PLATFORM_WINDOWS
return ::_mkgmtime(timeptr);
#else
return ::timegm(timeptr);
#endif
}
int TC_Port::gettimeofday(struct timeval &tv)
{
#if TARGET_PLATFORM_WINDOWS
static const DWORDLONG FILETIME_to_timeval_skew = 116444736000000000;
FILETIME tfile;
::GetSystemTimeAsFileTime(&tfile);
ULARGE_INTEGER tmp;
tmp.LowPart = tfile.dwLowDateTime;
tmp.HighPart = tfile.dwHighDateTime;
tmp.QuadPart -= FILETIME_to_timeval_skew;
ULARGE_INTEGER largeInt;
largeInt.QuadPart = tmp.QuadPart / (10000 * 1000);
tv.tv_sec = (long)(tmp.QuadPart / (10000 * 1000));
tv.tv_usec = (long)((tmp.QuadPart % (10000 * 1000)) / 10);
return 0;
#else
return ::gettimeofday(&tv, 0);
#endif
}
int TC_Port::chmod(const char *path, mode_t mode)
{
//带时区时间
#if TARGET_PLATFORM_WINDOWS
return ::_chmod(path, mode);
#else
return ::chmod(path, mode);
#endif
}
FILE * TC_Port::fopen(const char * path, const char * mode)
{
#if TARGET_PLATFORM_WINDOWS
FILE *fp;
if (fopen_s(&fp, path, mode) != 0)
{
return NULL;
}
return fp;
#else
return ::fopen(path, mode);
#endif
}
int TC_Port::lstat(const char * path, TC_Port::stat_t * buf)
{
#if TARGET_PLATFORM_WINDOWS
return ::_stat(path, buf);
#else
return ::lstat(path, buf);
#endif
}
int TC_Port::mkdir(const char *path)
{
#if TARGET_PLATFORM_WINDOWS
int iRetCode = ::_mkdir(path);
#else
int iRetCode = ::mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
#endif
return iRetCode;
}
int TC_Port::rmdir(const char *path)
{
#if TARGET_PLATFORM_WINDOWS
return ::_rmdir(path);
#else
return ::rmdir(path);
#endif
}
int TC_Port::closeSocket(int fd)
{
#if TARGET_PLATFORM_WINDOWS
return ::closesocket(fd);
#else
return ::close(fd);
#endif
}
int64_t TC_Port::getpid()
{
#if TARGET_PLATFORM_WINDOWS
int64_t pid = ::GetCurrentProcessId();
#else
int64_t pid = ::getpid();
#endif
return pid;
}
}