mirror of
https://github.com/tars-node/tars2node.git
synced 2024-03-22 13:10:56 +08:00
update to new tars-version
This commit is contained in:
parent
b868046b6b
commit
22b483e618
|
@ -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
BIN
build/mac/bin/tars2node
Executable file
Binary file not shown.
BIN
build/tars2node
BIN
build/tars2node
Binary file not shown.
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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,11 +76,11 @@ public:
|
|||
*
|
||||
* @return int 计数值
|
||||
*/
|
||||
int getRef() const { return _atomic.get(); }
|
||||
int getRef() const { return _atomic; }
|
||||
|
||||
/**
|
||||
* @brief 设置不自动释放.
|
||||
*
|
||||
* @brief 设置不自动释放.
|
||||
*
|
||||
* @param b 是否自动删除,true or false
|
||||
*/
|
||||
void setNoDelete(bool b) { _bNoDelete = b; }
|
||||
|
@ -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 智能指针模板类.
|
||||
*
|
||||
|
@ -180,8 +143,8 @@ public:
|
|||
typedef T element_type;
|
||||
|
||||
/**
|
||||
* @brief 用原生指针初始化, 计数+1.
|
||||
*
|
||||
* @brief 用原生指针初始化, 计数+1.
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
TC_AutoPtr(T* p = 0)
|
||||
|
@ -195,8 +158,8 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 用其他智能指针r的原生指针初始化, 计数+1.
|
||||
*
|
||||
* @brief 用其他智能指针r的原生指针初始化, 计数+1.
|
||||
*
|
||||
* @param Y
|
||||
* @param r
|
||||
*/
|
||||
|
@ -212,8 +175,8 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 拷贝构造, 计数+1.
|
||||
*
|
||||
* @brief 拷贝构造, 计数+1.
|
||||
*
|
||||
* @param r
|
||||
*/
|
||||
TC_AutoPtr(const TC_AutoPtr& r)
|
||||
|
@ -238,9 +201,9 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 赋值, 普通指针.
|
||||
*
|
||||
* @param p
|
||||
* @brief 赋值, 普通指针.
|
||||
*
|
||||
* @param p
|
||||
* @return TC_AutoPtr&
|
||||
*/
|
||||
TC_AutoPtr& operator=(T* p)
|
||||
|
@ -264,10 +227,10 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 赋值, 其他类型智能指针.
|
||||
*
|
||||
* @brief 赋值, 其他类型智能指针.
|
||||
*
|
||||
* @param Y
|
||||
* @param r
|
||||
* @param r
|
||||
* @return TC_AutoPtr&
|
||||
*/
|
||||
template<typename Y>
|
||||
|
@ -292,9 +255,9 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 赋值, 该类型其他执政指针.
|
||||
*
|
||||
* @param r
|
||||
* @brief 赋值, 该类型其他执政指针.
|
||||
*
|
||||
* @param r
|
||||
* @return TC_AutoPtr&
|
||||
*/
|
||||
TC_AutoPtr& operator=(const TC_AutoPtr& r)
|
||||
|
@ -318,10 +281,10 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 将其他类型的智能指针换成当前类型的智能指针.
|
||||
*
|
||||
* @brief 将其他类型的智能指针换成当前类型的智能指针.
|
||||
*
|
||||
* @param Y
|
||||
* @param r
|
||||
* @param r
|
||||
* @return TC_AutoPtr
|
||||
*/
|
||||
template<class Y>
|
||||
|
@ -331,10 +294,10 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 将其他原生类型的指针转换成当前类型的智能指针.
|
||||
*
|
||||
* @brief 将其他原生类型的指针转换成当前类型的智能指针.
|
||||
*
|
||||
* @param Y
|
||||
* @param p
|
||||
* @param p
|
||||
* @return TC_AutoPtr
|
||||
*/
|
||||
template<class Y>
|
||||
|
@ -394,8 +357,8 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 交换指针.
|
||||
*
|
||||
* @brief 交换指针.
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
void swap(TC_AutoPtr& other)
|
||||
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 默认取6位精度,float默认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对象
|
||||
|
@ -311,7 +407,7 @@ public:
|
|||
* @param sSep 两个元素之间的分隔符
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
template <typename InputIter>
|
||||
template<typename InputIter>
|
||||
static string tostr(InputIter iFirst, InputIter iLast, const string &sSep = "|");
|
||||
|
||||
/**
|
||||
|
@ -372,7 +468,7 @@ public:
|
|||
* @param mSrcDest map<原字符串,目的字符串>
|
||||
* @return string 替换后的字符串
|
||||
*/
|
||||
static string replace(const string &sString, const map<string,string>& mSrcDest);
|
||||
static string replace(const string &sString, const map<string, string>& mSrcDest);
|
||||
|
||||
/**
|
||||
* @brief 匹配以.分隔的字符串,pat中*则代表通配符,代表非空的任何字符串
|
||||
|
@ -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类型转成一个字节 .
|
||||
*
|
||||
|
@ -426,12 +533,12 @@ public:
|
|||
*/
|
||||
static size_t toSize(const string &s, size_t iDefaultSize);
|
||||
|
||||
/**
|
||||
* @brief 生成基于16进制字符的随机串
|
||||
* @param p 存储随机字符串
|
||||
* @param len 字符串大小
|
||||
*/
|
||||
static void getRandomHexChars(char* p, unsigned int len);
|
||||
/**
|
||||
* @brief 获取主机名称.
|
||||
* @return string 主机名,失败是返回空
|
||||
*/
|
||||
static string getHostName();
|
||||
|
||||
};
|
||||
|
||||
namespace p
|
||||
|
@ -475,9 +582,13 @@ namespace p
|
|||
{
|
||||
short operator()(const string &sStr)
|
||||
{
|
||||
if(!sStr.empty())
|
||||
{
|
||||
return atoi(sStr.c_str());
|
||||
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,9 +616,13 @@ namespace p
|
|||
{
|
||||
int operator()(const string &sStr)
|
||||
{
|
||||
if(!sStr.empty())
|
||||
{
|
||||
return atoi(sStr.c_str());
|
||||
if (!sStr.empty()) {
|
||||
if (sStr.find("0x") == 0) {
|
||||
return ::strtol(sStr.c_str(), NULL, 16);
|
||||
}
|
||||
else {
|
||||
return atoi(sStr.c_str());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -514,9 +633,13 @@ namespace p
|
|||
{
|
||||
unsigned int operator()(const string &sStr)
|
||||
{
|
||||
if(!sStr.empty())
|
||||
{
|
||||
return strtoul(sStr.c_str(), NULL, 10);
|
||||
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,9 +650,13 @@ namespace p
|
|||
{
|
||||
long operator()(const string &sStr)
|
||||
{
|
||||
if(!sStr.empty())
|
||||
{
|
||||
return atol(sStr.c_str());
|
||||
if (!sStr.empty()) {
|
||||
if (sStr.find("0x") == 0) {
|
||||
return ::strtol(sStr.c_str(), NULL, 16);
|
||||
}
|
||||
else {
|
||||
return atol(sStr.c_str());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -540,9 +667,13 @@ namespace p
|
|||
{
|
||||
long long operator()(const string &sStr)
|
||||
{
|
||||
if(!sStr.empty())
|
||||
{
|
||||
return atoll(sStr.c_str());
|
||||
if (!sStr.empty()) {
|
||||
if (sStr.find("0x") == 0) {
|
||||
return ::strtoll(sStr.c_str(), NULL, 16);
|
||||
}
|
||||
else {
|
||||
return atoll(sStr.c_str());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -553,9 +684,13 @@ namespace p
|
|||
{
|
||||
unsigned long operator()(const string &sStr)
|
||||
{
|
||||
if(!sStr.empty())
|
||||
{
|
||||
return strtoul(sStr.c_str(), NULL, 10);
|
||||
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)
|
||||
{
|
||||
|
@ -756,7 +931,7 @@ string TC_Common::tostr(const pair<F, S> &itPair)
|
|||
return sBuffer;
|
||||
}
|
||||
|
||||
template <typename InputIter>
|
||||
template<typename InputIter>
|
||||
string TC_Common::tostr(InputIter iFirst, InputIter iLast, const string &sSep)
|
||||
{
|
||||
string sBuffer;
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -37,9 +37,9 @@ namespace tars
|
|||
*/
|
||||
struct TC_Encoder_Exception : public TC_Exception
|
||||
{
|
||||
TC_Encoder_Exception(const string &buffer) : TC_Exception(buffer){};
|
||||
TC_Encoder_Exception(const string &buffer, int err) : TC_Exception(buffer, err){};
|
||||
~TC_Encoder_Exception() throw(){};
|
||||
TC_Encoder_Exception(const string &buffer) : TC_Exception(buffer){};
|
||||
TC_Encoder_Exception(const string &buffer, int err) : TC_Exception(buffer, err){};
|
||||
~TC_Encoder_Exception() throw(){};
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -54,85 +54,77 @@ 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.
|
||||
*
|
||||
* @param sIn 输入buffer*
|
||||
* @throws TC_Encoder_Exception
|
||||
* @return 转换后的utf8编码
|
||||
*/
|
||||
static string gbk2utf8(const string &sIn);
|
||||
/**
|
||||
* @brief gbk 转换到 utf8.
|
||||
*
|
||||
* @param sIn 输入buffer*
|
||||
* @throws TC_Encoder_Exception
|
||||
* @return 转换后的utf8编码
|
||||
*/
|
||||
static string gbk2utf8(const string &sIn);
|
||||
|
||||
/**
|
||||
* @brief gbk 转换到 utf8.
|
||||
*
|
||||
* @param sIn 输入buffer
|
||||
* @param vtStr 输出gbk的vector
|
||||
* @throws TC_Encoder_Exception
|
||||
* @return
|
||||
*/
|
||||
static void gbk2utf8(const string &sIn, vector<string> &vtStr);
|
||||
/**
|
||||
* @brief gbk 转换到 utf8.
|
||||
*
|
||||
* @param sIn 输入buffer
|
||||
* @param vtStr 输出gbk的vector
|
||||
* @throws TC_Encoder_Exception
|
||||
* @return
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param sIn 输入buffer
|
||||
* @throws TC_Encoder_Exception
|
||||
* @return 转换后的gbk编码
|
||||
*/
|
||||
static string utf82gbk(const string &sIn);
|
||||
/**
|
||||
* @brief utf8 转换到 gbk.
|
||||
*
|
||||
* @param sIn 输入buffer
|
||||
* @throws TC_Encoder_Exception
|
||||
* @return 转换后的gbk编码
|
||||
*/
|
||||
static string utf82gbk(const string &sIn);
|
||||
|
||||
/**
|
||||
* @brief 将string的\n替换掉,转义字符串中的某个字符
|
||||
*
|
||||
* 缺省:\n 转换为 \r\0; \r转换为\,
|
||||
*
|
||||
* 主要用于将string记录在一行,通常用于写bin-log的地方;
|
||||
* @param str 待转换字符串
|
||||
* @param f 需要转义的字符
|
||||
* @param t 转义后的字符
|
||||
* @param u 借用的转义符
|
||||
* @return str 转换后的字符串
|
||||
*/
|
||||
static string transTo(const string& str, char f = '\n', char t = '\r', char u = '\0');
|
||||
/**
|
||||
* @brief 将string的\n替换掉,转义字符串中的某个字符
|
||||
*
|
||||
* 缺省:\n 转换为 \r\0; \r转换为\,
|
||||
*
|
||||
* 主要用于将string记录在一行,通常用于写bin-log的地方;
|
||||
* @param str 待转换字符串
|
||||
* @param f 需要转义的字符
|
||||
* @param t 转义后的字符
|
||||
* @param u 借用的转义符
|
||||
* @return str 转换后的字符串
|
||||
*/
|
||||
static string transTo(const string& str, char f = '\n', char t = '\r', char u = '\0');
|
||||
|
||||
/**
|
||||
* @brief 从替换的数据恢复源数据,将 transTo 的字符串还原,
|
||||
*
|
||||
* 缺省:\r\0 还原为\n,\r\r还原为,
|
||||
*
|
||||
* 主要用于将string记录在一行,通常用于写bin-log的地方
|
||||
* @param str 待还原的字符串(必须是transTo后得到的字符串)
|
||||
* @param f 被转义的字符
|
||||
* @param t 转义后的字符
|
||||
* @param u 借用的转义符
|
||||
* @return str 还原后的字符串
|
||||
*/
|
||||
static string transFrom(const string& str, char f = '\n', char t = '\r', char u = '\0');
|
||||
/**
|
||||
* @brief 从替换的数据恢复源数据,将 transTo 的字符串还原,
|
||||
*
|
||||
* 缺省:\r\0 还原为\n,\r\r还原为,
|
||||
*
|
||||
* 主要用于将string记录在一行,通常用于写bin-log的地方
|
||||
* @param str 待还原的字符串(必须是transTo后得到的字符串)
|
||||
* @param f 被转义的字符
|
||||
* @param t 转义后的字符
|
||||
* @param u 借用的转义符
|
||||
* @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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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,23 +38,22 @@ class TC_Exception : public exception
|
|||
{
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数,提供了一个可以传入errno的构造函数,
|
||||
*
|
||||
* 异常抛出时直接获取的错误信息
|
||||
*
|
||||
* @param buffer 异常的告警信息
|
||||
* @brief 构造函数,提供了一个可以传入errno的构造函数
|
||||
* @param err, 是否附带系统错误信息(linux版本, 用errno获取错误码, windows版本, 用GetLastError()获取错误)
|
||||
*
|
||||
* @param buffer 异常的告警信息
|
||||
*/
|
||||
explicit TC_Exception(const string &buffer);
|
||||
explicit TC_Exception(const string &buffer);
|
||||
|
||||
/**
|
||||
* @brief 构造函数,提供了一个可以传入errno的构造函数,
|
||||
*
|
||||
* 异常抛出时直接获取的错误信息
|
||||
*
|
||||
* @brief 构造函数,提供了一个可以传入errno的构造函数,
|
||||
*
|
||||
* 异常抛出时直接获取的错误信息
|
||||
*
|
||||
* @param buffer 异常的告警信息
|
||||
* @param err 错误码, 可用strerror获取错误信息
|
||||
* @param errno 传入:errno, windows版本 传入:GetLastError()
|
||||
*/
|
||||
TC_Exception(const string &buffer, int err);
|
||||
TC_Exception(const string &buffer, int err);
|
||||
|
||||
/**
|
||||
* @brief 析够数函
|
||||
|
@ -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:
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
int _code;
|
||||
/**
|
||||
* 异常的相关信息
|
||||
* 异常的相关信息
|
||||
*/
|
||||
string _buffer;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
int _code;
|
||||
|
||||
};
|
||||
|
||||
//为了避免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
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
|
@ -50,73 +59,117 @@ struct TC_File_Exception : public TC_Exception
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief 常用文件名处理函数.
|
||||
* @brief 常用文件名处理函数.
|
||||
*
|
||||
*/
|
||||
class TC_File
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief 获取文件大小, 如果文件不存在, 则返回-1.
|
||||
*
|
||||
* @param sFullFileName 文件全路径(所在目录和文件名)
|
||||
* @return ofstream::pos_type类型文件大小
|
||||
*/
|
||||
static ifstream::pos_type getFileSize(const string &sFullFileName);
|
||||
/**
|
||||
* @brief 获取文件大小, 如果文件不存在, 则返回-1.
|
||||
*
|
||||
* @param sFullFileName 文件全路径(所在目录和文件名)
|
||||
* @return ofstream::pos_type类型文件大小
|
||||
*/
|
||||
static ifstream::pos_type getFileSize(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 判断是否为绝对路径, 忽略空格以'/'开头.
|
||||
*
|
||||
* @param sFullFileName 文件全路径(所在目录和文件名)
|
||||
* @return ture是绝对路径,false代表非绝对路径
|
||||
*/
|
||||
static bool isAbsolute(const string &sFullFileName);
|
||||
/**
|
||||
* @brief 判断是否为绝对路径, 忽略空格以'/'开头.
|
||||
*
|
||||
* @param sFullFileName 文件全路径(所在目录和文件名)
|
||||
* @return ture是绝对路径,false代表非绝对路径
|
||||
*/
|
||||
static bool isAbsolute(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 判断给定路径的文件是否存在.
|
||||
* 如果文件是符号连接,则以符号连接判断而不是以符号连接指向的文件判断
|
||||
* @param sFullFileName 文件全路径
|
||||
* @param iFileType 文件类型, 缺省S_IFREG
|
||||
* @return true代表存在,fals代表不存在
|
||||
*/
|
||||
static bool isFileExist(const string &sFullFileName, mode_t iFileType = S_IFREG);
|
||||
/**
|
||||
* @brief 判断给定路径的文件是否存在.
|
||||
* 如果文件是符号连接,则以符号连接判断而不是以符号连接指向的文件判断
|
||||
* @param sFullFileName 文件全路径
|
||||
* @param iFileType 文件类型, 缺省S_IFREG
|
||||
* @return true代表存在,fals代表不存在
|
||||
*/
|
||||
static bool isFileExist(const string &sFullFileName, mode_t iFileType = S_IFREG);
|
||||
|
||||
/**
|
||||
* @brief 判断给定路径的文件是否存在.
|
||||
* 注意: 如果文件是符号连接,则以符号连接指向的文件判断
|
||||
* @param sFullFileName 文件全路径
|
||||
* @param iFileType 文件类型, 缺省S_IFREG
|
||||
* @return true-存在,fals-不存在
|
||||
*/
|
||||
static bool isFileExistEx(const string &sFullFileName, mode_t iFileType = S_IFREG);
|
||||
/**
|
||||
* @brief 判断给定路径的文件是否存在.
|
||||
* 注意: 如果文件是符号连接,则以符号连接指向的文件判断
|
||||
* @param sFullFileName 文件全路径
|
||||
* @param iFileType 文件类型, 缺省S_IFREG
|
||||
* @return true-存在,fals-不存在
|
||||
*/
|
||||
static bool isFileExistEx(const string &sFullFileName, mode_t iFileType = S_IFREG);
|
||||
|
||||
/**
|
||||
* @brief 规则化目录名称, 把一些不用的去掉, 例如./等.
|
||||
*
|
||||
* @param path 目录名称
|
||||
* @return 规范后的目录名称
|
||||
*/
|
||||
static string simplifyDirectory(const string& path);
|
||||
/**
|
||||
* @brief 规则化目录名称, 把一些不用的去掉, 例如./等.
|
||||
*
|
||||
* @param path 目录名称
|
||||
* @return 规范后的目录名称
|
||||
*/
|
||||
static string simplifyDirectory(const string& path);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
/**
|
||||
* @brief 创建目录, 如果目录已经存在, 则也返回成功.
|
||||
*
|
||||
* @param sFullPath 要创建的目录名称
|
||||
* @return bool true-创建成功 ,false-创建失败
|
||||
*/
|
||||
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-创建失败
|
||||
*/
|
||||
/**
|
||||
*@brief 循环创建目录, 如果目录已经存在, 则也返回成功.
|
||||
*
|
||||
* @param sFullPath 要创建的目录名称
|
||||
* @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);
|
||||
static bool makeDirRecursive(const string &sDirectoryPath);
|
||||
|
||||
/**
|
||||
* @brief 删除一个文件或目录.
|
||||
*
|
||||
* @param sFullFileName 文件或者目录的全路径
|
||||
* @param bRecursive 如果是目录是否递归删除
|
||||
* @return 0-成功,失败可以通过errno查看失败的原因
|
||||
*/
|
||||
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
|
||||
* 文件存在则返回文件数据,不存在或者读取文件错误的时候, 返回为空
|
||||
* @param sFullFileName 文件名称
|
||||
* @return 文件数据
|
||||
*/
|
||||
static string load2str(const string &sFullFileName);
|
||||
static bool load2str(const string &sFullFileName, vector<char> &data);
|
||||
|
||||
/**
|
||||
* @brief 写文件.
|
||||
*
|
||||
* @param sFullFileName 文件名称
|
||||
* @param sFileData 文件内容
|
||||
* @return
|
||||
*/
|
||||
static void save2file(const string &sFullFileName, const string &sFileData);
|
||||
|
||||
/**
|
||||
* @brief 写文件.
|
||||
*
|
||||
* @param sFullFileName 文件名
|
||||
* @param sFileData 数据指针
|
||||
* @param length 写入长度
|
||||
* @return 0-成功,-1-失败
|
||||
*/
|
||||
static int save2file(const string &sFullFileName, const char *sFileData, size_t length);
|
||||
|
||||
/**
|
||||
* @brief 设置文件是否可执行.
|
||||
|
@ -134,50 +187,7 @@ public:
|
|||
* @return true-可执行, false-不可执行
|
||||
*/
|
||||
static bool canExecutable(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 删除一个文件或目录.
|
||||
*
|
||||
* @param sFullFileName 文件或者目录的全路径
|
||||
* @param bRecursive 如果是目录是否递归删除
|
||||
* @return 0-成功,失败可以通过errno查看失败的原因
|
||||
*/
|
||||
static int removeFile(const string &sFullFileName, bool bRecursive);
|
||||
|
||||
/**
|
||||
* @brief 读取文件到string
|
||||
* 文件存在则返回文件数据,不存在或者读取文件错误的时候, 返回为空
|
||||
* @param sFullFileName 文件名称
|
||||
* @return 文件数据
|
||||
*/
|
||||
static string load2str(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 读取文件到vector<char>
|
||||
* 文件存在则返回文件数据,不存在或者读取文件错误的时候, 返回为空
|
||||
* @param sFullFileName 文件名称
|
||||
*/
|
||||
static void load2str(const string &sFullFileName, vector<char> &buffer);
|
||||
|
||||
/**
|
||||
* @brief 写文件.
|
||||
*
|
||||
* @param sFullFileName 文件名称
|
||||
* @param sFileData 文件内容
|
||||
* @return
|
||||
*/
|
||||
static void save2file(const string &sFullFileName, const string &sFileData);
|
||||
|
||||
/**
|
||||
* @brief 写文件.
|
||||
*
|
||||
* @param sFullFileName 文件名
|
||||
* @param sFileData 数据指针
|
||||
* @param length 写入长度
|
||||
* @return 0-成功,-1-失败
|
||||
*/
|
||||
static int save2file(const string &sFullFileName, const char *sFileData, size_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 获取前当可执行文件路径.
|
||||
*
|
||||
|
@ -185,105 +195,115 @@ public:
|
|||
*/
|
||||
static string getExePath();
|
||||
|
||||
/**
|
||||
* @brief 提取文件名称
|
||||
*从一个完全文件名中去掉路径,例如:/usr/local/temp.gif获取temp.gif
|
||||
*@param sFullFileName 文件的完全名称
|
||||
*@return string 提取后的文件名称
|
||||
*/
|
||||
static string extractFileName(const string &sFullFileName);
|
||||
/**
|
||||
* @brief 提取文件名称
|
||||
*从一个完全文件名中去掉路径,例如:/usr/local/temp.gif获取temp.gif
|
||||
*@param sFullFileName 文件的完全名称
|
||||
*@return string 提取后的文件名称
|
||||
*/
|
||||
static string extractFileName(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 从一个完全文件名中提取文件的路径.
|
||||
*
|
||||
* 例如1: "/usr/local/temp.gif" 获取"/usr/local/"
|
||||
* 例如2: "temp.gif" 获取 "./"
|
||||
* @param sFullFileName 文件的完全名称
|
||||
* @return 提取后的文件路径
|
||||
*/
|
||||
static string extractFilePath(const string &sFullFileName);
|
||||
/**
|
||||
* @brief 从一个完全文件名中提取文件的路径.
|
||||
*
|
||||
* 例如1: "/usr/local/temp.gif" 获取"/usr/local/"
|
||||
* 例如2: "temp.gif" 获取 "./"
|
||||
* @param sFullFileName 文件的完全名称
|
||||
* @return 提取后的文件路径
|
||||
*/
|
||||
static string extractFilePath(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 提取文件扩展名.
|
||||
*
|
||||
* 例如1: "/usr/local/temp.gif" 获取"gif"
|
||||
* 例如2: "temp.gif" 获取"gif"
|
||||
*@param sFullFileName 文件名称
|
||||
*@return 文件扩展名
|
||||
*/
|
||||
static string extractFileExt(const string &sFullFileName);
|
||||
/**
|
||||
* @brief 提取文件扩展名.
|
||||
*
|
||||
* 例如1: "/usr/local/temp.gif" 获取"gif"
|
||||
* 例如2: "temp.gif" 获取"gif"
|
||||
*@param sFullFileName 文件名称
|
||||
*@return 文件扩展名
|
||||
*/
|
||||
static string extractFileExt(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 提取文件名称,去掉扩展名.
|
||||
* 例如1: "/usr/local/temp.gif" 获取"/usr/local/temp"
|
||||
* 例如2: "temp.gif" 获取"temp"
|
||||
* @param sFullFileName 文件名称
|
||||
* @return 去掉扩展名的文件名称
|
||||
*/
|
||||
static string excludeFileExt(const string &sFullFileName);
|
||||
/**
|
||||
* @brief 提取文件名称,去掉扩展名.
|
||||
* 例如1: "/usr/local/temp.gif" 获取"/usr/local/temp"
|
||||
* 例如2: "temp.gif" 获取"temp"
|
||||
* @param sFullFileName 文件名称
|
||||
* @return 去掉扩展名的文件名称
|
||||
*/
|
||||
static string excludeFileExt(const string &sFullFileName);
|
||||
|
||||
/**
|
||||
* @brief 替换文件扩展名
|
||||
*
|
||||
* 改变文件类型,如果无扩展名,则加上扩展名 =?1:
|
||||
* 例如1:"/usr/temp.gif" 替 换 "jpg" 得到"/usr/temp.jpg"
|
||||
* 例如2: "/usr/local/temp" 替 换 "jpg" 得到"/usr/local/temp.jpg"
|
||||
* @param sFullFileName 文件名称
|
||||
* @param sExt 扩展名
|
||||
* @return 替换扩展名后的文件名
|
||||
*/
|
||||
static string replaceFileExt(const string &sFullFileName, const string &sExt);
|
||||
/**
|
||||
* @brief 替换文件扩展名
|
||||
*
|
||||
* 改变文件类型,如果无扩展名,则加上扩展名 =?1:
|
||||
* 例如1:"/usr/temp.gif" 替 换 "jpg" 得到"/usr/temp.jpg"
|
||||
* 例如2: "/usr/local/temp" 替 换 "jpg" 得到"/usr/local/temp.jpg"
|
||||
* @param sFullFileName 文件名称
|
||||
* @param sExt 扩展名
|
||||
* @return 替换扩展名后的文件名
|
||||
*/
|
||||
static string replaceFileExt(const string &sFullFileName, const string &sExt);
|
||||
|
||||
/**
|
||||
* @brief 从一个url中获取完全文件名.
|
||||
*
|
||||
* 获取除http://外,第一个'/'后面的所有字符
|
||||
* 例如1:http://www.qq.com/tmp/temp.gif 获取tmp/temp.gif
|
||||
* 例如2:www.qq.com/tmp/temp.gif 获取tmp/temp.gif
|
||||
* 例如3:/tmp/temp.gif 获取tmp/temp.gif
|
||||
* @param sUrl url字符串
|
||||
* @return 文件名称
|
||||
*/
|
||||
static string extractUrlFilePath(const string &sUrl);
|
||||
/**
|
||||
* @brief 从一个url中获取完全文件名.
|
||||
*
|
||||
* 获取除http://外,第一个'/'后面的所有字符
|
||||
* 例如1:http://www.qq.com/tmp/temp.gif 获取tmp/temp.gif
|
||||
* 例如2:www.qq.com/tmp/temp.gif 获取tmp/temp.gif
|
||||
* 例如3:/tmp/temp.gif 获取tmp/temp.gif
|
||||
* @param sUrl url字符串
|
||||
* @return 文件名称
|
||||
*/
|
||||
static string extractUrlFilePath(const string &sUrl);
|
||||
|
||||
/**
|
||||
* @brief 遍历文件时确定是否选择.
|
||||
*
|
||||
* @return 1-选择, 0-不选择
|
||||
*/
|
||||
typedef int (*FILE_SELECT)(const dirent *);
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
/**
|
||||
* @brief 遍历文件时确定是否选择.
|
||||
*
|
||||
* @return 1-选择, 0-不选择
|
||||
*/
|
||||
typedef int(*FILE_SELECT)(const dirent *);
|
||||
|
||||
/**
|
||||
* @brief 扫描一个目录.
|
||||
*
|
||||
* @param sFilePath 需要扫描的路径
|
||||
* @param vtMatchFiles 返回的文件名矢量表
|
||||
* @param f 匹配函数,为NULL表示所有文件都获取
|
||||
* @param iMaxSize 最大文件个数,iMaxSize <=0时,返回所有匹配文件
|
||||
* @return 文件个数
|
||||
*/
|
||||
static size_t scanDir(const string &sFilePath, vector<string> &vtMatchFiles, FILE_SELECT f = NULL, int iMaxSize = 0);
|
||||
/**
|
||||
* @brief 扫描一个目录.
|
||||
*
|
||||
* @param sFilePath 需要扫描的路径
|
||||
* @param vtMatchFiles 返回的文件名矢量表
|
||||
* @param f 匹配函数,为NULL表示所有文件都获取
|
||||
* @param iMaxSize 最大文件个数,iMaxSize <=0时,返回所有匹配文件
|
||||
* @return 文件个数
|
||||
*/
|
||||
static size_t scanDir(const string &sFilePath, vector<string> &vtMatchFiles, FILE_SELECT f = NULL, int iMaxSize = 0);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 遍历目录, 获取目录下面的所有文件和子目录.
|
||||
*
|
||||
* @param path 需要遍历的路径
|
||||
* @param files 目标路径下面所有文件
|
||||
* @param bRecursive 是否递归子目录
|
||||
*
|
||||
**/
|
||||
static void listDirectory(const string &path, vector<string> &files, bool bRecursive);
|
||||
|
||||
/**
|
||||
* @brief 复制文件或目录.
|
||||
* 将文件或者目录从sExistFile复制到sNewFile
|
||||
* @param sExistFile 复制的文件或者目录源路径
|
||||
* @param sNewFile 复制的文件或者目录目标路径
|
||||
* @param bRemove 是否先删除sNewFile再copy ,防止Textfile busy导致复制失败
|
||||
* @return
|
||||
*/
|
||||
static void copyFile(const string &sExistFile, const string &sNewFile,bool bRemove = false);
|
||||
/**
|
||||
* @brief 遍历目录, 获取目录下面的所有文件和子目录.
|
||||
*
|
||||
* @param path 需要遍历的路径
|
||||
* @param files 目标路径下面所有文件
|
||||
* @param bRecursive 是否递归子目录
|
||||
*
|
||||
**/
|
||||
static void listDirectory(const string &path, vector<string> &files, bool bRecursive);
|
||||
|
||||
/**
|
||||
* @brief 复制文件或目录.
|
||||
* 将文件或者目录从sExistFile复制到sNewFile
|
||||
* @param sExistFile 复制的文件或者目录源路径
|
||||
* @param sNewFile 复制的文件或者目录目标路径
|
||||
* @param bRemove 是否先删除sNewFile再copy ,防止Textfile busy导致复制失败
|
||||
* @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
|
||||
|
|
|
@ -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 存在返回true,否则返回false
|
||||
*/
|
||||
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,
|
||||
* def,参数按照顺序在vector中
|
||||
* @return vector<string> 顺序存放参数的vector
|
||||
*/
|
||||
const vector<string>& getSingle() const;
|
||||
|
||||
/**
|
||||
* @brief 获取所有--标识的参数.
|
||||
|
|
46
third_partly/util/include/util/tc_platform.h
Normal file
46
third_partly/util/include/util/tc_platform.h
Normal 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
|
69
third_partly/util/include/util/tc_port.h
Executable file
69
third_partly/util/include/util/tc_port.h
Executable 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
|
|
@ -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,204 +15,291 @@
|
|||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = t ? '1' : '0';
|
||||
buf[1] = '\0';
|
||||
return string(buf);
|
||||
char buf[2];
|
||||
buf[0] = t ? '1' : '0';
|
||||
buf[1] = '\0';
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<char>(const char &t)
|
||||
{
|
||||
char buf[2];
|
||||
snprintf(buf, 2, "%c", t);
|
||||
return string(buf);
|
||||
char buf[2];
|
||||
snprintf(buf, 2, "%c", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<unsigned char>(const unsigned char &t)
|
||||
{
|
||||
char buf[2];
|
||||
snprintf(buf, 2, "%c", t);
|
||||
return string(buf);
|
||||
char buf[2];
|
||||
snprintf(buf, 2, "%c", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<short>(const short &t)
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%d", t);
|
||||
return string(buf);
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%d", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<unsigned short>(const unsigned short &t)
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%u", t);
|
||||
return string(buf);
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%u", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<int>(const int &t)
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%d", t);
|
||||
return string(buf);
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%d", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<unsigned int>(const unsigned int &t)
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%u", t);
|
||||
return string(buf);
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%u", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<long>(const long &t)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%ld", t);
|
||||
return string(buf);
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%ld", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<long long>(const long long &t)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%lld", t);
|
||||
return string(buf);
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%lld", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<unsigned long>(const unsigned long &t)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%lu", t);
|
||||
return string(buf);
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%lu", t);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
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;
|
||||
int pos = int(s.size() - 1);
|
||||
for(; pos > 0; --pos)
|
||||
{
|
||||
if(s[pos] == '0')
|
||||
{
|
||||
bFlag = true;
|
||||
if(s[pos-1] == '.')
|
||||
{
|
||||
//-2为了去掉"."号
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
|
||||
bool bFlag = false;
|
||||
int pos = int(s.size() - 1);
|
||||
for(; pos > 0; --pos)
|
||||
{
|
||||
if(s[pos] == '0')
|
||||
{
|
||||
bFlag = true;
|
||||
if(s[pos-1] == '.')
|
||||
{
|
||||
//-2为了去掉"."号
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bFlag)
|
||||
s = s.substr(0, pos+1);
|
||||
if(bFlag)
|
||||
s = s.substr(0, pos + 1);
|
||||
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
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);
|
||||
for(; pos > 0; --pos)
|
||||
{
|
||||
if(s[pos] == '0')
|
||||
{
|
||||
bFlag = true;
|
||||
if(s[pos-1] == '.')
|
||||
{
|
||||
//-2为了去掉"."号
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
|
||||
bool bFlag = false;
|
||||
int pos = int(s.size() - 1);
|
||||
for(; pos > 0; --pos)
|
||||
{
|
||||
if(s[pos] == '0')
|
||||
{
|
||||
bFlag = true;
|
||||
if(s[pos-1] == '.')
|
||||
{
|
||||
//-2为了去掉"."号
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(bFlag)
|
||||
s = s.substr(0, pos + 1);
|
||||
|
||||
if(bFlag)
|
||||
s = s.substr(0, pos+1);
|
||||
|
||||
return s;
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<long double>(const long double &t)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%Lf", t);
|
||||
string s(buf);
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "%Lf", t);
|
||||
string s(buf);
|
||||
|
||||
//去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
|
||||
bool bFlag = false;
|
||||
int pos = int(s.size() - 1);
|
||||
for(; pos > 0; --pos)
|
||||
{
|
||||
if(s[pos] == '0')
|
||||
{
|
||||
bFlag = true;
|
||||
if(s[pos-1] == '.')
|
||||
{
|
||||
//-2为了去掉"."号
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
|
||||
bool bFlag = false;
|
||||
int pos = int(s.size() - 1);
|
||||
for(; pos > 0; --pos)
|
||||
{
|
||||
if(s[pos] == '0')
|
||||
{
|
||||
bFlag = true;
|
||||
if(s[pos-1] == '.')
|
||||
{
|
||||
//-2为了去掉"."号
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bFlag)
|
||||
s = s.substr(0, pos+1);
|
||||
if(bFlag)
|
||||
s = s.substr(0, pos + 1);
|
||||
|
||||
return s;
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
string TC_Common::tostr<std::string>(const std::string &t)
|
||||
{
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
string TC_Common::trim(const string &sStr, const string &s, bool bChar)
|
||||
|
@ -227,10 +314,10 @@ string TC_Common::trim(const string &sStr, const string &s, bool bChar)
|
|||
*/
|
||||
if(!bChar)
|
||||
{
|
||||
return trimright(trimleft(sStr, s, false), s, false);
|
||||
return trimright(trimleft(sStr, s, false), s, false);
|
||||
}
|
||||
|
||||
return trimright(trimleft(sStr, s, true), s, true);
|
||||
return trimright(trimleft(sStr, s, true), s, true);
|
||||
}
|
||||
|
||||
string TC_Common::trimleft(const string &sStr, const string &s, bool bChar)
|
||||
|
@ -252,7 +339,7 @@ string TC_Common::trimleft(const string &sStr, const string &s, bool bChar)
|
|||
|
||||
if(sStr.compare(0, s.length(), s) == 0)
|
||||
{
|
||||
return sStr.substr(s.length());
|
||||
return sStr.substr(s.length());
|
||||
}
|
||||
|
||||
return sStr;
|
||||
|
@ -274,7 +361,7 @@ string TC_Common::trimleft(const string &sStr, const string &s, bool bChar)
|
|||
|
||||
if(pos == 0) return sStr;
|
||||
|
||||
return sStr.substr(pos);
|
||||
return sStr.substr(pos);
|
||||
}
|
||||
|
||||
string TC_Common::trimright(const string &sStr, const string &s, bool bChar)
|
||||
|
@ -296,7 +383,7 @@ string TC_Common::trimright(const string &sStr, const string &s, bool bChar)
|
|||
|
||||
if(sStr.compare(sStr.length() - s.length(), s.length(), s) == 0)
|
||||
{
|
||||
return sStr.substr(0, sStr.length() - s.length());
|
||||
return sStr.substr(0, sStr.length() - s.length());
|
||||
}
|
||||
|
||||
return sStr;
|
||||
|
@ -318,7 +405,7 @@ string TC_Common::trimright(const string &sStr, const string &s, bool bChar)
|
|||
|
||||
if(pos == sStr.length()) return sStr;
|
||||
|
||||
return sStr.substr(0, pos);
|
||||
return sStr.substr(0, pos);
|
||||
}
|
||||
|
||||
string TC_Common::lower(const string &s)
|
||||
|
@ -329,7 +416,7 @@ string TC_Common::lower(const string &s)
|
|||
*iter = tolower(*iter);
|
||||
}
|
||||
|
||||
return sString;
|
||||
return sString;
|
||||
}
|
||||
|
||||
string TC_Common::upper(const string &s)
|
||||
|
@ -341,7 +428,7 @@ string TC_Common::upper(const string &s)
|
|||
*iter = toupper(*iter);
|
||||
}
|
||||
|
||||
return sString;
|
||||
return sString;
|
||||
}
|
||||
|
||||
bool TC_Common::isdigit(const string &sInput)
|
||||
|
@ -364,15 +451,56 @@ 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);
|
||||
return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm);
|
||||
}
|
||||
|
||||
string TC_Common::tm2str(const struct tm &stTm, const string &sFormat)
|
||||
|
@ -381,65 +509,91 @@ string TC_Common::tm2str(const struct tm &stTm, const string &sFormat)
|
|||
|
||||
strftime(sTimeString, sizeof(sTimeString), sFormat.c_str(), &stTm);
|
||||
|
||||
return string(sTimeString);
|
||||
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);
|
||||
struct tm 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);
|
||||
|
||||
return tm2str(tt, sFormat);
|
||||
}
|
||||
|
||||
string TC_Common::now2str(const string &sFormat)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
return tm2str(t, sFormat.c_str());
|
||||
return tm2str(t, sFormat.c_str());
|
||||
}
|
||||
|
||||
string TC_Common::now2GMTstr()
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
return tm2GMTstr(t);
|
||||
return tm2GMTstr(t);
|
||||
}
|
||||
|
||||
string TC_Common::tm2GMTstr(const time_t &t)
|
||||
{
|
||||
struct tm tt;
|
||||
gmtime_r(&t, &tt);
|
||||
return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT");
|
||||
|
||||
TC_Port::gmtime_r(&t, &tt);
|
||||
return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT");
|
||||
}
|
||||
|
||||
string TC_Common::tm2GMTstr(const struct tm &stTm)
|
||||
{
|
||||
return tm2str(stTm, "%a, %d %b %Y %H:%M:%S GMT");
|
||||
return tm2str(stTm, "%a, %d %b %Y %H:%M:%S GMT");
|
||||
}
|
||||
|
||||
string TC_Common::nowdate2str()
|
||||
{
|
||||
return now2str("%Y%m%d");
|
||||
return now2str("%Y%m%d");
|
||||
}
|
||||
|
||||
string TC_Common::nowtime2str()
|
||||
{
|
||||
return now2str("%H%M%S");
|
||||
return now2str("%H%M%S");
|
||||
}
|
||||
|
||||
int64_t TC_Common::now2ms()
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
TC_Common::gettimeofday(tv);
|
||||
|
||||
return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000;
|
||||
return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -470,17 +624,17 @@ string TC_Common::bin2str(const void *buf, size_t len, const string &sSep, size_
|
|||
}
|
||||
}
|
||||
|
||||
return sOut;
|
||||
return sOut;
|
||||
}
|
||||
|
||||
string TC_Common::bin2str(const string &sBinData, const string &sSep, size_t lines)
|
||||
{
|
||||
return bin2str((const void *)sBinData.data(), sBinData.length(), sSep, lines);
|
||||
return bin2str((const void *) sBinData.data(), sBinData.length(), sSep, lines);
|
||||
}
|
||||
|
||||
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++;
|
||||
|
@ -508,7 +662,7 @@ string TC_Common::str2bin(const string &sString, const string &sSep, size_t line
|
|||
}
|
||||
}
|
||||
|
||||
return sBinData;
|
||||
return sBinData;
|
||||
}
|
||||
|
||||
char TC_Common::x2c(const string &sWhat)
|
||||
|
@ -544,33 +698,33 @@ string TC_Common::replace(const string &sString, const string &sSrc, const strin
|
|||
pos += sDest.length();
|
||||
}
|
||||
|
||||
return sBuf;
|
||||
return sBuf;
|
||||
}
|
||||
|
||||
string TC_Common::replace(const string &sString, const map<string,string>& mSrcDest)
|
||||
{
|
||||
if(sString.empty())
|
||||
{
|
||||
return sString;
|
||||
}
|
||||
if(sString.empty())
|
||||
{
|
||||
return sString;
|
||||
}
|
||||
|
||||
string tmp = sString;
|
||||
map<string,string>::const_iterator it = mSrcDest.begin();
|
||||
string tmp = sString;
|
||||
map<string,string>::const_iterator it = mSrcDest.begin();
|
||||
|
||||
while(it != mSrcDest.end())
|
||||
{
|
||||
while(it != mSrcDest.end())
|
||||
{
|
||||
|
||||
string::size_type pos = 0;
|
||||
while((pos = tmp.find(it->first, pos)) != string::npos)
|
||||
{
|
||||
tmp.replace(pos, it->first.length(), it->second);
|
||||
pos += it->second.length();
|
||||
}
|
||||
string::size_type pos = 0;
|
||||
while((pos = tmp.find(it->first, pos)) != string::npos)
|
||||
{
|
||||
tmp.replace(pos, it->first.length(), it->second);
|
||||
pos += it->second.length();
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool TC_Common::matchPeriod(const string& s, const string& pat)
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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,272 +13,394 @@
|
|||
* 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)
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
#include <windows.h>
|
||||
|
||||
void TC_Encoder::gbk2utf8(const string &sIn, vector<string> &vtStr)
|
||||
{
|
||||
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;
|
||||
|
||||
cd = iconv_open("UTF-8","GBK");
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error", errno);
|
||||
}
|
||||
|
||||
string sOut;
|
||||
|
||||
for(string::size_type pos = 0; pos < sIn.length(); ++pos)
|
||||
{
|
||||
if((unsigned char)sIn[pos] == 0x80)
|
||||
{
|
||||
//注意GBK的0x80转换为UTF-8时为E2 82 AC
|
||||
sOut += 0xe2;
|
||||
sOut += 0x82;
|
||||
sOut += 0xac;
|
||||
}
|
||||
else if((unsigned char)sIn[pos] < 0x80)
|
||||
if((unsigned char)sIn[pos] < 0x80)
|
||||
{
|
||||
//单字节(GBK: 0x00-0x7F)
|
||||
sOut += sIn[pos];
|
||||
}
|
||||
sOut += sIn[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
//双字节
|
||||
size_t sizeGbkLen = 2;
|
||||
char pIn[128] = "\0";
|
||||
|
||||
strncpy(pIn, sIn.c_str() + pos, sizeGbkLen);
|
||||
char *p = pIn;
|
||||
strncpy(pIn, sIn.c_str() + pos, 2);
|
||||
|
||||
size_t sizeLeftLen = 128;
|
||||
char pOut[128] = "\0";
|
||||
char *o = pOut;
|
||||
int iRet = iconv(cd, &p, &sizeGbkLen, (char **)&o, &sizeLeftLen);
|
||||
if(iRet < 0)
|
||||
{
|
||||
//转换不了, 暂时替换为空格
|
||||
sOut += ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
sOut += pOut;
|
||||
}
|
||||
sOut = gbk2utf8(pIn);
|
||||
|
||||
++pos;
|
||||
}
|
||||
|
||||
}
|
||||
vtStr.push_back(sOut);
|
||||
}
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
return sOut;
|
||||
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;
|
||||
|
||||
cd = iconv_open("UTF-8","GBK");
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
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;
|
||||
|
||||
for(string::size_type pos = 0; pos < sIn.length(); ++pos)
|
||||
{
|
||||
if((unsigned char)sIn[pos] == 0x80)
|
||||
{
|
||||
//注意GBK的0x80转换为UTF-8时为E2 82 AC
|
||||
sOut += 0xe2;
|
||||
sOut += 0x82;
|
||||
sOut += 0xac;
|
||||
}
|
||||
else if((unsigned char)sIn[pos] < 0x80)
|
||||
{
|
||||
//单字节(GBK: 0x00-0x7F)
|
||||
sOut += sIn[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
//双字节
|
||||
size_t sizeGbkLen = 2;
|
||||
char pIn[128] = "\0";
|
||||
|
||||
strncpy(pIn, sIn.c_str() + pos, sizeGbkLen);
|
||||
char *p = pIn;
|
||||
|
||||
size_t sizeLeftLen = 128;
|
||||
char pOut[128] = "\0";
|
||||
char *o = pOut;
|
||||
int iRet = iconv(cd, &p, &sizeGbkLen, (char **)&o, &sizeLeftLen);
|
||||
if(iRet < 0)
|
||||
{
|
||||
//转换不了, 暂时替换为空格
|
||||
sOut += ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
sOut += pOut;
|
||||
}
|
||||
|
||||
++pos;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
return sOut;
|
||||
}
|
||||
|
||||
void TC_Encoder::gbk2utf8(const string &sIn, vector<string> &vtStr)
|
||||
{
|
||||
iconv_t cd;
|
||||
iconv_t cd;
|
||||
|
||||
cd = iconv_open("UTF-8","GBK");
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
throw TC_Encoder_Exception("[TC_Encoder::gbk2utf8] iconv_open error", errno);
|
||||
}
|
||||
cd = iconv_open("UTF-8","GBK");
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
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();
|
||||
vtStr.clear();
|
||||
|
||||
for(string::size_type pos = 0; pos < sIn.length(); ++pos)
|
||||
{
|
||||
string sOut;
|
||||
for(string::size_type pos = 0; pos < sIn.length(); ++pos)
|
||||
{
|
||||
string sOut;
|
||||
|
||||
if((unsigned char)sIn[pos] == 0x80)
|
||||
{
|
||||
//注意GBK的0x80转换为UTF-8时为E2 82 AC
|
||||
sOut += 0xe2;
|
||||
sOut += 0x82;
|
||||
sOut += 0xac;
|
||||
}
|
||||
else if((unsigned char)sIn[pos] < 0x80)
|
||||
{
|
||||
//单字节(GBK: 0x00-0x7F)
|
||||
sOut += sIn[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
//双字节
|
||||
size_t iGbkLen = 2;
|
||||
char pIn[128] = "\0";
|
||||
if((unsigned char)sIn[pos] == 0x80)
|
||||
{
|
||||
//注意GBK的0x80转换为UTF-8时为E2 82 AC
|
||||
sOut += 0xe2;
|
||||
sOut += 0x82;
|
||||
sOut += 0xac;
|
||||
}
|
||||
else if((unsigned char)sIn[pos] < 0x80)
|
||||
{
|
||||
//单字节(GBK: 0x00-0x7F)
|
||||
sOut += sIn[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
//双字节
|
||||
size_t iGbkLen = 2;
|
||||
char pIn[128] = "\0";
|
||||
|
||||
strncpy(pIn, sIn.c_str() + pos, iGbkLen);
|
||||
char *p = pIn;
|
||||
strncpy(pIn, sIn.c_str() + pos, iGbkLen);
|
||||
char *p = pIn;
|
||||
|
||||
size_t iLeftLen = 128;
|
||||
char pOut[128] = "\0";
|
||||
char *o = pOut;
|
||||
int iRet = iconv(cd, &p, (size_t *)&iGbkLen, (char **)&o, (size_t *)&iLeftLen);
|
||||
if(iRet < 0)
|
||||
{
|
||||
//转换不了, 暂时替换为空格
|
||||
sOut += ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
sOut += pOut;
|
||||
}
|
||||
size_t iLeftLen = 128;
|
||||
char pOut[128] = "\0";
|
||||
char *o = pOut;
|
||||
int iRet = iconv(cd, &p, (size_t *)&iGbkLen, (char **)&o, (size_t *)&iLeftLen);
|
||||
if(iRet < 0)
|
||||
{
|
||||
//转换不了, 暂时替换为空格
|
||||
sOut += ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
sOut += pOut;
|
||||
}
|
||||
|
||||
++pos;
|
||||
++pos;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
vtStr.push_back(sOut);
|
||||
}
|
||||
vtStr.push_back(sOut);
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
cd = iconv_open("GBK","UTF-8");
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
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;
|
||||
size_t sizeLeftLen = iMaxOutLen;
|
||||
size_t sizeInLen = iInLen;
|
||||
char* pOut = sOut;
|
||||
char * pIn = (char*)sIn;
|
||||
size_t sizeLeftLen = iMaxOutLen;
|
||||
size_t sizeInLen = iInLen;
|
||||
char* pOut = sOut;
|
||||
|
||||
size_t ret = iconv(cd, &pIn, &sizeInLen, (char **)&sOut, &sizeLeftLen);
|
||||
if (ret == (size_t) - 1)
|
||||
{
|
||||
iMaxOutLen = 0;
|
||||
iconv_close(cd);
|
||||
throw TC_Encoder_Exception("[TC_Encoder::utf82gbk] iconv error", errno);
|
||||
return;
|
||||
}
|
||||
size_t ret = iconv(cd, &pIn, &sizeInLen, (char **)&sOut, &sizeLeftLen);
|
||||
if (ret == (size_t) - 1)
|
||||
{
|
||||
iMaxOutLen = 0;
|
||||
iconv_close(cd);
|
||||
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;
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
iconv_close(cd);
|
||||
|
||||
pOut[iMaxOutLen - (int)sizeLeftLen] = '\0';
|
||||
pOut[iMaxOutLen - (int)sizeLeftLen] = '\0';
|
||||
|
||||
iMaxOutLen = iMaxOutLen - (int)sizeLeftLen;
|
||||
iMaxOutLen = iMaxOutLen - (int)sizeLeftLen;
|
||||
}
|
||||
|
||||
string TC_Encoder::utf82gbk(const string &sIn)
|
||||
{
|
||||
if(sIn.length() == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if(sIn.length() == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string sOut;
|
||||
string sOut;
|
||||
|
||||
int iLen = sIn.length() * 2 + 1;
|
||||
char *pOut = new char[iLen];
|
||||
int iLen = sIn.length() * 2 + 1;
|
||||
char *pOut = new char[iLen];
|
||||
|
||||
try
|
||||
{
|
||||
utf82gbk(pOut, iLen, sIn.c_str(), sIn.length());
|
||||
}
|
||||
catch (TC_Encoder_Exception& e)
|
||||
{
|
||||
delete[] pOut;
|
||||
try
|
||||
{
|
||||
utf82gbk(pOut, iLen, sIn.c_str(), sIn.length());
|
||||
}
|
||||
catch (TC_Encoder_Exception& e)
|
||||
{
|
||||
delete[] pOut;
|
||||
|
||||
throw e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
sOut.assign(pOut, iLen);
|
||||
sOut.assign(pOut, iLen);
|
||||
|
||||
delete[] pOut;
|
||||
delete[] pOut;
|
||||
|
||||
return sOut;
|
||||
return sOut;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \n -> \r\0
|
||||
* \r -> \r\r
|
||||
*/
|
||||
string TC_Encoder::transTo(const string& str, char f /*='\n'*/, char t /*= '\r'*/, char u /*= '\0'*/)
|
||||
{
|
||||
string ret = str;
|
||||
string ret = str;
|
||||
|
||||
for (size_t i = 0; i < ret.length(); ++i)
|
||||
{
|
||||
if (ret[i] == f)
|
||||
{
|
||||
ret[i] = t;
|
||||
for (size_t i = 0; i < ret.length(); ++i)
|
||||
{
|
||||
if (ret[i] == f)
|
||||
{
|
||||
ret[i] = t;
|
||||
|
||||
ret.insert(++i, 1, u);
|
||||
}
|
||||
else if (ret[i] == t)
|
||||
{
|
||||
ret.insert(++i, 1, t);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
ret.insert(++i, 1, u);
|
||||
}
|
||||
else if (ret[i] == t)
|
||||
{
|
||||
ret.insert(++i, 1, t);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -287,24 +409,26 @@ string TC_Encoder::transTo(const string& str, char f /*='\n'*/, char t /*= '\r'*
|
|||
*/
|
||||
string TC_Encoder::transFrom(const string& str, char f /*= '\n'*/, char t /*= '\r'*/, char u /*= '\0'*/)
|
||||
{
|
||||
string ret = "";
|
||||
string ret = "";
|
||||
|
||||
for (string::const_iterator it = str.begin()
|
||||
; it != str.end()
|
||||
; ++it)
|
||||
{
|
||||
ret.append(1, *it);
|
||||
for (string::const_iterator it = str.begin()
|
||||
; it != str.end()
|
||||
; ++it)
|
||||
{
|
||||
ret.append(1, *it);
|
||||
|
||||
if (*it == t)
|
||||
{
|
||||
if (*(++it) == u)
|
||||
{
|
||||
*ret.rbegin() = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
if (*it == t)
|
||||
{
|
||||
if (*(++it) == u)
|
||||
{
|
||||
*ret.rbegin() = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -56,7 +61,60 @@ void TC_Exception::getBacktrace()
|
|||
_buffer += symbols[i];
|
||||
_buffer += "\n";
|
||||
}
|
||||
free(symbols);
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,32 +46,39 @@ 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;
|
||||
}
|
||||
|
||||
if (!(f_stat.st_mode & iFileType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(f_stat.st_mode & 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)
|
||||
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,81 +380,43 @@ 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");
|
||||
if(fp == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
FILE *fp = TC_Port::fopen(sFullFileName.c_str(), "wb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t ret = fwrite((void*)sFileData, 1, length, fp);
|
||||
fclose(fp);
|
||||
size_t ret = fwrite((void*)sFileData, 1, length, fp);
|
||||
fclose(fp);
|
||||
|
||||
if(ret == length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
if(ret == length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
string TC_File::extractFileName(const string &sFullFileName)
|
||||
|
@ -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,40 +526,43 @@ 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();
|
||||
vtMatchFiles.clear();
|
||||
|
||||
struct dirent **namelist;
|
||||
int n = scandir(sFilePath.c_str(), &namelist, f, alphasort);
|
||||
struct dirent **namelist;
|
||||
int n = scandir(sFilePath.c_str(), &namelist, f, alphasort);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(n-- )
|
||||
{
|
||||
if(iMaxSize > 0 && vtMatchFiles.size() >= (size_t)iMaxSize )
|
||||
{
|
||||
free(namelist[n]);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtMatchFiles.push_back(namelist[n]->d_name);
|
||||
free(namelist[n]);
|
||||
}
|
||||
}
|
||||
free(namelist);
|
||||
}
|
||||
if (n < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(n-- )
|
||||
{
|
||||
if(iMaxSize > 0 && vtMatchFiles.size() >= (size_t)iMaxSize )
|
||||
{
|
||||
free(namelist[n]);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtMatchFiles.push_back(namelist[n]->d_name);
|
||||
free(namelist[n]);
|
||||
}
|
||||
}
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return vtMatchFiles.size();
|
||||
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] == "..")
|
||||
continue;
|
||||
string s = sExistFile + "/" + tf[i];
|
||||
string d = sNewFile + "/" + tf[i];
|
||||
string fileName = TC_File::extractFileName(tf[i]);
|
||||
if(fileName == "." || fileName == "..")
|
||||
continue;
|
||||
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();
|
||||
|
||||
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] == ':');
|
||||
}
|
||||
}
|
|
@ -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
174
third_partly/util/src/tc_port.cpp
Executable 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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user