mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2026-06-21 01:07:11 +02:00
Major plugin refactor and cleanup.
Switched to POCO library for unified platform/library interface. Deprecated the external module API. It was creating more problems than solving. Removed most built-in libraries in favor of system libraries for easier maintenance. Cleaned and secured code with help from static analyzers.
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// ASCIIEncoding.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Text
|
||||
// Module: ASCIIEncoding
|
||||
//
|
||||
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ASCIIEncoding.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const char* ASCIIEncoding::_names[] =
|
||||
{
|
||||
"US-ASCII",
|
||||
"ASCII",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap ASCIIEncoding::_charMap =
|
||||
{
|
||||
/* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
/* 10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
/* 20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
/* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
/* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
/* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
/* 60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
/* 70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
/* 80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* 90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* a0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* b0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* c0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* d0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* e0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
/* f0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
|
||||
ASCIIEncoding::ASCIIEncoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ASCIIEncoding::~ASCIIEncoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char* ASCIIEncoding::canonicalName() const
|
||||
{
|
||||
return _names[0];
|
||||
}
|
||||
|
||||
|
||||
bool ASCIIEncoding::isA(const std::string& encodingName) const
|
||||
{
|
||||
for (const char** name = _names; *name; ++name)
|
||||
{
|
||||
if (Poco::icompare(encodingName, *name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap& ASCIIEncoding::characterMap() const
|
||||
{
|
||||
return _charMap;
|
||||
}
|
||||
|
||||
|
||||
int ASCIIEncoding::convert(const unsigned char* bytes) const
|
||||
{
|
||||
return _charMap[*bytes];
|
||||
}
|
||||
|
||||
|
||||
int ASCIIEncoding::convert(int ch, unsigned char* bytes, int length) const
|
||||
{
|
||||
if (ch >= 0 && ch <= 127)
|
||||
{
|
||||
if (bytes && length >= 1)
|
||||
*bytes = (unsigned char) ch;
|
||||
return 1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
int ASCIIEncoding::queryConvert(const unsigned char* bytes, int length) const
|
||||
{
|
||||
if (1 <= length)
|
||||
return _charMap [*bytes];
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int ASCIIEncoding::sequenceLength(const unsigned char* /*bytes*/, int /*length*/) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// AbstractObserver.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Notifications
|
||||
// Module: NotificationCenter
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/AbstractObserver.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
AbstractObserver::AbstractObserver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AbstractObserver::AbstractObserver(const AbstractObserver& /*observer*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AbstractObserver::~AbstractObserver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AbstractObserver& AbstractObserver::operator = (const AbstractObserver& /*observer*/)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// ActiveDispatcher.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: ActiveObjects
|
||||
//
|
||||
// Copyright (c) 2006-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ActiveDispatcher.h"
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class MethodNotification: public Notification
|
||||
{
|
||||
public:
|
||||
MethodNotification(ActiveRunnableBase::Ptr pRunnable):
|
||||
_pRunnable(pRunnable)
|
||||
{
|
||||
}
|
||||
|
||||
ActiveRunnableBase::Ptr runnable() const
|
||||
{
|
||||
return _pRunnable;
|
||||
}
|
||||
|
||||
private:
|
||||
ActiveRunnableBase::Ptr _pRunnable;
|
||||
};
|
||||
|
||||
class StopNotification: public Notification
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
ActiveDispatcher::ActiveDispatcher()
|
||||
{
|
||||
_thread.start(*this);
|
||||
}
|
||||
|
||||
|
||||
ActiveDispatcher::ActiveDispatcher(Thread::Priority prio)
|
||||
{
|
||||
_thread.setPriority(prio);
|
||||
_thread.start(*this);
|
||||
}
|
||||
|
||||
|
||||
ActiveDispatcher::~ActiveDispatcher()
|
||||
{
|
||||
try
|
||||
{
|
||||
stop();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ActiveDispatcher::start(ActiveRunnableBase::Ptr pRunnable)
|
||||
{
|
||||
poco_check_ptr (pRunnable);
|
||||
|
||||
_queue.enqueueNotification(new MethodNotification(pRunnable));
|
||||
}
|
||||
|
||||
|
||||
void ActiveDispatcher::cancel()
|
||||
{
|
||||
_queue.clear();
|
||||
}
|
||||
|
||||
|
||||
void ActiveDispatcher::run()
|
||||
{
|
||||
AutoPtr<Notification> pNf = _queue.waitDequeueNotification();
|
||||
while (pNf && !dynamic_cast<StopNotification*>(pNf.get()))
|
||||
{
|
||||
MethodNotification* pMethodNf = dynamic_cast<MethodNotification*>(pNf.get());
|
||||
poco_check_ptr (pMethodNf);
|
||||
ActiveRunnableBase::Ptr pRunnable = pMethodNf->runnable();
|
||||
pRunnable->duplicate(); // run will release
|
||||
pRunnable->run();
|
||||
pRunnable = 0;
|
||||
pNf = 0;
|
||||
pNf = _queue.waitDequeueNotification();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ActiveDispatcher::stop()
|
||||
{
|
||||
_queue.clear();
|
||||
_queue.wakeUpAll();
|
||||
_queue.enqueueNotification(new StopNotification);
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
//
|
||||
// ArchiveStrategy.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: FileChannel
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ArchiveStrategy.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/DeflatingStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/ActiveDispatcher.h"
|
||||
#include "Poco/ActiveMethod.h"
|
||||
#include "Poco/Void.h"
|
||||
#include "Poco/FileStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
//
|
||||
// ArchiveCompressor
|
||||
//
|
||||
|
||||
|
||||
class ArchiveCompressor: public ActiveDispatcher
|
||||
{
|
||||
public:
|
||||
ArchiveCompressor():
|
||||
compress(this, &ArchiveCompressor::compressImpl)
|
||||
{
|
||||
}
|
||||
|
||||
~ArchiveCompressor()
|
||||
{
|
||||
}
|
||||
|
||||
ActiveMethod<void, std::string, ArchiveCompressor, ActiveStarter<ActiveDispatcher>> compress;
|
||||
|
||||
protected:
|
||||
void compressImpl(const std::string& path)
|
||||
{
|
||||
std::string gzPath(path);
|
||||
gzPath.append(".gz");
|
||||
FileInputStream istr(path);
|
||||
FileOutputStream ostr(gzPath);
|
||||
try
|
||||
{
|
||||
DeflatingOutputStream deflater(ostr, DeflatingStreamBuf::STREAM_GZIP);
|
||||
StreamCopier::copyStream(istr, deflater);
|
||||
if (!deflater.good() || !ostr.good()) throw WriteFileException(gzPath);
|
||||
deflater.close();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
catch (Poco::Exception&)
|
||||
{
|
||||
// deflating failed - remove gz file and leave uncompressed log file
|
||||
ostr.close();
|
||||
Poco::File gzf(gzPath);
|
||||
gzf.remove();
|
||||
return;
|
||||
}
|
||||
File f(path);
|
||||
f.remove();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// ArchiveStrategy
|
||||
//
|
||||
|
||||
|
||||
ArchiveStrategy::ArchiveStrategy():
|
||||
_compress(false),
|
||||
_pCompressor(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ArchiveStrategy::~ArchiveStrategy()
|
||||
{
|
||||
delete _pCompressor;
|
||||
}
|
||||
|
||||
|
||||
void ArchiveStrategy::compress(bool flag)
|
||||
{
|
||||
_compress = flag;
|
||||
}
|
||||
|
||||
|
||||
void ArchiveStrategy::moveFile(const std::string& oldPath, const std::string& newPath)
|
||||
{
|
||||
bool compressed = false;
|
||||
Path p(oldPath);
|
||||
File f(oldPath);
|
||||
if (!f.exists())
|
||||
{
|
||||
f = oldPath + ".gz";
|
||||
compressed = true;
|
||||
}
|
||||
std::string mvPath(newPath);
|
||||
if (_compress || compressed)
|
||||
mvPath.append(".gz");
|
||||
if (!_compress || compressed)
|
||||
{
|
||||
f.renameTo(mvPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.renameTo(newPath);
|
||||
if (!_pCompressor) _pCompressor = new ArchiveCompressor;
|
||||
_pCompressor->compress(newPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ArchiveStrategy::exists(const std::string& name)
|
||||
{
|
||||
File f(name);
|
||||
if (f.exists())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (_compress)
|
||||
{
|
||||
std::string gzName(name);
|
||||
gzName.append(".gz");
|
||||
File gzf(gzName);
|
||||
return gzf.exists();
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ArchiveByNumberStrategy
|
||||
//
|
||||
|
||||
|
||||
ArchiveByNumberStrategy::ArchiveByNumberStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ArchiveByNumberStrategy::~ArchiveByNumberStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogFile* ArchiveByNumberStrategy::archive(LogFile* pFile)
|
||||
{
|
||||
std::string basePath = pFile->path();
|
||||
delete pFile;
|
||||
int n = -1;
|
||||
std::string path;
|
||||
do
|
||||
{
|
||||
path = basePath;
|
||||
path.append(".");
|
||||
NumberFormatter::append(path, ++n);
|
||||
}
|
||||
while (exists(path));
|
||||
|
||||
while (n >= 0)
|
||||
{
|
||||
std::string oldPath = basePath;
|
||||
if (n > 0)
|
||||
{
|
||||
oldPath.append(".");
|
||||
NumberFormatter::append(oldPath, n - 1);
|
||||
}
|
||||
std::string newPath = basePath;
|
||||
newPath.append(".");
|
||||
NumberFormatter::append(newPath, n);
|
||||
moveFile(oldPath, newPath);
|
||||
--n;
|
||||
}
|
||||
return new LogFile(basePath);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+154
@@ -0,0 +1,154 @@
|
||||
//
|
||||
// Ascii.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Ascii
|
||||
//
|
||||
// Copyright (c) 2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Ascii.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const int Ascii::CHARACTER_PROPERTIES[128] =
|
||||
{
|
||||
/* 00 . */ ACP_CONTROL,
|
||||
/* 01 . */ ACP_CONTROL,
|
||||
/* 02 . */ ACP_CONTROL,
|
||||
/* 03 . */ ACP_CONTROL,
|
||||
/* 04 . */ ACP_CONTROL,
|
||||
/* 05 . */ ACP_CONTROL,
|
||||
/* 06 . */ ACP_CONTROL,
|
||||
/* 07 . */ ACP_CONTROL,
|
||||
/* 08 . */ ACP_CONTROL,
|
||||
/* 09 . */ ACP_CONTROL | ACP_SPACE,
|
||||
/* 0a . */ ACP_CONTROL | ACP_SPACE,
|
||||
/* 0b . */ ACP_CONTROL | ACP_SPACE,
|
||||
/* 0c . */ ACP_CONTROL | ACP_SPACE,
|
||||
/* 0d . */ ACP_CONTROL | ACP_SPACE,
|
||||
/* 0e . */ ACP_CONTROL,
|
||||
/* 0f . */ ACP_CONTROL,
|
||||
/* 10 . */ ACP_CONTROL,
|
||||
/* 11 . */ ACP_CONTROL,
|
||||
/* 12 . */ ACP_CONTROL,
|
||||
/* 13 . */ ACP_CONTROL,
|
||||
/* 14 . */ ACP_CONTROL,
|
||||
/* 15 . */ ACP_CONTROL,
|
||||
/* 16 . */ ACP_CONTROL,
|
||||
/* 17 . */ ACP_CONTROL,
|
||||
/* 18 . */ ACP_CONTROL,
|
||||
/* 19 . */ ACP_CONTROL,
|
||||
/* 1a . */ ACP_CONTROL,
|
||||
/* 1b . */ ACP_CONTROL,
|
||||
/* 1c . */ ACP_CONTROL,
|
||||
/* 1d . */ ACP_CONTROL,
|
||||
/* 1e . */ ACP_CONTROL,
|
||||
/* 1f . */ ACP_CONTROL,
|
||||
/* 20 */ ACP_SPACE | ACP_PRINT,
|
||||
/* 21 ! */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 22 " */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 23 # */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 24 $ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 25 % */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 26 & */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 27 ' */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 28 ( */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 29 ) */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 2a * */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 2b + */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 2c , */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 2d - */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 2e . */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 2f / */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 30 0 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 31 1 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 32 2 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 33 3 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 34 4 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 35 5 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 36 6 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 37 7 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 38 8 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 39 9 */ ACP_DIGIT | ACP_HEXDIGIT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 3a : */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 3b ; */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 3c < */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 3d = */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 3e > */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 3f ? */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 40 @ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 41 A */ ACP_HEXDIGIT | ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 42 B */ ACP_HEXDIGIT | ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 43 C */ ACP_HEXDIGIT | ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 44 D */ ACP_HEXDIGIT | ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 45 E */ ACP_HEXDIGIT | ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 46 F */ ACP_HEXDIGIT | ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 47 G */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 48 H */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 49 I */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 4a J */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 4b K */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 4c L */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 4d M */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 4e N */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 4f O */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 50 P */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 51 Q */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 52 R */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 53 S */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 54 T */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 55 U */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 56 V */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 57 W */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 58 X */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 59 Y */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 5a Z */ ACP_ALPHA | ACP_UPPER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 5b [ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 5c \ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 5d ] */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 5e ^ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 5f _ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 60 ` */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 61 a */ ACP_HEXDIGIT | ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 62 b */ ACP_HEXDIGIT | ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 63 c */ ACP_HEXDIGIT | ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 64 d */ ACP_HEXDIGIT | ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 65 e */ ACP_HEXDIGIT | ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 66 f */ ACP_HEXDIGIT | ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 67 g */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 68 h */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 69 i */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 6a j */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 6b k */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 6c l */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 6d m */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 6e n */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 6f o */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 70 p */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 71 q */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 72 r */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 73 s */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 74 t */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 75 u */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 76 v */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 77 w */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 78 x */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 79 y */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 7a z */ ACP_ALPHA | ACP_LOWER | ACP_GRAPH | ACP_PRINT,
|
||||
/* 7b { */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 7c | */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 7d } */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 7e ~ */ ACP_PUNCT | ACP_GRAPH | ACP_PRINT,
|
||||
/* 7f . */ ACP_CONTROL
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// AsyncChannel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: AsyncChannel
|
||||
//
|
||||
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/AsyncChannel.h"
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/Formatter.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/LoggingRegistry.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Format.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class MessageNotification: public Notification
|
||||
{
|
||||
public:
|
||||
MessageNotification(const Message& msg):
|
||||
_msg(msg)
|
||||
{
|
||||
}
|
||||
|
||||
~MessageNotification()
|
||||
{
|
||||
}
|
||||
|
||||
const Message& message() const
|
||||
{
|
||||
return _msg;
|
||||
}
|
||||
|
||||
private:
|
||||
Message _msg;
|
||||
};
|
||||
|
||||
|
||||
AsyncChannel::AsyncChannel(Channel::Ptr pChannel, Thread::Priority prio):
|
||||
_pChannel(pChannel),
|
||||
_thread("AsyncChannel")
|
||||
{
|
||||
_thread.setPriority(prio);
|
||||
}
|
||||
|
||||
|
||||
AsyncChannel::~AsyncChannel()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::setChannel(Channel::Ptr pChannel)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_channelMutex);
|
||||
|
||||
_pChannel = pChannel;
|
||||
}
|
||||
|
||||
|
||||
Channel::Ptr AsyncChannel::getChannel() const
|
||||
{
|
||||
return _pChannel;
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::open()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_threadMutex);
|
||||
|
||||
if (!_thread.isRunning()) _thread.start(*this);
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::close()
|
||||
{
|
||||
if (_thread.isRunning())
|
||||
{
|
||||
while (!_queue.empty()) Thread::sleep(100);
|
||||
|
||||
do
|
||||
{
|
||||
_queue.wakeUpAll();
|
||||
}
|
||||
while (!_thread.tryJoin(100));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::log(const Message& msg)
|
||||
{
|
||||
if (_queueSize != 0 && _queue.size() >= _queueSize)
|
||||
{
|
||||
++_dropCount;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dropCount != 0)
|
||||
{
|
||||
_queue.enqueueNotification(new MessageNotification(Message(msg, Poco::format("Dropped %z messages.", _dropCount))));
|
||||
_dropCount = 0;
|
||||
}
|
||||
|
||||
open();
|
||||
|
||||
_queue.enqueueNotification(new MessageNotification(msg));
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name == "channel")
|
||||
{
|
||||
setChannel(LoggingRegistry::defaultRegistry().channelForName(value));
|
||||
}
|
||||
else if (name == "priority")
|
||||
{
|
||||
setPriority(value);
|
||||
}
|
||||
else if (name == "queueSize")
|
||||
{
|
||||
if (Poco::icompare(value, "none") == 0 || Poco::icompare(value, "unlimited") == 0 || value.empty())
|
||||
_queueSize = 0;
|
||||
else
|
||||
_queueSize = Poco::NumberParser::parseUnsigned(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Channel::setProperty(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::run()
|
||||
{
|
||||
AutoPtr<Notification> nf = _queue.waitDequeueNotification();
|
||||
while (nf)
|
||||
{
|
||||
MessageNotification* pNf = dynamic_cast<MessageNotification*>(nf.get());
|
||||
{
|
||||
FastMutex::ScopedLock lock(_channelMutex);
|
||||
|
||||
if (pNf && _pChannel) _pChannel->log(pNf->message());
|
||||
}
|
||||
nf = _queue.waitDequeueNotification();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsyncChannel::setPriority(const std::string& value)
|
||||
{
|
||||
Thread::Priority prio = Thread::PRIO_NORMAL;
|
||||
|
||||
if (value == "lowest")
|
||||
prio = Thread::PRIO_LOWEST;
|
||||
else if (value == "low")
|
||||
prio = Thread::PRIO_LOW;
|
||||
else if (value == "normal")
|
||||
prio = Thread::PRIO_NORMAL;
|
||||
else if (value == "high")
|
||||
prio = Thread::PRIO_HIGH;
|
||||
else if (value == "highest")
|
||||
prio = Thread::PRIO_HIGHEST;
|
||||
else
|
||||
throw InvalidArgumentException("thread priority", value);
|
||||
|
||||
_thread.setPriority(prio);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// AtomicCounter.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: AtomicCounter
|
||||
//
|
||||
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/AtomicCounter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
AtomicCounter::AtomicCounter():
|
||||
_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AtomicCounter::AtomicCounter(AtomicCounter::ValueType initialValue):
|
||||
_counter(initialValue)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AtomicCounter::AtomicCounter(const AtomicCounter& counter):
|
||||
_counter(counter.value())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AtomicCounter::~AtomicCounter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AtomicCounter& AtomicCounter::operator = (const AtomicCounter& counter)
|
||||
{
|
||||
_counter.store(counter._counter.load());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AtomicCounter& AtomicCounter::operator = (AtomicCounter::ValueType value)
|
||||
{
|
||||
_counter.store(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// AtomicFlag.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: AtomicFlag
|
||||
//
|
||||
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/AtomicCounter.h"
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Base32Decoder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: Base32
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Base32Decoder.h"
|
||||
#include "Poco/Base32Encoder.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
unsigned char Base32DecoderBuf::IN_ENCODING[256];
|
||||
bool Base32DecoderBuf::IN_ENCODING_INIT = false;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static FastMutex mutex;
|
||||
}
|
||||
|
||||
|
||||
Base32DecoderBuf::Base32DecoderBuf(std::istream& istr):
|
||||
_groupLength(0),
|
||||
_groupIndex(0),
|
||||
_buf(*istr.rdbuf())
|
||||
{
|
||||
FastMutex::ScopedLock lock(mutex);
|
||||
if (!IN_ENCODING_INIT)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(IN_ENCODING); i++)
|
||||
{
|
||||
IN_ENCODING[i] = 0xFF;
|
||||
}
|
||||
for (unsigned i = 0; i < sizeof(Base32EncoderBuf::OUT_ENCODING); i++)
|
||||
{
|
||||
IN_ENCODING[Base32EncoderBuf::OUT_ENCODING[i]] = static_cast<UInt8>(i);
|
||||
}
|
||||
IN_ENCODING[static_cast<unsigned char>('=')] = '\0';
|
||||
IN_ENCODING_INIT = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Base32DecoderBuf::~Base32DecoderBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Base32DecoderBuf::readFromDevice()
|
||||
{
|
||||
if (_groupIndex < _groupLength)
|
||||
{
|
||||
return _group[_groupIndex++];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char buffer[8];
|
||||
std::memset(buffer, '=', sizeof(buffer));
|
||||
int c;
|
||||
|
||||
// per RFC-4648, Section 6, permissible block lengths are:
|
||||
// 2, 4, 5, 7, and 8 bytes. Any other length is malformed.
|
||||
//
|
||||
do {
|
||||
if ((c = readOne()) == -1) return -1;
|
||||
buffer[0] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[0]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) throw DataFormatException();
|
||||
buffer[1] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[1]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) break;
|
||||
buffer[2] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[2]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) throw DataFormatException();
|
||||
buffer[3] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[3]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) break;
|
||||
buffer[4] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[4]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) break;
|
||||
buffer[5] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[5]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) throw DataFormatException();
|
||||
buffer[6] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[6]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) break;
|
||||
buffer[7] = (unsigned char) c;
|
||||
if (IN_ENCODING[buffer[7]] == 0xFF) throw DataFormatException();
|
||||
} while (false);
|
||||
|
||||
_group[0] = (IN_ENCODING[buffer[0]] << 3) | (IN_ENCODING[buffer[1]] >> 2);
|
||||
_group[1] = ((IN_ENCODING[buffer[1]] & 0x03) << 6) | (IN_ENCODING[buffer[2]] << 1) | (IN_ENCODING[buffer[3]] >> 4);
|
||||
_group[2] = ((IN_ENCODING[buffer[3]] & 0x0F) << 4) | (IN_ENCODING[buffer[4]] >> 1);
|
||||
_group[3] = ((IN_ENCODING[buffer[4]] & 0x01) << 7) | (IN_ENCODING[buffer[5]] << 2) | (IN_ENCODING[buffer[6]] >> 3);
|
||||
_group[4] = ((IN_ENCODING[buffer[6]] & 0x07) << 5) | IN_ENCODING[buffer[7]];
|
||||
|
||||
if (buffer[2] == '=')
|
||||
_groupLength = 1;
|
||||
else if (buffer[4] == '=')
|
||||
_groupLength = 2;
|
||||
else if (buffer[5] == '=')
|
||||
_groupLength = 3;
|
||||
else if (buffer[7] == '=')
|
||||
_groupLength = 4;
|
||||
else
|
||||
_groupLength = 5;
|
||||
_groupIndex = 1;
|
||||
return _group[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Base32DecoderBuf::readOne()
|
||||
{
|
||||
int ch = _buf.sbumpc();
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
Base32DecoderIOS::Base32DecoderIOS(std::istream& istr): _buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
Base32DecoderIOS::~Base32DecoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base32DecoderBuf* Base32DecoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
Base32Decoder::Base32Decoder(std::istream& istr): Base32DecoderIOS(istr), std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base32Decoder::~Base32Decoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
//
|
||||
// Base32Encoder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: Base32
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Base32Encoder.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const unsigned char Base32EncoderBuf::OUT_ENCODING[32] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7',
|
||||
};
|
||||
|
||||
|
||||
Base32EncoderBuf::Base32EncoderBuf(std::ostream& ostr, bool padding):
|
||||
_groupLength(0),
|
||||
_buf(*ostr.rdbuf()),
|
||||
_doPadding(padding)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base32EncoderBuf::~Base32EncoderBuf()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Base32EncoderBuf::writeToDevice(char c)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
_group[_groupLength++] = (unsigned char) c;
|
||||
if (_groupLength == 5)
|
||||
{
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 3;
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x3E) >> 1);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x01) << 4) | (_group[2] >> 4);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[2] & 0x0F) << 1) | (_group[3] >> 7);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[3] & 0x7C) >> 2);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[3] & 0x03) << 3) | (_group[4] >> 5);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = (_group[4] & 0x1F);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
_groupLength = 0;
|
||||
}
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
int Base32EncoderBuf::close()
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
if (sync() == eof) return eof;
|
||||
if (_groupLength == 1)
|
||||
{
|
||||
_group[1] = 0;
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 3;
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x07) << 2);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
if (_doPadding) {
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
}
|
||||
}
|
||||
else if (_groupLength == 2)
|
||||
{
|
||||
_group[2] = 0;
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 3;
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x3E) >> 1);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x01) << 4);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
if (_doPadding) {
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
}
|
||||
}
|
||||
else if (_groupLength == 3)
|
||||
{
|
||||
_group[3] = 0;
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 3;
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x3E) >> 1);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x01) << 4) | (_group[2] >> 4);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[2] & 0x0F) << 1);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
if (_doPadding) {
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
}
|
||||
}
|
||||
else if (_groupLength == 4)
|
||||
{
|
||||
_group[4] = 0;
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 3;
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x3E) >> 1);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x01) << 4) | (_group[2] >> 4);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[2] & 0x0F) << 1) | (_group[3] >> 7);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[3] & 0x7C) >> 2);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
idx = ((_group[3] & 0x03) << 3);
|
||||
if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
|
||||
if (_doPadding && _buf.sputc('=') == eof) return eof;
|
||||
}
|
||||
_groupLength = 0;
|
||||
return _buf.pubsync();
|
||||
}
|
||||
|
||||
|
||||
Base32EncoderIOS::Base32EncoderIOS(std::ostream& ostr, bool padding):
|
||||
_buf(ostr, padding)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
Base32EncoderIOS::~Base32EncoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Base32EncoderIOS::close()
|
||||
{
|
||||
return _buf.close();
|
||||
}
|
||||
|
||||
|
||||
Base32EncoderBuf* Base32EncoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
Base32Encoder::Base32Encoder(std::ostream& ostr, bool padding):
|
||||
Base32EncoderIOS(ostr, padding), std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base32Encoder::~Base32Encoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
//
|
||||
// Base64Decoder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: Base64
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/Base64Encoder.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Mutex.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
unsigned char Base64DecoderBuf::IN_ENCODING[256];
|
||||
bool Base64DecoderBuf::IN_ENCODING_INIT = false;
|
||||
unsigned char Base64DecoderBuf::IN_ENCODING_URL[256];
|
||||
bool Base64DecoderBuf::IN_ENCODING_URL_INIT = false;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static FastMutex mutex;
|
||||
}
|
||||
|
||||
|
||||
Base64DecoderBuf::Base64DecoderBuf(std::istream& istr, int options):
|
||||
_options(options),
|
||||
_groupLength(0),
|
||||
_groupIndex(0),
|
||||
_buf(*istr.rdbuf()),
|
||||
_pInEncoding((options & BASE64_URL_ENCODING) ? IN_ENCODING_URL : IN_ENCODING)
|
||||
{
|
||||
FastMutex::ScopedLock lock(mutex);
|
||||
if (options & BASE64_URL_ENCODING)
|
||||
{
|
||||
if (!IN_ENCODING_URL_INIT)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(IN_ENCODING_URL); i++)
|
||||
{
|
||||
IN_ENCODING_URL[i] = 0xFF;
|
||||
}
|
||||
for (unsigned i = 0; i < sizeof(Base64EncoderBuf::OUT_ENCODING_URL); i++)
|
||||
{
|
||||
IN_ENCODING_URL[Base64EncoderBuf::OUT_ENCODING_URL[i]] = static_cast<UInt8>(i);
|
||||
}
|
||||
IN_ENCODING_URL[static_cast<unsigned char>('=')] = '\0';
|
||||
IN_ENCODING_URL_INIT = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IN_ENCODING_INIT)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(IN_ENCODING); i++)
|
||||
{
|
||||
IN_ENCODING[i] = 0xFF;
|
||||
}
|
||||
for (unsigned i = 0; i < sizeof(Base64EncoderBuf::OUT_ENCODING); i++)
|
||||
{
|
||||
IN_ENCODING[Base64EncoderBuf::OUT_ENCODING[i]] = static_cast<UInt8>(i);
|
||||
}
|
||||
IN_ENCODING[static_cast<unsigned char>('=')] = '\0';
|
||||
IN_ENCODING_INIT = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Base64DecoderBuf::~Base64DecoderBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Base64DecoderBuf::readFromDevice()
|
||||
{
|
||||
if (_groupIndex < _groupLength)
|
||||
{
|
||||
return _group[_groupIndex++];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char buffer[4];
|
||||
int c;
|
||||
if ((c = readOne()) == -1) return -1;
|
||||
buffer[0] = static_cast<UInt8>(c);
|
||||
if (_pInEncoding[buffer[0]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) return -1;
|
||||
buffer[1] = static_cast<UInt8>(c);
|
||||
if (_pInEncoding[buffer[1]] == 0xFF) throw DataFormatException();
|
||||
if (_options & BASE64_NO_PADDING)
|
||||
{
|
||||
if ((c = readOne()) != -1)
|
||||
buffer[2] = static_cast<UInt8>(c);
|
||||
else
|
||||
buffer[2] = '=';
|
||||
if (_pInEncoding[buffer[2]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) != -1)
|
||||
buffer[3] = static_cast<UInt8>(c);
|
||||
else
|
||||
buffer[3] = '=';
|
||||
if (_pInEncoding[buffer[3]] == 0xFF) throw DataFormatException();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((c = readOne()) == -1) throw DataFormatException();
|
||||
buffer[2] = static_cast<UInt8>(c);
|
||||
if (_pInEncoding[buffer[2]] == 0xFF) throw DataFormatException();
|
||||
if ((c = readOne()) == -1) throw DataFormatException();
|
||||
buffer[3] = static_cast<UInt8>(c);
|
||||
if (_pInEncoding[buffer[3]] == 0xFF) throw DataFormatException();
|
||||
}
|
||||
|
||||
_group[0] = (_pInEncoding[buffer[0]] << 2) | (_pInEncoding[buffer[1]] >> 4);
|
||||
_group[1] = ((_pInEncoding[buffer[1]] & 0x0F) << 4) | (_pInEncoding[buffer[2]] >> 2);
|
||||
_group[2] = (_pInEncoding[buffer[2]] << 6) | _pInEncoding[buffer[3]];
|
||||
|
||||
if (buffer[2] == '=')
|
||||
_groupLength = 1;
|
||||
else if (buffer[3] == '=')
|
||||
_groupLength = 2;
|
||||
else
|
||||
_groupLength = 3;
|
||||
_groupIndex = 1;
|
||||
return _group[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Base64DecoderBuf::readOne()
|
||||
{
|
||||
int ch = _buf.sbumpc();
|
||||
if (!(_options & BASE64_URL_ENCODING))
|
||||
{
|
||||
while (ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n')
|
||||
ch = _buf.sbumpc();
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
Base64DecoderIOS::Base64DecoderIOS(std::istream& istr, int options): _buf(istr, options)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
Base64DecoderIOS::~Base64DecoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base64DecoderBuf* Base64DecoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
Base64Decoder::Base64Decoder(std::istream& istr, int options): Base64DecoderIOS(istr, options), std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base64Decoder::~Base64Decoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// Base64Encoder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: Base64
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Base64Encoder.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const unsigned char Base64EncoderBuf::OUT_ENCODING[64] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
|
||||
const unsigned char Base64EncoderBuf::OUT_ENCODING_URL[64] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '-', '_'
|
||||
};
|
||||
|
||||
|
||||
Base64EncoderBuf::Base64EncoderBuf(std::ostream& ostr, int options):
|
||||
_options(options),
|
||||
_groupLength(0),
|
||||
_pos(0),
|
||||
_lineLength((options & BASE64_URL_ENCODING) ? 0 : 72),
|
||||
_buf(*ostr.rdbuf()),
|
||||
_pOutEncoding((options & BASE64_URL_ENCODING) ? OUT_ENCODING_URL : OUT_ENCODING)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base64EncoderBuf::~Base64EncoderBuf()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Base64EncoderBuf::setLineLength(int lineLength)
|
||||
{
|
||||
_lineLength = lineLength;
|
||||
}
|
||||
|
||||
|
||||
int Base64EncoderBuf::getLineLength() const
|
||||
{
|
||||
return _lineLength;
|
||||
}
|
||||
|
||||
|
||||
int Base64EncoderBuf::writeToDevice(char c)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
_group[_groupLength++] = (unsigned char) c;
|
||||
if (_groupLength == 3)
|
||||
{
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 2;
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6);
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
idx = _group[2] & 0x3F;
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
_pos += 4;
|
||||
if (_lineLength > 0 && _pos >= _lineLength)
|
||||
{
|
||||
if (_buf.sputc('\r') == eof) return eof;
|
||||
if (_buf.sputc('\n') == eof) return eof;
|
||||
_pos = 0;
|
||||
}
|
||||
_groupLength = 0;
|
||||
}
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
int Base64EncoderBuf::close()
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
if (sync() == eof) return eof;
|
||||
if (_groupLength == 1)
|
||||
{
|
||||
_group[1] = 0;
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 2;
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
if (!(_options & BASE64_NO_PADDING))
|
||||
{
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
}
|
||||
}
|
||||
else if (_groupLength == 2)
|
||||
{
|
||||
_group[2] = 0;
|
||||
unsigned char idx;
|
||||
idx = _group[0] >> 2;
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6);
|
||||
if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
|
||||
if (!(_options & BASE64_NO_PADDING))
|
||||
{
|
||||
if (_buf.sputc('=') == eof) return eof;
|
||||
}
|
||||
}
|
||||
_groupLength = 0;
|
||||
return _buf.pubsync();
|
||||
}
|
||||
|
||||
|
||||
Base64EncoderIOS::Base64EncoderIOS(std::ostream& ostr, int options): _buf(ostr, options)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
Base64EncoderIOS::~Base64EncoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Base64EncoderIOS::close()
|
||||
{
|
||||
return _buf.close();
|
||||
}
|
||||
|
||||
|
||||
Base64EncoderBuf* Base64EncoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
Base64Encoder::Base64Encoder(std::ostream& ostr, int options): Base64EncoderIOS(ostr, options), std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Base64Encoder::~Base64Encoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
//
|
||||
// BinaryReader.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: BinaryReaderWriter
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/BinaryReader.h"
|
||||
#include "Poco/ByteOrder.h"
|
||||
#include "Poco/TextEncoding.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
BinaryReader::BinaryReader(std::istream& istr, StreamByteOrder byteOrder):
|
||||
_istr(istr),
|
||||
_pTextConverter(0)
|
||||
{
|
||||
#if defined(POCO_ARCH_BIG_ENDIAN)
|
||||
_flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
|
||||
#else
|
||||
_flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BinaryReader::BinaryReader(std::istream& istr, TextEncoding& encoding, StreamByteOrder byteOrder):
|
||||
_istr(istr),
|
||||
_pTextConverter(new TextConverter(encoding, Poco::TextEncoding::global()))
|
||||
{
|
||||
#if defined(POCO_ARCH_BIG_ENDIAN)
|
||||
_flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
|
||||
#else
|
||||
_flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BinaryReader::~BinaryReader()
|
||||
{
|
||||
delete _pTextConverter;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (bool& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (char& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (unsigned char& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (signed char& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (short& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (unsigned short& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (int& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (unsigned int& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (long& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
#if defined(POCO_LONG_IS_64_BIT)
|
||||
if (_flipBytes) value = ByteOrder::flipBytes((Int64) value);
|
||||
#else
|
||||
if (_flipBytes) value = ByteOrder::flipBytes((Int32) value);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (unsigned long& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
#if defined(POCO_LONG_IS_64_BIT)
|
||||
if (_flipBytes) value = ByteOrder::flipBytes((UInt64) value);
|
||||
#else
|
||||
if (_flipBytes) value = ByteOrder::flipBytes((UInt32) value);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (float& value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
char* ptr = (char*) &value;
|
||||
ptr += sizeof(value);
|
||||
for (unsigned i = 0; i < sizeof(value); ++i)
|
||||
_istr.read(--ptr, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (double& value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
char* ptr = (char*) &value;
|
||||
ptr += sizeof(value);
|
||||
for (unsigned i = 0; i < sizeof(value); ++i)
|
||||
_istr.read(--ptr, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (long long& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(static_cast<Poco::Int64>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (unsigned long long& value)
|
||||
{
|
||||
_istr.read((char*) &value, sizeof(value));
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(static_cast<Poco::UInt64>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
BinaryReader& BinaryReader::operator >> (std::string& value)
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read7BitEncoded(size);
|
||||
value.clear();
|
||||
if (!_istr.good()) return *this;
|
||||
value.reserve(size);
|
||||
while (size--)
|
||||
{
|
||||
char c;
|
||||
if (!_istr.read(&c, 1).good()) break;
|
||||
value += c;
|
||||
}
|
||||
if (_pTextConverter)
|
||||
{
|
||||
std::string converted;
|
||||
_pTextConverter->convert(value, converted);
|
||||
std::swap(value, converted);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void BinaryReader::read7BitEncoded(UInt32& value)
|
||||
{
|
||||
char c;
|
||||
value = 0;
|
||||
int s = 0;
|
||||
do
|
||||
{
|
||||
c = 0;
|
||||
_istr.read(&c, 1);
|
||||
UInt32 x = (c & 0x7F);
|
||||
x <<= s;
|
||||
value += x;
|
||||
s += 7;
|
||||
}
|
||||
while (c & 0x80);
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
|
||||
|
||||
void BinaryReader::read7BitEncoded(UInt64& value)
|
||||
{
|
||||
char c;
|
||||
value = 0;
|
||||
int s = 0;
|
||||
do
|
||||
{
|
||||
c = 0;
|
||||
_istr.read(&c, 1);
|
||||
UInt64 x = (c & 0x7F);
|
||||
x <<= s;
|
||||
value += x;
|
||||
s += 7;
|
||||
}
|
||||
while (c & 0x80);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void BinaryReader::readRaw(std::streamsize length, std::string& value)
|
||||
{
|
||||
value.clear();
|
||||
value.reserve(static_cast<std::string::size_type>(length));
|
||||
while (length--)
|
||||
{
|
||||
char c;
|
||||
if (!_istr.read(&c, 1).good()) break;
|
||||
value += c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BinaryReader::readRaw(char* buffer, std::streamsize length)
|
||||
{
|
||||
_istr.read(buffer, length);
|
||||
}
|
||||
|
||||
|
||||
void BinaryReader::readBOM()
|
||||
{
|
||||
UInt16 bom;
|
||||
_istr.read((char*) &bom, sizeof(bom));
|
||||
_flipBytes = bom != 0xFEFF;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+351
@@ -0,0 +1,351 @@
|
||||
//
|
||||
// BinaryWriter.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: BinaryReaderWriter
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/BinaryWriter.h"
|
||||
#include "Poco/ByteOrder.h"
|
||||
#include "Poco/TextEncoding.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
BinaryWriter::BinaryWriter(std::ostream& ostr, StreamByteOrder byteOrder):
|
||||
_ostr(ostr),
|
||||
_pTextConverter(0)
|
||||
{
|
||||
#if defined(POCO_ARCH_BIG_ENDIAN)
|
||||
_flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
|
||||
#else
|
||||
_flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter::BinaryWriter(std::ostream& ostr, TextEncoding& encoding, StreamByteOrder byteOrder):
|
||||
_ostr(ostr),
|
||||
_pTextConverter(new TextConverter(Poco::TextEncoding::global(), encoding))
|
||||
{
|
||||
#if defined(POCO_ARCH_BIG_ENDIAN)
|
||||
_flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
|
||||
#else
|
||||
_flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter::~BinaryWriter()
|
||||
{
|
||||
delete _pTextConverter;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (bool value)
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (char value)
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (unsigned char value)
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (signed char value)
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (short value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
short fValue = ByteOrder::flipBytes(value);
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (unsigned short value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
unsigned short fValue = ByteOrder::flipBytes(value);
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (int value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
int fValue = ByteOrder::flipBytes(value);
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (unsigned int value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
unsigned int fValue = ByteOrder::flipBytes(value);
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (long value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
#if defined(POCO_LONG_IS_64_BIT)
|
||||
long fValue = ByteOrder::flipBytes((Int64) value);
|
||||
#else
|
||||
long fValue = ByteOrder::flipBytes((Int32) value);
|
||||
#endif
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (unsigned long value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
#if defined(POCO_LONG_IS_64_BIT)
|
||||
long fValue = ByteOrder::flipBytes((UInt64) value);
|
||||
#else
|
||||
long fValue = ByteOrder::flipBytes((UInt32) value);
|
||||
#endif
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (float value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
const char* ptr = (const char*) &value;
|
||||
ptr += sizeof(value);
|
||||
for (unsigned i = 0; i < sizeof(value); ++i)
|
||||
_ostr.write(--ptr, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (double value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
const char* ptr = (const char*) &value;
|
||||
ptr += sizeof(value);
|
||||
for (unsigned i = 0; i < sizeof(value); ++i)
|
||||
_ostr.write(--ptr, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (long long value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
Int64 fValue = ByteOrder::flipBytes(static_cast<Int64>(value));
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (unsigned long long value)
|
||||
{
|
||||
if (_flipBytes)
|
||||
{
|
||||
UInt64 fValue = ByteOrder::flipBytes(static_cast<UInt64>(value));
|
||||
_ostr.write((const char*) &fValue, sizeof(fValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (const std::string& value)
|
||||
{
|
||||
if (_pTextConverter)
|
||||
{
|
||||
std::string converted;
|
||||
_pTextConverter->convert(value, converted);
|
||||
UInt32 length = (UInt32) converted.size();
|
||||
write7BitEncoded(length);
|
||||
_ostr.write(converted.data(), length);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 length = (UInt32) value.size();
|
||||
write7BitEncoded(length);
|
||||
_ostr.write(value.data(), length);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& BinaryWriter::operator << (const char* value)
|
||||
{
|
||||
poco_check_ptr (value);
|
||||
|
||||
if (_pTextConverter)
|
||||
{
|
||||
std::string converted;
|
||||
_pTextConverter->convert(value, static_cast<int>(std::strlen(value)), converted);
|
||||
UInt32 length = (UInt32) converted.size();
|
||||
write7BitEncoded(length);
|
||||
_ostr.write(converted.data(), length);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 length = static_cast<UInt32>(std::strlen(value));
|
||||
write7BitEncoded(length);
|
||||
_ostr.write(value, length);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void BinaryWriter::write7BitEncoded(UInt32 value)
|
||||
{
|
||||
do
|
||||
{
|
||||
unsigned char c = (unsigned char) (value & 0x7F);
|
||||
value >>= 7;
|
||||
if (value) c |= 0x80;
|
||||
_ostr.write((const char*) &c, 1);
|
||||
}
|
||||
while (value);
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
|
||||
|
||||
void BinaryWriter::write7BitEncoded(UInt64 value)
|
||||
{
|
||||
do
|
||||
{
|
||||
unsigned char c = (unsigned char) (value & 0x7F);
|
||||
value >>= 7;
|
||||
if (value) c |= 0x80;
|
||||
_ostr.write((const char*) &c, 1);
|
||||
}
|
||||
while (value);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void BinaryWriter::writeRaw(const std::string& rawData)
|
||||
{
|
||||
_ostr.write(rawData.data(), (std::streamsize) rawData.length());
|
||||
}
|
||||
|
||||
|
||||
void BinaryWriter::writeRaw(const char* buffer, std::streamsize length)
|
||||
{
|
||||
_ostr.write(buffer, length);
|
||||
}
|
||||
|
||||
|
||||
void BinaryWriter::writeBOM()
|
||||
{
|
||||
UInt16 value = 0xFEFF;
|
||||
if (_flipBytes) value = ByteOrder::flipBytes(value);
|
||||
_ostr.write((const char*) &value, sizeof(value));
|
||||
}
|
||||
|
||||
|
||||
void BinaryWriter::flush()
|
||||
{
|
||||
_ostr.flush();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// Bugcheck.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Bugcheck
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Bugcheck.h"
|
||||
#include "Poco/Debugger.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
void Bugcheck::assertion(const char* cond, const char* file, int line, const char* text)
|
||||
{
|
||||
std::string message("Assertion violation: ");
|
||||
message += cond;
|
||||
if (text)
|
||||
{
|
||||
message += " (";
|
||||
message += text;
|
||||
message += ")";
|
||||
}
|
||||
Debugger::enter(message, file, line);
|
||||
throw AssertionViolationException(what(cond, file, line, text));
|
||||
}
|
||||
|
||||
|
||||
void Bugcheck::nullPointer(const char* ptr, const char* file, int line)
|
||||
{
|
||||
Debugger::enter(std::string("NULL pointer: ") + ptr, file, line);
|
||||
throw NullPointerException(what(ptr, file, line));
|
||||
}
|
||||
|
||||
|
||||
void Bugcheck::bugcheck(const char* file, int line)
|
||||
{
|
||||
Debugger::enter("Bugcheck", file, line);
|
||||
throw BugcheckException(what(0, file, line));
|
||||
}
|
||||
|
||||
|
||||
void Bugcheck::bugcheck(const char* msg, const char* file, int line)
|
||||
{
|
||||
std::string m("Bugcheck");
|
||||
if (msg)
|
||||
{
|
||||
m.append(": ");
|
||||
m.append(msg);
|
||||
}
|
||||
Debugger::enter(m, file, line);
|
||||
throw BugcheckException(what(msg, file, line));
|
||||
}
|
||||
|
||||
|
||||
void Bugcheck::unexpected(const char* file, int line)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
try
|
||||
{
|
||||
std::string msg("Unexpected exception in noexcept function or destructor: ");
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
msg += exc.displayText();
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
msg += exc.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
msg += "unknown exception";
|
||||
}
|
||||
Debugger::enter(msg, file, line);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Bugcheck::debugger(const char* file, int line)
|
||||
{
|
||||
Debugger::enter(file, line);
|
||||
}
|
||||
|
||||
|
||||
void Bugcheck::debugger(const char* msg, const char* file, int line)
|
||||
{
|
||||
Debugger::enter(msg, file, line);
|
||||
}
|
||||
|
||||
|
||||
std::string Bugcheck::what(const char* msg, const char* file, int line, const char* text)
|
||||
{
|
||||
std::ostringstream str;
|
||||
if (msg) str << msg << " ";
|
||||
if (text != NULL) str << "(" << text << ") ";
|
||||
str << "in file \"" << file << "\", line " << line;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// ByteOrder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: ByteOrder
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ByteOrder.h"
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Channel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: Channel
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Channel.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Channel::Channel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Channel::~Channel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Channel::open()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Channel::close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Channel::setProperty(const std::string& name, const std::string& /*value*/)
|
||||
{
|
||||
throw PropertyNotSupportedException(name);
|
||||
}
|
||||
|
||||
|
||||
std::string Channel::getProperty(const std::string& name) const
|
||||
{
|
||||
throw PropertyNotSupportedException(name);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Checksum.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Checksum
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Checksum.h"
|
||||
#if defined(POCO_UNBUNDLED)
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include "Poco/zlib.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Checksum::Checksum():
|
||||
_type(TYPE_CRC32),
|
||||
_value(crc32(0L, Z_NULL, 0))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Checksum::Checksum(Type t):
|
||||
_type(t),
|
||||
_value(0)
|
||||
{
|
||||
if (t == TYPE_CRC32)
|
||||
_value = crc32(0L, Z_NULL, 0);
|
||||
else
|
||||
_value = adler32(0L, Z_NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
Checksum::~Checksum()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Checksum::update(const char* data, unsigned length)
|
||||
{
|
||||
if (_type == TYPE_ADLER32)
|
||||
_value = adler32(_value, reinterpret_cast<const Bytef*>(data), length);
|
||||
else
|
||||
_value = crc32(_value, reinterpret_cast<const Bytef*>(data), length);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+231
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// Clock.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: DateTime
|
||||
// Module: Clock
|
||||
//
|
||||
// Copyright (c) 2013, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Clock.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#if defined(__MACH__)
|
||||
#include <mach/mach.h>
|
||||
#include <mach/clock.h>
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(POCO_VXWORKS)
|
||||
#include <timers.h>
|
||||
#elif defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "Poco/UnWindows.h"
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#undef min
|
||||
#undef max
|
||||
#include <limits>
|
||||
|
||||
|
||||
#ifndef POCO_HAVE_CLOCK_GETTIME
|
||||
#if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__)
|
||||
#ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10
|
||||
#define POCO_HAVE_CLOCK_GETTIME
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const Clock::ClockVal Clock::CLOCKVAL_MIN = std::numeric_limits<Clock::ClockVal>::min();
|
||||
const Clock::ClockVal Clock::CLOCKVAL_MAX = std::numeric_limits<Clock::ClockVal>::max();
|
||||
|
||||
|
||||
Clock::Clock()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
Clock::Clock(ClockVal tv)
|
||||
{
|
||||
_clock = tv;
|
||||
}
|
||||
|
||||
|
||||
Clock::Clock(const Clock& other)
|
||||
{
|
||||
_clock = other._clock;
|
||||
}
|
||||
|
||||
|
||||
Clock::~Clock()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Clock& Clock::operator = (const Clock& other)
|
||||
{
|
||||
_clock = other._clock;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Clock& Clock::operator = (ClockVal tv)
|
||||
{
|
||||
_clock = tv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Clock::swap(Clock& timestamp)
|
||||
{
|
||||
std::swap(_clock, timestamp._clock);
|
||||
}
|
||||
|
||||
|
||||
void Clock::update()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
|
||||
LARGE_INTEGER perfCounter;
|
||||
LARGE_INTEGER perfFreq;
|
||||
if (QueryPerformanceCounter(&perfCounter) && QueryPerformanceFrequency(&perfFreq))
|
||||
{
|
||||
_clock = resolution()*(perfCounter.QuadPart/perfFreq.QuadPart);
|
||||
_clock += (perfCounter.QuadPart % perfFreq.QuadPart)*resolution()/perfFreq.QuadPart;
|
||||
}
|
||||
else throw Poco::SystemException("cannot get system clock");
|
||||
|
||||
#elif defined(__MACH__)
|
||||
|
||||
clock_serv_t cs;
|
||||
mach_timespec_t ts;
|
||||
|
||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cs);
|
||||
clock_get_time(cs, &ts);
|
||||
mach_port_deallocate(mach_task_self(), cs);
|
||||
|
||||
_clock = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000;
|
||||
|
||||
#elif defined(POCO_VXWORKS)
|
||||
|
||||
struct timespec ts;
|
||||
#if defined(CLOCK_MONOTONIC) // should be in VxWorks 6.x
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts))
|
||||
throw SystemException("cannot get system clock");
|
||||
#else
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts))
|
||||
throw SystemException("cannot get system clock");
|
||||
#endif
|
||||
_clock = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000;
|
||||
|
||||
#elif defined(POCO_HAVE_CLOCK_GETTIME)
|
||||
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts))
|
||||
throw SystemException("cannot get system clock");
|
||||
_clock = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000;
|
||||
|
||||
#else
|
||||
|
||||
Poco::Timestamp now;
|
||||
_clock = now.epochMicroseconds();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Clock::ClockDiff Clock::accuracy()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
|
||||
LARGE_INTEGER perfFreq;
|
||||
if (QueryPerformanceFrequency(&perfFreq) && perfFreq.QuadPart > 0)
|
||||
{
|
||||
ClockVal acc = resolution()/perfFreq.QuadPart;
|
||||
return acc > 0 ? acc : 1;
|
||||
}
|
||||
else throw Poco::SystemException("cannot get system clock accuracy");
|
||||
|
||||
#elif defined(__MACH__)
|
||||
|
||||
clock_serv_t cs;
|
||||
int nanosecs;
|
||||
mach_msg_type_number_t n = 1;
|
||||
|
||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cs);
|
||||
clock_get_attributes(cs, CLOCK_GET_TIME_RES, (clock_attr_t)&nanosecs, &n);
|
||||
mach_port_deallocate(mach_task_self(), cs);
|
||||
|
||||
ClockVal acc = nanosecs/1000;
|
||||
return acc > 0 ? acc : 1;
|
||||
|
||||
#elif defined(POCO_VXWORKS)
|
||||
|
||||
struct timespec ts;
|
||||
#if defined(CLOCK_MONOTONIC) // should be in VxWorks 6.x
|
||||
if (clock_getres(CLOCK_MONOTONIC, &ts))
|
||||
throw SystemException("cannot get system clock");
|
||||
#else
|
||||
if (clock_getres(CLOCK_REALTIME, &ts))
|
||||
throw SystemException("cannot get system clock");
|
||||
#endif
|
||||
ClockVal acc = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000;
|
||||
return acc > 0 ? acc : 1;
|
||||
|
||||
#elif defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||
|
||||
struct timespec ts;
|
||||
if (clock_getres(CLOCK_MONOTONIC, &ts))
|
||||
throw SystemException("cannot get system clock");
|
||||
|
||||
ClockVal acc = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000;
|
||||
return acc > 0 ? acc : 1;
|
||||
|
||||
#else
|
||||
|
||||
return 1000;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Clock::monotonic()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
|
||||
return true;
|
||||
|
||||
#elif defined(__MACH__)
|
||||
|
||||
return true;
|
||||
|
||||
#elif defined(POCO_VXWORKS)
|
||||
|
||||
#if defined(CLOCK_MONOTONIC) // should be in VxWorks 6.x
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#elif defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Condition.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: Condition
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Condition.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Condition::Condition()
|
||||
{
|
||||
}
|
||||
|
||||
Condition::~Condition()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Condition::signal()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_waitQueue.empty())
|
||||
{
|
||||
_waitQueue.front()->set();
|
||||
dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Condition::broadcast()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
for (auto p: _waitQueue)
|
||||
{
|
||||
p->set();
|
||||
}
|
||||
_waitQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
void Condition::enqueue(Event& event)
|
||||
{
|
||||
_waitQueue.push_back(&event);
|
||||
}
|
||||
|
||||
|
||||
void Condition::dequeue()
|
||||
{
|
||||
_waitQueue.pop_front();
|
||||
}
|
||||
|
||||
|
||||
void Condition::dequeue(Event& event)
|
||||
{
|
||||
for (WaitQueue::iterator it = _waitQueue.begin(); it != _waitQueue.end(); ++it)
|
||||
{
|
||||
if (*it == &event)
|
||||
{
|
||||
_waitQueue.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Configurable.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: Configurable
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Configurable.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Configurable::Configurable()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Configurable::~Configurable()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
//
|
||||
// ConsoleChannel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: ConsoleChannel
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ConsoleChannel.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FastMutex ConsoleChannel::_mutex;
|
||||
|
||||
|
||||
ConsoleChannel::ConsoleChannel(): _str(std::clog)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ConsoleChannel::ConsoleChannel(std::ostream& str): _str(str)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ConsoleChannel::~ConsoleChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ConsoleChannel::log(const Message& msg)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_str << msg.getText() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
FastMutex ColorConsoleChannel::_mutex;
|
||||
const std::string ColorConsoleChannel::CSI("\033[");
|
||||
|
||||
|
||||
ColorConsoleChannel::ColorConsoleChannel():
|
||||
_str(std::clog),
|
||||
_enableColors(true)
|
||||
{
|
||||
initColors();
|
||||
}
|
||||
|
||||
|
||||
ColorConsoleChannel::ColorConsoleChannel(std::ostream& str):
|
||||
_str(str),
|
||||
_enableColors(true)
|
||||
{
|
||||
initColors();
|
||||
}
|
||||
|
||||
|
||||
ColorConsoleChannel::~ColorConsoleChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ColorConsoleChannel::log(const Message& msg)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (_enableColors)
|
||||
{
|
||||
int color = _colors[msg.getPriority()];
|
||||
if (color & 0x100)
|
||||
{
|
||||
_str << CSI << "1m";
|
||||
}
|
||||
color &= 0xff;
|
||||
_str << CSI << color << "m";
|
||||
}
|
||||
|
||||
_str << msg.getText();
|
||||
|
||||
if (_enableColors)
|
||||
{
|
||||
_str << CSI << "0m";
|
||||
}
|
||||
|
||||
_str << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void ColorConsoleChannel::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name == "enableColors")
|
||||
{
|
||||
_enableColors = icompare(value, "true") == 0;
|
||||
}
|
||||
else if (name == "traceColor")
|
||||
{
|
||||
_colors[Message::PRIO_TRACE] = parseColor(value);
|
||||
}
|
||||
else if (name == "debugColor")
|
||||
{
|
||||
_colors[Message::PRIO_DEBUG] = parseColor(value);
|
||||
}
|
||||
else if (name == "informationColor")
|
||||
{
|
||||
_colors[Message::PRIO_INFORMATION] = parseColor(value);
|
||||
}
|
||||
else if (name == "noticeColor")
|
||||
{
|
||||
_colors[Message::PRIO_NOTICE] = parseColor(value);
|
||||
}
|
||||
else if (name == "warningColor")
|
||||
{
|
||||
_colors[Message::PRIO_WARNING] = parseColor(value);
|
||||
}
|
||||
else if (name == "errorColor")
|
||||
{
|
||||
_colors[Message::PRIO_ERROR] = parseColor(value);
|
||||
}
|
||||
else if (name == "criticalColor")
|
||||
{
|
||||
_colors[Message::PRIO_CRITICAL] = parseColor(value);
|
||||
}
|
||||
else if (name == "fatalColor")
|
||||
{
|
||||
_colors[Message::PRIO_FATAL] = parseColor(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Channel::setProperty(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ColorConsoleChannel::getProperty(const std::string& name) const
|
||||
{
|
||||
if (name == "enableColors")
|
||||
{
|
||||
return _enableColors ? "true" : "false";
|
||||
}
|
||||
else if (name == "traceColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_TRACE]);
|
||||
}
|
||||
else if (name == "debugColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_DEBUG]);
|
||||
}
|
||||
else if (name == "informationColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_INFORMATION]);
|
||||
}
|
||||
else if (name == "noticeColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_NOTICE]);
|
||||
}
|
||||
else if (name == "warningColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_WARNING]);
|
||||
}
|
||||
else if (name == "errorColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_ERROR]);
|
||||
}
|
||||
else if (name == "criticalColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_CRITICAL]);
|
||||
}
|
||||
else if (name == "fatalColor")
|
||||
{
|
||||
return formatColor(_colors[Message::PRIO_FATAL]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Channel::getProperty(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ColorConsoleChannel::Color ColorConsoleChannel::parseColor(const std::string& color) const
|
||||
{
|
||||
if (icompare(color, "default") == 0)
|
||||
return CC_DEFAULT;
|
||||
else if (icompare(color, "black") == 0)
|
||||
return CC_BLACK;
|
||||
else if (icompare(color, "red") == 0)
|
||||
return CC_RED;
|
||||
else if (icompare(color, "green") == 0)
|
||||
return CC_GREEN;
|
||||
else if (icompare(color, "brown") == 0)
|
||||
return CC_BROWN;
|
||||
else if (icompare(color, "blue") == 0)
|
||||
return CC_BLUE;
|
||||
else if (icompare(color, "magenta") == 0)
|
||||
return CC_MAGENTA;
|
||||
else if (icompare(color, "cyan") == 0)
|
||||
return CC_CYAN;
|
||||
else if (icompare(color, "gray") == 0)
|
||||
return CC_GRAY;
|
||||
else if (icompare(color, "darkGray") == 0)
|
||||
return CC_DARKGRAY;
|
||||
else if (icompare(color, "lightRed") == 0)
|
||||
return CC_LIGHTRED;
|
||||
else if (icompare(color, "lightGreen") == 0)
|
||||
return CC_LIGHTGREEN;
|
||||
else if (icompare(color, "yellow") == 0)
|
||||
return CC_YELLOW;
|
||||
else if (icompare(color, "lightBlue") == 0)
|
||||
return CC_LIGHTBLUE;
|
||||
else if (icompare(color, "lightMagenta") == 0)
|
||||
return CC_LIGHTMAGENTA;
|
||||
else if (icompare(color, "lightCyan") == 0)
|
||||
return CC_LIGHTCYAN;
|
||||
else if (icompare(color, "white") == 0)
|
||||
return CC_WHITE;
|
||||
else throw InvalidArgumentException("Invalid color value", color);
|
||||
}
|
||||
|
||||
|
||||
std::string ColorConsoleChannel::formatColor(Color color) const
|
||||
{
|
||||
switch (color)
|
||||
{
|
||||
case CC_DEFAULT: return "default";
|
||||
case CC_BLACK: return "black";
|
||||
case CC_RED: return "red";
|
||||
case CC_GREEN: return "green";
|
||||
case CC_BROWN: return "brown";
|
||||
case CC_BLUE: return "blue";
|
||||
case CC_MAGENTA: return "magenta";
|
||||
case CC_CYAN: return "cyan";
|
||||
case CC_GRAY: return "gray";
|
||||
case CC_DARKGRAY: return "darkGray";
|
||||
case CC_LIGHTRED: return "lightRed";
|
||||
case CC_LIGHTGREEN: return "lightGreen";
|
||||
case CC_YELLOW: return "yellow";
|
||||
case CC_LIGHTBLUE: return "lightBlue";
|
||||
case CC_LIGHTMAGENTA: return "lightMagenta";
|
||||
case CC_LIGHTCYAN: return "lightCyan";
|
||||
case CC_WHITE: return "white";
|
||||
default: return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ColorConsoleChannel::initColors()
|
||||
{
|
||||
_colors[0] = CC_DEFAULT; // unused
|
||||
_colors[Message::PRIO_FATAL] = CC_LIGHTRED;
|
||||
_colors[Message::PRIO_CRITICAL] = CC_LIGHTRED;
|
||||
_colors[Message::PRIO_ERROR] = CC_LIGHTRED;
|
||||
_colors[Message::PRIO_WARNING] = CC_YELLOW;
|
||||
_colors[Message::PRIO_NOTICE] = CC_DEFAULT;
|
||||
_colors[Message::PRIO_INFORMATION] = CC_DEFAULT;
|
||||
_colors[Message::PRIO_DEBUG] = CC_GRAY;
|
||||
_colors[Message::PRIO_TRACE] = CC_GRAY;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
//
|
||||
// CountingStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: CountingStream
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/CountingStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
CountingStreamBuf::CountingStreamBuf():
|
||||
_pIstr(0),
|
||||
_pOstr(0),
|
||||
_chars(0),
|
||||
_lines(0),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingStreamBuf::CountingStreamBuf(std::istream& istr):
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_chars(0),
|
||||
_lines(0),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingStreamBuf::CountingStreamBuf(std::ostream& ostr):
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_chars(0),
|
||||
_lines(0),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingStreamBuf::~CountingStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int CountingStreamBuf::readFromDevice()
|
||||
{
|
||||
if (_pIstr)
|
||||
{
|
||||
int c = _pIstr->get();
|
||||
if (c != -1)
|
||||
{
|
||||
++_chars;
|
||||
if (_pos++ == 0) ++_lines;
|
||||
if (c == '\n') _pos = 0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int CountingStreamBuf::writeToDevice(char c)
|
||||
{
|
||||
++_chars;
|
||||
if (_pos++ == 0) ++_lines;
|
||||
if (c == '\n') _pos = 0;
|
||||
if (_pOstr) _pOstr->put(c);
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
void CountingStreamBuf::reset()
|
||||
{
|
||||
_chars = 0;
|
||||
_lines = 0;
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
|
||||
void CountingStreamBuf::setCurrentLineNumber(std::streamsize line)
|
||||
{
|
||||
_lines = line;
|
||||
}
|
||||
|
||||
|
||||
void CountingStreamBuf::addChars(std::streamsize charsToAdd)
|
||||
{
|
||||
_chars += charsToAdd;
|
||||
}
|
||||
|
||||
|
||||
void CountingStreamBuf::addLines(std::streamsize linesToAdd)
|
||||
{
|
||||
_lines += linesToAdd;
|
||||
}
|
||||
|
||||
|
||||
void CountingStreamBuf::addPos(std::streamsize posToAdd)
|
||||
{
|
||||
_pos += posToAdd;
|
||||
}
|
||||
|
||||
|
||||
CountingIOS::CountingIOS()
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
CountingIOS::CountingIOS(std::istream& istr): _buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
CountingIOS::CountingIOS(std::ostream& ostr): _buf(ostr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
CountingIOS::~CountingIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CountingIOS::reset()
|
||||
{
|
||||
_buf.reset();
|
||||
}
|
||||
|
||||
|
||||
void CountingIOS::setCurrentLineNumber(std::streamsize line)
|
||||
{
|
||||
_buf.setCurrentLineNumber(line);
|
||||
}
|
||||
|
||||
|
||||
void CountingIOS::addChars(std::streamsize charsToAdd)
|
||||
{
|
||||
_buf.addChars(charsToAdd);
|
||||
}
|
||||
|
||||
|
||||
void CountingIOS::addLines(std::streamsize linesToAdd)
|
||||
{
|
||||
_buf.addLines(linesToAdd);
|
||||
}
|
||||
|
||||
|
||||
void CountingIOS::addPos(std::streamsize posToAdd)
|
||||
{
|
||||
_buf.addPos(posToAdd);
|
||||
}
|
||||
|
||||
|
||||
CountingStreamBuf* CountingIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
CountingInputStream::CountingInputStream(std::istream& istr): CountingIOS(istr), std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingInputStream::~CountingInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingOutputStream::CountingOutputStream(): std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingOutputStream::CountingOutputStream(std::ostream& ostr): CountingIOS(ostr), std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CountingOutputStream::~CountingOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// DataURIStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: DataURIStreamFactory
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DataURIStream.h"
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/StreamUtil.h"
|
||||
#include "Poco/URI.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DataURIStreamIOS::DataURIStreamIOS(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "data");
|
||||
|
||||
const std::string& path = uri.getPath();
|
||||
size_t comma = path.find(',');
|
||||
if (comma == std::string::npos)
|
||||
throw DataFormatException();
|
||||
_data = path.substr(comma + 1);
|
||||
_memoryStream.reset(new MemoryInputStream(_data.data(), _data.length()));
|
||||
constexpr char base64[] = ";base64";
|
||||
const size_t base64Len = strlen(base64);
|
||||
if ((comma >= base64Len) && !path.compare(comma - base64Len, base64Len, base64, base64Len))
|
||||
{
|
||||
_base64Decoder.reset(new Base64Decoder(*_memoryStream, 0));
|
||||
_buf = _base64Decoder->rdbuf();
|
||||
}
|
||||
else
|
||||
_buf = _memoryStream->rdbuf();
|
||||
poco_ios_init(_buf);
|
||||
}
|
||||
|
||||
|
||||
DataURIStreamIOS::~DataURIStreamIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::streambuf* DataURIStreamIOS::rdbuf()
|
||||
{
|
||||
return _buf;
|
||||
}
|
||||
|
||||
|
||||
DataURIStream::DataURIStream(const URI& uri): DataURIStreamIOS(uri), std::istream(_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataURIStream::~DataURIStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// DataURIStreamFactory.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: URI
|
||||
// Module: DataURIStreamFactory
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DataURIStreamFactory.h"
|
||||
#include "Poco/DataURIStream.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/URIStreamOpener.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DataURIStreamFactory::DataURIStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataURIStreamFactory::~DataURIStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* DataURIStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "data");
|
||||
|
||||
return new DataURIStream(uri);
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamFactory::registerFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().registerStreamFactory("data", new DataURIStreamFactory);
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamFactory::unregisterFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().unregisterStreamFactory("data");
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+463
@@ -0,0 +1,463 @@
|
||||
//
|
||||
// DateTime.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: DateTime
|
||||
// Module: DateTime
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Timespan.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DateTime::DateTime()
|
||||
{
|
||||
Timestamp now;
|
||||
_utcTime = now.utcTime();
|
||||
computeGregorian(julianDay());
|
||||
computeDaytime();
|
||||
}
|
||||
|
||||
|
||||
DateTime::DateTime(const tm& tmStruct):
|
||||
_year(tmStruct.tm_year + 1900),
|
||||
_month(tmStruct.tm_mon + 1),
|
||||
_day(tmStruct.tm_mday),
|
||||
_hour(tmStruct.tm_hour),
|
||||
_minute(tmStruct.tm_min),
|
||||
_second(tmStruct.tm_sec),
|
||||
_millisecond(0),
|
||||
_microsecond(0)
|
||||
{
|
||||
poco_assert (_year >= 0 && _year <= 9999);
|
||||
poco_assert (_month >= 1 && _month <= 12);
|
||||
poco_assert (_day >= 1 && _day <= daysOfMonth(_year, _month));
|
||||
poco_assert (_hour >= 0 && _hour <= 23);
|
||||
poco_assert (_minute >= 0 && _minute <= 59);
|
||||
poco_assert (_second >= 0 && _second <= 60);
|
||||
|
||||
_utcTime = toUtcTime(toJulianDay(_year, _month, _day)) + 10*(_hour*Timespan::HOURS + _minute*Timespan::MINUTES + _second*Timespan::SECONDS);
|
||||
}
|
||||
|
||||
|
||||
DateTime::DateTime(const Timestamp& timestamp):
|
||||
_utcTime(timestamp.utcTime())
|
||||
{
|
||||
computeGregorian(julianDay());
|
||||
computeDaytime();
|
||||
}
|
||||
|
||||
|
||||
DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond):
|
||||
_year(year),
|
||||
_month(month),
|
||||
_day(day),
|
||||
_hour(hour),
|
||||
_minute(minute),
|
||||
_second(second),
|
||||
_millisecond(millisecond),
|
||||
_microsecond(microsecond)
|
||||
{
|
||||
poco_assert (year >= 0 && year <= 9999);
|
||||
poco_assert (month >= 1 && month <= 12);
|
||||
poco_assert (day >= 1 && day <= daysOfMonth(year, month));
|
||||
poco_assert (hour >= 0 && hour <= 23);
|
||||
poco_assert (minute >= 0 && minute <= 59);
|
||||
poco_assert (second >= 0 && second <= 60); // allow leap seconds
|
||||
poco_assert (millisecond >= 0 && millisecond <= 999);
|
||||
poco_assert (microsecond >= 0 && microsecond <= 999);
|
||||
|
||||
_utcTime = toUtcTime(toJulianDay(year, month, day)) + 10*(hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS + millisecond*Timespan::MILLISECONDS + microsecond);
|
||||
}
|
||||
|
||||
|
||||
DateTime::DateTime(double julianDay):
|
||||
_utcTime(toUtcTime(julianDay))
|
||||
{
|
||||
computeGregorian(julianDay);
|
||||
}
|
||||
|
||||
|
||||
DateTime::DateTime(Timestamp::UtcTimeVal utcTime, Timestamp::TimeDiff diff):
|
||||
_utcTime(utcTime + diff*10)
|
||||
{
|
||||
computeGregorian(julianDay());
|
||||
computeDaytime();
|
||||
}
|
||||
|
||||
|
||||
DateTime::DateTime(const DateTime& dateTime):
|
||||
_utcTime(dateTime._utcTime),
|
||||
_year(dateTime._year),
|
||||
_month(dateTime._month),
|
||||
_day(dateTime._day),
|
||||
_hour(dateTime._hour),
|
||||
_minute(dateTime._minute),
|
||||
_second(dateTime._second),
|
||||
_millisecond(dateTime._millisecond),
|
||||
_microsecond(dateTime._microsecond)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DateTime::~DateTime()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DateTime& DateTime::operator = (const DateTime& dateTime)
|
||||
{
|
||||
if (&dateTime != this)
|
||||
{
|
||||
_utcTime = dateTime._utcTime;
|
||||
_year = dateTime._year;
|
||||
_month = dateTime._month;
|
||||
_day = dateTime._day;
|
||||
_hour = dateTime._hour;
|
||||
_minute = dateTime._minute;
|
||||
_second = dateTime._second;
|
||||
_millisecond = dateTime._millisecond;
|
||||
_microsecond = dateTime._microsecond;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DateTime& DateTime::operator = (const Timestamp& timestamp)
|
||||
{
|
||||
_utcTime = timestamp.utcTime();
|
||||
computeGregorian(julianDay());
|
||||
computeDaytime();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DateTime& DateTime::operator = (double julianDay)
|
||||
{
|
||||
_utcTime = toUtcTime(julianDay);
|
||||
computeGregorian(julianDay);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DateTime& DateTime::assign(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
|
||||
{
|
||||
poco_assert (year >= 0 && year <= 9999);
|
||||
poco_assert (month >= 1 && month <= 12);
|
||||
poco_assert (day >= 1 && day <= daysOfMonth(year, month));
|
||||
poco_assert (hour >= 0 && hour <= 23);
|
||||
poco_assert (minute >= 0 && minute <= 59);
|
||||
poco_assert (second >= 0 && second <= 60); // allow leap seconds
|
||||
poco_assert (millisecond >= 0 && millisecond <= 999);
|
||||
poco_assert (microsecond >= 0 && microsecond <= 999);
|
||||
|
||||
_utcTime = toUtcTime(toJulianDay(year, month, day)) + 10*(hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS + millisecond*Timespan::MILLISECONDS + microsecond);
|
||||
_year = year;
|
||||
_month = month;
|
||||
_day = day;
|
||||
_hour = hour;
|
||||
_minute = minute;
|
||||
_second = second;
|
||||
_millisecond = millisecond;
|
||||
_microsecond = microsecond;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void DateTime::swap(DateTime& dateTime)
|
||||
{
|
||||
std::swap(_utcTime, dateTime._utcTime);
|
||||
std::swap(_year, dateTime._year);
|
||||
std::swap(_month, dateTime._month);
|
||||
std::swap(_day, dateTime._day);
|
||||
std::swap(_hour, dateTime._hour);
|
||||
std::swap(_minute, dateTime._minute);
|
||||
std::swap(_second, dateTime._second);
|
||||
std::swap(_millisecond, dateTime._millisecond);
|
||||
std::swap(_microsecond, dateTime._microsecond);
|
||||
}
|
||||
|
||||
|
||||
int DateTime::dayOfWeek() const
|
||||
{
|
||||
return int((std::floor(julianDay() + 1.5))) % 7;
|
||||
}
|
||||
|
||||
|
||||
int DateTime::dayOfYear() const
|
||||
{
|
||||
int doy = 0;
|
||||
for (int month = 1; month < _month; ++month)
|
||||
doy += daysOfMonth(_year, month);
|
||||
doy += _day;
|
||||
return doy;
|
||||
}
|
||||
|
||||
|
||||
int DateTime::daysOfMonth(int year, int month)
|
||||
{
|
||||
poco_assert (month >= 1 && month <= 12);
|
||||
|
||||
static int daysOfMonthTable[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
if (month == 2 && isLeapYear(year))
|
||||
return 29;
|
||||
else
|
||||
return daysOfMonthTable[month];
|
||||
}
|
||||
|
||||
|
||||
bool DateTime::isValid(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
|
||||
{
|
||||
return
|
||||
(year >= 0 && year <= 9999) &&
|
||||
(month >= 1 && month <= 12) &&
|
||||
(day >= 1 && day <= daysOfMonth(year, month)) &&
|
||||
(hour >= 0 && hour <= 23) &&
|
||||
(minute >= 0 && minute <= 59) &&
|
||||
(second >= 0 && second <= 60) &&
|
||||
(millisecond >= 0 && millisecond <= 999) &&
|
||||
(microsecond >= 0 && microsecond <= 999);
|
||||
}
|
||||
|
||||
|
||||
int DateTime::week(int firstDayOfWeek) const
|
||||
{
|
||||
poco_assert (firstDayOfWeek >= 0 && firstDayOfWeek <= 6);
|
||||
|
||||
/// find the first firstDayOfWeek.
|
||||
int baseDay = 1;
|
||||
while (DateTime(_year, 1, baseDay).dayOfWeek() != firstDayOfWeek) ++baseDay;
|
||||
|
||||
int doy = dayOfYear();
|
||||
int offs = baseDay <= 4 ? 0 : 1;
|
||||
if (doy < baseDay)
|
||||
return offs;
|
||||
else
|
||||
return (doy - baseDay)/7 + 1 + offs;
|
||||
}
|
||||
|
||||
|
||||
double DateTime::julianDay() const
|
||||
{
|
||||
return toJulianDay(_utcTime);
|
||||
}
|
||||
|
||||
|
||||
DateTime DateTime::operator + (const Timespan& span) const
|
||||
{
|
||||
return DateTime(_utcTime, span.totalMicroseconds());
|
||||
}
|
||||
|
||||
|
||||
DateTime DateTime::operator - (const Timespan& span) const
|
||||
{
|
||||
return DateTime(_utcTime, -span.totalMicroseconds());
|
||||
}
|
||||
|
||||
|
||||
Timespan DateTime::operator - (const DateTime& dateTime) const
|
||||
{
|
||||
return Timespan((_utcTime - dateTime._utcTime)/10);
|
||||
}
|
||||
|
||||
|
||||
DateTime& DateTime::operator += (const Timespan& span)
|
||||
{
|
||||
_utcTime += span.totalMicroseconds()*10;
|
||||
computeGregorian(julianDay());
|
||||
computeDaytime();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DateTime& DateTime::operator -= (const Timespan& span)
|
||||
{
|
||||
_utcTime -= span.totalMicroseconds()*10;
|
||||
computeGregorian(julianDay());
|
||||
computeDaytime();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
tm DateTime::makeTM() const
|
||||
{
|
||||
tm tmStruct;
|
||||
|
||||
tmStruct.tm_sec = _second;
|
||||
tmStruct.tm_min = _minute;
|
||||
tmStruct.tm_hour = _hour;
|
||||
tmStruct.tm_mday = _day;
|
||||
poco_assert (_month > 0);
|
||||
tmStruct.tm_mon = _month - 1;
|
||||
poco_assert (_year >= 1900);
|
||||
tmStruct.tm_year = _year - 1900;
|
||||
tmStruct.tm_wday = dayOfWeek();
|
||||
int doy = dayOfYear();
|
||||
poco_assert (_year >0);
|
||||
tmStruct.tm_yday = doy - 1;
|
||||
tmStruct.tm_isdst = -1;
|
||||
|
||||
return tmStruct;
|
||||
}
|
||||
|
||||
|
||||
void DateTime::makeUTC(int tzd)
|
||||
{
|
||||
operator -= (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS));
|
||||
}
|
||||
|
||||
|
||||
void DateTime::makeLocal(int tzd)
|
||||
{
|
||||
operator += (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS));
|
||||
}
|
||||
|
||||
|
||||
double DateTime::toJulianDay(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
|
||||
{
|
||||
// lookup table for (153*month - 457)/5 - note that 3 <= month <= 14.
|
||||
static int lookup[] = {-91, -60, -30, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337};
|
||||
|
||||
// day to double
|
||||
double dday = double(day) + ((double((hour*60 + minute)*60 + second)*1000 + millisecond)*1000 + microsecond)/86400000000.0;
|
||||
if (month < 3)
|
||||
{
|
||||
month += 12;
|
||||
--year;
|
||||
}
|
||||
double dyear = double(year);
|
||||
return dday + lookup[month] + 365*year + std::floor(dyear/4) - std::floor(dyear/100) + std::floor(dyear/400) + 1721118.5;
|
||||
}
|
||||
|
||||
|
||||
void DateTime::checkLimit(short& lower, short& higher, short limit)
|
||||
{
|
||||
if (lower >= limit)
|
||||
{
|
||||
higher += short(lower / limit);
|
||||
lower = short(lower % limit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DateTime::normalize()
|
||||
{
|
||||
checkLimit(_microsecond, _millisecond, 1000);
|
||||
checkLimit(_millisecond, _second, 1000);
|
||||
checkLimit(_second, _minute, 60);
|
||||
checkLimit(_minute, _hour, 60);
|
||||
checkLimit(_hour, _day, 24);
|
||||
|
||||
if (_day > daysOfMonth(_year, _month))
|
||||
{
|
||||
_day -= daysOfMonth(_year, _month);
|
||||
if (++_month > 12)
|
||||
{
|
||||
++_year;
|
||||
_month -= 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DateTime::computeGregorian(double julianDay)
|
||||
{
|
||||
double z = std::floor(julianDay - 1721118.5);
|
||||
double r = julianDay - 1721118.5 - z;
|
||||
double g = z - 0.25;
|
||||
double a = std::floor(g / 36524.25);
|
||||
double b = a - std::floor(a/4);
|
||||
_year = short(std::floor((b + g)/365.25));
|
||||
double c = b + z - std::floor(365.25*_year);
|
||||
_month = short(std::floor((5*c + 456)/153));
|
||||
double dday = c - std::floor((153.0*_month - 457)/5) + r;
|
||||
_day = short(dday);
|
||||
if (_month > 12)
|
||||
{
|
||||
++_year;
|
||||
_month -= 12;
|
||||
}
|
||||
r *= 24;
|
||||
_hour = short(std::floor(r));
|
||||
r -= std::floor(r);
|
||||
r *= 60;
|
||||
_minute = short(std::floor(r));
|
||||
r -= std::floor(r);
|
||||
r *= 60;
|
||||
_second = short(std::floor(r));
|
||||
r -= std::floor(r);
|
||||
r *= 1000;
|
||||
_millisecond = short(std::floor(r));
|
||||
r -= std::floor(r);
|
||||
r *= 1000;
|
||||
_microsecond = short(r + 0.5);
|
||||
|
||||
normalize();
|
||||
|
||||
poco_assert_dbg (_month >= 1 && _month <= 12);
|
||||
poco_assert_dbg (_day >= 1 && _day <= daysOfMonth(_year, _month));
|
||||
poco_assert_dbg (_hour >= 0 && _hour <= 23);
|
||||
poco_assert_dbg (_minute >= 0 && _minute <= 59);
|
||||
poco_assert_dbg (_second >= 0 && _second <= 59);
|
||||
poco_assert_dbg (_millisecond >= 0 && _millisecond <= 999);
|
||||
poco_assert_dbg (_microsecond >= 0 && _microsecond <= 999);
|
||||
}
|
||||
|
||||
|
||||
void DateTime::computeDaytime()
|
||||
{
|
||||
Timespan span(_utcTime/10);
|
||||
int hour = span.hours();
|
||||
// Due to double rounding issues, the previous call to computeGregorian()
|
||||
// may have crossed into the next or previous day. We need to correct that.
|
||||
if (hour == 23 && _hour == 0)
|
||||
{
|
||||
_day--;
|
||||
if (_day == 0)
|
||||
{
|
||||
_month--;
|
||||
if (_month == 0)
|
||||
{
|
||||
_month = 12;
|
||||
_year--;
|
||||
}
|
||||
_day = daysOfMonth(_year, _month);
|
||||
}
|
||||
}
|
||||
else if (hour == 0 && _hour == 23)
|
||||
{
|
||||
_day++;
|
||||
if (_day > daysOfMonth(_year, _month))
|
||||
{
|
||||
_month++;
|
||||
if (_month > 12)
|
||||
{
|
||||
_month = 1;
|
||||
_year++;
|
||||
}
|
||||
_day = 1;
|
||||
}
|
||||
}
|
||||
_hour = hour;
|
||||
_minute = span.minutes();
|
||||
_second = span.seconds();
|
||||
_millisecond = span.milliseconds();
|
||||
_microsecond = span.microseconds();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// DateTimeFormat.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: DateTime
|
||||
// Module: DateTimeFormat
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const std::string DateTimeFormat::ISO8601_FORMAT("%Y-%m-%dT%H:%M:%S%z");
|
||||
const std::string DateTimeFormat::ISO8601_FRAC_FORMAT("%Y-%m-%dT%H:%M:%s%z");
|
||||
const std::string DateTimeFormat::RFC822_FORMAT("%w, %e %b %y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::RFC1123_FORMAT("%w, %e %b %Y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::HTTP_FORMAT("%w, %d %b %Y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::RFC850_FORMAT("%W, %e-%b-%y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::RFC1036_FORMAT("%W, %e %b %y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::ASCTIME_FORMAT("%w %b %f %H:%M:%S %Y");
|
||||
const std::string DateTimeFormat::SORTABLE_FORMAT("%Y-%m-%d %H:%M:%S");
|
||||
|
||||
|
||||
const std::string DateTimeFormat::WEEKDAY_NAMES[] =
|
||||
{
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday"
|
||||
};
|
||||
|
||||
|
||||
const std::string DateTimeFormat::MONTH_NAMES[] =
|
||||
{
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
//
|
||||
// DateTimeFormatter.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: DateTime
|
||||
// Module: DateTimeFormatter
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
void DateTimeFormatter::append(std::string& str, const LocalDateTime& dateTime, const std::string& fmt)
|
||||
{
|
||||
DateTimeFormatter::append(str, dateTime._dateTime, fmt, dateTime.tzd());
|
||||
}
|
||||
|
||||
|
||||
void DateTimeFormatter::append(std::string& str, const DateTime& dateTime, const std::string& fmt, int timeZoneDifferential)
|
||||
{
|
||||
std::string::const_iterator it = fmt.begin();
|
||||
std::string::const_iterator end = fmt.end();
|
||||
while (it != end)
|
||||
{
|
||||
if (*it == '%')
|
||||
{
|
||||
if (++it != end)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case 'w': str.append(DateTimeFormat::WEEKDAY_NAMES[dateTime.dayOfWeek()], 0, 3); break;
|
||||
case 'W': str.append(DateTimeFormat::WEEKDAY_NAMES[dateTime.dayOfWeek()]); break;
|
||||
case 'b': str.append(DateTimeFormat::MONTH_NAMES[dateTime.month() - 1], 0, 3); break;
|
||||
case 'B': str.append(DateTimeFormat::MONTH_NAMES[dateTime.month() - 1]); break;
|
||||
case 'd': NumberFormatter::append0(str, dateTime.day(), 2); break;
|
||||
case 'e': NumberFormatter::append(str, dateTime.day()); break;
|
||||
case 'f': NumberFormatter::append(str, dateTime.day(), 2); break;
|
||||
case 'm': NumberFormatter::append0(str, dateTime.month(), 2); break;
|
||||
case 'n': NumberFormatter::append(str, dateTime.month()); break;
|
||||
case 'o': NumberFormatter::append(str, dateTime.month(), 2); break;
|
||||
case 'y': NumberFormatter::append0(str, dateTime.year() % 100, 2); break;
|
||||
case 'Y': NumberFormatter::append0(str, dateTime.year(), 4); break;
|
||||
case 'H': NumberFormatter::append0(str, dateTime.hour(), 2); break;
|
||||
case 'h': NumberFormatter::append0(str, dateTime.hourAMPM(), 2); break;
|
||||
case 'a': str.append(dateTime.isAM() ? "am" : "pm"); break;
|
||||
case 'A': str.append(dateTime.isAM() ? "AM" : "PM"); break;
|
||||
case 'M': NumberFormatter::append0(str, dateTime.minute(), 2); break;
|
||||
case 'S': NumberFormatter::append0(str, dateTime.second(), 2); break;
|
||||
case 's': NumberFormatter::append0(str, dateTime.second(), 2);
|
||||
str += '.';
|
||||
NumberFormatter::append0(str, dateTime.millisecond()*1000 + dateTime.microsecond(), 6);
|
||||
break;
|
||||
case 'i': NumberFormatter::append0(str, dateTime.millisecond(), 3); break;
|
||||
case 'c': NumberFormatter::append(str, dateTime.millisecond()/100); break;
|
||||
case 'F': NumberFormatter::append0(str, dateTime.millisecond()*1000 + dateTime.microsecond(), 6); break;
|
||||
case 'z': tzdISO(str, timeZoneDifferential); break;
|
||||
case 'Z': tzdRFC(str, timeZoneDifferential); break;
|
||||
default: str += *it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
else str += *it++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DateTimeFormatter::append(std::string& str, const Timespan& timespan, const std::string& fmt)
|
||||
{
|
||||
std::string::const_iterator it = fmt.begin();
|
||||
std::string::const_iterator end = fmt.end();
|
||||
while (it != end)
|
||||
{
|
||||
if (*it == '%')
|
||||
{
|
||||
if (++it != end)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case 'd': NumberFormatter::append(str, timespan.days()); break;
|
||||
case 'H': NumberFormatter::append0(str, timespan.hours(), 2); break;
|
||||
case 'h': NumberFormatter::append(str, timespan.totalHours()); break;
|
||||
case 'M': NumberFormatter::append0(str, timespan.minutes(), 2); break;
|
||||
case 'm': NumberFormatter::append(str, timespan.totalMinutes()); break;
|
||||
case 'S': NumberFormatter::append0(str, timespan.seconds(), 2); break;
|
||||
case 's': NumberFormatter::append(str, timespan.totalSeconds()); break;
|
||||
case 'i': NumberFormatter::append0(str, timespan.milliseconds(), 3); break;
|
||||
case 'c': NumberFormatter::append(str, timespan.milliseconds()/100); break;
|
||||
case 'F': NumberFormatter::append0(str, timespan.milliseconds()*1000 + timespan.microseconds(), 6); break;
|
||||
default: str += *it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
else str += *it++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DateTimeFormatter::tzdISO(std::string& str, int timeZoneDifferential)
|
||||
{
|
||||
if (timeZoneDifferential != UTC)
|
||||
{
|
||||
if (timeZoneDifferential >= 0)
|
||||
{
|
||||
str += '+';
|
||||
NumberFormatter::append0(str, timeZoneDifferential/3600, 2);
|
||||
str += ':';
|
||||
NumberFormatter::append0(str, (timeZoneDifferential%3600)/60, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
str += '-';
|
||||
NumberFormatter::append0(str, -timeZoneDifferential/3600, 2);
|
||||
str += ':';
|
||||
NumberFormatter::append0(str, (-timeZoneDifferential%3600)/60, 2);
|
||||
}
|
||||
}
|
||||
else str += 'Z';
|
||||
}
|
||||
|
||||
|
||||
void DateTimeFormatter::tzdRFC(std::string& str, int timeZoneDifferential)
|
||||
{
|
||||
if (timeZoneDifferential != UTC)
|
||||
{
|
||||
if (timeZoneDifferential >= 0)
|
||||
{
|
||||
str += '+';
|
||||
NumberFormatter::append0(str, timeZoneDifferential/3600, 2);
|
||||
NumberFormatter::append0(str, (timeZoneDifferential%3600)/60, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
str += '-';
|
||||
NumberFormatter::append0(str, -timeZoneDifferential/3600, 2);
|
||||
NumberFormatter::append0(str, (-timeZoneDifferential%3600)/60, 2);
|
||||
}
|
||||
}
|
||||
else str += "GMT";
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+393
@@ -0,0 +1,393 @@
|
||||
//
|
||||
// DateTimeParser.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: DateTime
|
||||
// Module: DateTimeParser
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DateTimeParser.h"
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Ascii.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
#define SKIP_JUNK() \
|
||||
while (it != end && !Ascii::isDigit(*it)) ++it
|
||||
|
||||
|
||||
#define SKIP_DIGITS() \
|
||||
while (it != end && Ascii::isDigit(*it)) ++it
|
||||
|
||||
|
||||
#define PARSE_NUMBER(var) \
|
||||
while (it != end && Ascii::isDigit(*it)) var = var*10 + ((*it++) - '0')
|
||||
|
||||
|
||||
#define PARSE_NUMBER_N(var, n) \
|
||||
{ int i = 0; while (i++ < n && it != end && Ascii::isDigit(*it)) var = var*10 + ((*it++) - '0'); }
|
||||
|
||||
|
||||
#define PARSE_FRACTIONAL_N(var, n) \
|
||||
{ int i = 0; while (i < n && it != end && Ascii::isDigit(*it)) { var = var*10 + ((*it++) - '0'); i++; } while (i++ < n) var *= 10; }
|
||||
|
||||
|
||||
void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
|
||||
{
|
||||
if (fmt.empty() || str.empty())
|
||||
throw SyntaxException("Empty string.");
|
||||
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
int day = 0;
|
||||
int hour = 0;
|
||||
int minute = 0;
|
||||
int second = 0;
|
||||
int millis = 0;
|
||||
int micros = 0;
|
||||
int tzd = 0;
|
||||
|
||||
std::string::const_iterator it = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
std::string::const_iterator itf = fmt.begin();
|
||||
std::string::const_iterator endf = fmt.end();
|
||||
|
||||
while (itf != endf && it != end)
|
||||
{
|
||||
if (*itf == '%')
|
||||
{
|
||||
if (++itf != endf)
|
||||
{
|
||||
switch (*itf)
|
||||
{
|
||||
case 'w':
|
||||
case 'W':
|
||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||
while (it != end && Ascii::isAlpha(*it)) ++it;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
month = parseMonth(it, end);
|
||||
break;
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(day, 2);
|
||||
break;
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(month, 2);
|
||||
break;
|
||||
case 'y':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(year, 2);
|
||||
if (year >= 69)
|
||||
year += 1900;
|
||||
else
|
||||
year += 2000;
|
||||
break;
|
||||
case 'Y':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(year, 4);
|
||||
break;
|
||||
case 'r':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER(year);
|
||||
if (year < 1000)
|
||||
{
|
||||
if (year >= 69)
|
||||
year += 1900;
|
||||
else
|
||||
year += 2000;
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
case 'h':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(hour, 2);
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
hour = parseAMPM(it, end, hour);
|
||||
break;
|
||||
case 'M':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(minute, 2);
|
||||
break;
|
||||
case 'S':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(second, 2);
|
||||
break;
|
||||
case 's':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(second, 2);
|
||||
if (it != end && (*it == '.' || *it == ','))
|
||||
{
|
||||
++it;
|
||||
PARSE_FRACTIONAL_N(millis, 3);
|
||||
PARSE_FRACTIONAL_N(micros, 3);
|
||||
SKIP_DIGITS();
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(millis, 3);
|
||||
break;
|
||||
case 'c':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(millis, 1);
|
||||
millis *= 100;
|
||||
break;
|
||||
case 'F':
|
||||
SKIP_JUNK();
|
||||
PARSE_FRACTIONAL_N(millis, 3);
|
||||
PARSE_FRACTIONAL_N(micros, 3);
|
||||
SKIP_DIGITS();
|
||||
break;
|
||||
case 'z':
|
||||
case 'Z':
|
||||
tzd = parseTZD(it, end);
|
||||
break;
|
||||
}
|
||||
++itf;
|
||||
}
|
||||
}
|
||||
else ++itf;
|
||||
}
|
||||
if (month == 0) month = 1;
|
||||
if (day == 0) day = 1;
|
||||
if (DateTime::isValid(year, month, day, hour, minute, second, millis, micros))
|
||||
dateTime.assign(year, month, day, hour, minute, second, millis, micros);
|
||||
else
|
||||
throw SyntaxException("date/time component out of range");
|
||||
timeZoneDifferential = tzd;
|
||||
}
|
||||
|
||||
|
||||
DateTime DateTimeParser::parse(const std::string& fmt, const std::string& str, int& timeZoneDifferential)
|
||||
{
|
||||
DateTime result;
|
||||
parse(fmt, str, result, timeZoneDifferential);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool DateTimeParser::tryParse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
|
||||
{
|
||||
try
|
||||
{
|
||||
parse(fmt, str, dateTime, timeZoneDifferential);
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DateTimeParser::parse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
|
||||
{
|
||||
if (!tryParse(str, dateTime, timeZoneDifferential))
|
||||
throw SyntaxException("Unsupported or invalid date/time format");
|
||||
}
|
||||
|
||||
|
||||
DateTime DateTimeParser::parse(const std::string& str, int& timeZoneDifferential)
|
||||
{
|
||||
DateTime result;
|
||||
if (tryParse(str, result, timeZoneDifferential))
|
||||
return result;
|
||||
else
|
||||
throw SyntaxException("Unsupported or invalid date/time format");
|
||||
}
|
||||
|
||||
|
||||
bool DateTimeParser::tryParse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
|
||||
{
|
||||
if (str.length() < 4) return false;
|
||||
|
||||
if (str[3] == ',')
|
||||
return tryParse("%w, %e %b %r %H:%M:%S %Z", str, dateTime, timeZoneDifferential);
|
||||
else if (str[3] == ' ')
|
||||
return tryParse(DateTimeFormat::ASCTIME_FORMAT, str, dateTime, timeZoneDifferential);
|
||||
else if (str.find(',') < 10)
|
||||
return tryParse("%W, %e %b %r %H:%M:%S %Z", str, dateTime, timeZoneDifferential);
|
||||
else if (Ascii::isDigit(str[0]))
|
||||
{
|
||||
if (str.find(' ') != std::string::npos || str.length() == 10)
|
||||
return tryParse(DateTimeFormat::SORTABLE_FORMAT, str, dateTime, timeZoneDifferential);
|
||||
else if (str.find('.') != std::string::npos || str.find(',') != std::string::npos)
|
||||
return tryParse(DateTimeFormat::ISO8601_FRAC_FORMAT, str, dateTime, timeZoneDifferential);
|
||||
else
|
||||
return tryParse(DateTimeFormat::ISO8601_FORMAT, str, dateTime, timeZoneDifferential);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
int DateTimeParser::parseTZD(std::string::const_iterator& it, const std::string::const_iterator& end)
|
||||
{
|
||||
struct Zone
|
||||
{
|
||||
const char* designator;
|
||||
int timeZoneDifferential;
|
||||
};
|
||||
|
||||
static Zone zones[] =
|
||||
{
|
||||
{"Z", 0},
|
||||
{"UT", 0},
|
||||
{"GMT", 0},
|
||||
{"BST", 1*3600},
|
||||
{"IST", 1*3600},
|
||||
{"WET", 0},
|
||||
{"WEST", 1*3600},
|
||||
{"CET", 1*3600},
|
||||
{"CEST", 2*3600},
|
||||
{"EET", 2*3600},
|
||||
{"EEST", 3*3600},
|
||||
{"MSK", 3*3600},
|
||||
{"MSD", 4*3600},
|
||||
{"NST", -3*3600-1800},
|
||||
{"NDT", -2*3600-1800},
|
||||
{"AST", -4*3600},
|
||||
{"ADT", -3*3600},
|
||||
{"EST", -5*3600},
|
||||
{"EDT", -4*3600},
|
||||
{"CST", -6*3600},
|
||||
{"CDT", -5*3600},
|
||||
{"MST", -7*3600},
|
||||
{"MDT", -6*3600},
|
||||
{"PST", -8*3600},
|
||||
{"PDT", -7*3600},
|
||||
{"AKST", -9*3600},
|
||||
{"AKDT", -8*3600},
|
||||
{"HST", -10*3600},
|
||||
{"AEST", 10*3600},
|
||||
{"AEDT", 11*3600},
|
||||
{"ACST", 9*3600+1800},
|
||||
{"ACDT", 10*3600+1800},
|
||||
{"AWST", 8*3600},
|
||||
{"AWDT", 9*3600}
|
||||
};
|
||||
|
||||
int tzd = 0;
|
||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||
if (it != end)
|
||||
{
|
||||
if (Ascii::isAlpha(*it))
|
||||
{
|
||||
std::string designator;
|
||||
designator += *it++;
|
||||
if (it != end && Ascii::isAlpha(*it)) designator += *it++;
|
||||
if (it != end && Ascii::isAlpha(*it)) designator += *it++;
|
||||
if (it != end && Ascii::isAlpha(*it)) designator += *it++;
|
||||
for (unsigned i = 0; i < sizeof(zones)/sizeof(Zone); ++i)
|
||||
{
|
||||
if (designator == zones[i].designator)
|
||||
{
|
||||
tzd = zones[i].timeZoneDifferential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it != end && (*it == '+' || *it == '-'))
|
||||
{
|
||||
int sign = *it == '+' ? 1 : -1;
|
||||
++it;
|
||||
int hours = 0;
|
||||
PARSE_NUMBER_N(hours, 2);
|
||||
if (it != end && *it == ':') ++it;
|
||||
int minutes = 0;
|
||||
PARSE_NUMBER_N(minutes, 2);
|
||||
tzd += sign*(hours*3600 + minutes*60);
|
||||
}
|
||||
}
|
||||
return tzd;
|
||||
}
|
||||
|
||||
|
||||
int DateTimeParser::parseMonth(std::string::const_iterator& it, const std::string::const_iterator& end)
|
||||
{
|
||||
std::string month;
|
||||
while (it != end && (Ascii::isSpace(*it) || Ascii::isPunct(*it))) ++it;
|
||||
bool isFirst = true;
|
||||
while (it != end && Ascii::isAlpha(*it))
|
||||
{
|
||||
char ch = (*it++);
|
||||
if (isFirst) { month += Ascii::toUpper(ch); isFirst = false; }
|
||||
else month += Ascii::toLower(ch);
|
||||
}
|
||||
if (month.length() < 3) throw SyntaxException("Month name must be at least three characters long", month);
|
||||
for (int i = 0; i < 12; ++i)
|
||||
{
|
||||
if (DateTimeFormat::MONTH_NAMES[i].find(month) == 0)
|
||||
return i + 1;
|
||||
}
|
||||
throw SyntaxException("Not a valid month name", month);
|
||||
}
|
||||
|
||||
|
||||
int DateTimeParser::parseDayOfWeek(std::string::const_iterator& it, const std::string::const_iterator& end)
|
||||
{
|
||||
std::string dow;
|
||||
while (it != end && (Ascii::isSpace(*it) || Ascii::isPunct(*it))) ++it;
|
||||
bool isFirst = true;
|
||||
while (it != end && Ascii::isAlpha(*it))
|
||||
{
|
||||
char ch = (*it++);
|
||||
if (isFirst) { dow += Ascii::toUpper(ch); isFirst = false; }
|
||||
else dow += Ascii::toLower(ch);
|
||||
}
|
||||
if (dow.length() < 3) throw SyntaxException("Weekday name must be at least three characters long", dow);
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
if (DateTimeFormat::WEEKDAY_NAMES[i].find(dow) == 0)
|
||||
return i;
|
||||
}
|
||||
throw SyntaxException("Not a valid weekday name", dow);
|
||||
}
|
||||
|
||||
|
||||
int DateTimeParser::parseAMPM(std::string::const_iterator& it, const std::string::const_iterator& end, int hour)
|
||||
{
|
||||
std::string ampm;
|
||||
while (it != end && (Ascii::isSpace(*it) || Ascii::isPunct(*it))) ++it;
|
||||
while (it != end && Ascii::isAlpha(*it))
|
||||
{
|
||||
char ch = (*it++);
|
||||
ampm += Ascii::toUpper(ch);
|
||||
}
|
||||
if (ampm == "AM")
|
||||
{
|
||||
if (hour == 12)
|
||||
return 0;
|
||||
else
|
||||
return hour;
|
||||
}
|
||||
else if (ampm == "PM")
|
||||
{
|
||||
if (hour < 12)
|
||||
return hour + 12;
|
||||
else
|
||||
return hour;
|
||||
}
|
||||
else throw SyntaxException("Not a valid AM/PM designator", ampm);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// Debugger.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Debugger
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Debugger.h"
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "Poco/UnWindows.h"
|
||||
#elif defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS)
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
|
||||
|
||||
// NOTE: In this module, we use the C library functions (fputs) for,
|
||||
// output since, at the time we're called, the C++ iostream objects std::cout, etc.
|
||||
// might not have been initialized yet.
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
bool Debugger::isAvailable()
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#if defined(_WIN32_WCE)
|
||||
#if (_WIN32_WCE >= 0x600)
|
||||
BOOL isDebuggerPresent;
|
||||
if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &isDebuggerPresent))
|
||||
{
|
||||
return isDebuggerPresent ? true : false;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
#else
|
||||
return IsDebuggerPresent() ? true : false;
|
||||
#endif
|
||||
#elif defined(POCO_VXWORKS)
|
||||
return false;
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
return std::getenv("POCO_ENABLE_DEBUGGER") ? true : false;
|
||||
#endif
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Debugger::message(const std::string& msg)
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
|
||||
std::fputs(msg.c_str(), stderr);
|
||||
std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
if (isAvailable())
|
||||
{
|
||||
std::wstring umsg;
|
||||
UnicodeConverter::toUTF16(msg, umsg);
|
||||
umsg += '\n';
|
||||
OutputDebugStringW(umsg.c_str());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Debugger::message(const std::string& msg, const char* file, int line)
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
std::ostringstream str;
|
||||
str << msg << " [in file \"" << file << "\", line " << line << "]";
|
||||
message(str.str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Debugger::enter()
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
if (isAvailable())
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
#elif defined(POCO_VXWORKS)
|
||||
{
|
||||
// not supported
|
||||
}
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
if (isAvailable())
|
||||
{
|
||||
kill(getpid(), SIGINT);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Debugger::enter(const std::string& msg)
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
message(msg);
|
||||
enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Debugger::enter(const std::string& msg, const char* file, int line)
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
message(msg, file, line);
|
||||
enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Debugger::enter(const char* file, int line)
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
message("BREAK", file, line);
|
||||
enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
//
|
||||
// DeflatingStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: ZLibStream
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DeflatingStream.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DeflatingStreamBuf::DeflatingStreamBuf(std::istream& istr, StreamType type, int level):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_eof(false)
|
||||
{
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.total_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
_zstr.total_out = 0;
|
||||
_zstr.msg = 0;
|
||||
_zstr.state = 0;
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.data_type = 0;
|
||||
_zstr.adler = 0;
|
||||
_zstr.reserved = 0;
|
||||
|
||||
_buffer = new char[DEFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = deflateInit2(&_zstr, level, Z_DEFLATED, 15 + (type == STREAM_GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeflatingStreamBuf::DeflatingStreamBuf(std::istream& istr, int windowBits, int level):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_eof(false)
|
||||
{
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
|
||||
_buffer = new char[DEFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = deflateInit2(&_zstr, level, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeflatingStreamBuf::DeflatingStreamBuf(std::ostream& ostr, StreamType type, int level):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_eof(false)
|
||||
{
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
|
||||
_buffer = new char[DEFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = deflateInit2(&_zstr, level, Z_DEFLATED, 15 + (type == STREAM_GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeflatingStreamBuf::DeflatingStreamBuf(std::ostream& ostr, int windowBits, int level):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_eof(false)
|
||||
{
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
|
||||
_buffer = new char[DEFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = deflateInit2(&_zstr, level, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeflatingStreamBuf::~DeflatingStreamBuf()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
delete [] _buffer;
|
||||
deflateEnd(&_zstr);
|
||||
}
|
||||
|
||||
|
||||
int DeflatingStreamBuf::close()
|
||||
{
|
||||
BufferedStreamBuf::sync();
|
||||
_pIstr = 0;
|
||||
if (_pOstr)
|
||||
{
|
||||
if (_zstr.next_out)
|
||||
{
|
||||
int rc = deflate(&_zstr, Z_FINISH);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END) throw IOException(zError(rc));
|
||||
_pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing deflated data to output stream");
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
while (rc != Z_STREAM_END)
|
||||
{
|
||||
rc = deflate(&_zstr, Z_FINISH);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END) throw IOException(zError(rc));
|
||||
_pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing deflated data to output stream");
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
_pOstr->flush();
|
||||
_pOstr = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DeflatingStreamBuf::sync()
|
||||
{
|
||||
if (BufferedStreamBuf::sync())
|
||||
return -1;
|
||||
|
||||
if (_pOstr)
|
||||
{
|
||||
if (_zstr.next_out)
|
||||
{
|
||||
int rc = deflate(&_zstr, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK) throw IOException(zError(rc));
|
||||
_pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing deflated data to output stream");
|
||||
while (_zstr.avail_out == 0)
|
||||
{
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
rc = deflate(&_zstr, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK) throw IOException(zError(rc));
|
||||
_pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing deflated data to output stream");
|
||||
};
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
}
|
||||
// NOTE: This breaks the Zip library and causes corruption in some files.
|
||||
// See GH #1828
|
||||
// _pOstr->flush();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DeflatingStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
if (!_pIstr) return 0;
|
||||
if (_zstr.avail_in == 0 && !_eof)
|
||||
{
|
||||
int n = 0;
|
||||
if (_pIstr->good())
|
||||
{
|
||||
_pIstr->read(_buffer, DEFLATE_BUFFER_SIZE);
|
||||
n = static_cast<int>(_pIstr->gcount());
|
||||
}
|
||||
if (n > 0)
|
||||
{
|
||||
_zstr.next_in = (unsigned char*) _buffer;
|
||||
_zstr.avail_in = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_eof = true;
|
||||
}
|
||||
}
|
||||
_zstr.next_out = (unsigned char*) buffer;
|
||||
_zstr.avail_out = static_cast<unsigned>(length);
|
||||
for (;;)
|
||||
{
|
||||
int rc = deflate(&_zstr, _eof ? Z_FINISH : Z_NO_FLUSH);
|
||||
if (_eof && rc == Z_STREAM_END)
|
||||
{
|
||||
_pIstr = 0;
|
||||
return static_cast<int>(length) - _zstr.avail_out;
|
||||
}
|
||||
if (rc != Z_OK) throw IOException(zError(rc));
|
||||
if (_zstr.avail_out == 0)
|
||||
{
|
||||
return static_cast<int>(length);
|
||||
}
|
||||
if (_zstr.avail_in == 0)
|
||||
{
|
||||
int n = 0;
|
||||
if (_pIstr->good())
|
||||
{
|
||||
_pIstr->read(_buffer, DEFLATE_BUFFER_SIZE);
|
||||
n = static_cast<int>(_pIstr->gcount());
|
||||
}
|
||||
if (n > 0)
|
||||
{
|
||||
_zstr.next_in = (unsigned char*) _buffer;
|
||||
_zstr.avail_in = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_eof = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int DeflatingStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
if (length == 0 || !_pOstr) return 0;
|
||||
|
||||
_zstr.next_in = (unsigned char*) buffer;
|
||||
_zstr.avail_in = static_cast<unsigned>(length);
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
for (;;)
|
||||
{
|
||||
int rc = deflate(&_zstr, Z_NO_FLUSH);
|
||||
if (rc != Z_OK) throw IOException(zError(rc));
|
||||
if (_zstr.avail_out == 0)
|
||||
{
|
||||
_pOstr->write(_buffer, DEFLATE_BUFFER_SIZE);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing deflated data to output stream");
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
}
|
||||
if (_zstr.avail_in == 0)
|
||||
{
|
||||
_pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing deflated data to output stream");
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = DEFLATE_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<int>(length);
|
||||
}
|
||||
|
||||
|
||||
DeflatingIOS::DeflatingIOS(std::ostream& ostr, DeflatingStreamBuf::StreamType type, int level):
|
||||
_buf(ostr, type, level)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DeflatingIOS::DeflatingIOS(std::ostream& ostr, int windowBits, int level):
|
||||
_buf(ostr, windowBits, level)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DeflatingIOS::DeflatingIOS(std::istream& istr, DeflatingStreamBuf::StreamType type, int level):
|
||||
_buf(istr, type, level)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DeflatingIOS::DeflatingIOS(std::istream& istr, int windowBits, int level):
|
||||
_buf(istr, windowBits, level)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DeflatingIOS::~DeflatingIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeflatingStreamBuf* DeflatingIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
DeflatingOutputStream::DeflatingOutputStream(std::ostream& ostr, DeflatingStreamBuf::StreamType type, int level):
|
||||
std::ostream(&_buf),
|
||||
DeflatingIOS(ostr, type, level)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeflatingOutputStream::DeflatingOutputStream(std::ostream& ostr, int windowBits, int level):
|
||||
std::ostream(&_buf),
|
||||
DeflatingIOS(ostr, windowBits, level)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeflatingOutputStream::~DeflatingOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int DeflatingOutputStream::close()
|
||||
{
|
||||
return _buf.close();
|
||||
}
|
||||
|
||||
|
||||
int DeflatingOutputStream::sync()
|
||||
{
|
||||
return _buf.pubsync();
|
||||
}
|
||||
|
||||
|
||||
DeflatingInputStream::DeflatingInputStream(std::istream& istr, DeflatingStreamBuf::StreamType type, int level):
|
||||
std::istream(&_buf),
|
||||
DeflatingIOS(istr, type, level)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeflatingInputStream::DeflatingInputStream(std::istream& istr, int windowBits, int level):
|
||||
std::istream(&_buf),
|
||||
DeflatingIOS(istr, windowBits, level)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeflatingInputStream::~DeflatingInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// DigestEngine.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Crypt
|
||||
// Module: DigestEngine
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DigestEngine.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco
|
||||
{
|
||||
|
||||
DigestEngine::DigestEngine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestEngine::~DigestEngine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::string DigestEngine::digestToHex(const Digest& bytes)
|
||||
{
|
||||
static const char digits[] = "0123456789abcdef";
|
||||
std::string result;
|
||||
result.reserve(bytes.size() * 2);
|
||||
for (auto b: bytes)
|
||||
{
|
||||
result += digits[(b >> 4) & 0xF];
|
||||
result += digits[b & 0xF];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DigestEngine::Digest DigestEngine::digestFromHex(const std::string& digest)
|
||||
{
|
||||
if (digest.size() % 2 != 0)
|
||||
throw DataFormatException();
|
||||
Digest result;
|
||||
result.reserve(digest.size() / 2);
|
||||
for (std::size_t i = 0; i < digest.size(); ++i)
|
||||
{
|
||||
int c = 0;
|
||||
// first upper 4 bits
|
||||
if (digest[i] >= '0' && digest[i] <= '9')
|
||||
c = digest[i] - '0';
|
||||
else if (digest[i] >= 'a' && digest[i] <= 'f')
|
||||
c = digest[i] - 'a' + 10;
|
||||
else if (digest[i] >= 'A' && digest[i] <= 'F')
|
||||
c = digest[i] - 'A' + 10;
|
||||
else
|
||||
throw DataFormatException();
|
||||
c <<= 4;
|
||||
++i;
|
||||
if (digest[i] >= '0' && digest[i] <= '9')
|
||||
c += digest[i] - '0';
|
||||
else if (digest[i] >= 'a' && digest[i] <= 'f')
|
||||
c += digest[i] - 'a' + 10;
|
||||
else if (digest[i] >= 'A' && digest[i] <= 'F')
|
||||
c += digest[i] - 'A' + 10;
|
||||
else
|
||||
throw DataFormatException();
|
||||
|
||||
result.push_back(static_cast<unsigned char>(c));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool DigestEngine::constantTimeEquals(const Digest& d1, const Digest& d2)
|
||||
{
|
||||
if (d1.size() != d2.size()) return false;
|
||||
|
||||
int result = 0;
|
||||
Digest::const_iterator it1 = d1.begin();
|
||||
Digest::const_iterator it2 = d2.begin();
|
||||
Digest::const_iterator end1 = d1.end();
|
||||
while (it1 != end1)
|
||||
{
|
||||
result |= *it1++ ^ *it2++;
|
||||
}
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// DigestStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Crypt
|
||||
// Module: DigestStream
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DigestStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const int DigestBuf::BUFFER_SIZE = 256;
|
||||
|
||||
|
||||
DigestBuf::DigestBuf(DigestEngine& eng):
|
||||
BufferedStreamBuf(BUFFER_SIZE, std::ios::out),
|
||||
_eng(eng),
|
||||
_pIstr(0),
|
||||
_pOstr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestBuf::DigestBuf(DigestEngine& eng, std::istream& istr):
|
||||
BufferedStreamBuf(BUFFER_SIZE, std::ios::in),
|
||||
_eng(eng),
|
||||
_pIstr(&istr),
|
||||
_pOstr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestBuf::DigestBuf(DigestEngine& eng, std::ostream& ostr):
|
||||
BufferedStreamBuf(BUFFER_SIZE, std::ios::out),
|
||||
_eng(eng),
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestBuf::~DigestBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int DigestBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
if (_pIstr && _pIstr->good())
|
||||
{
|
||||
_pIstr->read(buffer, length);
|
||||
std::streamsize n = _pIstr->gcount();
|
||||
if (n > 0) _eng.update(buffer, static_cast<unsigned>(n));
|
||||
return static_cast<int>(n);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int DigestBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
_eng.update(buffer, (unsigned) length);
|
||||
if (_pOstr) _pOstr->write(buffer, length);
|
||||
return static_cast<int>(length);
|
||||
}
|
||||
|
||||
|
||||
void DigestBuf::close()
|
||||
{
|
||||
sync();
|
||||
if (_pOstr) _pOstr->flush();
|
||||
}
|
||||
|
||||
|
||||
DigestIOS::DigestIOS(DigestEngine& eng): _buf(eng)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DigestIOS::DigestIOS(DigestEngine& eng, std::istream& istr): _buf(eng, istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DigestIOS::DigestIOS(DigestEngine& eng, std::ostream& ostr): _buf(eng, ostr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
DigestIOS::~DigestIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestBuf* DigestIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
DigestInputStream::DigestInputStream(DigestEngine& eng, std::istream& istr):
|
||||
DigestIOS(eng, istr),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestInputStream::~DigestInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestOutputStream::DigestOutputStream(DigestEngine& eng):
|
||||
DigestIOS(eng),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestOutputStream::DigestOutputStream(DigestEngine& eng, std::ostream& ostr):
|
||||
DigestIOS(eng, ostr),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DigestOutputStream::~DigestOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DigestOutputStream::close()
|
||||
{
|
||||
_buf.close();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// DirectoryIterator.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: DirectoryIterator
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DirectoryIterator.h"
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "DirectoryIterator_WIN32U.cpp"
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
#include "DirectoryIterator_UNIX.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(): _pImpl(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(const std::string& path): _path(path), _pImpl(new DirectoryIteratorImpl(path))
|
||||
{
|
||||
_path.makeDirectory();
|
||||
_path.setFileName(_pImpl->get());
|
||||
_file = _path;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(const DirectoryIterator& iterator): _path(iterator._path), _pImpl(iterator._pImpl)
|
||||
{
|
||||
if (_pImpl)
|
||||
{
|
||||
_pImpl->duplicate();
|
||||
_file = _path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(const File& file): _path(file.path()), _pImpl(new DirectoryIteratorImpl(file.path()))
|
||||
{
|
||||
_path.makeDirectory();
|
||||
_path.setFileName(_pImpl->get());
|
||||
_file = _path;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(const Path& path): _path(path), _pImpl(new DirectoryIteratorImpl(path.toString()))
|
||||
{
|
||||
_path.makeDirectory();
|
||||
_path.setFileName(_pImpl->get());
|
||||
_file = _path;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator::~DirectoryIterator()
|
||||
{
|
||||
if (_pImpl) _pImpl->release();
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator& DirectoryIterator::operator = (const DirectoryIterator& it)
|
||||
{
|
||||
if (&it != this)
|
||||
{
|
||||
if (_pImpl) _pImpl->release();
|
||||
_pImpl = it._pImpl;
|
||||
if (_pImpl)
|
||||
{
|
||||
_pImpl->duplicate();
|
||||
_path = it._path;
|
||||
_file = _path;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator& DirectoryIterator::operator = (const File& file)
|
||||
{
|
||||
if (_pImpl) _pImpl->release();
|
||||
_pImpl = new DirectoryIteratorImpl(file.path());
|
||||
_path.parseDirectory(file.path());
|
||||
_path.setFileName(_pImpl->get());
|
||||
_file = _path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator& DirectoryIterator::operator = (const Path& path)
|
||||
{
|
||||
if (_pImpl) _pImpl->release();
|
||||
_pImpl = new DirectoryIteratorImpl(path.toString());
|
||||
_path = path;
|
||||
_path.makeDirectory();
|
||||
_path.setFileName(_pImpl->get());
|
||||
_file = _path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator& DirectoryIterator::operator = (const std::string& path)
|
||||
{
|
||||
if (_pImpl) _pImpl->release();
|
||||
_pImpl = new DirectoryIteratorImpl(path);
|
||||
_path.parseDirectory(path);
|
||||
_path.setFileName(_pImpl->get());
|
||||
_file = _path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator& DirectoryIterator::operator ++ ()
|
||||
{
|
||||
if (_pImpl)
|
||||
{
|
||||
_path.setFileName(_pImpl->next());
|
||||
_file = _path;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator DirectoryIterator::operator ++ (int dummy)
|
||||
{
|
||||
if (_pImpl)
|
||||
{
|
||||
_path.setFileName(_pImpl->next());
|
||||
_file = _path;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,168 @@
|
||||
//
|
||||
// RecursiveDirectoryIteratorStategies.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: RecursiveDirectoryIterator
|
||||
//
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DirectoryIteratorStrategy.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
//
|
||||
// TraverseBase
|
||||
//
|
||||
TraverseBase::TraverseBase(DepthFun depthDeterminer, UInt16 maxDepth)
|
||||
: _depthDeterminer(depthDeterminer), _maxDepth(maxDepth)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline bool TraverseBase::isFiniteDepth()
|
||||
{
|
||||
return _maxDepth != D_INFINITE;
|
||||
}
|
||||
|
||||
|
||||
bool TraverseBase::isDirectory(Poco::File& file)
|
||||
{
|
||||
try
|
||||
{
|
||||
return file.isDirectory();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ChildrenFirstTraverse
|
||||
//
|
||||
ChildrenFirstTraverse::ChildrenFirstTraverse(DepthFun depthDeterminer, UInt16 maxDepth)
|
||||
: TraverseBase(depthDeterminer, maxDepth)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const std::string ChildrenFirstTraverse::next(Stack* itStack, bool* isFinished)
|
||||
{
|
||||
// pointer mustn't point to NULL and iteration mustn't be finished
|
||||
poco_check_ptr(isFinished);
|
||||
poco_assert(!(*isFinished));
|
||||
|
||||
std::stack<DirectoryIterator> it;
|
||||
|
||||
//_depthDeterminer(it);
|
||||
|
||||
// go deeper into not empty directory
|
||||
// (if depth limit allows)
|
||||
bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth;
|
||||
if (!isDepthLimitReached && isDirectory(*itStack->top()))
|
||||
{
|
||||
DirectoryIterator child_it(itStack->top().path());
|
||||
// check if directory is empty
|
||||
if (child_it != _itEnd)
|
||||
{
|
||||
itStack->push(child_it);
|
||||
return child_it->path();
|
||||
}
|
||||
}
|
||||
|
||||
++(itStack->top());
|
||||
|
||||
poco_assert(!itStack->empty());
|
||||
// return up until there isn't right sibling
|
||||
while (itStack->top() == _itEnd)
|
||||
{
|
||||
itStack->pop();
|
||||
|
||||
// detect end of traversal
|
||||
if (itStack->empty())
|
||||
{
|
||||
*isFinished = true;
|
||||
return _itEnd->path();
|
||||
}
|
||||
else
|
||||
{
|
||||
++(itStack->top());
|
||||
}
|
||||
}
|
||||
|
||||
return itStack->top()->path();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SiblingsFirstTraverse
|
||||
//
|
||||
SiblingsFirstTraverse::SiblingsFirstTraverse(DepthFun depthDeterminer, UInt16 maxDepth)
|
||||
: TraverseBase(depthDeterminer, maxDepth)
|
||||
{
|
||||
_dirsStack.push(std::queue<std::string>());
|
||||
}
|
||||
|
||||
|
||||
const std::string SiblingsFirstTraverse::next(Stack* itStack, bool* isFinished)
|
||||
{
|
||||
// pointer mustn't point to NULL and iteration mustn't be finished
|
||||
poco_check_ptr(isFinished);
|
||||
poco_assert(!(*isFinished));
|
||||
|
||||
// add dirs to queue (if depth limit allows)
|
||||
bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth;
|
||||
if (!isDepthLimitReached && isDirectory(*itStack->top()))
|
||||
{
|
||||
const std::string& p = itStack->top()->path();
|
||||
_dirsStack.top().push(p);
|
||||
}
|
||||
|
||||
++(itStack->top());
|
||||
|
||||
poco_assert(!itStack->empty());
|
||||
// return up until there isn't right sibling
|
||||
while (itStack->top() == _itEnd)
|
||||
{
|
||||
// try to find first not empty directory and go deeper
|
||||
while (!_dirsStack.top().empty())
|
||||
{
|
||||
std::string dir = _dirsStack.top().front();
|
||||
_dirsStack.top().pop();
|
||||
DirectoryIterator child_it(dir);
|
||||
|
||||
// check if directory is empty
|
||||
if (child_it != _itEnd)
|
||||
{
|
||||
itStack->push(child_it);
|
||||
_dirsStack.push(std::queue<std::string>());
|
||||
return child_it->path();
|
||||
}
|
||||
}
|
||||
|
||||
// if fail go upper
|
||||
itStack->pop();
|
||||
_dirsStack.pop();
|
||||
|
||||
// detect end of traversal
|
||||
if (itStack->empty())
|
||||
{
|
||||
*isFinished = true;
|
||||
return _itEnd->path();
|
||||
}
|
||||
}
|
||||
|
||||
return itStack->top()->path();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// DirectoryIterator_UNIX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: DirectoryIterator
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DirectoryIterator_UNIX.h"
|
||||
#if defined(POCO_VXWORKS)
|
||||
#include "Poco/File_VX.h"
|
||||
#else
|
||||
#include "Poco/File_UNIX.h"
|
||||
#endif
|
||||
#include "Poco/Path.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DirectoryIteratorImpl::DirectoryIteratorImpl(const std::string& path): _pDir(0), _rc(1)
|
||||
{
|
||||
Path p(path);
|
||||
p.makeFile();
|
||||
|
||||
#if defined(POCO_VXWORKS)
|
||||
_pDir = opendir(const_cast<char*>(p.toString().c_str()));
|
||||
#else
|
||||
_pDir = opendir(p.toString().c_str());
|
||||
#endif
|
||||
if (!_pDir) File::handleLastError(path);
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
|
||||
DirectoryIteratorImpl::~DirectoryIteratorImpl()
|
||||
{
|
||||
if (_pDir) closedir(_pDir);
|
||||
}
|
||||
|
||||
|
||||
const std::string& DirectoryIteratorImpl::next()
|
||||
{
|
||||
do
|
||||
{
|
||||
struct dirent* pEntry = readdir(_pDir);
|
||||
if (pEntry)
|
||||
_current = pEntry->d_name;
|
||||
else
|
||||
_current.clear();
|
||||
}
|
||||
while (_current == "." || _current == "..");
|
||||
return _current;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// DirectoryIterator_WIN32U.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: DirectoryIterator
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DirectoryIterator_WIN32U.h"
|
||||
#if defined(_WIN32_WCE)
|
||||
#include "Poco/File_WINCE.h"
|
||||
#else
|
||||
#include "Poco/File_WIN32U.h"
|
||||
#endif
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DirectoryIteratorImpl::DirectoryIteratorImpl(const std::string& path): _fh(INVALID_HANDLE_VALUE), _rc(1)
|
||||
{
|
||||
Path p(path);
|
||||
p.makeDirectory();
|
||||
std::string findPath = p.toString();
|
||||
findPath.append("*");
|
||||
std::wstring uFindPath;
|
||||
FileImpl::convertPath(findPath, uFindPath);
|
||||
|
||||
_fh = FindFirstFileW(uFindPath.c_str(), &_fd);
|
||||
if (_fh == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
File::handleLastError(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnicodeConverter::toUTF8(_fd.cFileName, _current);
|
||||
if (_current == "." || _current == "..")
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DirectoryIteratorImpl::~DirectoryIteratorImpl()
|
||||
{
|
||||
if (_fh != INVALID_HANDLE_VALUE)
|
||||
FindClose(_fh);
|
||||
}
|
||||
|
||||
|
||||
const std::string& DirectoryIteratorImpl::next()
|
||||
{
|
||||
do
|
||||
{
|
||||
_current.clear();
|
||||
if (FindNextFileW(_fh, &_fd) != 0)
|
||||
{
|
||||
UnicodeConverter::toUTF8(_fd.cFileName, _current);
|
||||
}
|
||||
}
|
||||
while (_current == "." || _current == "..");
|
||||
return _current;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+604
@@ -0,0 +1,604 @@
|
||||
//
|
||||
// DirectoryWatcher.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: DirectoryWatcher
|
||||
//
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DirectoryWatcher.h"
|
||||
|
||||
|
||||
#ifndef POCO_NO_INOTIFY
|
||||
|
||||
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Glob.h"
|
||||
#include "Poco/DirectoryIterator.h"
|
||||
#include "Poco/Event.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#if POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#if (POCO_OS == POCO_OS_FREE_BSD) && !defined(O_EVTONLY)
|
||||
#define O_EVTONLY 0x8000
|
||||
#endif
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
DirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
_owner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~DirectoryWatcherStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryWatcher& owner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
virtual void run() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual bool supportsMoveEvents() const = 0;
|
||||
|
||||
protected:
|
||||
struct ItemInfo
|
||||
{
|
||||
ItemInfo():
|
||||
size(0)
|
||||
{
|
||||
}
|
||||
|
||||
ItemInfo(const ItemInfo& other):
|
||||
path(other.path),
|
||||
size(other.size),
|
||||
lastModified(other.lastModified)
|
||||
{
|
||||
}
|
||||
|
||||
explicit ItemInfo(const File& f):
|
||||
path(f.path()),
|
||||
size(f.isFile() ? f.getSize() : 0),
|
||||
lastModified(f.getLastModified())
|
||||
{
|
||||
}
|
||||
|
||||
std::string path;
|
||||
File::FileSize size;
|
||||
Timestamp lastModified;
|
||||
};
|
||||
typedef std::map<std::string, ItemInfo> ItemInfoMap;
|
||||
|
||||
void scan(ItemInfoMap& entries)
|
||||
{
|
||||
DirectoryIterator it(owner().directory());
|
||||
DirectoryIterator end;
|
||||
while (it != end)
|
||||
{
|
||||
entries[it.path().getFileName()] = ItemInfo(*it);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void compare(ItemInfoMap& oldEntries, ItemInfoMap& newEntries)
|
||||
{
|
||||
for (auto& np: newEntries)
|
||||
{
|
||||
ItemInfoMap::iterator ito = oldEntries.find(np.first);
|
||||
if (ito != oldEntries.end())
|
||||
{
|
||||
if ((owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED) && !owner().eventsSuspended())
|
||||
{
|
||||
if (np.second.size != ito->second.size || np.second.lastModified != ito->second.lastModified)
|
||||
{
|
||||
Poco::File f(np.second.path);
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MODIFIED);
|
||||
owner().itemModified(&owner(), ev);
|
||||
}
|
||||
}
|
||||
oldEntries.erase(ito);
|
||||
}
|
||||
else if ((owner().eventMask() & DirectoryWatcher::DW_ITEM_ADDED) && !owner().eventsSuspended())
|
||||
{
|
||||
Poco::File f(np.second.path);
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_ADDED);
|
||||
owner().itemAdded(&owner(), ev);
|
||||
}
|
||||
}
|
||||
if ((owner().eventMask() & DirectoryWatcher::DW_ITEM_REMOVED) && !owner().eventsSuspended())
|
||||
{
|
||||
for (const auto& i: oldEntries)
|
||||
{
|
||||
Poco::File f(i.second.path);
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_REMOVED);
|
||||
owner().itemRemoved(&owner(), ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DirectoryWatcherStrategy();
|
||||
DirectoryWatcherStrategy(const DirectoryWatcherStrategy&);
|
||||
DirectoryWatcherStrategy& operator = (const DirectoryWatcherStrategy&);
|
||||
|
||||
DirectoryWatcher& _owner;
|
||||
};
|
||||
|
||||
|
||||
#if (POCO_OS == POCO_OS_WINDOWS_NT) && !defined(POCO_DW_FORCE_POLLING)
|
||||
|
||||
|
||||
class WindowsDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
WindowsDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner)
|
||||
{
|
||||
_hStopped = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!_hStopped)
|
||||
throw SystemException("cannot create event");
|
||||
}
|
||||
|
||||
~WindowsDirectoryWatcherStrategy()
|
||||
{
|
||||
CloseHandle(_hStopped);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
ItemInfoMap entries;
|
||||
scan(entries);
|
||||
|
||||
DWORD filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED)
|
||||
filter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
|
||||
std::string path(owner().directory().path());
|
||||
std::wstring upath;
|
||||
FileImpl::convertPath(path.c_str(), upath);
|
||||
HANDLE hChange = FindFirstChangeNotificationW(upath.c_str(), FALSE, filter);
|
||||
|
||||
if (hChange == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(path);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool stopped = false;
|
||||
while (!stopped)
|
||||
{
|
||||
try
|
||||
{
|
||||
HANDLE h[2];
|
||||
h[0] = _hStopped;
|
||||
h[1] = hChange;
|
||||
switch (WaitForMultipleObjects(2, h, FALSE, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
stopped = true;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
{
|
||||
ItemInfoMap newEntries;
|
||||
scan(newEntries);
|
||||
compare(entries, newEntries);
|
||||
std::swap(entries, newEntries);
|
||||
if (FindNextChangeNotification(hChange) == FALSE)
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(path);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw SystemException("failed to wait for directory changes");
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
FindCloseChangeNotification(hChange);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
SetEvent(_hStopped);
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _hStopped;
|
||||
};
|
||||
|
||||
|
||||
#elif (POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID) && !defined(POCO_DW_FORCE_POLLING)
|
||||
|
||||
|
||||
class LinuxDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
LinuxDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner),
|
||||
_fd(-1),
|
||||
_stopped(false)
|
||||
{
|
||||
_fd = inotify_init();
|
||||
if (_fd == -1) throw Poco::IOException("cannot initialize inotify", errno);
|
||||
}
|
||||
|
||||
~LinuxDirectoryWatcherStrategy()
|
||||
{
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
int mask = 0;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_ADDED)
|
||||
mask |= IN_CREATE;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_REMOVED)
|
||||
mask |= IN_DELETE;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED)
|
||||
mask |= IN_MODIFY;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_FROM)
|
||||
mask |= IN_MOVED_FROM;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_TO)
|
||||
mask |= IN_MOVED_TO;
|
||||
int wd = inotify_add_watch(_fd, owner().directory().path().c_str(), mask);
|
||||
if (wd == -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(owner().directory().path());
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Buffer<char> buffer(4096);
|
||||
while (!_stopped)
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(_fd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 200000;
|
||||
|
||||
if (select(_fd + 1, &fds, NULL, NULL, &tv) == 1)
|
||||
{
|
||||
int n = read(_fd, buffer.begin(), buffer.size());
|
||||
int i = 0;
|
||||
if (n > 0)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
struct inotify_event* pEvent = reinterpret_cast<struct inotify_event*>(buffer.begin() + i);
|
||||
|
||||
if (pEvent->len > 0)
|
||||
{
|
||||
if (!owner().eventsSuspended())
|
||||
{
|
||||
Poco::Path p(owner().directory().path());
|
||||
p.makeDirectory();
|
||||
p.setFileName(pEvent->name);
|
||||
Poco::File f(p.toString());
|
||||
|
||||
if ((pEvent->mask & IN_CREATE) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_ADDED))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_ADDED);
|
||||
owner().itemAdded(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_DELETE) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_REMOVED))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_REMOVED);
|
||||
owner().itemRemoved(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_MODIFY) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MODIFIED);
|
||||
owner().itemModified(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_MOVED_FROM) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_FROM))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MOVED_FROM);
|
||||
owner().itemMovedFrom(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_MOVED_TO) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_TO))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MOVED_TO);
|
||||
owner().itemMovedTo(&owner(), ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i += sizeof(inotify_event) + pEvent->len;
|
||||
n -= sizeof(inotify_event) + pEvent->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
_stopped = true;
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int _fd;
|
||||
bool _stopped;
|
||||
};
|
||||
|
||||
|
||||
#elif (POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD) && !defined(POCO_DW_FORCE_POLLING)
|
||||
|
||||
|
||||
class BSDDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
BSDDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner),
|
||||
_queueFD(-1),
|
||||
_dirFD(-1),
|
||||
_stopped(false)
|
||||
{
|
||||
_dirFD = open(owner.directory().path().c_str(), O_EVTONLY);
|
||||
if (_dirFD < 0) throw Poco::FileNotFoundException(owner.directory().path());
|
||||
_queueFD = kqueue();
|
||||
if (_queueFD < 0)
|
||||
{
|
||||
close(_dirFD);
|
||||
throw Poco::SystemException("Cannot create kqueue", errno);
|
||||
}
|
||||
}
|
||||
|
||||
~BSDDirectoryWatcherStrategy()
|
||||
{
|
||||
close(_dirFD);
|
||||
close(_queueFD);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
Poco::Timestamp lastScan;
|
||||
ItemInfoMap entries;
|
||||
scan(entries);
|
||||
|
||||
while (!_stopped)
|
||||
{
|
||||
struct timespec timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = 200000000;
|
||||
unsigned eventFilter = NOTE_WRITE;
|
||||
struct kevent event;
|
||||
struct kevent eventData;
|
||||
EV_SET(&event, _dirFD, EVFILT_VNODE, EV_ADD | EV_CLEAR, eventFilter, 0, 0);
|
||||
int nEvents = kevent(_queueFD, &event, 1, &eventData, 1, &timeout);
|
||||
if (nEvents < 0 || eventData.flags == EV_ERROR)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(owner().directory().path());
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
else if (nEvents > 0 || ((owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED) && lastScan.isElapsed(owner().scanInterval()*1000000)))
|
||||
{
|
||||
ItemInfoMap newEntries;
|
||||
scan(newEntries);
|
||||
compare(entries, newEntries);
|
||||
std::swap(entries, newEntries);
|
||||
lastScan.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
_stopped = true;
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
int _queueFD;
|
||||
int _dirFD;
|
||||
bool _stopped;
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
class PollingDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
PollingDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner)
|
||||
{
|
||||
}
|
||||
|
||||
~PollingDirectoryWatcherStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
ItemInfoMap entries;
|
||||
scan(entries);
|
||||
while (!_stopped.tryWait(1000*owner().scanInterval()))
|
||||
{
|
||||
try
|
||||
{
|
||||
ItemInfoMap newEntries;
|
||||
scan(newEntries);
|
||||
compare(entries, newEntries);
|
||||
std::swap(entries, newEntries);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
_stopped.set();
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Event _stopped;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
DirectoryWatcher::DirectoryWatcher(const std::string& path, int eventMask, int scanInterval):
|
||||
_directory(path),
|
||||
_eventMask(eventMask),
|
||||
_scanInterval(scanInterval)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
DirectoryWatcher::DirectoryWatcher(const Poco::File& directory, int eventMask, int scanInterval):
|
||||
_directory(directory),
|
||||
_eventMask(eventMask),
|
||||
_scanInterval(scanInterval)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
DirectoryWatcher::~DirectoryWatcher()
|
||||
{
|
||||
try
|
||||
{
|
||||
stop();
|
||||
delete _pStrategy;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::suspendEvents()
|
||||
{
|
||||
poco_assert (_eventsSuspended > 0);
|
||||
|
||||
_eventsSuspended--;
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::resumeEvents()
|
||||
{
|
||||
_eventsSuspended++;
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::init()
|
||||
{
|
||||
if (!_directory.exists())
|
||||
throw Poco::FileNotFoundException(_directory.path());
|
||||
|
||||
if (!_directory.isDirectory())
|
||||
throw Poco::InvalidArgumentException("not a directory", _directory.path());
|
||||
|
||||
#if (POCO_OS == POCO_OS_WINDOWS_NT) && !defined(POCO_DW_FORCE_POLLING)
|
||||
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
|
||||
#elif (POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID) && !defined(POCO_DW_FORCE_POLLING)
|
||||
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
|
||||
#elif (POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD) && !defined(POCO_DW_FORCE_POLLING)
|
||||
_pStrategy = new BSDDirectoryWatcherStrategy(*this);
|
||||
#else
|
||||
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
|
||||
#endif
|
||||
_thread.start(*this);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::run()
|
||||
{
|
||||
_pStrategy->run();
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::stop()
|
||||
{
|
||||
_pStrategy->stop();
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
|
||||
bool DirectoryWatcher::supportsMoveEvents() const
|
||||
{
|
||||
return _pStrategy->supportsMoveEvents();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // POCO_NO_INOTIFY
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Environment.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Environment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/Version.h"
|
||||
#include <cstdlib>
|
||||
#include <cstdio> // sprintf()
|
||||
|
||||
|
||||
#if defined(POCO_VXWORKS)
|
||||
#include "Environment_VX.cpp"
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
#include "Environment_UNIX.cpp"
|
||||
#elif defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#if defined(_WIN32_WCE)
|
||||
#include "Environment_WINCE.cpp"
|
||||
#else
|
||||
#include "Environment_WIN32U.cpp"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
std::string Environment::get(const std::string& name)
|
||||
{
|
||||
return EnvironmentImpl::getImpl(name);
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::get(const std::string& name, const std::string& defaultValue)
|
||||
{
|
||||
if (has(name))
|
||||
return get(name);
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
bool Environment::has(const std::string& name)
|
||||
{
|
||||
return EnvironmentImpl::hasImpl(name);
|
||||
}
|
||||
|
||||
|
||||
void Environment::set(const std::string& name, const std::string& value)
|
||||
{
|
||||
EnvironmentImpl::setImpl(name, value);
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::osName()
|
||||
{
|
||||
return EnvironmentImpl::osNameImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::osDisplayName()
|
||||
{
|
||||
return EnvironmentImpl::osDisplayNameImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::osVersion()
|
||||
{
|
||||
return EnvironmentImpl::osVersionImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::osArchitecture()
|
||||
{
|
||||
return EnvironmentImpl::osArchitectureImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::nodeName()
|
||||
{
|
||||
return EnvironmentImpl::nodeNameImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::nodeId()
|
||||
{
|
||||
NodeId id;
|
||||
nodeId(id);
|
||||
char result[18];
|
||||
std::sprintf(result, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
id[0],
|
||||
id[1],
|
||||
id[2],
|
||||
id[3],
|
||||
id[4],
|
||||
id[5]);
|
||||
return std::string(result);
|
||||
}
|
||||
|
||||
|
||||
void Environment::nodeId(NodeId& id)
|
||||
{
|
||||
return EnvironmentImpl::nodeIdImpl(id);
|
||||
}
|
||||
|
||||
|
||||
unsigned Environment::processorCount()
|
||||
{
|
||||
return EnvironmentImpl::processorCountImpl();
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt32 Environment::libraryVersion()
|
||||
{
|
||||
return POCO_VERSION;
|
||||
}
|
||||
|
||||
|
||||
Poco::Int32 Environment::os()
|
||||
{
|
||||
return POCO_OS;
|
||||
}
|
||||
|
||||
|
||||
Poco::Int32 Environment::arch()
|
||||
{
|
||||
return POCO_ARCH;
|
||||
}
|
||||
|
||||
|
||||
bool Environment::isUnix()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Environment::isWindows()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
|
||||
// Environment_UNIX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Environment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Environment_UNIX.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/param.h>
|
||||
#if defined(POCO_OS_FAMILY_BSD)
|
||||
#include <sys/sysctl.h>
|
||||
#elif POCO_OS == POCO_OS_HPUX
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EnvironmentImpl::StringMap EnvironmentImpl::_map;
|
||||
FastMutex EnvironmentImpl::_mutex;
|
||||
|
||||
|
||||
std::string EnvironmentImpl::getImpl(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
const char* val = getenv(name.c_str());
|
||||
if (val)
|
||||
return std::string(val);
|
||||
else
|
||||
throw NotFoundException(name);
|
||||
}
|
||||
|
||||
|
||||
bool EnvironmentImpl::hasImpl(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return getenv(name.c_str()) != 0;
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::setImpl(const std::string& name, const std::string& value)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
std::string var = name;
|
||||
var.append("=");
|
||||
var.append(value);
|
||||
std::swap(_map[name], var);
|
||||
if (putenv((char*) _map[name].c_str()))
|
||||
{
|
||||
std::string msg = "cannot set environment variable: ";
|
||||
msg.append(name);
|
||||
throw SystemException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osNameImpl()
|
||||
{
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
return uts.sysname;
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osDisplayNameImpl()
|
||||
{
|
||||
return osNameImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osVersionImpl()
|
||||
{
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
return uts.release;
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osArchitectureImpl()
|
||||
{
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
return uts.machine;
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::nodeNameImpl()
|
||||
{
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
return uts.nodename;
|
||||
}
|
||||
|
||||
|
||||
unsigned EnvironmentImpl::processorCountImpl()
|
||||
{
|
||||
#if defined(_SC_NPROCESSORS_ONLN)
|
||||
int count = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (count <= 0) count = 1;
|
||||
return static_cast<int>(count);
|
||||
#elif defined(POCO_OS_FAMILY_BSD)
|
||||
unsigned count;
|
||||
std::size_t size = sizeof(count);
|
||||
if (sysctlbyname("hw.ncpu", &count, &size, 0, 0))
|
||||
return 1;
|
||||
else
|
||||
return count;
|
||||
#elif POCO_OS == POCO_OS_HPUX
|
||||
return pthread_num_processors_np();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
//
|
||||
// nodeIdImpl
|
||||
//
|
||||
#if defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX
|
||||
//
|
||||
// BSD variants
|
||||
//
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
std::memset(&id, 0, sizeof(id));
|
||||
struct ifaddrs* ifaphead;
|
||||
int rc = getifaddrs(&ifaphead);
|
||||
if (rc) return;
|
||||
|
||||
for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next)
|
||||
{
|
||||
if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_LINK)
|
||||
{
|
||||
struct sockaddr_dl* sdl = reinterpret_cast<struct sockaddr_dl*>(ifap->ifa_addr);
|
||||
caddr_t ap = LLADDR(sdl);
|
||||
int alen = sdl->sdl_alen;
|
||||
if (ap && alen > 0)
|
||||
{
|
||||
std::memcpy(&id, ap, sizeof(id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifaphead);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#elif defined(__CYGWIN__) || POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID
|
||||
//
|
||||
// Linux, Cygwin
|
||||
//
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#ifndef __CYGWIN__
|
||||
#include <net/if_arp.h>
|
||||
#else // workaround for Cygwin, which does not have if_arp.h
|
||||
#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
std::memset(&id, 0, sizeof(id));
|
||||
|
||||
// ideally, the following code should be rewritten
|
||||
// to use netlink
|
||||
|
||||
// first try to obtain the MAC address of eth0 using /sys/class/net
|
||||
int fd = open("/sys/class/net/eth0/address", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
char buffer[18];
|
||||
int n = read(fd, buffer, 17);
|
||||
close(fd);
|
||||
if (n == 17)
|
||||
{
|
||||
buffer[n] = 0;
|
||||
if (std::sscanf(buffer, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &id[0], &id[1], &id[2], &id[3], &id[4], &id[5]) == 6)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if that did not work, search active interfaces
|
||||
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sock == -1) return;
|
||||
|
||||
// the following code is loosely based
|
||||
// on W. Richard Stevens, UNIX Network Programming, pp 434ff.
|
||||
int lastlen = 0;
|
||||
int len = 100*sizeof(struct ifreq);
|
||||
struct ifconf ifc;
|
||||
char* buf = 0;
|
||||
for (;;)
|
||||
{
|
||||
buf = new char[len];
|
||||
ifc.ifc_len = len;
|
||||
ifc.ifc_buf = buf;
|
||||
if (::ioctl(sock, SIOCGIFCONF, &ifc) < 0)
|
||||
{
|
||||
if (errno != EINVAL || lastlen != 0)
|
||||
{
|
||||
close(sock);
|
||||
delete [] buf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ifc.ifc_len == lastlen)
|
||||
break;
|
||||
lastlen = ifc.ifc_len;
|
||||
}
|
||||
len += 10*sizeof(struct ifreq);
|
||||
delete [] buf;
|
||||
}
|
||||
for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)
|
||||
{
|
||||
const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);
|
||||
int rc = ioctl(sock, SIOCGIFHWADDR, ifr);
|
||||
if (rc != -1)
|
||||
{
|
||||
const struct sockaddr* sa = reinterpret_cast<const struct sockaddr*>(&ifr->ifr_hwaddr);
|
||||
if (sa->sa_family == ARPHRD_ETHER)
|
||||
{
|
||||
std::memcpy(&id, sa->sa_data, sizeof(id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr += sizeof(struct ifreq);
|
||||
}
|
||||
close(sock);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
//
|
||||
// General Unix
|
||||
//
|
||||
#include <sys/ioctl.h>
|
||||
#if defined(sun) || defined(__sun)
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
std::memset(&id, 0, sizeof(id));
|
||||
char name[MAXHOSTNAMELEN];
|
||||
if (gethostname(name, sizeof(name)))
|
||||
return;
|
||||
|
||||
struct hostent* pHost = gethostbyname(name);
|
||||
if (!pHost) return;
|
||||
|
||||
int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (s == -1) return;
|
||||
|
||||
struct arpreq ar;
|
||||
std::memset(&ar, 0, sizeof(ar));
|
||||
struct sockaddr_in* pAddr = reinterpret_cast<struct sockaddr_in*>(&ar.arp_pa);
|
||||
pAddr->sin_family = AF_INET;
|
||||
std::memcpy(&pAddr->sin_addr, *pHost->h_addr_list, sizeof(struct in_addr));
|
||||
int rc = ioctl(s, SIOCGARP, &ar);
|
||||
close(s);
|
||||
if (rc < 0) return;
|
||||
std::memcpy(&id, ar.arp_ha.sa_data, sizeof(id));
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
|
||||
// Environment_VX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Environment
|
||||
//
|
||||
// Copyright (c) 2004-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Environment_VX.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include <VxWorks.h>
|
||||
#include <envLib.h>
|
||||
#include <hostLib.h>
|
||||
#include <ifLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <version.h>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <ifLib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EnvironmentImpl::StringMap EnvironmentImpl::_map;
|
||||
FastMutex EnvironmentImpl::_mutex;
|
||||
|
||||
|
||||
std::string EnvironmentImpl::getImpl(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
const char* val = getenv(name.c_str());
|
||||
if (val)
|
||||
return std::string(val);
|
||||
else
|
||||
throw NotFoundException(name);
|
||||
}
|
||||
|
||||
|
||||
bool EnvironmentImpl::hasImpl(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return getenv(name.c_str()) != 0;
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::setImpl(const std::string& name, const std::string& value)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
std::string var = name;
|
||||
var.append("=");
|
||||
var.append(value);
|
||||
std::swap(_map[name], var);
|
||||
if (putenv((char*) _map[name].c_str()))
|
||||
{
|
||||
std::string msg = "cannot set environment variable: ";
|
||||
msg.append(name);
|
||||
throw SystemException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osNameImpl()
|
||||
{
|
||||
return runtimeName;
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osDisplayNameImpl()
|
||||
{
|
||||
return osNameImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osVersionImpl()
|
||||
{
|
||||
return runtimeVersion;
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osArchitectureImpl()
|
||||
{
|
||||
#if POCO_ARCH == POCO_ARCH_IA32
|
||||
return "i386";
|
||||
#elif POCO_ARCH == POCO_ARCH_MIPS
|
||||
return "mips";
|
||||
#elif POCO_ARCH == POCO_ARCH_PPC
|
||||
return "ppc";
|
||||
#elif POCO_ARCH == POCO_ARCH_ARM
|
||||
return "arm";
|
||||
#elif POCO_ARCH == POCO_ARCH_SH
|
||||
return "sh";
|
||||
#else
|
||||
return "unknown";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::nodeNameImpl()
|
||||
{
|
||||
char buffer[64];
|
||||
if (gethostname(buffer, sizeof(buffer)) == OK)
|
||||
return buffer;
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
|
||||
unsigned EnvironmentImpl::processorCountImpl()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
std::memset(&id, 0, sizeof(id));
|
||||
|
||||
int ifIndex = 1;
|
||||
char ifName[32];
|
||||
for (;;)
|
||||
{
|
||||
if (ifIndexToIfName(ifIndex, ifName) == OK)
|
||||
{
|
||||
struct ifnet* pIf = ifunit(ifName);
|
||||
if (pIf)
|
||||
{
|
||||
std::memcpy(&id, ((struct arpcom *) pIf)->ac_enaddr, sizeof(id));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
++ifIndex;
|
||||
}
|
||||
throw SystemException("cannot get Ethernet hardware address");
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
//
|
||||
// Environment_WIN32U.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Environment
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Environment_WIN32U.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include "Poco/UnWindows.h"
|
||||
#include <winsock2.h>
|
||||
#include <wincrypt.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
std::string EnvironmentImpl::getImpl(const std::string& name)
|
||||
{
|
||||
std::wstring uname;
|
||||
UnicodeConverter::toUTF16(name, uname);
|
||||
DWORD len = GetEnvironmentVariableW(uname.c_str(), 0, 0);
|
||||
if (len == 0) throw NotFoundException(name);
|
||||
Buffer<wchar_t> buffer(len);
|
||||
GetEnvironmentVariableW(uname.c_str(), buffer.begin(), len);
|
||||
std::string result;
|
||||
UnicodeConverter::toUTF8(buffer.begin(), len - 1, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool EnvironmentImpl::hasImpl(const std::string& name)
|
||||
{
|
||||
std::wstring uname;
|
||||
UnicodeConverter::toUTF16(name, uname);
|
||||
DWORD len = GetEnvironmentVariableW(uname.c_str(), 0, 0);
|
||||
return len > 0;
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::setImpl(const std::string& name, const std::string& value)
|
||||
{
|
||||
std::wstring uname;
|
||||
std::wstring uvalue;
|
||||
UnicodeConverter::toUTF16(name, uname);
|
||||
UnicodeConverter::toUTF16(value, uvalue);
|
||||
if (SetEnvironmentVariableW(uname.c_str(), uvalue.c_str()) == 0)
|
||||
{
|
||||
std::string msg = "cannot set environment variable: ";
|
||||
msg.append(name);
|
||||
throw SystemException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osNameImpl()
|
||||
{
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (GetVersionEx(&vi) == 0) throw SystemException("Cannot get OS version information");
|
||||
switch (vi.dwPlatformId)
|
||||
{
|
||||
case VER_PLATFORM_WIN32s:
|
||||
return "Windows 3.x";
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
return vi.dwMinorVersion == 0 ? "Windows 95" : "Windows 98";
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
return "Windows NT";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osDisplayNameImpl()
|
||||
{
|
||||
OSVERSIONINFOEX vi; // OSVERSIONINFOEX is supported starting at Windows 2000
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (GetVersionEx((OSVERSIONINFO*) &vi) == 0) throw SystemException("Cannot get OS version information");
|
||||
switch (vi.dwMajorVersion)
|
||||
{
|
||||
case 10:
|
||||
switch (vi.dwMinorVersion)
|
||||
{
|
||||
case 0:
|
||||
return vi.wProductType == VER_NT_WORKSTATION ? "Windows 10" : "Windows Server 2016";
|
||||
}
|
||||
case 6:
|
||||
switch (vi.dwMinorVersion)
|
||||
{
|
||||
case 0:
|
||||
return vi.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008";
|
||||
case 1:
|
||||
return vi.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2";
|
||||
case 2:
|
||||
return vi.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012";
|
||||
case 3:
|
||||
return vi.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
case 5:
|
||||
switch (vi.dwMinorVersion)
|
||||
{
|
||||
case 0:
|
||||
return "Windows 2000";
|
||||
case 1:
|
||||
return "Windows XP";
|
||||
case 2:
|
||||
return "Windows Server 2003/Windows Server 2003 R2";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osVersionImpl()
|
||||
{
|
||||
OSVERSIONINFOW vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (GetVersionExW(&vi) == 0) throw SystemException("Cannot get OS version information");
|
||||
std::ostringstream str;
|
||||
str << vi.dwMajorVersion << "." << vi.dwMinorVersion << " (Build " << (vi.dwBuildNumber & 0xFFFF);
|
||||
std::string version;
|
||||
UnicodeConverter::toUTF8(vi.szCSDVersion, version);
|
||||
if (!version.empty()) str << ": " << version;
|
||||
str << ")";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osArchitectureImpl()
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
switch (si.wProcessorArchitecture)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
return "IA32";
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
return "MIPS";
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
return "ALPHA";
|
||||
case PROCESSOR_ARCHITECTURE_PPC:
|
||||
return "PPC";
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
return "IA64";
|
||||
#ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
|
||||
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
||||
return "IA64/32";
|
||||
#endif
|
||||
#ifdef PROCESSOR_ARCHITECTURE_AMD64
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
return "AMD64";
|
||||
#endif
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::nodeNameImpl()
|
||||
{
|
||||
wchar_t name[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
if (GetComputerNameW(name, &size) == 0) throw SystemException("Cannot get computer name");
|
||||
std::string result;
|
||||
UnicodeConverter::toUTF8(name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
std::memset(&id, 0, sizeof(id));
|
||||
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
PIP_ADAPTER_INFO pAdapter = 0;
|
||||
ULONG len = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
|
||||
// Make an initial call to GetAdaptersInfo to get
|
||||
// the necessary size into len
|
||||
DWORD rc = GetAdaptersInfo(pAdapterInfo, &len);
|
||||
if (rc == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
|
||||
}
|
||||
else if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
|
||||
{
|
||||
pAdapter = pAdapterInfo;
|
||||
bool found = false;
|
||||
while (pAdapter && !found)
|
||||
{
|
||||
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
|
||||
{
|
||||
found = true;
|
||||
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
}
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
}
|
||||
|
||||
|
||||
unsigned EnvironmentImpl::processorCountImpl()
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
return si.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
//
|
||||
// Environment_WINCE.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Environment
|
||||
//
|
||||
// Copyright (c) 2009-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Environment_WINCE.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const std::string EnvironmentImpl::TEMP("TEMP");
|
||||
const std::string EnvironmentImpl::TMP("TMP");
|
||||
const std::string EnvironmentImpl::HOMEPATH("HOMEPATH");
|
||||
const std::string EnvironmentImpl::COMPUTERNAME("COMPUTERNAME");
|
||||
const std::string EnvironmentImpl::OS("OS");
|
||||
const std::string EnvironmentImpl::NUMBER_OF_PROCESSORS("NUMBER_OF_PROCESSORS");
|
||||
const std::string EnvironmentImpl::PROCESSOR_ARCHITECTURE("PROCESSOR_ARCHITECTURE");
|
||||
|
||||
|
||||
std::string EnvironmentImpl::getImpl(const std::string& name)
|
||||
{
|
||||
std::string value;
|
||||
if (!envVar(name, &value)) throw NotFoundException(name);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
bool EnvironmentImpl::hasImpl(const std::string& name)
|
||||
{
|
||||
return envVar(name, 0);
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::setImpl(const std::string& name, const std::string& value)
|
||||
{
|
||||
throw NotImplementedException("Cannot set environment variables on Windows CE");
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osNameImpl()
|
||||
{
|
||||
return "Windows CE";
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osDisplayNameImpl()
|
||||
{
|
||||
return osNameImpl();
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osVersionImpl()
|
||||
{
|
||||
OSVERSIONINFOW vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (GetVersionExW(&vi) == 0) throw SystemException("Cannot get OS version information");
|
||||
std::ostringstream str;
|
||||
str << vi.dwMajorVersion << "." << vi.dwMinorVersion << " (Build " << (vi.dwBuildNumber & 0xFFFF);
|
||||
std::string version;
|
||||
UnicodeConverter::toUTF8(vi.szCSDVersion, version);
|
||||
if (!version.empty()) str << ": " << version;
|
||||
str << ")";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::osArchitectureImpl()
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
switch (si.wProcessorArchitecture)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
return "IA32";
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
return "MIPS";
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
return "ALPHA";
|
||||
case PROCESSOR_ARCHITECTURE_PPC:
|
||||
return "PPC";
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
return "IA64";
|
||||
#ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
|
||||
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
||||
return "IA64/32";
|
||||
#endif
|
||||
#ifdef PROCESSOR_ARCHITECTURE_AMD64
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
return "AMD64";
|
||||
#endif
|
||||
case PROCESSOR_ARCHITECTURE_SHX:
|
||||
return "SHX";
|
||||
case PROCESSOR_ARCHITECTURE_ARM:
|
||||
return "ARM";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string EnvironmentImpl::nodeNameImpl()
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwDisposition;
|
||||
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"\\Ident", 0, 0, 0, 0, 0, &hKey, &dwDisposition) != ERROR_SUCCESS)
|
||||
throw SystemException("Cannot get node name", "registry key not found");
|
||||
|
||||
std::string value;
|
||||
DWORD dwType;
|
||||
BYTE bData[1026];
|
||||
DWORD dwData = sizeof(bData);
|
||||
if (RegQueryValueExW(hKey, L"Name", 0, &dwType, bData, &dwData) == ERROR_SUCCESS)
|
||||
{
|
||||
switch (dwType)
|
||||
{
|
||||
case REG_SZ:
|
||||
UnicodeConverter::toUTF8(reinterpret_cast<wchar_t*>(bData), value);
|
||||
break;
|
||||
|
||||
default:
|
||||
RegCloseKey(hKey);
|
||||
throw SystemException("Cannot get node name", "registry value has wrong type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
throw SystemException("Cannot get node name", "registry value not found");
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
PIP_ADAPTER_INFO pAdapter = 0;
|
||||
ULONG len = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
|
||||
// Make an initial call to GetAdaptersInfo to get
|
||||
// the necessary size into len
|
||||
DWORD rc = GetAdaptersInfo(pAdapterInfo, &len);
|
||||
if (rc == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
|
||||
}
|
||||
else if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
throw SystemException("cannot get network adapter list");
|
||||
}
|
||||
try
|
||||
{
|
||||
bool found = false;
|
||||
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
|
||||
{
|
||||
pAdapter = pAdapterInfo;
|
||||
while (pAdapter && !found)
|
||||
{
|
||||
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
|
||||
{
|
||||
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
|
||||
found = true;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
}
|
||||
else throw SystemException("cannot get network adapter list");
|
||||
if (!found) throw SystemException("no Ethernet adapter found");
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
throw;
|
||||
}
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
}
|
||||
|
||||
|
||||
unsigned EnvironmentImpl::processorCountImpl()
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
return si.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
|
||||
bool EnvironmentImpl::envVar(const std::string& name, std::string* value)
|
||||
{
|
||||
if (icompare(name, TEMP) == 0)
|
||||
{
|
||||
if (value) *value = Path::temp();
|
||||
}
|
||||
else if (icompare(name, TMP) == 0)
|
||||
{
|
||||
if (value) *value = Path::temp();
|
||||
}
|
||||
else if (icompare(name, HOMEPATH) == 0)
|
||||
{
|
||||
if (value) *value = Path::home();
|
||||
}
|
||||
else if (icompare(name, COMPUTERNAME) == 0)
|
||||
{
|
||||
if (value) *value = nodeNameImpl();
|
||||
}
|
||||
else if (icompare(name, OS) == 0)
|
||||
{
|
||||
if (value) *value = osNameImpl();
|
||||
}
|
||||
else if (icompare(name, NUMBER_OF_PROCESSORS) == 0)
|
||||
{
|
||||
if (value) *value = NumberFormatter::format(processorCountImpl());
|
||||
}
|
||||
else if (icompare(name, PROCESSOR_ARCHITECTURE) == 0)
|
||||
{
|
||||
if (value) *value = osArchitectureImpl();
|
||||
}
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+111
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// Error.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Error
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/Error.h"
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
|
||||
|
||||
DWORD Error::last()
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
|
||||
std::string Error::getMessage(DWORD errorCode)
|
||||
{
|
||||
std::string errMsg;
|
||||
DWORD dwFlg = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||
LPWSTR lpMsgBuf = 0;
|
||||
if (FormatMessageW(dwFlg, 0, errorCode, 0, (LPWSTR) & lpMsgBuf, 0, NULL))
|
||||
UnicodeConverter::toUTF8(lpMsgBuf, errMsg);
|
||||
LocalFree(lpMsgBuf);
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
int Error::last()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
class StrErrorHelper
|
||||
/// This little hack magically handles all variants
|
||||
/// of strerror_r() (POSIX and GLIBC) and strerror().
|
||||
{
|
||||
public:
|
||||
explicit StrErrorHelper(int err)
|
||||
{
|
||||
_buffer[0] = 0;
|
||||
|
||||
#if (_XOPEN_SOURCE >= 600) || POCO_OS == POCO_OS_ANDROID || __APPLE__
|
||||
setMessage(strerror_r(err, _buffer, sizeof(_buffer)));
|
||||
#elif _GNU_SOURCE
|
||||
setMessage(strerror_r(err, _buffer, sizeof(_buffer)));
|
||||
#else
|
||||
setMessage(strerror(err));
|
||||
#endif
|
||||
}
|
||||
|
||||
~StrErrorHelper()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& message() const
|
||||
{
|
||||
return _message;
|
||||
}
|
||||
|
||||
protected:
|
||||
void setMessage(int rc)
|
||||
/// Handles POSIX variant
|
||||
{
|
||||
_message = _buffer;
|
||||
}
|
||||
|
||||
void setMessage(const char* msg)
|
||||
/// Handles GLIBC variant
|
||||
{
|
||||
_message = msg;
|
||||
}
|
||||
|
||||
private:
|
||||
char _buffer[256];
|
||||
std::string _message;
|
||||
};
|
||||
|
||||
std::string Error::getMessage(int errorCode)
|
||||
{
|
||||
StrErrorHelper helper(errorCode);
|
||||
return helper.message();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// ErrorHandler.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: ErrorHandler
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ErrorHandler.h"
|
||||
#include "Poco/SingletonHolder.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
ErrorHandler* ErrorHandler::_pHandler = ErrorHandler::defaultHandler();
|
||||
FastMutex ErrorHandler::_mutex;
|
||||
|
||||
|
||||
ErrorHandler::ErrorHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ErrorHandler::~ErrorHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::exception(const Exception& exc)
|
||||
{
|
||||
poco_debugger_msg(exc.what());
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::exception(const std::exception& exc)
|
||||
{
|
||||
poco_debugger_msg(exc.what());
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::exception()
|
||||
{
|
||||
poco_debugger_msg("unknown exception");
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::handle(const Exception& exc)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
try
|
||||
{
|
||||
_pHandler->exception(exc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::handle(const std::exception& exc)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
try
|
||||
{
|
||||
_pHandler->exception(exc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::handle()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
try
|
||||
{
|
||||
_pHandler->exception();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ErrorHandler* ErrorHandler::set(ErrorHandler* pHandler)
|
||||
{
|
||||
poco_check_ptr(pHandler);
|
||||
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
ErrorHandler* pOld = _pHandler;
|
||||
_pHandler = pHandler;
|
||||
return pOld;
|
||||
}
|
||||
|
||||
|
||||
ErrorHandler* ErrorHandler::defaultHandler()
|
||||
{
|
||||
// NOTE: Since this is called to initialize the static _pHandler
|
||||
// variable, sh has to be a local static, otherwise we run
|
||||
// into static initialization order issues.
|
||||
static SingletonHolder<ErrorHandler> sh;
|
||||
return sh.get();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Event.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: Event
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Event.h"
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "Event_WIN32.cpp"
|
||||
#elif defined(POCO_VXWORKS)
|
||||
#include "Event_VX.cpp"
|
||||
#else
|
||||
#include "Event_POSIX.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Event::Event(EventType type): EventImpl(type == EVENT_AUTORESET)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Event::Event(bool autoReset): EventImpl(autoReset)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Event::~Event()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// EventArgs.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Events
|
||||
// Module: EventArgs
|
||||
//
|
||||
// Implementation of EventArgs
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/EventArgs.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EventArgs::EventArgs()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EventArgs::~EventArgs()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// EventChannel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: EventChannel
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/EventChannel.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EventChannel::EventChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EventChannel::~EventChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void EventChannel::log(const Message& msg)
|
||||
{
|
||||
messageLogged(this, msg);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// EventLogChannel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: EventLogChannel
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/EventLogChannel.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/String.h"
|
||||
#include "pocomsg.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const std::string EventLogChannel::PROP_NAME = "name";
|
||||
const std::string EventLogChannel::PROP_HOST = "host";
|
||||
const std::string EventLogChannel::PROP_LOGHOST = "loghost";
|
||||
const std::string EventLogChannel::PROP_LOGFILE = "logfile";
|
||||
|
||||
|
||||
EventLogChannel::EventLogChannel():
|
||||
_logFile("Application"),
|
||||
_h(0)
|
||||
{
|
||||
const DWORD maxPathLen = MAX_PATH + 1;
|
||||
wchar_t name[maxPathLen];
|
||||
int n = GetModuleFileNameW(NULL, name, maxPathLen);
|
||||
if (n > 0)
|
||||
{
|
||||
wchar_t* end = name + n - 1;
|
||||
while (end > name && *end != '\\') --end;
|
||||
if (*end == '\\') ++end;
|
||||
std::wstring uname(end);
|
||||
UnicodeConverter::toUTF8(uname, _name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EventLogChannel::EventLogChannel(const std::string& name):
|
||||
_name(name),
|
||||
_logFile("Application"),
|
||||
_h(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EventLogChannel::EventLogChannel(const std::string& name, const std::string& host):
|
||||
_name(name),
|
||||
_host(host),
|
||||
_logFile("Application"),
|
||||
_h(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EventLogChannel::~EventLogChannel()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventLogChannel::open()
|
||||
{
|
||||
setUpRegistry();
|
||||
std::wstring uhost;
|
||||
UnicodeConverter::toUTF16(_host, uhost);
|
||||
std::wstring uname;
|
||||
UnicodeConverter::toUTF16(_name, uname);
|
||||
_h = RegisterEventSourceW(uhost.empty() ? NULL : uhost.c_str(), uname.c_str());
|
||||
if (!_h) throw SystemException("cannot register event source");
|
||||
}
|
||||
|
||||
|
||||
void EventLogChannel::close()
|
||||
{
|
||||
if (_h) DeregisterEventSource(_h);
|
||||
_h = 0;
|
||||
}
|
||||
|
||||
|
||||
void EventLogChannel::log(const Message& msg)
|
||||
{
|
||||
if (!_h) open();
|
||||
std::wstring utext;
|
||||
UnicodeConverter::toUTF16(msg.getText(), utext);
|
||||
const wchar_t* pMsg = utext.c_str();
|
||||
ReportEventW(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL);
|
||||
}
|
||||
|
||||
|
||||
void EventLogChannel::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (icompare(name, PROP_NAME) == 0)
|
||||
_name = value;
|
||||
else if (icompare(name, PROP_HOST) == 0)
|
||||
_host = value;
|
||||
else if (icompare(name, PROP_LOGHOST) == 0)
|
||||
_host = value;
|
||||
else if (icompare(name, PROP_LOGFILE) == 0)
|
||||
_logFile = value;
|
||||
else
|
||||
Channel::setProperty(name, value);
|
||||
}
|
||||
|
||||
|
||||
std::string EventLogChannel::getProperty(const std::string& name) const
|
||||
{
|
||||
if (icompare(name, PROP_NAME) == 0)
|
||||
return _name;
|
||||
else if (icompare(name, PROP_HOST) == 0)
|
||||
return _host;
|
||||
else if (icompare(name, PROP_LOGHOST) == 0)
|
||||
return _host;
|
||||
else if (icompare(name, PROP_LOGFILE) == 0)
|
||||
return _logFile;
|
||||
else
|
||||
return Channel::getProperty(name);
|
||||
}
|
||||
|
||||
|
||||
int EventLogChannel::getType(const Message& msg)
|
||||
{
|
||||
switch (msg.getPriority())
|
||||
{
|
||||
case Message::PRIO_TRACE:
|
||||
case Message::PRIO_DEBUG:
|
||||
case Message::PRIO_INFORMATION:
|
||||
return EVENTLOG_INFORMATION_TYPE;
|
||||
case Message::PRIO_NOTICE:
|
||||
case Message::PRIO_WARNING:
|
||||
return EVENTLOG_WARNING_TYPE;
|
||||
default:
|
||||
return EVENTLOG_ERROR_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EventLogChannel::getCategory(const Message& msg)
|
||||
{
|
||||
switch (msg.getPriority())
|
||||
{
|
||||
case Message::PRIO_TRACE:
|
||||
return POCO_CTG_TRACE;
|
||||
case Message::PRIO_DEBUG:
|
||||
return POCO_CTG_DEBUG;
|
||||
case Message::PRIO_INFORMATION:
|
||||
return POCO_CTG_INFORMATION;
|
||||
case Message::PRIO_NOTICE:
|
||||
return POCO_CTG_NOTICE;
|
||||
case Message::PRIO_WARNING:
|
||||
return POCO_CTG_WARNING;
|
||||
case Message::PRIO_ERROR:
|
||||
return POCO_CTG_ERROR;
|
||||
case Message::PRIO_CRITICAL:
|
||||
return POCO_CTG_CRITICAL;
|
||||
case Message::PRIO_FATAL:
|
||||
return POCO_CTG_FATAL;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventLogChannel::setUpRegistry() const
|
||||
{
|
||||
std::string key = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
|
||||
key.append(_logFile);
|
||||
key.append("\\");
|
||||
key.append(_name);
|
||||
HKEY hKey;
|
||||
DWORD disp;
|
||||
std::wstring ukey;
|
||||
UnicodeConverter::toUTF16(key, ukey);
|
||||
DWORD rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ukey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp);
|
||||
if (rc != ERROR_SUCCESS) return;
|
||||
|
||||
if (disp == REG_CREATED_NEW_KEY)
|
||||
{
|
||||
std::wstring path;
|
||||
#if defined(POCO_DLL)
|
||||
#if defined(_DEBUG)
|
||||
#if defined(_WIN64)
|
||||
path = findLibrary(L"PocoFoundation64d.dll");
|
||||
#else
|
||||
path = findLibrary(L"PocoFoundationd.dll");
|
||||
#endif
|
||||
#else
|
||||
#if defined(_WIN64)
|
||||
path = findLibrary(L"PocoFoundation64.dll");
|
||||
#else
|
||||
path = findLibrary(L"PocoFoundation.dll");
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (path.empty())
|
||||
path = findLibrary(L"PocoMsg.dll");
|
||||
|
||||
if (!path.empty())
|
||||
{
|
||||
DWORD count = 8;
|
||||
DWORD types = 7;
|
||||
RegSetValueExW(hKey, L"CategoryMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), static_cast<DWORD>(sizeof(wchar_t)*(path.size() + 1)));
|
||||
RegSetValueExW(hKey, L"EventMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), static_cast<DWORD>(sizeof(wchar_t)*(path.size() + 1)));
|
||||
RegSetValueExW(hKey, L"CategoryCount", 0, REG_DWORD, (const BYTE*) &count, static_cast<DWORD>(sizeof(count)));
|
||||
RegSetValueExW(hKey, L"TypesSupported", 0, REG_DWORD, (const BYTE*) &types, static_cast<DWORD>(sizeof(types)));
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
|
||||
std::wstring EventLogChannel::findLibrary(const wchar_t* name)
|
||||
{
|
||||
std::wstring path;
|
||||
HMODULE dll = LoadLibraryW(name);
|
||||
if (dll)
|
||||
{
|
||||
const DWORD maxPathLen = MAX_PATH + 1;
|
||||
wchar_t name[maxPathLen];
|
||||
int n = GetModuleFileNameW(dll, name, maxPathLen);
|
||||
if (n > 0) path = name;
|
||||
FreeLibrary(dll);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// Event_POSIX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: Event
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Event_POSIX.h"
|
||||
#if defined(POCO_VXWORKS)
|
||||
#include <timers.h>
|
||||
#include <cstring>
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Note: pthread_cond_timedwait() with CLOCK_MONOTONIC is supported
|
||||
// on Linux and QNX, as well as on Android >= 5.0 (API level 21).
|
||||
// On Android < 5.0, HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC is defined
|
||||
// to indicate availability of non-standard pthread_cond_timedwait_monotonic().
|
||||
//
|
||||
#ifndef POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT
|
||||
#if (defined(__linux__) || defined(__QNX__)) && !(defined(__ANDROID__) && (defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC) || __ANDROID_API__ <= 21))
|
||||
#define POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef POCO_HAVE_CLOCK_GETTIME
|
||||
#if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__)
|
||||
#ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10
|
||||
#define POCO_HAVE_CLOCK_GETTIME
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EventImpl::EventImpl(bool autoReset): _auto(autoReset), _state(false)
|
||||
{
|
||||
#if defined(POCO_VXWORKS)
|
||||
// This workaround is for VxWorks 5.x where
|
||||
// pthread_mutex_init() won't properly initialize the mutex
|
||||
// resulting in a subsequent freeze in pthread_mutex_destroy()
|
||||
// if the mutex has never been used.
|
||||
std::memset(&_mutex, 0, sizeof(_mutex));
|
||||
#endif
|
||||
|
||||
if (pthread_mutex_init(&_mutex, NULL))
|
||||
throw SystemException("cannot create event (mutex)");
|
||||
|
||||
#if defined(POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT)
|
||||
pthread_condattr_t attr;
|
||||
if (pthread_condattr_init(&attr))
|
||||
{
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
throw SystemException("cannot create event (condition attribute)");
|
||||
}
|
||||
if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
|
||||
{
|
||||
pthread_condattr_destroy(&attr);
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
throw SystemException("cannot create event (condition attribute clock)");
|
||||
}
|
||||
if (pthread_cond_init(&_cond, &attr))
|
||||
{
|
||||
pthread_condattr_destroy(&attr);
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
throw SystemException("cannot create event (condition)");
|
||||
}
|
||||
pthread_condattr_destroy(&attr);
|
||||
#else
|
||||
if (pthread_cond_init(&_cond, NULL))
|
||||
{
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
throw SystemException("cannot create event (condition)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
EventImpl::~EventImpl()
|
||||
{
|
||||
pthread_cond_destroy(&_cond);
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
}
|
||||
|
||||
|
||||
void EventImpl::waitImpl()
|
||||
{
|
||||
if (pthread_mutex_lock(&_mutex))
|
||||
throw SystemException("wait for event failed (lock)");
|
||||
while (!_state)
|
||||
{
|
||||
if (pthread_cond_wait(&_cond, &_mutex))
|
||||
{
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
throw SystemException("wait for event failed");
|
||||
}
|
||||
}
|
||||
if (_auto)
|
||||
_state = false;
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
|
||||
bool EventImpl::waitImpl(long milliseconds)
|
||||
{
|
||||
int rc = 0;
|
||||
struct timespec abstime;
|
||||
|
||||
#if defined(POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT)
|
||||
clock_gettime(CLOCK_MONOTONIC, &abstime);
|
||||
abstime.tv_sec += milliseconds / 1000;
|
||||
abstime.tv_nsec += (milliseconds % 1000)*1000000;
|
||||
if (abstime.tv_nsec >= 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
#elif defined(POCO_HAVE_CLOCK_GETTIME)
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
abstime.tv_sec += milliseconds / 1000;
|
||||
abstime.tv_nsec += (milliseconds % 1000)*1000000;
|
||||
if (abstime.tv_nsec >= 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
|
||||
abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000;
|
||||
if (abstime.tv_nsec >= 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pthread_mutex_lock(&_mutex) != 0)
|
||||
throw SystemException("wait for event failed (lock)");
|
||||
while (!_state)
|
||||
{
|
||||
if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime)))
|
||||
{
|
||||
if (rc == ETIMEDOUT) break;
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
throw SystemException("cannot wait for event");
|
||||
}
|
||||
}
|
||||
if (rc == 0 && _auto) _state = false;
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
return rc == 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Event_POSIX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: Event
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Event_VX.h"
|
||||
#include <sysLib.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EventImpl::EventImpl(bool autoReset): _auto(autoReset), _state(false)
|
||||
{
|
||||
_sem = semCCreate(SEM_Q_PRIORITY, 0);
|
||||
if (_sem == 0)
|
||||
throw Poco::SystemException("cannot create event");
|
||||
}
|
||||
|
||||
|
||||
EventImpl::~EventImpl()
|
||||
{
|
||||
semDelete(_sem);
|
||||
}
|
||||
|
||||
|
||||
void EventImpl::setImpl()
|
||||
{
|
||||
if (_auto)
|
||||
{
|
||||
if (semGive(_sem) != OK)
|
||||
throw SystemException("cannot set event");
|
||||
}
|
||||
else
|
||||
{
|
||||
_state = true;
|
||||
if (semFlush(_sem) != OK)
|
||||
throw SystemException("cannot set event");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventImpl::resetImpl()
|
||||
{
|
||||
_state = false;
|
||||
}
|
||||
|
||||
|
||||
void EventImpl::waitImpl()
|
||||
{
|
||||
if (!_state)
|
||||
{
|
||||
if (semTake(_sem, WAIT_FOREVER) != OK)
|
||||
throw SystemException("cannot wait for event");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EventImpl::waitImpl(long milliseconds)
|
||||
{
|
||||
if (!_state)
|
||||
{
|
||||
int ticks = milliseconds*sysClkRateGet()/1000;
|
||||
return semTake(_sem, ticks) == OK;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// Event_WIN32.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Threading
|
||||
// Module: Event
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Event_WIN32.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
EventImpl::EventImpl(bool autoReset)
|
||||
{
|
||||
_event = CreateEventW(NULL, autoReset ? FALSE : TRUE, FALSE, NULL);
|
||||
if (!_event)
|
||||
throw SystemException("cannot create event");
|
||||
}
|
||||
|
||||
|
||||
EventImpl::~EventImpl()
|
||||
{
|
||||
CloseHandle(_event);
|
||||
}
|
||||
|
||||
|
||||
void EventImpl::waitImpl()
|
||||
{
|
||||
switch (WaitForSingleObject(_event, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
return;
|
||||
default:
|
||||
throw SystemException("wait for event failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EventImpl::waitImpl(long milliseconds)
|
||||
{
|
||||
switch (WaitForSingleObject(_event, milliseconds + 1))
|
||||
{
|
||||
case WAIT_TIMEOUT:
|
||||
return false;
|
||||
case WAIT_OBJECT_0:
|
||||
return true;
|
||||
default:
|
||||
throw SystemException("wait for event failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// Exception.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Exception
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Exception.h"
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Exception::Exception(int code): _pNested(0), _code(code)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Exception::Exception(const std::string& msg, int code): _msg(msg), _pNested(0), _code(code)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Exception::Exception(const std::string& msg, const std::string& arg, int code): _msg(msg), _pNested(0), _code(code)
|
||||
{
|
||||
if (!arg.empty())
|
||||
{
|
||||
_msg.append(": ");
|
||||
_msg.append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Exception::Exception(const std::string& msg, const Exception& nested, int code): _msg(msg), _pNested(nested.clone()), _code(code)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Exception::Exception(const Exception& exc):
|
||||
std::exception(exc),
|
||||
_msg(exc._msg),
|
||||
_code(exc._code)
|
||||
{
|
||||
_pNested = exc._pNested ? exc._pNested->clone() : 0;
|
||||
}
|
||||
|
||||
|
||||
Exception::~Exception() noexcept
|
||||
{
|
||||
delete _pNested;
|
||||
}
|
||||
|
||||
|
||||
Exception& Exception::operator = (const Exception& exc)
|
||||
{
|
||||
if (&exc != this)
|
||||
{
|
||||
Exception* newPNested = exc._pNested ? exc._pNested->clone() : 0;
|
||||
delete _pNested;
|
||||
_msg = exc._msg;
|
||||
_pNested = newPNested;
|
||||
_code = exc._code;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
const char* Exception::name() const noexcept
|
||||
{
|
||||
return "Exception";
|
||||
}
|
||||
|
||||
|
||||
const char* Exception::className() const noexcept
|
||||
{
|
||||
return typeid(*this).name();
|
||||
}
|
||||
|
||||
|
||||
const char* Exception::what() const noexcept
|
||||
{
|
||||
return name();
|
||||
}
|
||||
|
||||
|
||||
std::string Exception::displayText() const
|
||||
{
|
||||
std::string txt = name();
|
||||
if (!_msg.empty())
|
||||
{
|
||||
txt.append(": ");
|
||||
txt.append(_msg);
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
|
||||
|
||||
void Exception::extendedMessage(const std::string& arg)
|
||||
{
|
||||
if (!arg.empty())
|
||||
{
|
||||
if (!_msg.empty()) _msg.append(": ");
|
||||
_msg.append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Exception* Exception::clone() const
|
||||
{
|
||||
return new Exception(*this);
|
||||
}
|
||||
|
||||
|
||||
void Exception::rethrow() const
|
||||
{
|
||||
throw *this;
|
||||
}
|
||||
|
||||
|
||||
POCO_IMPLEMENT_EXCEPTION(LogicException, Exception, "Logic exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(AssertionViolationException, LogicException, "Assertion violation")
|
||||
POCO_IMPLEMENT_EXCEPTION(NullPointerException, LogicException, "Null pointer")
|
||||
POCO_IMPLEMENT_EXCEPTION(NullValueException, LogicException, "Null value")
|
||||
POCO_IMPLEMENT_EXCEPTION(BugcheckException, LogicException, "Bugcheck")
|
||||
POCO_IMPLEMENT_EXCEPTION(InvalidArgumentException, LogicException, "Invalid argument")
|
||||
POCO_IMPLEMENT_EXCEPTION(NotImplementedException, LogicException, "Not implemented")
|
||||
POCO_IMPLEMENT_EXCEPTION(RangeException, LogicException, "Out of range")
|
||||
POCO_IMPLEMENT_EXCEPTION(IllegalStateException, LogicException, "Illegal state")
|
||||
POCO_IMPLEMENT_EXCEPTION(InvalidAccessException, LogicException, "Invalid access")
|
||||
POCO_IMPLEMENT_EXCEPTION(SignalException, LogicException, "Signal received")
|
||||
POCO_IMPLEMENT_EXCEPTION(UnhandledException, LogicException, "Unhandled exception")
|
||||
|
||||
POCO_IMPLEMENT_EXCEPTION(RuntimeException, Exception, "Runtime exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(NotFoundException, RuntimeException, "Not found")
|
||||
POCO_IMPLEMENT_EXCEPTION(ExistsException, RuntimeException, "Exists")
|
||||
POCO_IMPLEMENT_EXCEPTION(TimeoutException, RuntimeException, "Timeout")
|
||||
POCO_IMPLEMENT_EXCEPTION(SystemException, RuntimeException, "System exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(RegularExpressionException, RuntimeException, "Error in regular expression")
|
||||
POCO_IMPLEMENT_EXCEPTION(LibraryLoadException, RuntimeException, "Cannot load library")
|
||||
POCO_IMPLEMENT_EXCEPTION(LibraryAlreadyLoadedException, RuntimeException, "Library already loaded")
|
||||
POCO_IMPLEMENT_EXCEPTION(NoThreadAvailableException, RuntimeException, "No thread available")
|
||||
POCO_IMPLEMENT_EXCEPTION(PropertyNotSupportedException, RuntimeException, "Property not supported")
|
||||
POCO_IMPLEMENT_EXCEPTION(PoolOverflowException, RuntimeException, "Pool overflow")
|
||||
POCO_IMPLEMENT_EXCEPTION(NoPermissionException, RuntimeException, "No permission")
|
||||
POCO_IMPLEMENT_EXCEPTION(OutOfMemoryException, RuntimeException, "Out of memory")
|
||||
POCO_IMPLEMENT_EXCEPTION(DataException, RuntimeException, "Data error")
|
||||
|
||||
POCO_IMPLEMENT_EXCEPTION(DataFormatException, DataException, "Bad data format")
|
||||
POCO_IMPLEMENT_EXCEPTION(SyntaxException, DataException, "Syntax error")
|
||||
POCO_IMPLEMENT_EXCEPTION(CircularReferenceException, DataException, "Circular reference")
|
||||
POCO_IMPLEMENT_EXCEPTION(PathSyntaxException, SyntaxException, "Bad path syntax")
|
||||
POCO_IMPLEMENT_EXCEPTION(IOException, RuntimeException, "I/O error")
|
||||
POCO_IMPLEMENT_EXCEPTION(ProtocolException, IOException, "Protocol error")
|
||||
POCO_IMPLEMENT_EXCEPTION(FileException, IOException, "File access error")
|
||||
POCO_IMPLEMENT_EXCEPTION(FileExistsException, FileException, "File exists")
|
||||
POCO_IMPLEMENT_EXCEPTION(FileNotFoundException, FileException, "File not found")
|
||||
POCO_IMPLEMENT_EXCEPTION(PathNotFoundException, FileException, "Path not found")
|
||||
POCO_IMPLEMENT_EXCEPTION(FileReadOnlyException, FileException, "File is read-only")
|
||||
POCO_IMPLEMENT_EXCEPTION(FileAccessDeniedException, FileException, "Access to file denied")
|
||||
POCO_IMPLEMENT_EXCEPTION(CreateFileException, FileException, "Cannot create file")
|
||||
POCO_IMPLEMENT_EXCEPTION(OpenFileException, FileException, "Cannot open file")
|
||||
POCO_IMPLEMENT_EXCEPTION(WriteFileException, FileException, "Cannot write file")
|
||||
POCO_IMPLEMENT_EXCEPTION(ReadFileException, FileException, "Cannot read file")
|
||||
POCO_IMPLEMENT_EXCEPTION(DirectoryNotEmptyException, FileException, "Directory not empty")
|
||||
POCO_IMPLEMENT_EXCEPTION(UnknownURISchemeException, RuntimeException, "Unknown URI scheme")
|
||||
POCO_IMPLEMENT_EXCEPTION(TooManyURIRedirectsException, RuntimeException, "Too many URI redirects")
|
||||
POCO_IMPLEMENT_EXCEPTION(URISyntaxException, SyntaxException, "Bad URI syntax")
|
||||
|
||||
POCO_IMPLEMENT_EXCEPTION(ApplicationException, Exception, "Application exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(BadCastException, RuntimeException, "Bad cast exception")
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
//
|
||||
// FIFOBufferStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: FIFOBufferStream
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FIFOBufferStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
//
|
||||
// FIFOBufferStreamBuf
|
||||
//
|
||||
|
||||
|
||||
FIFOBufferStreamBuf::FIFOBufferStreamBuf():
|
||||
BufferedBidirectionalStreamBuf(STREAM_BUFFER_SIZE + 4, std::ios::in | std::ios::out),
|
||||
_pFIFOBuffer(new FIFOBuffer(STREAM_BUFFER_SIZE, true)),
|
||||
_fifoBuffer(*_pFIFOBuffer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStreamBuf::FIFOBufferStreamBuf(FIFOBuffer& fifoBuffer):
|
||||
BufferedBidirectionalStreamBuf(fifoBuffer.size() + 4, std::ios::in | std::ios::out),
|
||||
_pFIFOBuffer(0),
|
||||
_fifoBuffer(fifoBuffer)
|
||||
{
|
||||
fifoBuffer.setNotify(true);
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStreamBuf::FIFOBufferStreamBuf(char* pBuffer, std::size_t length):
|
||||
BufferedBidirectionalStreamBuf(length + 4, std::ios::in | std::ios::out),
|
||||
_pFIFOBuffer(new FIFOBuffer(pBuffer, length, true)),
|
||||
_fifoBuffer(*_pFIFOBuffer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStreamBuf::FIFOBufferStreamBuf(const char* pBuffer, std::size_t length):
|
||||
BufferedBidirectionalStreamBuf(length + 4, std::ios::in | std::ios::out),
|
||||
_pFIFOBuffer(new FIFOBuffer(pBuffer, length, true)),
|
||||
_fifoBuffer(*_pFIFOBuffer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStreamBuf::FIFOBufferStreamBuf(std::size_t length):
|
||||
BufferedBidirectionalStreamBuf(length + 4, std::ios::in | std::ios::out),
|
||||
_pFIFOBuffer(new FIFOBuffer(length, true)),
|
||||
_fifoBuffer(*_pFIFOBuffer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStreamBuf::~FIFOBufferStreamBuf()
|
||||
{
|
||||
delete _pFIFOBuffer;
|
||||
}
|
||||
|
||||
|
||||
int FIFOBufferStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
poco_assert (length > 0);
|
||||
return static_cast<int>(_fifoBuffer.read(buffer, static_cast<std::size_t>(length)));
|
||||
}
|
||||
|
||||
|
||||
int FIFOBufferStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
poco_assert (length > 0);
|
||||
return static_cast<int>(_fifoBuffer.write(buffer, static_cast<std::size_t>(length)));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FIFOIOS
|
||||
//
|
||||
|
||||
|
||||
FIFOIOS::FIFOIOS(FIFOBuffer& fifoBuffer): _buf(fifoBuffer)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
FIFOIOS::FIFOIOS(char* pBuffer, std::size_t length): _buf(pBuffer, length)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
FIFOIOS::FIFOIOS(const char* pBuffer, std::size_t length): _buf(pBuffer, length)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
FIFOIOS::FIFOIOS(std::size_t length): _buf(length)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
FIFOIOS::~FIFOIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStreamBuf* FIFOIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
void FIFOIOS::close()
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FIFOBufferStream
|
||||
//
|
||||
|
||||
|
||||
FIFOBufferStream::FIFOBufferStream(FIFOBuffer& fifoBuffer):
|
||||
FIFOIOS(fifoBuffer),
|
||||
std::iostream(&_buf),
|
||||
readable(_buf.fifoBuffer().readable),
|
||||
writable(_buf.fifoBuffer().writable)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStream::FIFOBufferStream(char* pBuffer, std::size_t length):
|
||||
FIFOIOS(pBuffer, length),
|
||||
std::iostream(&_buf),
|
||||
readable(_buf.fifoBuffer().readable),
|
||||
writable(_buf.fifoBuffer().writable)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStream::FIFOBufferStream(const char* pBuffer, std::size_t length):
|
||||
FIFOIOS(pBuffer, length),
|
||||
std::iostream(&_buf),
|
||||
readable(_buf.fifoBuffer().readable),
|
||||
writable(_buf.fifoBuffer().writable)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStream::FIFOBufferStream(std::size_t length):
|
||||
FIFOIOS(length),
|
||||
std::iostream(&_buf),
|
||||
readable(_buf.fifoBuffer().readable),
|
||||
writable(_buf.fifoBuffer().writable)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FIFOBufferStream::~FIFOBufferStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// FPEnvironment.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
// pull in platform identification macros needed below
|
||||
#include "Poco/Platform.h"
|
||||
#include "Poco/FPEnvironment.h"
|
||||
|
||||
|
||||
#if defined(POCO_NO_FPENVIRONMENT)
|
||||
#include "FPEnvironment_DUMMY.cpp"
|
||||
#elif defined(__osf__)
|
||||
#include "FPEnvironment_DEC.cpp"
|
||||
#elif defined(sun) || defined(__sun)
|
||||
#include "FPEnvironment_SUN.cpp"
|
||||
#elif defined(__QNX__)
|
||||
#include "FPEnvironment_QNX.cpp"
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
#include "FPEnvironment_C99.cpp"
|
||||
#elif defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "FPEnvironment_WIN32.cpp"
|
||||
#else
|
||||
#include "FPEnvironment_DUMMY.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironment::FPEnvironment()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FPEnvironment::FPEnvironment(RoundingMode rm)
|
||||
{
|
||||
setRoundingMode(rm);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironment::FPEnvironment(const FPEnvironment& env): FPEnvironmentImpl(env)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FPEnvironment::~FPEnvironment()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FPEnvironment& FPEnvironment::operator = (const FPEnvironment& env)
|
||||
{
|
||||
if (&env != this)
|
||||
{
|
||||
FPEnvironmentImpl::operator = (env);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironment::keepCurrent()
|
||||
{
|
||||
keepCurrentImpl();
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironment::clearFlags()
|
||||
{
|
||||
clearFlagsImpl();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// FPEnvironment_C99.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FPEnvironment_C99.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl()
|
||||
{
|
||||
fegetenv(&_env);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::~FPEnvironmentImpl()
|
||||
{
|
||||
fesetenv(&_env);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::keepCurrentImpl()
|
||||
{
|
||||
fegetenv(&_env);
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::clearFlagsImpl()
|
||||
{
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
|
||||
{
|
||||
return fetestexcept(flag) != 0;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
|
||||
{
|
||||
fesetround(mode);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
|
||||
{
|
||||
return (RoundingModeImpl) fegetround();
|
||||
}
|
||||
|
||||
|
||||
long double FPEnvironmentImpl::copySignImpl(long double target, long double source)
|
||||
{
|
||||
return (source >= 0 && target >= 0) || (source < 0 && target < 0) ? target : -target;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// FPEnvironment_DEC.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// _XOPEN_SOURCE disables the ieee fp functions
|
||||
// in <math.h>, therefore we undefine it for this file.
|
||||
//
|
||||
#undef _XOPEN_SOURCE
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <fp.h>
|
||||
#include <fp_class.h>
|
||||
#if defined(__VMS)
|
||||
#include <starlet.h>
|
||||
#endif
|
||||
#include "Poco/FPEnvironment_DEC.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl()
|
||||
{
|
||||
#if defined(__VMS)
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size 32
|
||||
struct _ieee env;
|
||||
sys$ieee_set_fp_control(0, 0, &env);
|
||||
#pragma pointer_size restore
|
||||
_env = env;
|
||||
#else
|
||||
_env = ieee_get_fp_control();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::~FPEnvironmentImpl()
|
||||
{
|
||||
#if defined(__VMS)
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size 32
|
||||
struct _ieee mask;
|
||||
mask.ieee$q_flags = 0xFFFFFFFFFFFFFFFF;
|
||||
struct _ieee env = _env;
|
||||
sys$ieee_set_fp_control(&mask, &env, 0);
|
||||
#pragma pointer_size restore
|
||||
#else
|
||||
ieee_set_fp_control(_env);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isInfiniteImpl(float value)
|
||||
{
|
||||
int cls = fp_classf(value);
|
||||
return cls == FP_POS_INF || cls == FP_NEG_INF;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isInfiniteImpl(double value)
|
||||
{
|
||||
int cls = fp_class(value);
|
||||
return cls == FP_POS_INF || cls == FP_NEG_INF;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isInfiniteImpl(long double value)
|
||||
{
|
||||
int cls = fp_classl(value);
|
||||
return cls == FP_POS_INF || cls == FP_NEG_INF;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isNaNImpl(float value)
|
||||
{
|
||||
return isnanf(value) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isNaNImpl(double value)
|
||||
{
|
||||
return isnan(value) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isNaNImpl(long double value)
|
||||
{
|
||||
return isnanl(value) != 0;
|
||||
}
|
||||
|
||||
|
||||
float FPEnvironmentImpl::copySignImpl(float target, float source)
|
||||
{
|
||||
return copysignf(target, source);
|
||||
}
|
||||
|
||||
|
||||
double FPEnvironmentImpl::copySignImpl(double target, double source)
|
||||
{
|
||||
return copysign(target, source);
|
||||
}
|
||||
|
||||
|
||||
long double FPEnvironmentImpl::copySignImpl(long double target, long double source)
|
||||
{
|
||||
return copysignl(target, source);
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::keepCurrentImpl()
|
||||
{
|
||||
#if defined(__VMS)
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size 32
|
||||
struct _ieee env;
|
||||
sys$ieee_set_fp_control(0, 0, &env);
|
||||
#pragma pointer_size restore
|
||||
_env = env;
|
||||
#else
|
||||
ieee_set_fp_control(_env);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::clearFlagsImpl()
|
||||
{
|
||||
#if defined(__VMS)
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size 32
|
||||
struct _ieee mask;
|
||||
mask.ieee$q_flags = 0xFFFFFFFFFFFFFFFF;
|
||||
struct _ieee clr;
|
||||
clr.ieee$q_flags = 0;
|
||||
sys$ieee_set_fp_control(&mask, &clr, 0);
|
||||
#pragma pointer_size restore
|
||||
#else
|
||||
ieee_set_fp_control(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
|
||||
{
|
||||
#if defined(__VMS)
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size 32
|
||||
struct _ieee flags;
|
||||
sys$ieee_set_fp_control(0, 0, &flags);
|
||||
return (flags.ieee$q_flags & flag) != 0;
|
||||
#pragma pointer_size restore
|
||||
#else
|
||||
return (ieee_get_fp_control() & flag) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
|
||||
{
|
||||
// not supported
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
|
||||
{
|
||||
// not supported
|
||||
return FPEnvironmentImpl::RoundingModeImpl(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// FPEnvironment_C99.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FPEnvironment_DUMMY.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::_roundingMode;
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::~FPEnvironmentImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::keepCurrentImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::clearFlagsImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
|
||||
{
|
||||
_roundingMode = mode;
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
|
||||
{
|
||||
return _roundingMode;
|
||||
}
|
||||
|
||||
|
||||
long double FPEnvironmentImpl::copySignImpl(long double target, long double source)
|
||||
{
|
||||
return (source >= 0 && target >= 0) || (source < 0 && target < 0) ? target : -target;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// FPEnvironment_QNX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FPEnvironment_QNX.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl()
|
||||
{
|
||||
fegetenv(&_env);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::~FPEnvironmentImpl()
|
||||
{
|
||||
fesetenv(&_env);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::keepCurrentImpl()
|
||||
{
|
||||
fegetenv(&_env);
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::clearFlagsImpl()
|
||||
{
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
|
||||
{
|
||||
return fetestexcept(flag) != 0;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
|
||||
{
|
||||
fesetround(mode);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
|
||||
{
|
||||
return (RoundingModeImpl) fegetround();
|
||||
}
|
||||
|
||||
|
||||
long double FPEnvironmentImpl::copySignImpl(long double target, long double source)
|
||||
{
|
||||
return (source >= 0 && target >= 0) || (source < 0 && target < 0) ? target : -target;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// FPEnvironment_SUN.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include "Poco/FPEnvironment_SUN.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl()
|
||||
{
|
||||
_rnd = fpgetround();
|
||||
_exc = fpgetmask();
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
|
||||
{
|
||||
_rnd = env._rnd;
|
||||
_exc = env._exc;
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::~FPEnvironmentImpl()
|
||||
{
|
||||
fpsetround(_rnd);
|
||||
fpsetmask(_exc);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
|
||||
{
|
||||
_rnd = env._rnd;
|
||||
_exc = env._exc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isInfiniteImpl(float value)
|
||||
{
|
||||
int cls = fpclass(value);
|
||||
return cls == FP_PINF || cls == FP_NINF;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isInfiniteImpl(double value)
|
||||
{
|
||||
int cls = fpclass(value);
|
||||
return cls == FP_PINF || cls == FP_NINF;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isInfiniteImpl(long double value)
|
||||
{
|
||||
int cls = fpclass(value);
|
||||
return cls == FP_PINF || cls == FP_NINF;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isNaNImpl(float value)
|
||||
{
|
||||
return isnanf(value) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isNaNImpl(double value)
|
||||
{
|
||||
return isnan(value) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isNaNImpl(long double value)
|
||||
{
|
||||
return isnan((double) value) != 0;
|
||||
}
|
||||
|
||||
|
||||
float FPEnvironmentImpl::copySignImpl(float target, float source)
|
||||
{
|
||||
return (float) copysign(target, source);
|
||||
}
|
||||
|
||||
|
||||
double FPEnvironmentImpl::copySignImpl(double target, double source)
|
||||
{
|
||||
return (float) copysign(target, source);
|
||||
}
|
||||
|
||||
|
||||
long double FPEnvironmentImpl::copySignImpl(long double target, long double source)
|
||||
{
|
||||
return (source > 0 && target > 0) || (source < 0 && target < 0) ? target : -target;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::keepCurrentImpl()
|
||||
{
|
||||
fpsetround(_rnd);
|
||||
fpsetmask(_exc);
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::clearFlagsImpl()
|
||||
{
|
||||
fpsetsticky(0);
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
|
||||
{
|
||||
return (fpgetsticky() & flag) != 0;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
|
||||
{
|
||||
fpsetround((fp_rnd) mode);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
|
||||
{
|
||||
return (FPEnvironmentImpl::RoundingModeImpl) fpgetround();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// FPEnvironment_WIN32.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: FPEnvironment
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FPEnvironment_WIN32.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl()
|
||||
{
|
||||
_env = _controlfp(0, 0);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::~FPEnvironmentImpl()
|
||||
{
|
||||
_controlfp(_env, _MCW_RC);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
|
||||
{
|
||||
_env = env._env;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::keepCurrentImpl()
|
||||
{
|
||||
_env = _controlfp(0, 0);
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::clearFlagsImpl()
|
||||
{
|
||||
_clearfp();
|
||||
}
|
||||
|
||||
|
||||
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
|
||||
{
|
||||
return (_statusfp() & flag) != 0;
|
||||
}
|
||||
|
||||
|
||||
void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
|
||||
{
|
||||
_controlfp(mode, _MCW_RC);
|
||||
}
|
||||
|
||||
|
||||
FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
|
||||
{
|
||||
return RoundingModeImpl(_controlfp(0, 0) & _MCW_RC);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+392
@@ -0,0 +1,392 @@
|
||||
//
|
||||
// File.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: File
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/DirectoryIterator.h"
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#if defined(_WIN32_WCE)
|
||||
#include "File_WINCE.cpp"
|
||||
#else
|
||||
#include "File_WIN32U.cpp"
|
||||
#endif
|
||||
#elif defined(POCO_VXWORKS)
|
||||
#include "File_VX.cpp"
|
||||
#elif defined(POCO_OS_FAMILY_UNIX)
|
||||
#include "File_UNIX.cpp"
|
||||
#endif
|
||||
#include "Poco/Thread.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
File::File()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::File(const std::string& path): FileImpl(path)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::File(const char* path): FileImpl(std::string(path))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::File(const Path& path): FileImpl(path.toString())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::File(const File& file): FileImpl(file.getPathImpl())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::~File()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File& File::operator = (const File& file)
|
||||
{
|
||||
setPathImpl(file.getPathImpl());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File& File::operator = (const std::string& path)
|
||||
{
|
||||
setPathImpl(path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File& File::operator = (const char* path)
|
||||
{
|
||||
poco_check_ptr (path);
|
||||
setPathImpl(path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File& File::operator = (const Path& path)
|
||||
{
|
||||
setPathImpl(path.toString());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void File::swap(File& file)
|
||||
{
|
||||
swapImpl(file);
|
||||
}
|
||||
|
||||
|
||||
bool File::exists() const
|
||||
{
|
||||
return existsImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::canRead() const
|
||||
{
|
||||
return canReadImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::canWrite() const
|
||||
{
|
||||
return canWriteImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::canExecute() const
|
||||
{
|
||||
return canExecuteImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::isFile() const
|
||||
{
|
||||
return isFileImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
return isDirectoryImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::isLink() const
|
||||
{
|
||||
return isLinkImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::isDevice() const
|
||||
{
|
||||
return isDeviceImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::isHidden() const
|
||||
{
|
||||
return isHiddenImpl();
|
||||
}
|
||||
|
||||
|
||||
Timestamp File::created() const
|
||||
{
|
||||
return createdImpl();
|
||||
}
|
||||
|
||||
|
||||
Timestamp File::getLastModified() const
|
||||
{
|
||||
return getLastModifiedImpl();
|
||||
}
|
||||
|
||||
|
||||
File& File::setLastModified(const Timestamp& ts)
|
||||
{
|
||||
setLastModifiedImpl(ts);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File::FileSize File::getSize() const
|
||||
{
|
||||
return getSizeImpl();
|
||||
}
|
||||
|
||||
|
||||
File& File::setSize(FileSizeImpl size)
|
||||
{
|
||||
setSizeImpl(size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File& File::setWriteable(bool flag)
|
||||
{
|
||||
setWriteableImpl(flag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File& File::setReadOnly(bool flag)
|
||||
{
|
||||
setWriteableImpl(!flag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
File& File::setExecutable(bool flag)
|
||||
{
|
||||
setExecutableImpl(flag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void File::copyTo(const std::string& path, int options) const
|
||||
{
|
||||
Path src(getPathImpl());
|
||||
Path dest(path);
|
||||
File destFile(path);
|
||||
if ((destFile.exists() && destFile.isDirectory()) || dest.isDirectory())
|
||||
{
|
||||
dest.makeDirectory();
|
||||
dest.setFileName(src.getFileName());
|
||||
}
|
||||
if (isDirectory())
|
||||
copyDirectory(dest.toString(), options);
|
||||
else
|
||||
copyToImpl(dest.toString(), options);
|
||||
}
|
||||
|
||||
|
||||
void File::copyDirectory(const std::string& path, int options) const
|
||||
{
|
||||
File target(path);
|
||||
target.createDirectories();
|
||||
|
||||
Path src(getPathImpl());
|
||||
src.makeFile();
|
||||
DirectoryIterator it(src);
|
||||
DirectoryIterator end;
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
it->copyTo(path, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void File::moveTo(const std::string& path, int options)
|
||||
{
|
||||
copyTo(path, options);
|
||||
remove(true);
|
||||
setPathImpl(path);
|
||||
}
|
||||
|
||||
|
||||
void File::renameTo(const std::string& path, int options)
|
||||
{
|
||||
renameToImpl(path, options);
|
||||
setPathImpl(path);
|
||||
}
|
||||
|
||||
|
||||
void File::linkTo(const std::string& path, LinkType type) const
|
||||
{
|
||||
linkToImpl(path, type);
|
||||
}
|
||||
|
||||
|
||||
void File::remove(bool recursive)
|
||||
{
|
||||
if (recursive && !isLink() && isDirectory())
|
||||
{
|
||||
std::vector<File> files;
|
||||
list(files);
|
||||
for (auto& f: files)
|
||||
{
|
||||
f.remove(true);
|
||||
}
|
||||
|
||||
// Note: On Windows, removing a directory may not succeed at first
|
||||
// try because deleting files is not a synchronous operation. Files
|
||||
// are merely marked as deleted, and actually removed at a later time.
|
||||
//
|
||||
// An alternate strategy would be moving files to a different directory
|
||||
// first (on the same drive, but outside the deleted tree), and marking
|
||||
// them as hidden, before deleting them, but this could lead to other issues.
|
||||
// So we simply retry after some time until we succeed, or give up.
|
||||
|
||||
int retry = 8;
|
||||
long sleep = 10;
|
||||
while (retry > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
removeImpl();
|
||||
retry = 0;
|
||||
}
|
||||
catch (DirectoryNotEmptyException&)
|
||||
{
|
||||
if (--retry == 0) throw;
|
||||
Poco::Thread::sleep(sleep);
|
||||
sleep *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
removeImpl();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool File::createFile()
|
||||
{
|
||||
return createFileImpl();
|
||||
}
|
||||
|
||||
|
||||
bool File::createDirectory()
|
||||
{
|
||||
return createDirectoryImpl();
|
||||
}
|
||||
|
||||
|
||||
void File::createDirectories()
|
||||
{
|
||||
if (!exists())
|
||||
{
|
||||
Path p(getPathImpl());
|
||||
p.makeDirectory();
|
||||
if (p.depth() > 1)
|
||||
{
|
||||
p.makeParent();
|
||||
File f(p);
|
||||
f.createDirectories();
|
||||
}
|
||||
try
|
||||
{
|
||||
createDirectoryImpl();
|
||||
}
|
||||
catch (FileExistsException&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void File::list(std::vector<std::string>& files) const
|
||||
{
|
||||
files.clear();
|
||||
DirectoryIterator it(*this);
|
||||
DirectoryIterator end;
|
||||
while (it != end)
|
||||
{
|
||||
files.push_back(it.name());
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File::FileSize File::totalSpace() const
|
||||
{
|
||||
return totalSpaceImpl();
|
||||
}
|
||||
|
||||
|
||||
File::FileSize File::usableSpace() const
|
||||
{
|
||||
return usableSpaceImpl();
|
||||
}
|
||||
|
||||
|
||||
File::FileSize File::freeSpace() const
|
||||
{
|
||||
return freeSpaceImpl();
|
||||
}
|
||||
|
||||
|
||||
void File::list(std::vector<File>& files) const
|
||||
{
|
||||
files.clear();
|
||||
DirectoryIterator it(*this);
|
||||
DirectoryIterator end;
|
||||
while (it != end)
|
||||
{
|
||||
files.push_back(*it);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void File::handleLastError(const std::string& path)
|
||||
{
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+428
@@ -0,0 +1,428 @@
|
||||
//
|
||||
// FileChannel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: FileChannel
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FileChannel.h"
|
||||
#include "Poco/ArchiveStrategy.h"
|
||||
#include "Poco/RotateStrategy.h"
|
||||
#include "Poco/PurgeStrategy.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/LocalDateTime.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Ascii.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const std::string FileChannel::PROP_PATH = "path";
|
||||
const std::string FileChannel::PROP_ROTATION = "rotation";
|
||||
const std::string FileChannel::PROP_ARCHIVE = "archive";
|
||||
const std::string FileChannel::PROP_TIMES = "times";
|
||||
const std::string FileChannel::PROP_COMPRESS = "compress";
|
||||
const std::string FileChannel::PROP_PURGEAGE = "purgeAge";
|
||||
const std::string FileChannel::PROP_PURGECOUNT = "purgeCount";
|
||||
const std::string FileChannel::PROP_FLUSH = "flush";
|
||||
const std::string FileChannel::PROP_ROTATEONOPEN = "rotateOnOpen";
|
||||
|
||||
FileChannel::FileChannel():
|
||||
_times("utc"),
|
||||
_compress(false),
|
||||
_flush(true),
|
||||
_rotateOnOpen(false),
|
||||
_pFile(0),
|
||||
_pRotateStrategy(0),
|
||||
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
||||
_pPurgeStrategy(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileChannel::FileChannel(const std::string& path):
|
||||
_path(path),
|
||||
_times("utc"),
|
||||
_compress(false),
|
||||
_flush(true),
|
||||
_rotateOnOpen(false),
|
||||
_pFile(0),
|
||||
_pRotateStrategy(0),
|
||||
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
||||
_pPurgeStrategy(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileChannel::~FileChannel()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
delete _pRotateStrategy;
|
||||
delete _pArchiveStrategy;
|
||||
delete _pPurgeStrategy;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::open()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_pFile)
|
||||
{
|
||||
_pFile = new LogFile(_path);
|
||||
if (_rotateOnOpen && _pFile->size() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
_pFile = _pArchiveStrategy->archive(_pFile);
|
||||
purge();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
_pFile = new LogFile(_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::close()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
delete _pFile;
|
||||
_pFile = 0;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::log(const Message& msg)
|
||||
{
|
||||
open();
|
||||
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (_pRotateStrategy && _pArchiveStrategy && _pRotateStrategy->mustRotate(_pFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
_pFile = _pArchiveStrategy->archive(_pFile);
|
||||
purge();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
_pFile = new LogFile(_path);
|
||||
}
|
||||
// we must call mustRotate() again to give the
|
||||
// RotateByIntervalStrategy a chance to write its timestamp
|
||||
// to the new file.
|
||||
_pRotateStrategy->mustRotate(_pFile);
|
||||
}
|
||||
_pFile->write(msg.getText(), _flush);
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (name == PROP_TIMES)
|
||||
{
|
||||
_times = value;
|
||||
|
||||
if (!_rotation.empty())
|
||||
setRotation(_rotation);
|
||||
|
||||
if (!_archive.empty())
|
||||
setArchive(_archive);
|
||||
}
|
||||
else if (name == PROP_PATH)
|
||||
_path = value;
|
||||
else if (name == PROP_ROTATION)
|
||||
setRotation(value);
|
||||
else if (name == PROP_ARCHIVE)
|
||||
setArchive(value);
|
||||
else if (name == PROP_COMPRESS)
|
||||
setCompress(value);
|
||||
else if (name == PROP_PURGEAGE)
|
||||
setPurgeAge(value);
|
||||
else if (name == PROP_PURGECOUNT)
|
||||
setPurgeCount(value);
|
||||
else if (name == PROP_FLUSH)
|
||||
setFlush(value);
|
||||
else if (name == PROP_ROTATEONOPEN)
|
||||
setRotateOnOpen(value);
|
||||
else
|
||||
Channel::setProperty(name, value);
|
||||
}
|
||||
|
||||
|
||||
std::string FileChannel::getProperty(const std::string& name) const
|
||||
{
|
||||
if (name == PROP_TIMES)
|
||||
return _times;
|
||||
else if (name == PROP_PATH)
|
||||
return _path;
|
||||
else if (name == PROP_ROTATION)
|
||||
return _rotation;
|
||||
else if (name == PROP_ARCHIVE)
|
||||
return _archive;
|
||||
else if (name == PROP_COMPRESS)
|
||||
return std::string(_compress ? "true" : "false");
|
||||
else if (name == PROP_PURGEAGE)
|
||||
return _purgeAge;
|
||||
else if (name == PROP_PURGECOUNT)
|
||||
return _purgeCount;
|
||||
else if (name == PROP_FLUSH)
|
||||
return std::string(_flush ? "true" : "false");
|
||||
else if (name == PROP_ROTATEONOPEN)
|
||||
return std::string(_rotateOnOpen ? "true" : "false");
|
||||
else
|
||||
return Channel::getProperty(name);
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileChannel::creationDate() const
|
||||
{
|
||||
if (_pFile)
|
||||
return _pFile->creationDate();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
UInt64 FileChannel::size() const
|
||||
{
|
||||
if (_pFile)
|
||||
return _pFile->size();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const std::string& FileChannel::path() const
|
||||
{
|
||||
return _path;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setRotation(const std::string& rotation)
|
||||
{
|
||||
std::string::const_iterator it = rotation.begin();
|
||||
std::string::const_iterator end = rotation.end();
|
||||
int n = 0;
|
||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||
while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; }
|
||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||
std::string unit;
|
||||
while (it != end && Ascii::isAlpha(*it)) unit += *it++;
|
||||
|
||||
RotateStrategy* pStrategy = 0;
|
||||
if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos))
|
||||
{
|
||||
if (_times == "utc")
|
||||
pStrategy = new RotateAtTimeStrategy<DateTime>(rotation);
|
||||
else if (_times == "local")
|
||||
pStrategy = new RotateAtTimeStrategy<LocalDateTime>(rotation);
|
||||
else
|
||||
throw PropertyNotSupportedException("times", _times);
|
||||
}
|
||||
else if (unit == "daily")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(1*Timespan::DAYS));
|
||||
else if (unit == "weekly")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(7*Timespan::DAYS));
|
||||
else if (unit == "monthly")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(30*Timespan::DAYS));
|
||||
else if (unit == "seconds") // for testing only
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::SECONDS));
|
||||
else if (unit == "minutes")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::MINUTES));
|
||||
else if (unit == "hours")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::HOURS));
|
||||
else if (unit == "days")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::DAYS));
|
||||
else if (unit == "weeks")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(n*7*Timespan::DAYS));
|
||||
else if (unit == "months")
|
||||
pStrategy = new RotateByIntervalStrategy(Timespan(n*30*Timespan::DAYS));
|
||||
else if (unit == "K")
|
||||
pStrategy = new RotateBySizeStrategy(n*1024);
|
||||
else if (unit == "M")
|
||||
pStrategy = new RotateBySizeStrategy(n*1024*1024);
|
||||
else if (unit.empty())
|
||||
pStrategy = new RotateBySizeStrategy(n);
|
||||
else if (unit != "never")
|
||||
throw InvalidArgumentException("rotation", rotation);
|
||||
delete _pRotateStrategy;
|
||||
_pRotateStrategy = pStrategy;
|
||||
_rotation = rotation;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setArchive(const std::string& archive)
|
||||
{
|
||||
ArchiveStrategy* pStrategy = 0;
|
||||
if (archive == "number")
|
||||
{
|
||||
pStrategy = new ArchiveByNumberStrategy;
|
||||
}
|
||||
else if (archive == "timestamp")
|
||||
{
|
||||
if (_times == "utc")
|
||||
pStrategy = new ArchiveByTimestampStrategy<DateTime>;
|
||||
else if (_times == "local")
|
||||
pStrategy = new ArchiveByTimestampStrategy<LocalDateTime>;
|
||||
else
|
||||
throw PropertyNotSupportedException("times", _times);
|
||||
}
|
||||
else throw InvalidArgumentException("archive", archive);
|
||||
delete _pArchiveStrategy;
|
||||
pStrategy->compress(_compress);
|
||||
_pArchiveStrategy = pStrategy;
|
||||
_archive = archive;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setCompress(const std::string& compress)
|
||||
{
|
||||
_compress = icompare(compress, "true") == 0;
|
||||
if (_pArchiveStrategy)
|
||||
_pArchiveStrategy->compress(_compress);
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setPurgeAge(const std::string& age)
|
||||
{
|
||||
if (setNoPurge(age)) return;
|
||||
|
||||
std::string::const_iterator nextToDigit;
|
||||
int num = extractDigit(age, &nextToDigit);
|
||||
Timespan::TimeDiff factor = extractFactor(age, nextToDigit);
|
||||
|
||||
setPurgeStrategy(new PurgeByAgeStrategy(Timespan(num * factor)));
|
||||
_purgeAge = age;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setPurgeCount(const std::string& count)
|
||||
{
|
||||
if (setNoPurge(count)) return;
|
||||
|
||||
setPurgeStrategy(new PurgeByCountStrategy(extractDigit(count)));
|
||||
_purgeCount = count;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setFlush(const std::string& flush)
|
||||
{
|
||||
_flush = icompare(flush, "true") == 0;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setRotateOnOpen(const std::string& rotateOnOpen)
|
||||
{
|
||||
_rotateOnOpen = icompare(rotateOnOpen, "true") == 0;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::purge()
|
||||
{
|
||||
if (_pPurgeStrategy)
|
||||
{
|
||||
try
|
||||
{
|
||||
_pPurgeStrategy->purge(_path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FileChannel::setNoPurge(const std::string& value)
|
||||
{
|
||||
if (value.empty() || 0 == icompare(value, "none"))
|
||||
{
|
||||
delete _pPurgeStrategy;
|
||||
_pPurgeStrategy = 0;
|
||||
_purgeAge = "none";
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
int FileChannel::extractDigit(const std::string& value, std::string::const_iterator* nextToDigit) const
|
||||
{
|
||||
std::string::const_iterator it = value.begin();
|
||||
std::string::const_iterator end = value.end();
|
||||
int digit = 0;
|
||||
|
||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||
while (it != end && Ascii::isDigit(*it))
|
||||
{
|
||||
digit *= 10;
|
||||
digit += *it++ - '0';
|
||||
}
|
||||
|
||||
if (digit == 0)
|
||||
throw InvalidArgumentException("Zero is not valid purge age.");
|
||||
|
||||
if (nextToDigit) *nextToDigit = it;
|
||||
return digit;
|
||||
}
|
||||
|
||||
|
||||
void FileChannel::setPurgeStrategy(PurgeStrategy* strategy)
|
||||
{
|
||||
delete _pPurgeStrategy;
|
||||
_pPurgeStrategy = strategy;
|
||||
}
|
||||
|
||||
|
||||
Timespan::TimeDiff FileChannel::extractFactor(const std::string& value, std::string::const_iterator start) const
|
||||
{
|
||||
while (start != value.end() && Ascii::isSpace(*start)) ++start;
|
||||
|
||||
std::string unit;
|
||||
while (start != value.end() && Ascii::isAlpha(*start)) unit += *start++;
|
||||
|
||||
if (unit == "seconds")
|
||||
return Timespan::SECONDS;
|
||||
if (unit == "minutes")
|
||||
return Timespan::MINUTES;
|
||||
else if (unit == "hours")
|
||||
return Timespan::HOURS;
|
||||
else if (unit == "days")
|
||||
return Timespan::DAYS;
|
||||
else if (unit == "weeks")
|
||||
return 7 * Timespan::DAYS;
|
||||
else if (unit == "months")
|
||||
return 30 * Timespan::DAYS;
|
||||
else throw InvalidArgumentException("purgeAge", value);
|
||||
|
||||
return Timespan::TimeDiff();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// FileStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: FileStream
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/Exception.h"
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "FileStream_WIN32.cpp"
|
||||
#else
|
||||
#include "FileStream_POSIX.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FileIOS::FileIOS(std::ios::openmode defaultMode):
|
||||
_defaultMode(defaultMode)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
FileIOS::~FileIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FileIOS::open(const std::string& path, std::ios::openmode mode)
|
||||
{
|
||||
clear();
|
||||
_buf.open(path, mode | _defaultMode);
|
||||
}
|
||||
|
||||
|
||||
void FileIOS::close()
|
||||
{
|
||||
if (!_buf.close())
|
||||
{
|
||||
setstate(ios_base::badbit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FileStreamBuf* FileIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
FileInputStream::FileInputStream():
|
||||
FileIOS(std::ios::in),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileInputStream::FileInputStream(const std::string& path, std::ios::openmode mode):
|
||||
FileIOS(std::ios::in),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
|
||||
FileInputStream::~FileInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileOutputStream::FileOutputStream():
|
||||
FileIOS(std::ios::out),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileOutputStream::FileOutputStream(const std::string& path, std::ios::openmode mode):
|
||||
FileIOS(std::ios::out),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
|
||||
FileOutputStream::~FileOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileStream::FileStream():
|
||||
FileIOS(std::ios::in | std::ios::out),
|
||||
std::iostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileStream::FileStream(const std::string& path, std::ios::openmode mode):
|
||||
FileIOS(std::ios::in | std::ios::out),
|
||||
std::iostream(&_buf)
|
||||
{
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
|
||||
FileStream::~FileStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// FileStreamFactory.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: URI
|
||||
// Module: FileStreamFactory
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FileStreamFactory.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/FileStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FileStreamFactory::FileStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileStreamFactory::~FileStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* FileStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.isRelative() || uri.getScheme() == "file");
|
||||
|
||||
std::string uriPath = uri.getPath();
|
||||
if (uriPath.substr(0, 2) == "./")
|
||||
uriPath.erase(0, 2);
|
||||
Path p(uriPath, Path::PATH_UNIX);
|
||||
p.setNode(uri.getHost());
|
||||
return open(p);
|
||||
}
|
||||
|
||||
|
||||
std::istream* FileStreamFactory::open(const Path& path)
|
||||
{
|
||||
File file(path);
|
||||
if (!file.exists()) throw FileNotFoundException(path.toString());
|
||||
|
||||
FileInputStream* istr = new FileInputStream(path.toString(), std::ios::binary);
|
||||
if (!istr->good())
|
||||
{
|
||||
delete istr;
|
||||
throw OpenFileException(path.toString());
|
||||
}
|
||||
return istr;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// FileStream_POSIX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: FileStream
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FileStreamBuf::FileStreamBuf():
|
||||
BufferedBidirectionalStreamBuf(BUFFER_SIZE, std::ios::in | std::ios::out),
|
||||
_fd(-1),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileStreamBuf::~FileStreamBuf()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void FileStreamBuf::open(const std::string& path, std::ios::openmode mode)
|
||||
{
|
||||
poco_assert (_fd == -1);
|
||||
|
||||
_pos = 0;
|
||||
_path = path;
|
||||
setMode(mode);
|
||||
resetBuffers();
|
||||
|
||||
int flags(0);
|
||||
if (mode & std::ios::trunc)
|
||||
flags |= O_TRUNC;
|
||||
if (mode & std::ios::app)
|
||||
flags |= O_APPEND;
|
||||
if (mode & std::ios::out)
|
||||
flags |= O_CREAT;
|
||||
if ((mode & std::ios::in) && (mode & std::ios::out))
|
||||
flags |= O_RDWR;
|
||||
else if (mode & std::ios::in)
|
||||
flags |= O_RDONLY;
|
||||
else
|
||||
flags |= O_WRONLY;
|
||||
|
||||
_fd = ::open(path.c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if (_fd == -1)
|
||||
File::handleLastError(_path);
|
||||
|
||||
if ((mode & std::ios::app) || (mode & std::ios::ate))
|
||||
seekoff(0, std::ios::end, mode);
|
||||
}
|
||||
|
||||
|
||||
int FileStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
if (_fd == -1) return -1;
|
||||
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
|
||||
int n = read(_fd, buffer, length);
|
||||
if (n == -1)
|
||||
File::handleLastError(_path);
|
||||
_pos += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int FileStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
if (_fd == -1) return -1;
|
||||
|
||||
#if defined(POCO_VXWORKS)
|
||||
int n = write(_fd, const_cast<char*>(buffer), length);
|
||||
#else
|
||||
int n = write(_fd, buffer, length);
|
||||
#endif
|
||||
if (n == -1)
|
||||
File::handleLastError(_path);
|
||||
_pos += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
bool FileStreamBuf::close()
|
||||
{
|
||||
bool success = true;
|
||||
if (_fd != -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
::close(_fd);
|
||||
_fd = -1;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, std::ios::openmode mode)
|
||||
{
|
||||
if (_fd == -1 || !(getMode() & mode))
|
||||
return -1;
|
||||
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
|
||||
std::streamoff adj;
|
||||
if (mode & std::ios::in)
|
||||
adj = static_cast<std::streamoff>(egptr() - gptr());
|
||||
else
|
||||
adj = 0;
|
||||
|
||||
resetBuffers();
|
||||
|
||||
int whence = SEEK_SET;
|
||||
if (dir == std::ios::cur)
|
||||
{
|
||||
whence = SEEK_CUR;
|
||||
off -= adj;
|
||||
}
|
||||
else if (dir == std::ios::end)
|
||||
{
|
||||
whence = SEEK_END;
|
||||
}
|
||||
_pos = lseek(_fd, off, whence);
|
||||
return _pos;
|
||||
}
|
||||
|
||||
|
||||
std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mode)
|
||||
{
|
||||
if (_fd == -1 || !(getMode() & mode))
|
||||
return -1;
|
||||
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
|
||||
resetBuffers();
|
||||
|
||||
_pos = lseek(_fd, pos, SEEK_SET);
|
||||
return _pos;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
//
|
||||
// FileStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: FileStream
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FileStreamBuf::FileStreamBuf():
|
||||
BufferedBidirectionalStreamBuf(BUFFER_SIZE, std::ios::in | std::ios::out),
|
||||
_handle(INVALID_HANDLE_VALUE),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileStreamBuf::~FileStreamBuf()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void FileStreamBuf::open(const std::string& path, std::ios::openmode mode)
|
||||
{
|
||||
poco_assert (_handle == INVALID_HANDLE_VALUE);
|
||||
|
||||
_path = path;
|
||||
_pos = 0;
|
||||
setMode(mode);
|
||||
resetBuffers();
|
||||
|
||||
DWORD access = 0;
|
||||
if (mode & std::ios::in)
|
||||
access |= GENERIC_READ;
|
||||
if (mode & std::ios::out)
|
||||
access |= GENERIC_WRITE;
|
||||
|
||||
DWORD shareMode = FILE_SHARE_READ;
|
||||
if (!(mode & std::ios::out))
|
||||
shareMode |= FILE_SHARE_WRITE;
|
||||
|
||||
DWORD creationDisp = OPEN_EXISTING;
|
||||
if (mode & std::ios::trunc)
|
||||
creationDisp = CREATE_ALWAYS;
|
||||
else if (mode & std::ios::out)
|
||||
creationDisp = OPEN_ALWAYS;
|
||||
|
||||
DWORD flags = FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
std::wstring utf16Path;
|
||||
FileImpl::convertPath(path, utf16Path);
|
||||
_handle = CreateFileW(utf16Path.c_str(), access, shareMode, NULL, creationDisp, flags, NULL);
|
||||
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
File::handleLastError(_path);
|
||||
|
||||
if ((mode & std::ios::ate) || (mode & std::ios::app))
|
||||
seekoff(0, std::ios::end, mode);
|
||||
}
|
||||
|
||||
|
||||
int FileStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == _handle || !(getMode() & std::ios::in))
|
||||
return -1;
|
||||
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
|
||||
DWORD bytesRead(0);
|
||||
BOOL rc = ReadFile(_handle, buffer, static_cast<DWORD>(length), &bytesRead, NULL);
|
||||
if (rc == 0)
|
||||
File::handleLastError(_path);
|
||||
|
||||
_pos += bytesRead;
|
||||
|
||||
return static_cast<int>(bytesRead);
|
||||
}
|
||||
|
||||
|
||||
int FileStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == _handle || !(getMode() & std::ios::out))
|
||||
return -1;
|
||||
|
||||
if (getMode() & std::ios::app)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = 0;
|
||||
li.LowPart = SetFilePointer(_handle, li.LowPart, &li.HighPart, FILE_END);
|
||||
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
File::handleLastError(_path);
|
||||
_pos = li.QuadPart;
|
||||
}
|
||||
|
||||
DWORD bytesWritten(0);
|
||||
BOOL rc = WriteFile(_handle, buffer, static_cast<DWORD>(length), &bytesWritten, NULL);
|
||||
if (rc == 0)
|
||||
File::handleLastError(_path);
|
||||
|
||||
_pos += bytesWritten;
|
||||
|
||||
return static_cast<int>(bytesWritten);
|
||||
}
|
||||
|
||||
|
||||
bool FileStreamBuf::close()
|
||||
{
|
||||
bool success = true;
|
||||
if (_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
CloseHandle(_handle);
|
||||
_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, std::ios::openmode mode)
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == _handle || !(getMode() & mode))
|
||||
return -1;
|
||||
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
|
||||
std::streamoff adj;
|
||||
if (mode & std::ios::in)
|
||||
adj = static_cast<std::streamoff>(egptr() - gptr());
|
||||
else
|
||||
adj = 0;
|
||||
|
||||
resetBuffers();
|
||||
|
||||
DWORD offset = FILE_BEGIN;
|
||||
if (dir == std::ios::cur)
|
||||
{
|
||||
offset = FILE_CURRENT;
|
||||
off -= adj;
|
||||
}
|
||||
else if (dir == std::ios::end)
|
||||
{
|
||||
offset = FILE_END;
|
||||
}
|
||||
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = off;
|
||||
li.LowPart = SetFilePointer(_handle, li.LowPart, &li.HighPart, offset);
|
||||
|
||||
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
File::handleLastError(_path);
|
||||
_pos = li.QuadPart;
|
||||
return std::streampos(static_cast<std::streamoff>(_pos));
|
||||
}
|
||||
|
||||
|
||||
std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mode)
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == _handle || !(getMode() & mode))
|
||||
return -1;
|
||||
|
||||
if (getMode() & std::ios::out)
|
||||
sync();
|
||||
|
||||
resetBuffers();
|
||||
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = pos;
|
||||
li.LowPart = SetFilePointer(_handle, li.LowPart, &li.HighPart, FILE_BEGIN);
|
||||
|
||||
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
File::handleLastError(_path);
|
||||
_pos = li.QuadPart;
|
||||
return std::streampos(static_cast<std::streamoff>(_pos));
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+532
@@ -0,0 +1,532 @@
|
||||
//
|
||||
// File_UNIX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: File
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/File_UNIX.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Error.h"
|
||||
#include <algorithm>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#if defined(POCO_OS_FAMILY_BSD)
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#elif (POCO_OS == POCO_OS_SOLARIS) || (POCO_OS == POCO_OS_QNX)
|
||||
#include <sys/statvfs.h>
|
||||
#else
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <utime.h>
|
||||
#include <cstring>
|
||||
|
||||
#if (POCO_OS == POCO_OS_SOLARIS) || (POCO_OS == POCO_OS_QNX)
|
||||
#define STATFSFN statvfs
|
||||
#define STATFSSTRUCT statvfs
|
||||
#else
|
||||
#define STATFSFN statfs
|
||||
#define STATFSSTRUCT statfs
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FileImpl::FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileImpl(const std::string& path): _path(path)
|
||||
{
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && _path[n - 1] == '/')
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::~FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::swapImpl(FileImpl& file)
|
||||
{
|
||||
std::swap(_path, file._path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setPathImpl(const std::string& path)
|
||||
{
|
||||
_path = path;
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && _path[n - 1] == '/')
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::existsImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
return stat(_path.c_str(), &st) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canReadImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
{
|
||||
if (st.st_uid == geteuid())
|
||||
return (st.st_mode & S_IRUSR) != 0;
|
||||
else if (st.st_gid == getegid())
|
||||
return (st.st_mode & S_IRGRP) != 0;
|
||||
else
|
||||
return (st.st_mode & S_IROTH) != 0 || geteuid() == 0;
|
||||
}
|
||||
else handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canWriteImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
{
|
||||
if (st.st_uid == geteuid())
|
||||
return (st.st_mode & S_IWUSR) != 0;
|
||||
else if (st.st_gid == getegid())
|
||||
return (st.st_mode & S_IWGRP) != 0;
|
||||
else
|
||||
return (st.st_mode & S_IWOTH) != 0 || geteuid() == 0;
|
||||
}
|
||||
else handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canExecuteImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
{
|
||||
if (st.st_uid == geteuid() || geteuid() == 0)
|
||||
return (st.st_mode & S_IXUSR) != 0;
|
||||
else if (st.st_gid == getegid())
|
||||
return (st.st_mode & S_IXGRP) != 0;
|
||||
else
|
||||
return (st.st_mode & S_IXOTH) != 0;
|
||||
}
|
||||
else handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isFileImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return S_ISREG(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDirectoryImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return S_ISDIR(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isLinkImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (lstat(_path.c_str(), &st) == 0)
|
||||
return S_ISLNK(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDeviceImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isHiddenImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
Path p(_path);
|
||||
p.makeFile();
|
||||
|
||||
return p.getFileName()[0] == '.';
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::createdImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
#if defined(__APPLE__) && defined(st_birthtime) && !defined(POCO_NO_STAT64) // st_birthtime is available only on 10.5
|
||||
struct stat64 st;
|
||||
if (stat64(_path.c_str(), &st) == 0)
|
||||
return Timestamp::fromEpochTime(st.st_birthtime);
|
||||
#elif defined(__FreeBSD__)
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return Timestamp::fromEpochTime(st.st_birthtime);
|
||||
#else
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return Timestamp::fromEpochTime(st.st_ctime);
|
||||
#endif
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::getLastModifiedImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return Timestamp::fromEpochTime(st.st_mtime);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setLastModifiedImpl(const Timestamp& ts)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct utimbuf tb;
|
||||
tb.actime = ts.epochTime();
|
||||
tb.modtime = ts.epochTime();
|
||||
if (utime(_path.c_str(), &tb) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) == 0)
|
||||
return st.st_size;
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setSizeImpl(FileSizeImpl size)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (truncate(_path.c_str(), size) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setWriteableImpl(bool flag)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
mode_t mode;
|
||||
if (flag)
|
||||
{
|
||||
mode = st.st_mode | S_IWUSR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_t wmask = S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
mode = st.st_mode & ~wmask;
|
||||
}
|
||||
if (chmod(_path.c_str(), mode) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setExecutableImpl(bool flag)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(_path.c_str(), &st) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
mode_t mode;
|
||||
if (flag)
|
||||
{
|
||||
mode = st.st_mode | S_IXUSR;
|
||||
if (st.st_mode & S_IRGRP)
|
||||
mode |= S_IXGRP;
|
||||
if (st.st_mode & S_IROTH)
|
||||
mode |= S_IXOTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_t wmask = S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
mode = st.st_mode & ~wmask;
|
||||
}
|
||||
if (chmod(_path.c_str(), mode) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::copyToImpl(const std::string& path, int options) const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int sd = open(_path.c_str(), O_RDONLY);
|
||||
if (sd == -1) handleLastErrorImpl(_path);
|
||||
|
||||
struct stat st;
|
||||
if (fstat(sd, &st) != 0)
|
||||
{
|
||||
close(sd);
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
const long blockSize = st.st_blksize;
|
||||
int dd;
|
||||
if (options & OPT_FAIL_ON_OVERWRITE_IMPL) {
|
||||
dd = open(path.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, st.st_mode);
|
||||
} else {
|
||||
dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode);
|
||||
}
|
||||
if (dd == -1)
|
||||
{
|
||||
close(sd);
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
Buffer<char> buffer(blockSize);
|
||||
try
|
||||
{
|
||||
int n;
|
||||
while ((n = read(sd, buffer.begin(), blockSize)) > 0)
|
||||
{
|
||||
if (write(dd, buffer.begin(), n) != n)
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
if (n < 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
close(sd);
|
||||
close(dd);
|
||||
throw;
|
||||
}
|
||||
close(sd);
|
||||
if (fsync(dd) != 0)
|
||||
{
|
||||
close(dd);
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
if (close(dd) != 0)
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::renameToImpl(const std::string& path, int options)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
|
||||
if (stat(path.c_str(), &st) == 0 && (options & OPT_FAIL_ON_OVERWRITE_IMPL))
|
||||
throw FileExistsException(path, EEXIST);
|
||||
|
||||
if (rename(_path.c_str(), path.c_str()) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::linkToImpl(const std::string& path, int type) const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
if (link(_path.c_str(), path.c_str()) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (symlink(_path.c_str(), path.c_str()) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::removeImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int rc;
|
||||
if (!isLinkImpl() && isDirectoryImpl())
|
||||
rc = rmdir(_path.c_str());
|
||||
else
|
||||
rc = unlink(_path.c_str());
|
||||
if (rc) handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createFileImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int n = open(_path.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if (n != -1)
|
||||
{
|
||||
close(n);
|
||||
return true;
|
||||
}
|
||||
if (n == -1 && errno == EEXIST)
|
||||
return false;
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createDirectoryImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (existsImpl() && isDirectoryImpl())
|
||||
return false;
|
||||
if (mkdir(_path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::totalSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
struct STATFSSTRUCT stats;
|
||||
if (STATFSFN(const_cast<char*>(_path.c_str()), &stats) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
|
||||
return (FileSizeImpl)stats.f_blocks * (FileSizeImpl)stats.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::usableSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
struct STATFSSTRUCT stats;
|
||||
if (STATFSFN(const_cast<char*>(_path.c_str()), &stats) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
|
||||
return (FileSizeImpl)stats.f_bavail * (FileSizeImpl)stats.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::freeSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
struct STATFSSTRUCT stats;
|
||||
if (STATFSFN(const_cast<char*>(_path.c_str()), &stats) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
|
||||
return (FileSizeImpl)stats.f_bfree * (FileSizeImpl)stats.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::handleLastErrorImpl(const std::string& path)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EIO:
|
||||
throw IOException(path, errno);
|
||||
case EPERM:
|
||||
throw FileAccessDeniedException("insufficient permissions", path, errno);
|
||||
case EACCES:
|
||||
throw FileAccessDeniedException(path, errno);
|
||||
case ENOENT:
|
||||
throw FileNotFoundException(path, errno);
|
||||
case ENOTDIR:
|
||||
throw OpenFileException("not a directory", path, errno);
|
||||
case EISDIR:
|
||||
throw OpenFileException("not a file", path, errno);
|
||||
case EROFS:
|
||||
throw FileReadOnlyException(path, errno);
|
||||
case EEXIST:
|
||||
throw FileExistsException(path, errno);
|
||||
case ENOSPC:
|
||||
throw FileException("no space left on device", path, errno);
|
||||
case EDQUOT:
|
||||
throw FileException("disk quota exceeded", path, errno);
|
||||
#if !defined(_AIX)
|
||||
case ENOTEMPTY:
|
||||
throw DirectoryNotEmptyException(path, errno);
|
||||
#endif
|
||||
case ENAMETOOLONG:
|
||||
throw PathSyntaxException(path, errno);
|
||||
case ENFILE:
|
||||
case EMFILE:
|
||||
throw FileException("too many open files", path, errno);
|
||||
default:
|
||||
throw FileException(Error::getMessage(errno), path, errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+419
@@ -0,0 +1,419 @@
|
||||
//
|
||||
// File_VX.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: File
|
||||
//
|
||||
// Copyright (c) 2004-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/File_VX.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <algorithm>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <utime.h>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FileImpl::FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileImpl(const std::string& path): _path(path)
|
||||
{
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && _path[n - 1] == '/')
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::~FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::swapImpl(FileImpl& file)
|
||||
{
|
||||
std::swap(_path, file._path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setPathImpl(const std::string& path)
|
||||
{
|
||||
_path = path;
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && _path[n - 1] == '/')
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::existsImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
return stat(const_cast<char*>(_path.c_str()), &st) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canReadImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canWriteImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canExecuteImpl() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isFileImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(const_cast<char*>(_path.c_str()), &st) == 0)
|
||||
return S_ISREG(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDirectoryImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(const_cast<char*>(_path.c_str()), &st) == 0)
|
||||
return S_ISDIR(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isLinkImpl() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDeviceImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(const_cast<char*>(_path.c_str()), &st) == 0)
|
||||
return S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isHiddenImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
Path p(_path);
|
||||
p.makeFile();
|
||||
|
||||
return p.getFileName()[0] == '.';
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::createdImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(const_cast<char*>(_path.c_str()), &st) == 0)
|
||||
return Timestamp::fromEpochTime(st.st_ctime);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::getLastModifiedImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(const_cast<char*>(_path.c_str()), &st) == 0)
|
||||
return Timestamp::fromEpochTime(st.st_mtime);
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setLastModifiedImpl(const Timestamp& ts)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct utimbuf tb;
|
||||
tb.actime = ts.epochTime();
|
||||
tb.modtime = ts.epochTime();
|
||||
if (utime(const_cast<char*>(_path.c_str()), &tb) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
if (stat(const_cast<char*>(_path.c_str()), &st) == 0)
|
||||
return st.st_size;
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setSizeImpl(FileSizeImpl size)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int fd = open(_path.c_str(), O_WRONLY, S_IRWXU);
|
||||
if (fd != -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ftruncate(fd, size) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
close(fd);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setWriteableImpl(bool flag)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setExecutableImpl(bool flag)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::copyToImpl(const std::string& path, int options) const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int sd = open(_path.c_str(), O_RDONLY, 0);
|
||||
if (sd == -1) handleLastErrorImpl(_path);
|
||||
|
||||
struct stat st;
|
||||
if (fstat(sd, &st) != 0)
|
||||
{
|
||||
close(sd);
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
const long blockSize = st.st_blksize;
|
||||
|
||||
int dd;
|
||||
if (options & OPT_FAIL_ON_OVERWRITE_IMPL) {
|
||||
dd = open(path.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, st.st_mode & S_IRWXU);
|
||||
} else {
|
||||
dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode & S_IRWXU);
|
||||
}
|
||||
|
||||
if (dd == -1)
|
||||
{
|
||||
close(sd);
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
Buffer<char> buffer(blockSize);
|
||||
try
|
||||
{
|
||||
int n;
|
||||
while ((n = read(sd, buffer.begin(), blockSize)) > 0)
|
||||
{
|
||||
if (write(dd, buffer.begin(), n) != n)
|
||||
handleLastErrorImpl(path);
|
||||
}
|
||||
if (n < 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
close(sd);
|
||||
close(dd);
|
||||
throw;
|
||||
}
|
||||
close(sd);
|
||||
close(dd);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::renameToImpl(const std::string& path, int options)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
struct stat st;
|
||||
|
||||
if (stat(path.c_str(), &st) == 0 && (options &OPT_FAIL_ON_OVERWRITE_IMPL))
|
||||
throw FileExistsException(path, EEXIST);
|
||||
|
||||
if (rename(_path.c_str(), path.c_str()) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::linkToImpl(const std::string& path, int type) const
|
||||
{
|
||||
throw Poco::NotImplementedException("File::linkTo() is not available on this platform");
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::removeImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int rc;
|
||||
if (!isLinkImpl() && isDirectoryImpl())
|
||||
rc = rmdir(_path.c_str());
|
||||
else
|
||||
rc = unlink(const_cast<char*>(_path.c_str()));
|
||||
if (rc) handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createFileImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
int n = open(_path.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if (n != -1)
|
||||
{
|
||||
close(n);
|
||||
return true;
|
||||
}
|
||||
if (n == -1 && errno == EEXIST)
|
||||
return false;
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createDirectoryImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (existsImpl() && isDirectoryImpl())
|
||||
return false;
|
||||
if (mkdir(_path.c_str()) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::totalSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
struct statfs stats;
|
||||
if (statfs(_path.c_str(), &stats) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
|
||||
return (FileSizeImpl)stats.f_blocks * (FileSizeImpl)stats.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::usableSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
struct statfs stats;
|
||||
if (statfs(_path.c_str(), &stats) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
|
||||
return (FileSizeImpl)stats.f_bavail * (FileSizeImpl)stats.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::freeSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
struct statfs stats;
|
||||
if (statfs(_path.c_str(), &stats) != 0)
|
||||
handleLastErrorImpl(_path);
|
||||
|
||||
return (FileSizeImpl)stats.f_bfree * (FileSizeImpl)stats.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::handleLastErrorImpl(const std::string& path)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EIO:
|
||||
throw IOException(path);
|
||||
case EPERM:
|
||||
throw FileAccessDeniedException("insufficient permissions", path);
|
||||
case EACCES:
|
||||
throw FileAccessDeniedException(path);
|
||||
case ENOENT:
|
||||
throw FileNotFoundException(path);
|
||||
case ENOTDIR:
|
||||
throw OpenFileException("not a directory", path);
|
||||
case EISDIR:
|
||||
throw OpenFileException("not a file", path);
|
||||
case EROFS:
|
||||
throw FileReadOnlyException(path);
|
||||
case EEXIST:
|
||||
throw FileExistsException(path);
|
||||
case ENOSPC:
|
||||
throw FileException("no space left on device", path);
|
||||
case ENOTEMPTY:
|
||||
throw DirectoryNotEmptyException(path);
|
||||
case ENAMETOOLONG:
|
||||
throw PathSyntaxException(path);
|
||||
case ENFILE:
|
||||
case EMFILE:
|
||||
throw FileException("too many open files", path);
|
||||
default:
|
||||
throw FileException(std::strerror(errno), path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+497
@@ -0,0 +1,497 @@
|
||||
//
|
||||
// File_WIN32U.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: File
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/File_WIN32U.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/UnWindows.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class FileHandle
|
||||
{
|
||||
public:
|
||||
FileHandle(const std::string& path, const std::wstring& upath, DWORD access, DWORD share, DWORD disp)
|
||||
{
|
||||
_h = CreateFileW(upath.c_str(), access, share, 0, disp, 0, 0);
|
||||
if (_h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(path);
|
||||
}
|
||||
}
|
||||
|
||||
~FileHandle()
|
||||
{
|
||||
if (_h != INVALID_HANDLE_VALUE) CloseHandle(_h);
|
||||
}
|
||||
|
||||
HANDLE get() const
|
||||
{
|
||||
return _h;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _h;
|
||||
};
|
||||
|
||||
|
||||
FileImpl::FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileImpl(const std::string& path): _path(path)
|
||||
{
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
|
||||
{
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
convertPath(_path, _upath);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::~FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::swapImpl(FileImpl& file)
|
||||
{
|
||||
std::swap(_path, file._path);
|
||||
std::swap(_upath, file._upath);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setPathImpl(const std::string& path)
|
||||
{
|
||||
_path = path;
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
|
||||
{
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
convertPath(_path, _upath);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::existsImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
case ERROR_NOT_READY:
|
||||
case ERROR_INVALID_DRIVE:
|
||||
return false;
|
||||
default:
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canReadImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return false;
|
||||
default:
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canWriteImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_READONLY) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canExecuteImpl() const
|
||||
{
|
||||
Path p(_path);
|
||||
return icompare(p.getExtension(), "exe") == 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isFileImpl() const
|
||||
{
|
||||
return !isDirectoryImpl() && !isDeviceImpl();
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDirectoryImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isLinkImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_DIRECTORY) == 0 && (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDeviceImpl() const
|
||||
{
|
||||
return
|
||||
_path.compare(0, 4, "\\\\.\\") == 0 ||
|
||||
icompare(_path, "CON") == 0 ||
|
||||
icompare(_path, "PRN") == 0 ||
|
||||
icompare(_path, "AUX") == 0 ||
|
||||
icompare(_path, "NUL") == 0 ||
|
||||
( (icompare(_path, 0, 3, "LPT") == 0 || icompare(_path, 0, 3, "COM") == 0) &&
|
||||
_path.size() == 4 &&
|
||||
_path[3] > 0x30 &&
|
||||
isdigit(_path[3])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isHiddenImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_HIDDEN) != 0;
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::createdImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return Timestamp::fromFileTimeNP(fad.ftCreationTime.dwLowDateTime, fad.ftCreationTime.dwHighDateTime);
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::getLastModifiedImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return Timestamp::fromFileTimeNP(fad.ftLastWriteTime.dwLowDateTime, fad.ftLastWriteTime.dwHighDateTime);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setLastModifiedImpl(const Timestamp& ts)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
UInt32 low;
|
||||
UInt32 high;
|
||||
ts.toFileTimeNP(low, high);
|
||||
FILETIME ft;
|
||||
ft.dwLowDateTime = low;
|
||||
ft.dwHighDateTime = high;
|
||||
FileHandle fh(_path, _upath, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
|
||||
if (SetFileTime(fh.get(), 0, &ft, &ft) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
LARGE_INTEGER li;
|
||||
li.LowPart = fad.nFileSizeLow;
|
||||
li.HighPart = fad.nFileSizeHigh;
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setSizeImpl(FileSizeImpl size)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
FileHandle fh(_path, _upath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = size;
|
||||
if (SetFilePointer(fh.get(), li.LowPart, &li.HighPart, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
handleLastErrorImpl(_path);
|
||||
if (SetEndOfFile(fh.get()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setWriteableImpl(bool flag)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == -1)
|
||||
handleLastErrorImpl(_path);
|
||||
if (flag)
|
||||
attr &= ~FILE_ATTRIBUTE_READONLY;
|
||||
else
|
||||
attr |= FILE_ATTRIBUTE_READONLY;
|
||||
if (SetFileAttributesW(_upath.c_str(), attr) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setExecutableImpl(bool flag)
|
||||
{
|
||||
// not supported
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::copyToImpl(const std::string& path, int options) const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
std::wstring upath;
|
||||
convertPath(path, upath);
|
||||
if (CopyFileW(_upath.c_str(), upath.c_str(), (options & OPT_FAIL_ON_OVERWRITE_IMPL) != 0) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::renameToImpl(const std::string& path, int options)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
std::wstring upath;
|
||||
convertPath(path, upath);
|
||||
if (options & OPT_FAIL_ON_OVERWRITE_IMPL) {
|
||||
if (MoveFileExW(_upath.c_str(), upath.c_str(), NULL) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
} else {
|
||||
if (MoveFileExW(_upath.c_str(), upath.c_str(), MOVEFILE_REPLACE_EXISTING) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::linkToImpl(const std::string& path, int type) const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
std::wstring upath;
|
||||
convertPath(path, upath);
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
if (CreateHardLinkW(upath.c_str(), _upath.c_str(), NULL) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if _WIN32_WINNT >= 0x0600 && defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
|
||||
DWORD flags = 0;
|
||||
if (isDirectoryImpl()) flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
|
||||
#ifdef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
|
||||
flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
|
||||
#endif
|
||||
if (CreateSymbolicLinkW(upath.c_str(), _upath.c_str(), flags) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
#else
|
||||
throw Poco::NotImplementedException("Symbolic link support not available in used version of the Windows SDK");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::removeImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (isDirectoryImpl())
|
||||
{
|
||||
if (RemoveDirectoryW(_upath.c_str()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DeleteFileW(_upath.c_str()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createFileImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
HANDLE hFile = CreateFileW(_upath.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return true;
|
||||
}
|
||||
else if (GetLastError() == ERROR_FILE_EXISTS)
|
||||
return false;
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createDirectoryImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (existsImpl() && isDirectoryImpl())
|
||||
return false;
|
||||
if (CreateDirectoryW(_upath.c_str(), 0) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::totalSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
ULARGE_INTEGER space;
|
||||
if (!GetDiskFreeSpaceExW(_upath.c_str(), NULL, &space, NULL))
|
||||
handleLastErrorImpl(_path);
|
||||
return space.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::usableSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
ULARGE_INTEGER space;
|
||||
if (!GetDiskFreeSpaceExW(_upath.c_str(), &space, NULL, NULL))
|
||||
handleLastErrorImpl(_path);
|
||||
return space.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::freeSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
ULARGE_INTEGER space;
|
||||
if (!GetDiskFreeSpaceExW(_upath.c_str(), NULL, NULL, &space))
|
||||
handleLastErrorImpl(_path);
|
||||
return space.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::handleLastErrorImpl(const std::string& path)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
switch (err)
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
throw FileNotFoundException(path, err);
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
case ERROR_BAD_NETPATH:
|
||||
case ERROR_CANT_RESOLVE_FILENAME:
|
||||
case ERROR_INVALID_DRIVE:
|
||||
throw PathNotFoundException(path, err);
|
||||
case ERROR_ACCESS_DENIED:
|
||||
throw FileAccessDeniedException(path, err);
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
case ERROR_FILE_EXISTS:
|
||||
throw FileExistsException(path, err);
|
||||
case ERROR_INVALID_NAME:
|
||||
case ERROR_DIRECTORY:
|
||||
case ERROR_FILENAME_EXCED_RANGE:
|
||||
case ERROR_BAD_PATHNAME:
|
||||
throw PathSyntaxException(path, err);
|
||||
case ERROR_FILE_READ_ONLY:
|
||||
throw FileReadOnlyException(path, err);
|
||||
case ERROR_CANNOT_MAKE:
|
||||
throw CreateFileException(path, err);
|
||||
case ERROR_DIR_NOT_EMPTY:
|
||||
throw DirectoryNotEmptyException(path, err);
|
||||
case ERROR_WRITE_FAULT:
|
||||
throw WriteFileException(path, err);
|
||||
case ERROR_READ_FAULT:
|
||||
throw ReadFileException(path, err);
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
throw FileException("sharing violation", path, err);
|
||||
case ERROR_LOCK_VIOLATION:
|
||||
throw FileException("lock violation", path, err);
|
||||
case ERROR_HANDLE_EOF:
|
||||
throw ReadFileException("EOF reached", path, err);
|
||||
case ERROR_HANDLE_DISK_FULL:
|
||||
case ERROR_DISK_FULL:
|
||||
throw WriteFileException("disk is full", path, err);
|
||||
case ERROR_NEGATIVE_SEEK:
|
||||
throw FileException("negative seek", path, err);
|
||||
default:
|
||||
throw FileException(path, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::convertPath(const std::string& utf8Path, std::wstring& utf16Path)
|
||||
{
|
||||
UnicodeConverter::toUTF16(utf8Path, utf16Path);
|
||||
if (utf16Path.size() > MAX_PATH - 12) // Note: CreateDirectory has a limit of MAX_PATH - 12 (room for 8.3 file name)
|
||||
{
|
||||
if (utf16Path[0] == '\\' || utf16Path[1] == ':')
|
||||
{
|
||||
if (utf16Path.compare(0, 4, L"\\\\?\\", 4) != 0)
|
||||
{
|
||||
if (utf16Path[1] == '\\')
|
||||
utf16Path.insert(0, L"\\\\?\\UNC\\", 8);
|
||||
else
|
||||
utf16Path.insert(0, L"\\\\?\\", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Poco
|
||||
+447
@@ -0,0 +1,447 @@
|
||||
//
|
||||
// File_WIN32U.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: File
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/File_WINCE.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/UnWindows.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class FileHandle
|
||||
{
|
||||
public:
|
||||
FileHandle(const std::string& path, const std::wstring& upath, DWORD access, DWORD share, DWORD disp)
|
||||
{
|
||||
_h = CreateFileW(upath.c_str(), access, share, 0, disp, 0, 0);
|
||||
if (_h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(path);
|
||||
}
|
||||
}
|
||||
|
||||
~FileHandle()
|
||||
{
|
||||
if (_h != INVALID_HANDLE_VALUE) CloseHandle(_h);
|
||||
}
|
||||
|
||||
HANDLE get() const
|
||||
{
|
||||
return _h;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _h;
|
||||
};
|
||||
|
||||
|
||||
FileImpl::FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileImpl(const std::string& path): _path(path)
|
||||
{
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
|
||||
{
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
convertPath(_path, _upath);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::~FileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::swapImpl(FileImpl& file)
|
||||
{
|
||||
std::swap(_path, file._path);
|
||||
std::swap(_upath, file._upath);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setPathImpl(const std::string& path)
|
||||
{
|
||||
_path = path;
|
||||
std::string::size_type n = _path.size();
|
||||
if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
|
||||
{
|
||||
_path.resize(n - 1);
|
||||
}
|
||||
convertPath(_path, _upath);
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::existsImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
case ERROR_NOT_READY:
|
||||
case ERROR_INVALID_DRIVE:
|
||||
return false;
|
||||
default:
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canReadImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return false;
|
||||
default:
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canWriteImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_READONLY) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::canExecuteImpl() const
|
||||
{
|
||||
Path p(_path);
|
||||
return icompare(p.getExtension(), "exe") == 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isFileImpl() const
|
||||
{
|
||||
return !isDirectoryImpl() && !isDeviceImpl();
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDirectoryImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isLinkImpl() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isDeviceImpl() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::isHiddenImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
handleLastErrorImpl(_path);
|
||||
return (attr & FILE_ATTRIBUTE_HIDDEN) != 0;
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::createdImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return Timestamp::fromFileTimeNP(fad.ftCreationTime.dwLowDateTime, fad.ftCreationTime.dwHighDateTime);
|
||||
}
|
||||
|
||||
|
||||
Timestamp FileImpl::getLastModifiedImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return Timestamp::fromFileTimeNP(fad.ftLastWriteTime.dwLowDateTime, fad.ftLastWriteTime.dwHighDateTime);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setLastModifiedImpl(const Timestamp& ts)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
UInt32 low;
|
||||
UInt32 high;
|
||||
ts.toFileTimeNP(low, high);
|
||||
FILETIME ft;
|
||||
ft.dwLowDateTime = low;
|
||||
ft.dwHighDateTime = high;
|
||||
FileHandle fh(_path, _upath, GENERIC_WRITE, FILE_SHARE_WRITE, OPEN_EXISTING);
|
||||
if (SetFileTime(fh.get(), 0, &ft, &ft) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
LARGE_INTEGER li;
|
||||
li.LowPart = fad.nFileSizeLow;
|
||||
li.HighPart = fad.nFileSizeHigh;
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setSizeImpl(FileSizeImpl size)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
FileHandle fh(_path, _upath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = size;
|
||||
if (SetFilePointer(fh.get(), li.LowPart, &li.HighPart, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
handleLastErrorImpl(_path);
|
||||
if (SetEndOfFile(fh.get()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setWriteableImpl(bool flag)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
DWORD attr = GetFileAttributesW(_upath.c_str());
|
||||
if (attr == -1)
|
||||
handleLastErrorImpl(_path);
|
||||
if (flag)
|
||||
attr &= ~FILE_ATTRIBUTE_READONLY;
|
||||
else
|
||||
attr |= FILE_ATTRIBUTE_READONLY;
|
||||
if (SetFileAttributesW(_upath.c_str(), attr) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::setExecutableImpl(bool flag)
|
||||
{
|
||||
// not supported
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::copyToImpl(const std::string& path, int options) const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
std::wstring upath;
|
||||
convertPath(path, upath);
|
||||
if (CopyFileW(_upath.c_str(), upath.c_str(), (options & OPT_FAIL_ON_OVERWRITE_IMPL) != 0) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::renameToImpl(const std::string& path, int options)
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
std::wstring upath;
|
||||
convertPath(path, upath);
|
||||
if (options & OPT_FAIL_ON_OVERWRITE_IMPL) {
|
||||
if (MoveFileW(_upath.c_str(), upath.c_str()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
} else {
|
||||
if (MoveFileW(_upath.c_str(), upath.c_str(), MOVEFILE_REPLACE_EXISTING) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::linkToImpl(const std::string& path, int type) const
|
||||
{
|
||||
throw Poco::NotImplementedException("File::linkTo() is not available on this platform");
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::removeImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (isDirectoryImpl())
|
||||
{
|
||||
if (RemoveDirectoryW(_upath.c_str()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DeleteFileW(_upath.c_str()) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createFileImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
HANDLE hFile = CreateFileW(_upath.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return true;
|
||||
}
|
||||
else if (GetLastError() == ERROR_FILE_EXISTS)
|
||||
return false;
|
||||
else
|
||||
handleLastErrorImpl(_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileImpl::createDirectoryImpl()
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
if (existsImpl() && isDirectoryImpl())
|
||||
return false;
|
||||
if (CreateDirectoryW(_upath.c_str(), 0) == 0)
|
||||
handleLastErrorImpl(_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::totalSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
ULARGE_INTEGER space;
|
||||
if (!GetDiskFreeSpaceExW(_upath.c_str(), NULL, &space, NULL))
|
||||
handleLastErrorImpl(_path);
|
||||
return space.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::usableSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
ULARGE_INTEGER space;
|
||||
if (!GetDiskFreeSpaceExW(_upath.c_str(), &space, NULL, NULL))
|
||||
handleLastErrorImpl(_path);
|
||||
return space.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
FileImpl::FileSizeImpl FileImpl::freeSpaceImpl() const
|
||||
{
|
||||
poco_assert(!_path.empty());
|
||||
|
||||
ULARGE_INTEGER space;
|
||||
if (!GetDiskFreeSpaceExW(_upath.c_str(), NULL, NULL, &space))
|
||||
handleLastErrorImpl(_path);
|
||||
return space.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::handleLastErrorImpl(const std::string& path)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
throw FileNotFoundException(path);
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
case ERROR_BAD_NETPATH:
|
||||
case ERROR_CANT_RESOLVE_FILENAME:
|
||||
case ERROR_INVALID_DRIVE:
|
||||
throw PathNotFoundException(path);
|
||||
case ERROR_ACCESS_DENIED:
|
||||
throw FileAccessDeniedException(path);
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
case ERROR_FILE_EXISTS:
|
||||
throw FileExistsException(path);
|
||||
case ERROR_INVALID_NAME:
|
||||
case ERROR_DIRECTORY:
|
||||
case ERROR_FILENAME_EXCED_RANGE:
|
||||
case ERROR_BAD_PATHNAME:
|
||||
throw PathSyntaxException(path);
|
||||
case ERROR_FILE_READ_ONLY:
|
||||
throw FileReadOnlyException(path);
|
||||
case ERROR_CANNOT_MAKE:
|
||||
throw CreateFileException(path);
|
||||
case ERROR_DIR_NOT_EMPTY:
|
||||
throw DirectoryNotEmptyException(path);
|
||||
case ERROR_WRITE_FAULT:
|
||||
throw WriteFileException(path);
|
||||
case ERROR_READ_FAULT:
|
||||
throw ReadFileException(path);
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
throw FileException("sharing violation", path);
|
||||
case ERROR_LOCK_VIOLATION:
|
||||
throw FileException("lock violation", path);
|
||||
case ERROR_HANDLE_EOF:
|
||||
throw ReadFileException("EOF reached", path);
|
||||
case ERROR_HANDLE_DISK_FULL:
|
||||
case ERROR_DISK_FULL:
|
||||
throw WriteFileException("disk is full", path);
|
||||
case ERROR_NEGATIVE_SEEK:
|
||||
throw FileException("negative seek", path);
|
||||
default:
|
||||
throw FileException(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileImpl::convertPath(const std::string& utf8Path, std::wstring& utf16Path)
|
||||
{
|
||||
UnicodeConverter::toUTF16(utf8Path, utf16Path);
|
||||
}
|
||||
|
||||
} // namespace Poco
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
//
|
||||
// Format.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Format
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Ascii.h"
|
||||
#include <sstream>
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
#include <locale>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
void parseFlags(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
|
||||
{
|
||||
bool isFlag = true;
|
||||
while (isFlag && itFmt != endFmt)
|
||||
{
|
||||
switch (*itFmt)
|
||||
{
|
||||
case '-': str.setf(std::ios::left); ++itFmt; break;
|
||||
case '+': str.setf(std::ios::showpos); ++itFmt; break;
|
||||
case '0': str.fill('0'); str.setf(std::ios::internal); ++itFmt; break;
|
||||
case '#': str.setf(std::ios::showpoint | std::ios::showbase); ++itFmt; break;
|
||||
default: isFlag = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parseWidth(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
|
||||
{
|
||||
int width = 0;
|
||||
if (itFmt != endFmt && *itFmt == '*')
|
||||
{
|
||||
++itFmt;
|
||||
width = AnyCast<int>(*itVal++);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
{
|
||||
width = 10*width + *itFmt - '0';
|
||||
++itFmt;
|
||||
}
|
||||
}
|
||||
if (width > 0) str.width(width);
|
||||
}
|
||||
|
||||
|
||||
void parsePrec(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
|
||||
{
|
||||
if (itFmt != endFmt && *itFmt == '.')
|
||||
{
|
||||
++itFmt;
|
||||
int prec = 0;
|
||||
if (itFmt != endFmt && *itFmt == '*')
|
||||
{
|
||||
++itFmt;
|
||||
prec = AnyCast<int>(*itVal++);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
{
|
||||
prec = 10*prec + *itFmt - '0';
|
||||
++itFmt;
|
||||
}
|
||||
}
|
||||
if (prec >= 0) str.precision(prec);
|
||||
}
|
||||
}
|
||||
|
||||
char parseMod(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
|
||||
{
|
||||
char mod = 0;
|
||||
if (itFmt != endFmt)
|
||||
{
|
||||
switch (*itFmt)
|
||||
{
|
||||
case 'l':
|
||||
case 'h':
|
||||
case 'L':
|
||||
case '?': mod = *itFmt++; break;
|
||||
}
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
|
||||
std::size_t parseIndex(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
|
||||
{
|
||||
int index = 0;
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
{
|
||||
index = 10*index + *itFmt - '0';
|
||||
++itFmt;
|
||||
}
|
||||
if (itFmt != endFmt && *itFmt == ']') ++itFmt;
|
||||
return index;
|
||||
}
|
||||
|
||||
void prepareFormat(std::ostream& str, char type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 'd':
|
||||
case 'i': str << std::dec; break;
|
||||
case 'o': str << std::oct; break;
|
||||
case 'x': str << std::hex; break;
|
||||
case 'X': str << std::hex << std::uppercase; break;
|
||||
case 'e': str << std::scientific; break;
|
||||
case 'E': str << std::scientific << std::uppercase; break;
|
||||
case 'f': str << std::fixed; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeAnyInt(std::ostream& str, const Any& any)
|
||||
{
|
||||
if (any.type() == typeid(char))
|
||||
str << static_cast<int>(AnyCast<char>(any));
|
||||
else if (any.type() == typeid(signed char))
|
||||
str << static_cast<int>(AnyCast<signed char>(any));
|
||||
else if (any.type() == typeid(unsigned char))
|
||||
str << static_cast<unsigned>(AnyCast<unsigned char>(any));
|
||||
else if (any.type() == typeid(short))
|
||||
str << AnyCast<short>(any);
|
||||
else if (any.type() == typeid(unsigned short))
|
||||
str << AnyCast<unsigned short>(any);
|
||||
else if (any.type() == typeid(int))
|
||||
str << AnyCast<int>(any);
|
||||
else if (any.type() == typeid(unsigned int))
|
||||
str << AnyCast<unsigned int>(any);
|
||||
else if (any.type() == typeid(long))
|
||||
str << AnyCast<long>(any);
|
||||
else if (any.type() == typeid(unsigned long))
|
||||
str << AnyCast<unsigned long>(any);
|
||||
else if (any.type() == typeid(Int64))
|
||||
str << AnyCast<Int64>(any);
|
||||
else if (any.type() == typeid(UInt64))
|
||||
str << AnyCast<UInt64>(any);
|
||||
else if (any.type() == typeid(bool))
|
||||
str << AnyCast<bool>(any);
|
||||
}
|
||||
|
||||
|
||||
void formatOne(std::string& result, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
|
||||
{
|
||||
std::ostringstream str;
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
str.imbue(std::locale::classic());
|
||||
#endif
|
||||
try
|
||||
{
|
||||
parseFlags(str, itFmt, endFmt);
|
||||
parseWidth(str, itFmt, endFmt, itVal);
|
||||
parsePrec(str, itFmt, endFmt, itVal);
|
||||
char mod = parseMod(itFmt, endFmt);
|
||||
if (itFmt != endFmt)
|
||||
{
|
||||
char type = *itFmt++;
|
||||
prepareFormat(str, type);
|
||||
switch (type)
|
||||
{
|
||||
case 'b':
|
||||
str << AnyCast<bool>(*itVal++);
|
||||
break;
|
||||
case 'c':
|
||||
str << AnyCast<char>(*itVal++);
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<long>(*itVal++); break;
|
||||
case 'L': str << AnyCast<Int64>(*itVal++); break;
|
||||
case 'h': str << AnyCast<short>(*itVal++); break;
|
||||
case '?': writeAnyInt(str, *itVal++); break;
|
||||
default: str << AnyCast<int>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<unsigned long>(*itVal++); break;
|
||||
case 'L': str << AnyCast<UInt64>(*itVal++); break;
|
||||
case 'h': str << AnyCast<unsigned short>(*itVal++); break;
|
||||
case '?': writeAnyInt(str, *itVal++); break;
|
||||
default: str << AnyCast<unsigned>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<long double>(*itVal++); break;
|
||||
case 'L': str << AnyCast<long double>(*itVal++); break;
|
||||
case 'h': str << AnyCast<float>(*itVal++); break;
|
||||
default: str << AnyCast<double>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
str << RefAnyCast<std::string>(*itVal++);
|
||||
break;
|
||||
case 'z':
|
||||
str << AnyCast<std::size_t>(*itVal++);
|
||||
break;
|
||||
case 'I':
|
||||
case 'D':
|
||||
default:
|
||||
str << type;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Poco::BadCastException&)
|
||||
{
|
||||
str << "[ERRFMT]";
|
||||
}
|
||||
result.append(str.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string format(const std::string& fmt, const Any& value)
|
||||
{
|
||||
std::string result;
|
||||
format(result, fmt, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void format(std::string& result, const char *fmt, const std::vector<Any>& values)
|
||||
{
|
||||
format(result, std::string(fmt), values);
|
||||
}
|
||||
|
||||
|
||||
void format(std::string& result, const std::string& fmt, const std::vector<Any>& values)
|
||||
{
|
||||
std::string::const_iterator itFmt = fmt.begin();
|
||||
std::string::const_iterator endFmt = fmt.end();
|
||||
std::vector<Any>::const_iterator itVal = values.begin();
|
||||
std::vector<Any>::const_iterator endVal = values.end();
|
||||
while (itFmt != endFmt)
|
||||
{
|
||||
switch (*itFmt)
|
||||
{
|
||||
case '%':
|
||||
++itFmt;
|
||||
if (itFmt != endFmt && (itVal != endVal || *itFmt == '['))
|
||||
{
|
||||
if (*itFmt == '[')
|
||||
{
|
||||
++itFmt;
|
||||
std::size_t index = parseIndex(itFmt, endFmt);
|
||||
if (index < values.size())
|
||||
{
|
||||
std::vector<Any>::const_iterator it = values.begin() + index;
|
||||
formatOne(result, itFmt, endFmt, it);
|
||||
}
|
||||
else throw InvalidArgumentException("format argument index out of range", fmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatOne(result, itFmt, endFmt, itVal);
|
||||
}
|
||||
}
|
||||
else if (itFmt != endFmt)
|
||||
{
|
||||
result += *itFmt++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result += *itFmt;
|
||||
++itFmt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Formatter.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: Formatter
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Formatter.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Formatter::Formatter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Formatter::~Formatter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Formatter::setProperty(const std::string& /*name*/, const std::string& /*value*/)
|
||||
{
|
||||
throw PropertyNotSupportedException();
|
||||
}
|
||||
|
||||
|
||||
std::string Formatter::getProperty(const std::string& /*name*/) const
|
||||
{
|
||||
throw PropertyNotSupportedException();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// FormattingChannel.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: Formatter
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/FormattingChannel.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/LoggingRegistry.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
FormattingChannel::FormattingChannel():
|
||||
_pFormatter(0),
|
||||
_pChannel(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FormattingChannel::FormattingChannel(Formatter::Ptr pFormatter):
|
||||
_pFormatter(pFormatter),
|
||||
_pChannel(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FormattingChannel::FormattingChannel(Formatter::Ptr pFormatter, Channel::Ptr pChannel):
|
||||
_pFormatter(pFormatter),
|
||||
_pChannel(pChannel)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FormattingChannel::~FormattingChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FormattingChannel::setFormatter(Formatter::Ptr pFormatter)
|
||||
{
|
||||
_pFormatter = pFormatter;
|
||||
}
|
||||
|
||||
|
||||
Formatter::Ptr FormattingChannel::getFormatter() const
|
||||
{
|
||||
return _pFormatter;
|
||||
}
|
||||
|
||||
|
||||
void FormattingChannel::setChannel(Channel::Ptr pChannel)
|
||||
{
|
||||
_pChannel = pChannel;
|
||||
}
|
||||
|
||||
|
||||
Channel::Ptr FormattingChannel::getChannel() const
|
||||
{
|
||||
return _pChannel;
|
||||
}
|
||||
|
||||
|
||||
void FormattingChannel::log(const Message& msg)
|
||||
{
|
||||
if (_pChannel)
|
||||
{
|
||||
if (_pFormatter)
|
||||
{
|
||||
std::string text;
|
||||
_pFormatter->format(msg, text);
|
||||
_pChannel->log(Message(msg, text));
|
||||
}
|
||||
else
|
||||
{
|
||||
_pChannel->log(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FormattingChannel::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name == "channel")
|
||||
setChannel(LoggingRegistry::defaultRegistry().channelForName(value));
|
||||
else if (name == "formatter")
|
||||
setFormatter(LoggingRegistry::defaultRegistry().formatterForName(value));
|
||||
else if (_pChannel)
|
||||
_pChannel->setProperty(name, value);
|
||||
}
|
||||
|
||||
|
||||
void FormattingChannel::open()
|
||||
{
|
||||
if (_pChannel)
|
||||
_pChannel->open();
|
||||
}
|
||||
|
||||
|
||||
void FormattingChannel::close()
|
||||
{
|
||||
if (_pChannel)
|
||||
_pChannel->close();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+285
@@ -0,0 +1,285 @@
|
||||
//
|
||||
// Glob.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: Glob
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Glob.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/DirectoryIterator.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/UTF8Encoding.h"
|
||||
#include "Poco/Unicode.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Glob::Glob(const std::string& pattern, int options)
|
||||
: _pattern(pattern), _options(options)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Glob::~Glob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Glob::match(const std::string& subject)
|
||||
{
|
||||
UTF8Encoding utf8;
|
||||
TextIterator itp(_pattern, utf8);
|
||||
TextIterator endp(_pattern);
|
||||
TextIterator its(subject, utf8);
|
||||
TextIterator ends(subject);
|
||||
|
||||
if ((_options & GLOB_DOT_SPECIAL) && its != ends && *its == '.' && (*itp == '?' || *itp == '*'))
|
||||
return false;
|
||||
else
|
||||
return match(itp, endp, its, ends);
|
||||
}
|
||||
|
||||
|
||||
void Glob::glob(const std::string& pathPattern, std::set<std::string>& files, int options)
|
||||
{
|
||||
glob(Path(Path::expand(pathPattern), Path::PATH_GUESS), files, options);
|
||||
}
|
||||
|
||||
|
||||
void Glob::glob(const char* pathPattern, std::set<std::string>& files, int options)
|
||||
{
|
||||
glob(Path(Path::expand(pathPattern), Path::PATH_GUESS), files, options);
|
||||
}
|
||||
|
||||
|
||||
void Glob::glob(const Path& pathPattern, std::set<std::string>& files, int options)
|
||||
{
|
||||
Path pattern(pathPattern);
|
||||
pattern.makeDirectory(); // to simplify pattern handling later on
|
||||
Path base(pattern);
|
||||
Path absBase(base);
|
||||
absBase.makeAbsolute();
|
||||
// In case of UNC paths we must not pop the topmost directory
|
||||
// (which must not contain wildcards), otherwise collect() will fail
|
||||
// as one cannot create a DirectoryIterator with only a node name ("\\srv\").
|
||||
int minDepth = base.getNode().empty() ? 0 : 1;
|
||||
while (base.depth() > minDepth && base[base.depth() - 1] != "..")
|
||||
{
|
||||
base.popDirectory();
|
||||
absBase.popDirectory();
|
||||
}
|
||||
if (pathPattern.isDirectory())
|
||||
options |= GLOB_DIRS_ONLY;
|
||||
collect(pattern, absBase, base, pathPattern[base.depth()], files, options);
|
||||
}
|
||||
|
||||
|
||||
void Glob::glob(const Path& pathPattern, const Path& basePath, std::set<std::string>& files, int options)
|
||||
{
|
||||
Path pattern(pathPattern);
|
||||
pattern.makeDirectory(); // to simplify pattern handling later on
|
||||
Path absBase(basePath);
|
||||
absBase.makeAbsolute();
|
||||
if (pathPattern.isDirectory())
|
||||
options |= GLOB_DIRS_ONLY;
|
||||
collect(pattern, absBase, basePath, pathPattern[basePath.depth()], files, options);
|
||||
}
|
||||
|
||||
|
||||
bool Glob::match(TextIterator& itp, const TextIterator& endp, TextIterator& its, const TextIterator& ends)
|
||||
{
|
||||
while (itp != endp)
|
||||
{
|
||||
if (its == ends)
|
||||
{
|
||||
while (itp != endp && *itp == '*') ++itp;
|
||||
break;
|
||||
}
|
||||
switch (*itp)
|
||||
{
|
||||
case '?':
|
||||
++itp; ++its;
|
||||
break;
|
||||
case '*':
|
||||
if (++itp != endp)
|
||||
{
|
||||
while (its != ends && !matchAfterAsterisk(itp, endp, its, ends)) ++its;
|
||||
return its != ends;
|
||||
}
|
||||
return true;
|
||||
case '[':
|
||||
if (++itp != endp)
|
||||
{
|
||||
bool invert = *itp == '!';
|
||||
if (invert) ++itp;
|
||||
if (itp != endp)
|
||||
{
|
||||
bool mtch = matchSet(itp, endp, *its++);
|
||||
if ((invert && mtch) || (!invert && !mtch)) return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw SyntaxException("bad range syntax in glob pattern");
|
||||
case '\\':
|
||||
if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern");
|
||||
// fallthrough
|
||||
default:
|
||||
if (_options & GLOB_CASELESS)
|
||||
{
|
||||
if (Unicode::toLower(*itp) != Unicode::toLower(*its)) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*itp != *its) return false;
|
||||
}
|
||||
++itp; ++its;
|
||||
}
|
||||
}
|
||||
return itp == endp && its == ends;
|
||||
}
|
||||
|
||||
|
||||
bool Glob::matchAfterAsterisk(TextIterator itp, const TextIterator& endp, TextIterator its, const TextIterator& ends)
|
||||
{
|
||||
return match(itp, endp, its, ends);
|
||||
}
|
||||
|
||||
|
||||
bool Glob::matchSet(TextIterator& itp, const TextIterator& endp, int c)
|
||||
{
|
||||
if (_options & GLOB_CASELESS)
|
||||
c = Unicode::toLower(c);
|
||||
|
||||
while (itp != endp)
|
||||
{
|
||||
switch (*itp)
|
||||
{
|
||||
case ']':
|
||||
++itp;
|
||||
return false;
|
||||
case '\\':
|
||||
if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern");
|
||||
}
|
||||
int first = *itp;
|
||||
int last = first;
|
||||
if (++itp != endp && *itp == '-')
|
||||
{
|
||||
if (++itp != endp)
|
||||
last = *itp++;
|
||||
else
|
||||
throw SyntaxException("bad range syntax in glob pattern");
|
||||
}
|
||||
if (_options & GLOB_CASELESS)
|
||||
{
|
||||
first = Unicode::toLower(first);
|
||||
last = Unicode::toLower(last);
|
||||
}
|
||||
if (first <= c && c <= last)
|
||||
{
|
||||
while (itp != endp)
|
||||
{
|
||||
switch (*itp)
|
||||
{
|
||||
case ']':
|
||||
++itp;
|
||||
return true;
|
||||
case '\\':
|
||||
if (++itp == endp) break;
|
||||
default:
|
||||
++itp;
|
||||
}
|
||||
}
|
||||
throw SyntaxException("range must be terminated by closing bracket in glob pattern");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Glob::collect(const Path& pathPattern, const Path& base, const Path& current, const std::string& pattern, std::set<std::string>& files, int options)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string pp = pathPattern.toString();
|
||||
std::string basep = base.toString();
|
||||
std::string curp = current.toString();
|
||||
Glob g(pattern, options);
|
||||
DirectoryIterator it(base);
|
||||
DirectoryIterator end;
|
||||
while (it != end)
|
||||
{
|
||||
const std::string& name = it.name();
|
||||
if (g.match(name))
|
||||
{
|
||||
Path p(current);
|
||||
if (p.depth() < pathPattern.depth() - 1)
|
||||
{
|
||||
p.pushDirectory(name);
|
||||
collect(pathPattern, it.path(), p, pathPattern[p.depth()], files, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.setFileName(name);
|
||||
if (isDirectory(p, (options & GLOB_FOLLOW_SYMLINKS) != 0))
|
||||
{
|
||||
p.makeDirectory();
|
||||
files.insert(p.toString());
|
||||
}
|
||||
else if (!(options & GLOB_DIRS_ONLY))
|
||||
{
|
||||
files.insert(p.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Glob::isDirectory(const Path& path, bool followSymlink)
|
||||
{
|
||||
File f(path);
|
||||
bool isDir = false;
|
||||
try
|
||||
{
|
||||
isDir = f.isDirectory();
|
||||
}
|
||||
catch (Poco::Exception&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (isDir)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (followSymlink && f.isLink())
|
||||
{
|
||||
try
|
||||
{
|
||||
// Test if link resolves to a directory.
|
||||
DirectoryIterator it(f);
|
||||
return true;
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Hash.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Hashing
|
||||
// Module: Hash
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Hash.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
std::size_t hash(const std::string& str)
|
||||
{
|
||||
std::size_t h = 0;
|
||||
std::string::const_iterator it = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
while (it != end)
|
||||
{
|
||||
h = h * 0xf4243 ^ *it++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// HashStatistic.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Hashing
|
||||
// Module: HashStatistic
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/HashStatistic.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
HashStatistic::HashStatistic(
|
||||
UInt32 tableSize,
|
||||
UInt32 numEntries,
|
||||
UInt32 numZeroEntries,
|
||||
UInt32 maxEntry,
|
||||
std::vector<UInt32> details):
|
||||
_sizeOfTable(tableSize),
|
||||
_numberOfEntries(numEntries),
|
||||
_numZeroEntries(numZeroEntries),
|
||||
_maxEntriesPerHash(maxEntry),
|
||||
_detailedEntriesPerHash(details)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HashStatistic::~HashStatistic()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::string HashStatistic::toString() const
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "HashTable of size " << _sizeOfTable << " containing " << _numberOfEntries << " entries:\n";
|
||||
str << " NumberOfZeroEntries: " << _numZeroEntries << "\n";
|
||||
str << " MaxEntry: " << _maxEntriesPerHash << "\n";
|
||||
str << " AvgEntry: " << avgEntriesPerHash() << ", excl Zero slots: " << avgEntriesPerHashExclZeroEntries() << "\n";
|
||||
str << " DetailedStatistics: \n";
|
||||
for (int i = 0; i < _detailedEntriesPerHash.size(); ++i)
|
||||
{
|
||||
// 10 entries per line
|
||||
if (i % 10 == 0)
|
||||
{
|
||||
str << "\n " << i << ":";
|
||||
}
|
||||
str << " " << _detailedEntriesPerHash[i];
|
||||
}
|
||||
str << "\n";
|
||||
str.flush();
|
||||
return str.str();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// HexBinaryDecoder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: HexBinary
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/HexBinaryDecoder.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
HexBinaryDecoderBuf::HexBinaryDecoderBuf(std::istream& istr):
|
||||
_buf(*istr.rdbuf())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HexBinaryDecoderBuf::~HexBinaryDecoderBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int HexBinaryDecoderBuf::readFromDevice()
|
||||
{
|
||||
int c;
|
||||
int n;
|
||||
if ((n = readOne()) == -1) return -1;
|
||||
if (n >= '0' && n <= '9')
|
||||
c = n - '0';
|
||||
else if (n >= 'A' && n <= 'F')
|
||||
c = n - 'A' + 10;
|
||||
else if (n >= 'a' && n <= 'f')
|
||||
c = n - 'a' + 10;
|
||||
else throw DataFormatException();
|
||||
c <<= 4;
|
||||
if ((n = readOne()) == -1) throw DataFormatException();
|
||||
if (n >= '0' && n <= '9')
|
||||
c |= n - '0';
|
||||
else if (n >= 'A' && n <= 'F')
|
||||
c |= n - 'A' + 10;
|
||||
else if (n >= 'a' && n <= 'f')
|
||||
c |= n - 'a' + 10;
|
||||
else throw DataFormatException();
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int HexBinaryDecoderBuf::readOne()
|
||||
{
|
||||
int ch = _buf.sbumpc();
|
||||
while (ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n')
|
||||
ch = _buf.sbumpc();
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
HexBinaryDecoderIOS::HexBinaryDecoderIOS(std::istream& istr): _buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HexBinaryDecoderIOS::~HexBinaryDecoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HexBinaryDecoderBuf* HexBinaryDecoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
HexBinaryDecoder::HexBinaryDecoder(std::istream& istr): HexBinaryDecoderIOS(istr), std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HexBinaryDecoder::~HexBinaryDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// HexBinaryEncoder.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: HexBinary
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/HexBinaryEncoder.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
HexBinaryEncoderBuf::HexBinaryEncoderBuf(std::ostream& ostr):
|
||||
_pos(0),
|
||||
_lineLength(72),
|
||||
_uppercase(0),
|
||||
_buf(*ostr.rdbuf())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HexBinaryEncoderBuf::~HexBinaryEncoderBuf()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HexBinaryEncoderBuf::setLineLength(int lineLength)
|
||||
{
|
||||
_lineLength = lineLength;
|
||||
}
|
||||
|
||||
|
||||
int HexBinaryEncoderBuf::getLineLength() const
|
||||
{
|
||||
return _lineLength;
|
||||
}
|
||||
|
||||
|
||||
void HexBinaryEncoderBuf::setUppercase(bool flag)
|
||||
{
|
||||
_uppercase = flag ? 16 : 0;
|
||||
}
|
||||
|
||||
|
||||
int HexBinaryEncoderBuf::writeToDevice(char c)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
static const char digits[] = "0123456789abcdef0123456789ABCDEF";
|
||||
|
||||
if (_buf.sputc(digits[_uppercase + ((c >> 4) & 0xF)]) == eof) return eof;
|
||||
++_pos;
|
||||
if (_buf.sputc(digits[_uppercase + (c & 0xF)]) == eof) return eof;
|
||||
if (++_pos >= _lineLength && _lineLength > 0)
|
||||
{
|
||||
if (_buf.sputc('\n') == eof) return eof;
|
||||
_pos = 0;
|
||||
}
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
int HexBinaryEncoderBuf::close()
|
||||
{
|
||||
sync();
|
||||
return _buf.pubsync();
|
||||
}
|
||||
|
||||
|
||||
HexBinaryEncoderIOS::HexBinaryEncoderIOS(std::ostream& ostr): _buf(ostr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HexBinaryEncoderIOS::~HexBinaryEncoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int HexBinaryEncoderIOS::close()
|
||||
{
|
||||
return _buf.close();
|
||||
}
|
||||
|
||||
|
||||
HexBinaryEncoderBuf* HexBinaryEncoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
HexBinaryEncoder::HexBinaryEncoder(std::ostream& ostr): HexBinaryEncoderIOS(ostr), std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HexBinaryEncoder::~HexBinaryEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+360
@@ -0,0 +1,360 @@
|
||||
//
|
||||
// InflatingStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: ZLibStream
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/InflatingStream.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
InflatingStreamBuf::InflatingStreamBuf(std::istream& istr, StreamType type):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_eof(false),
|
||||
_check(type != STREAM_ZIP)
|
||||
{
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.total_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
_zstr.total_out = 0;
|
||||
_zstr.msg = 0;
|
||||
_zstr.state = 0;
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.data_type = 0;
|
||||
_zstr.adler = 0;
|
||||
_zstr.reserved = 0;
|
||||
|
||||
_buffer = new char[INFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = inflateInit2(&_zstr, 15 + (type == STREAM_GZIP ? 16 : 0));
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InflatingStreamBuf::InflatingStreamBuf(std::istream& istr, int windowBits):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_eof(false),
|
||||
_check(false)
|
||||
{
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
|
||||
_buffer = new char[INFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = inflateInit2(&_zstr, windowBits);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InflatingStreamBuf::InflatingStreamBuf(std::ostream& ostr, StreamType type):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_eof(false),
|
||||
_check(type != STREAM_ZIP)
|
||||
{
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
|
||||
_buffer = new char[INFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = inflateInit2(&_zstr, 15 + (type == STREAM_GZIP ? 16 : 0));
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InflatingStreamBuf::InflatingStreamBuf(std::ostream& ostr, int windowBits):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_eof(false),
|
||||
_check(false)
|
||||
{
|
||||
_zstr.zalloc = Z_NULL;
|
||||
_zstr.zfree = Z_NULL;
|
||||
_zstr.opaque = Z_NULL;
|
||||
_zstr.next_in = 0;
|
||||
_zstr.avail_in = 0;
|
||||
_zstr.next_out = 0;
|
||||
_zstr.avail_out = 0;
|
||||
|
||||
_buffer = new char[INFLATE_BUFFER_SIZE];
|
||||
|
||||
int rc = inflateInit2(&_zstr, windowBits);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
delete [] _buffer;
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InflatingStreamBuf::~InflatingStreamBuf()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
delete [] _buffer;
|
||||
inflateEnd(&_zstr);
|
||||
}
|
||||
|
||||
|
||||
int InflatingStreamBuf::close()
|
||||
{
|
||||
sync();
|
||||
_pIstr = 0;
|
||||
_pOstr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void InflatingStreamBuf::reset()
|
||||
{
|
||||
int rc = inflateReset(&_zstr);
|
||||
if (rc == Z_OK)
|
||||
_eof = false;
|
||||
else
|
||||
throw IOException(zError(rc));
|
||||
}
|
||||
|
||||
|
||||
int InflatingStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
if (_eof || !_pIstr) return 0;
|
||||
|
||||
if (_zstr.avail_in == 0)
|
||||
{
|
||||
int n = 0;
|
||||
if (_pIstr->good())
|
||||
{
|
||||
_pIstr->read(_buffer, INFLATE_BUFFER_SIZE);
|
||||
n = static_cast<int>(_pIstr->gcount());
|
||||
}
|
||||
_zstr.next_in = (unsigned char*) _buffer;
|
||||
_zstr.avail_in = n;
|
||||
}
|
||||
_zstr.next_out = (unsigned char*) buffer;
|
||||
_zstr.avail_out = static_cast<unsigned>(length);
|
||||
for (;;)
|
||||
{
|
||||
int rc = inflate(&_zstr, Z_NO_FLUSH);
|
||||
if (rc == Z_DATA_ERROR && !_check)
|
||||
{
|
||||
if (_zstr.avail_in == 0)
|
||||
{
|
||||
if (_pIstr->good())
|
||||
rc = Z_OK;
|
||||
else
|
||||
rc = Z_STREAM_END;
|
||||
}
|
||||
}
|
||||
if (rc == Z_STREAM_END)
|
||||
{
|
||||
_eof = true;
|
||||
return static_cast<int>(length) - _zstr.avail_out;
|
||||
}
|
||||
if (rc != Z_OK) throw IOException(zError(rc));
|
||||
if (_zstr.avail_out == 0)
|
||||
return static_cast<int>(length);
|
||||
if (_zstr.avail_in == 0)
|
||||
{
|
||||
int n = 0;
|
||||
if (_pIstr->good())
|
||||
{
|
||||
_pIstr->read(_buffer, INFLATE_BUFFER_SIZE);
|
||||
n = static_cast<int>(_pIstr->gcount());
|
||||
}
|
||||
if (n > 0)
|
||||
{
|
||||
_zstr.next_in = (unsigned char*) _buffer;
|
||||
_zstr.avail_in = n;
|
||||
}
|
||||
else return static_cast<int>(length) - _zstr.avail_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int InflatingStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
if (length == 0 || !_pOstr) return 0;
|
||||
|
||||
_zstr.next_in = (unsigned char*) buffer;
|
||||
_zstr.avail_in = static_cast<unsigned>(length);
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = INFLATE_BUFFER_SIZE;
|
||||
for (;;)
|
||||
{
|
||||
int rc = inflate(&_zstr, Z_NO_FLUSH);
|
||||
if (rc == Z_STREAM_END)
|
||||
{
|
||||
_pOstr->write(_buffer, INFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing inflated data to output stream");
|
||||
break;
|
||||
}
|
||||
if (rc != Z_OK) throw IOException(zError(rc));
|
||||
if (_zstr.avail_out == 0)
|
||||
{
|
||||
_pOstr->write(_buffer, INFLATE_BUFFER_SIZE);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing inflated data to output stream");
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = INFLATE_BUFFER_SIZE;
|
||||
}
|
||||
if (_zstr.avail_in == 0)
|
||||
{
|
||||
_pOstr->write(_buffer, INFLATE_BUFFER_SIZE - _zstr.avail_out);
|
||||
if (!_pOstr->good()) throw IOException("Failed writing inflated data to output stream");
|
||||
_zstr.next_out = (unsigned char*) _buffer;
|
||||
_zstr.avail_out = INFLATE_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<int>(length);
|
||||
}
|
||||
|
||||
|
||||
int InflatingStreamBuf::sync()
|
||||
{
|
||||
int n = BufferedStreamBuf::sync();
|
||||
if (!n && _pOstr) _pOstr->flush();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
InflatingIOS::InflatingIOS(std::ostream& ostr, InflatingStreamBuf::StreamType type):
|
||||
_buf(ostr, type)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
InflatingIOS::InflatingIOS(std::ostream& ostr, int windowBits):
|
||||
_buf(ostr, windowBits)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
InflatingIOS::InflatingIOS(std::istream& istr, InflatingStreamBuf::StreamType type):
|
||||
_buf(istr, type)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
InflatingIOS::InflatingIOS(std::istream& istr, int windowBits):
|
||||
_buf(istr, windowBits)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
InflatingIOS::~InflatingIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InflatingStreamBuf* InflatingIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
InflatingOutputStream::InflatingOutputStream(std::ostream& ostr, InflatingStreamBuf::StreamType type):
|
||||
std::ostream(&_buf),
|
||||
InflatingIOS(ostr, type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InflatingOutputStream::InflatingOutputStream(std::ostream& ostr, int windowBits):
|
||||
std::ostream(&_buf),
|
||||
InflatingIOS(ostr, windowBits)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InflatingOutputStream::~InflatingOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int InflatingOutputStream::close()
|
||||
{
|
||||
return _buf.close();
|
||||
}
|
||||
|
||||
|
||||
InflatingInputStream::InflatingInputStream(std::istream& istr, InflatingStreamBuf::StreamType type):
|
||||
std::istream(&_buf),
|
||||
InflatingIOS(istr, type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InflatingInputStream::InflatingInputStream(std::istream& istr, int windowBits):
|
||||
std::istream(&_buf),
|
||||
InflatingIOS(istr, windowBits)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InflatingInputStream::~InflatingInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void InflatingInputStream::reset()
|
||||
{
|
||||
_buf.reset();
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// String.h
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: String
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
#include "Poco/JSONString.h"
|
||||
#include "Poco/UTF8String.h"
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
template<typename T, typename S>
|
||||
struct WriteFunc
|
||||
{
|
||||
typedef T& (T::*Type)(const char* s, S n);
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename T, typename S>
|
||||
void writeString(const std::string &value, T& obj, typename WriteFunc<T, S>::Type write, int options)
|
||||
{
|
||||
bool wrap = ((options & Poco::JSON_WRAP_STRINGS) != 0);
|
||||
bool escapeAllUnicode = ((options & Poco::JSON_ESCAPE_UNICODE) != 0);
|
||||
|
||||
if (value.size() == 0)
|
||||
{
|
||||
if(wrap) (obj.*write)("\"\"", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if(wrap) (obj.*write)("\"", 1);
|
||||
if(escapeAllUnicode)
|
||||
{
|
||||
std::string str = Poco::UTF8::escape(value.begin(), value.end(), true);
|
||||
(obj.*write)(str.c_str(), str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::string::const_iterator it = value.begin(), end = value.end(); it != end; ++it)
|
||||
{
|
||||
// Forward slash isn't strictly required by JSON spec, but some parsers expect it
|
||||
if((*it >= 0 && *it <= 31) || (*it == '"') || (*it == '\\') || (*it == '/'))
|
||||
{
|
||||
std::string str = Poco::UTF8::escape(it, it + 1, true);
|
||||
(obj.*write)(str.c_str(), str.size());
|
||||
}else (obj.*write)(&(*it), 1);
|
||||
}
|
||||
}
|
||||
if(wrap) (obj.*write)("\"", 1);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
void toJSON(const std::string& value, std::ostream& out, bool wrap)
|
||||
{
|
||||
int options = (wrap ? Poco::JSON_WRAP_STRINGS : 0);
|
||||
writeString<std::ostream, std::streamsize>(value, out, &std::ostream::write, options);
|
||||
}
|
||||
|
||||
|
||||
std::string toJSON(const std::string& value, bool wrap)
|
||||
{
|
||||
int options = (wrap ? Poco::JSON_WRAP_STRINGS : 0);
|
||||
std::string ret;
|
||||
writeString<std::string,
|
||||
std::string::size_type>(value, ret, &std::string::append, options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void toJSON(const std::string& value, std::ostream& out, int options)
|
||||
{
|
||||
writeString<std::ostream, std::streamsize>(value, out, &std::ostream::write, options);
|
||||
}
|
||||
|
||||
|
||||
std::string toJSON(const std::string& value, int options)
|
||||
{
|
||||
std::string ret;
|
||||
writeString<std::string, std::string::size_type>(value, ret, &std::string::append, options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// Latin1Encoding.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Text
|
||||
// Module: Latin1Encoding
|
||||
//
|
||||
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Latin1Encoding.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const char* Latin1Encoding::_names[] =
|
||||
{
|
||||
"ISO-8859-1",
|
||||
"Latin1",
|
||||
"Latin-1",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap Latin1Encoding::_charMap =
|
||||
{
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */
|
||||
/* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
/* 10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
/* 20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
/* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
/* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
/* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
/* 60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
/* 70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
/* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
/* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
/* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
/* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
/* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
/* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
/* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
/* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
};
|
||||
|
||||
|
||||
Latin1Encoding::Latin1Encoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Latin1Encoding::~Latin1Encoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char* Latin1Encoding::canonicalName() const
|
||||
{
|
||||
return _names[0];
|
||||
}
|
||||
|
||||
|
||||
bool Latin1Encoding::isA(const std::string& encodingName) const
|
||||
{
|
||||
for (const char** name = _names; *name; ++name)
|
||||
{
|
||||
if (Poco::icompare(encodingName, *name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap& Latin1Encoding::characterMap() const
|
||||
{
|
||||
return _charMap;
|
||||
}
|
||||
|
||||
|
||||
int Latin1Encoding::convert(const unsigned char* bytes) const
|
||||
{
|
||||
return *bytes;
|
||||
}
|
||||
|
||||
|
||||
int Latin1Encoding::convert(int ch, unsigned char* bytes, int length) const
|
||||
{
|
||||
if (ch >= 0 && ch <= 255)
|
||||
{
|
||||
if (bytes && length >= 1)
|
||||
*bytes = (unsigned char) ch;
|
||||
return 1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
int Latin1Encoding::queryConvert(const unsigned char* bytes, int length) const
|
||||
{
|
||||
if (1 <= length)
|
||||
return *bytes;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Latin1Encoding::sequenceLength(const unsigned char* bytes, int length) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
//
|
||||
// Latin2Encoding.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Text
|
||||
// Module: Latin2Encoding
|
||||
//
|
||||
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Latin2Encoding.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const char* Latin2Encoding::_names[] =
|
||||
{
|
||||
"ISO-8859-2",
|
||||
"Latin2",
|
||||
"Latin-2",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap Latin2Encoding::_charMap =
|
||||
{
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */
|
||||
/* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
/* 10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
/* 20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
/* 30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
/* 40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
/* 50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
/* 60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
/* 70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
/* 80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
|
||||
/* 90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
|
||||
/* a0 */ 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
|
||||
/* b0 */ 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
|
||||
/* c0 */ 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
|
||||
/* d0 */ 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
|
||||
/* e0 */ 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
|
||||
/* f0 */ 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
|
||||
};
|
||||
|
||||
|
||||
Latin2Encoding::Latin2Encoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Latin2Encoding::~Latin2Encoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char* Latin2Encoding::canonicalName() const
|
||||
{
|
||||
return _names[0];
|
||||
}
|
||||
|
||||
|
||||
bool Latin2Encoding::isA(const std::string& encodingName) const
|
||||
{
|
||||
for (const char** name = _names; *name; ++name)
|
||||
{
|
||||
if (Poco::icompare(encodingName, *name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap& Latin2Encoding::characterMap() const
|
||||
{
|
||||
return _charMap;
|
||||
}
|
||||
|
||||
|
||||
int Latin2Encoding::convert(const unsigned char* bytes) const
|
||||
{
|
||||
return _charMap[*bytes];
|
||||
}
|
||||
|
||||
|
||||
int Latin2Encoding::convert(int ch, unsigned char* bytes, int length) const
|
||||
{
|
||||
if (ch >= 0 && ch <= 255 && _charMap[ch] == ch)
|
||||
{
|
||||
if (bytes && length >= 1)
|
||||
*bytes = (unsigned char) ch;
|
||||
return 1;
|
||||
}
|
||||
switch(ch)
|
||||
{
|
||||
case 0x0104: if (bytes && length >= 1) *bytes = 0xa1; return 1;
|
||||
case 0x02d8: if (bytes && length >= 1) *bytes = 0xa2; return 1;
|
||||
case 0x0141: if (bytes && length >= 1) *bytes = 0xa3; return 1;
|
||||
case 0x013d: if (bytes && length >= 1) *bytes = 0xa5; return 1;
|
||||
case 0x015a: if (bytes && length >= 1) *bytes = 0xa6; return 1;
|
||||
case 0x0160: if (bytes && length >= 1) *bytes = 0xa9; return 1;
|
||||
case 0x015e: if (bytes && length >= 1) *bytes = 0xaa; return 1;
|
||||
case 0x0164: if (bytes && length >= 1) *bytes = 0xab; return 1;
|
||||
case 0x0179: if (bytes && length >= 1) *bytes = 0xac; return 1;
|
||||
case 0x017d: if (bytes && length >= 1) *bytes = 0xae; return 1;
|
||||
case 0x017b: if (bytes && length >= 1) *bytes = 0xaf; return 1;
|
||||
case 0x0105: if (bytes && length >= 1) *bytes = 0xb1; return 1;
|
||||
case 0x02db: if (bytes && length >= 1) *bytes = 0xb2; return 1;
|
||||
case 0x0142: if (bytes && length >= 1) *bytes = 0xb3; return 1;
|
||||
case 0x013e: if (bytes && length >= 1) *bytes = 0xb5; return 1;
|
||||
case 0x015b: if (bytes && length >= 1) *bytes = 0xb6; return 1;
|
||||
case 0x02c7: if (bytes && length >= 1) *bytes = 0xb7; return 1;
|
||||
case 0x0161: if (bytes && length >= 1) *bytes = 0xb9; return 1;
|
||||
case 0x015f: if (bytes && length >= 1) *bytes = 0xba; return 1;
|
||||
case 0x0165: if (bytes && length >= 1) *bytes = 0xbb; return 1;
|
||||
case 0x017a: if (bytes && length >= 1) *bytes = 0xbc; return 1;
|
||||
case 0x02dd: if (bytes && length >= 1) *bytes = 0xbd; return 1;
|
||||
case 0x017e: if (bytes && length >= 1) *bytes = 0xbe; return 1;
|
||||
case 0x017c: if (bytes && length >= 1) *bytes = 0xbf; return 1;
|
||||
case 0x0154: if (bytes && length >= 1) *bytes = 0xc0; return 1;
|
||||
case 0x0102: if (bytes && length >= 1) *bytes = 0xc3; return 1;
|
||||
case 0x0139: if (bytes && length >= 1) *bytes = 0xc5; return 1;
|
||||
case 0x0106: if (bytes && length >= 1) *bytes = 0xc6; return 1;
|
||||
case 0x010c: if (bytes && length >= 1) *bytes = 0xc8; return 1;
|
||||
case 0x0118: if (bytes && length >= 1) *bytes = 0xca; return 1;
|
||||
case 0x011a: if (bytes && length >= 1) *bytes = 0xcc; return 1;
|
||||
case 0x010e: if (bytes && length >= 1) *bytes = 0xcf; return 1;
|
||||
case 0x0110: if (bytes && length >= 1) *bytes = 0xd0; return 1;
|
||||
case 0x0143: if (bytes && length >= 1) *bytes = 0xd1; return 1;
|
||||
case 0x0147: if (bytes && length >= 1) *bytes = 0xd2; return 1;
|
||||
case 0x0150: if (bytes && length >= 1) *bytes = 0xd5; return 1;
|
||||
case 0x0158: if (bytes && length >= 1) *bytes = 0xd8; return 1;
|
||||
case 0x016e: if (bytes && length >= 1) *bytes = 0xd9; return 1;
|
||||
case 0x0170: if (bytes && length >= 1) *bytes = 0xdb; return 1;
|
||||
case 0x0162: if (bytes && length >= 1) *bytes = 0xde; return 1;
|
||||
case 0x0155: if (bytes && length >= 1) *bytes = 0xe0; return 1;
|
||||
case 0x0103: if (bytes && length >= 1) *bytes = 0xe3; return 1;
|
||||
case 0x013a: if (bytes && length >= 1) *bytes = 0xe5; return 1;
|
||||
case 0x0107: if (bytes && length >= 1) *bytes = 0xe6; return 1;
|
||||
case 0x010d: if (bytes && length >= 1) *bytes = 0xe8; return 1;
|
||||
case 0x0119: if (bytes && length >= 1) *bytes = 0xea; return 1;
|
||||
case 0x011b: if (bytes && length >= 1) *bytes = 0xec; return 1;
|
||||
case 0x010f: if (bytes && length >= 1) *bytes = 0xef; return 1;
|
||||
case 0x0111: if (bytes && length >= 1) *bytes = 0xf0; return 1;
|
||||
case 0x0144: if (bytes && length >= 1) *bytes = 0xf1; return 1;
|
||||
case 0x0148: if (bytes && length >= 1) *bytes = 0xf2; return 1;
|
||||
case 0x0151: if (bytes && length >= 1) *bytes = 0xf5; return 1;
|
||||
case 0x0159: if (bytes && length >= 1) *bytes = 0xf8; return 1;
|
||||
case 0x016f: if (bytes && length >= 1) *bytes = 0xf9; return 1;
|
||||
case 0x0171: if (bytes && length >= 1) *bytes = 0xfb; return 1;
|
||||
case 0x0163: if (bytes && length >= 1) *bytes = 0xfe; return 1;
|
||||
case 0x02d9: if (bytes && length >= 1) *bytes = 0xff; return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Latin2Encoding::queryConvert(const unsigned char* bytes, int length) const
|
||||
{
|
||||
if (1 <= length)
|
||||
return _charMap[*bytes];
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Latin2Encoding::sequenceLength(const unsigned char* bytes, int length) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// Latin9Encoding.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Text
|
||||
// Module: Latin9Encoding
|
||||
//
|
||||
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Latin9Encoding.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const char* Latin9Encoding::_names[] =
|
||||
{
|
||||
"ISO-8859-15",
|
||||
"Latin9",
|
||||
"Latin-9",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap Latin9Encoding::_charMap =
|
||||
{
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */
|
||||
/* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
/* 10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
/* 20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
/* 30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
/* 40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
/* 50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
/* 60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
/* 70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
/* 80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
|
||||
/* 90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
|
||||
/* a0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||
/* b0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
|
||||
/* c0 */ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
|
||||
/* d0 */ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
|
||||
/* e0 */ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
|
||||
/* f0 */ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
|
||||
};
|
||||
|
||||
|
||||
Latin9Encoding::Latin9Encoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Latin9Encoding::~Latin9Encoding()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char* Latin9Encoding::canonicalName() const
|
||||
{
|
||||
return _names[0];
|
||||
}
|
||||
|
||||
|
||||
bool Latin9Encoding::isA(const std::string& encodingName) const
|
||||
{
|
||||
for (const char** name = _names; *name; ++name)
|
||||
{
|
||||
if (Poco::icompare(encodingName, *name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const TextEncoding::CharacterMap& Latin9Encoding::characterMap() const
|
||||
{
|
||||
return _charMap;
|
||||
}
|
||||
|
||||
|
||||
int Latin9Encoding::convert(const unsigned char* bytes) const
|
||||
{
|
||||
return _charMap[*bytes];
|
||||
}
|
||||
|
||||
|
||||
int Latin9Encoding::convert(int ch, unsigned char* bytes, int length) const
|
||||
{
|
||||
if (ch >= 0 && ch <= 255 && _charMap[ch] == ch)
|
||||
{
|
||||
if (bytes && length >= 1)
|
||||
*bytes = ch;
|
||||
return 1;
|
||||
}
|
||||
else switch (ch)
|
||||
{
|
||||
case 0x0152: if (bytes && length >= 1) *bytes = 0xbc; return 1;
|
||||
case 0x0153: if (bytes && length >= 1) *bytes = 0xbd; return 1;
|
||||
case 0x0160: if (bytes && length >= 1) *bytes = 0xa6; return 1;
|
||||
case 0x0161: if (bytes && length >= 1) *bytes = 0xa8; return 1;
|
||||
case 0x017d: if (bytes && length >= 1) *bytes = 0xb4; return 1;
|
||||
case 0x017e: if (bytes && length >= 1) *bytes = 0xb8; return 1;
|
||||
case 0x0178: if (bytes && length >= 1) *bytes = 0xbe; return 1;
|
||||
case 0x20ac: if (bytes && length >= 1) *bytes = 0xa4; return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Latin9Encoding::queryConvert(const unsigned char* bytes, int length) const
|
||||
{
|
||||
if (1 <= length)
|
||||
return _charMap[*bytes];
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Latin9Encoding::sequenceLength(const unsigned char* bytes, int length) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
//
|
||||
// LineEndingConverter.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: LineEndingConverter
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LineEndingConverter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
const std::string LineEnding::NEWLINE_DEFAULT(POCO_DEFAULT_NEWLINE_CHARS);
|
||||
const std::string LineEnding::NEWLINE_CR("\r");
|
||||
const std::string LineEnding::NEWLINE_CRLF("\r\n");
|
||||
const std::string LineEnding::NEWLINE_LF("\n");
|
||||
|
||||
|
||||
LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::istream& istr):
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_newLine(LineEnding::NEWLINE_DEFAULT),
|
||||
_lastChar(0)
|
||||
{
|
||||
_it = _newLine.end();
|
||||
}
|
||||
|
||||
|
||||
LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::ostream& ostr):
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_newLine(LineEnding::NEWLINE_DEFAULT),
|
||||
_lastChar(0)
|
||||
{
|
||||
_it = _newLine.end();
|
||||
}
|
||||
|
||||
|
||||
LineEndingConverterStreamBuf::~LineEndingConverterStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LineEndingConverterStreamBuf::setNewLine(const std::string& newLineCharacters)
|
||||
{
|
||||
_newLine = newLineCharacters;
|
||||
_it = _newLine.end();
|
||||
}
|
||||
|
||||
|
||||
const std::string& LineEndingConverterStreamBuf::getNewLine() const
|
||||
{
|
||||
return _newLine;
|
||||
}
|
||||
|
||||
|
||||
int LineEndingConverterStreamBuf::readFromDevice()
|
||||
{
|
||||
poco_assert_dbg (_pIstr);
|
||||
|
||||
while (_it == _newLine.end())
|
||||
{
|
||||
int c = _pIstr->get();
|
||||
if (c == '\r')
|
||||
{
|
||||
if (_pIstr->peek() == '\n') _pIstr->get();
|
||||
_it = _newLine.begin();
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
_it = _newLine.begin();
|
||||
}
|
||||
else return c;
|
||||
}
|
||||
return *_it++;
|
||||
}
|
||||
|
||||
|
||||
int LineEndingConverterStreamBuf::writeToDevice(char c)
|
||||
{
|
||||
poco_assert_dbg (_pOstr);
|
||||
|
||||
if (c == '\r' || (c == '\n' && _lastChar != '\r'))
|
||||
_pOstr->write(_newLine.data(), (std::streamsize) _newLine.length());
|
||||
if (c != '\n' && c != '\r')
|
||||
_pOstr->put(c);
|
||||
_lastChar = c;
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
LineEndingConverterIOS::LineEndingConverterIOS(std::istream& istr): _buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
LineEndingConverterIOS::LineEndingConverterIOS(std::ostream& ostr): _buf(ostr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
LineEndingConverterIOS::~LineEndingConverterIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LineEndingConverterIOS::setNewLine(const std::string& newLineCharacters)
|
||||
{
|
||||
_buf.setNewLine(newLineCharacters);
|
||||
}
|
||||
|
||||
|
||||
const std::string& LineEndingConverterIOS::getNewLine() const
|
||||
{
|
||||
return _buf.getNewLine();
|
||||
}
|
||||
|
||||
|
||||
LineEndingConverterStreamBuf* LineEndingConverterIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
InputLineEndingConverter::InputLineEndingConverter(std::istream& istr):
|
||||
LineEndingConverterIOS(istr),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InputLineEndingConverter::InputLineEndingConverter(std::istream& istr, const std::string& newLineCharacters):
|
||||
LineEndingConverterIOS(istr),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
setNewLine(newLineCharacters);
|
||||
}
|
||||
|
||||
|
||||
InputLineEndingConverter::~InputLineEndingConverter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr):
|
||||
LineEndingConverterIOS(ostr),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr, const std::string& newLineCharacters):
|
||||
LineEndingConverterIOS(ostr),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
setNewLine(newLineCharacters);
|
||||
}
|
||||
|
||||
|
||||
OutputLineEndingConverter::~OutputLineEndingConverter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+317
@@ -0,0 +1,317 @@
|
||||
//
|
||||
// LocalDateTime.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: DateTime
|
||||
// Module: LocalDateTime
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LocalDateTime.h"
|
||||
#include "Poco/Timezone.h"
|
||||
#include "Poco/Timespan.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
|
||||
#include "wce_time.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime()
|
||||
{
|
||||
determineTzd(true);
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond):
|
||||
_dateTime(year, month, day, hour, minute, second, millisecond, microsecond)
|
||||
{
|
||||
determineTzd();
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(int tzd, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond):
|
||||
_dateTime(year, month, day, hour, minute, second, millisecond, microsecond),
|
||||
_tzd(tzd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(double julianDay):
|
||||
_dateTime(julianDay)
|
||||
{
|
||||
determineTzd(true);
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(int tzd, double julianDay):
|
||||
_dateTime(julianDay),
|
||||
_tzd(tzd)
|
||||
{
|
||||
adjustForTzd();
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(const DateTime& dateTime):
|
||||
_dateTime(dateTime)
|
||||
{
|
||||
determineTzd(true);
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(int tzd, const DateTime& dateTime):
|
||||
_dateTime(dateTime),
|
||||
_tzd(tzd)
|
||||
{
|
||||
adjustForTzd();
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(int tzd, const DateTime& dateTime, bool adjust):
|
||||
_dateTime(dateTime),
|
||||
_tzd(tzd)
|
||||
{
|
||||
if (adjust)
|
||||
adjustForTzd();
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(const LocalDateTime& dateTime):
|
||||
_dateTime(dateTime._dateTime),
|
||||
_tzd(dateTime._tzd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::LocalDateTime(Timestamp::UtcTimeVal utcTime, Timestamp::TimeDiff diff, int tzd):
|
||||
_dateTime(utcTime, diff),
|
||||
_tzd(tzd)
|
||||
{
|
||||
adjustForTzd();
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime::~LocalDateTime()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::operator = (const LocalDateTime& dateTime)
|
||||
{
|
||||
if (&dateTime != this)
|
||||
{
|
||||
_dateTime = dateTime._dateTime;
|
||||
_tzd = dateTime._tzd;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::operator = (const Timestamp& timestamp)
|
||||
{
|
||||
if (timestamp != this->timestamp())
|
||||
{
|
||||
_dateTime = timestamp;
|
||||
determineTzd(true);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::operator = (double julianDay)
|
||||
{
|
||||
_dateTime = julianDay;
|
||||
determineTzd(true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::assign(int year, int month, int day, int hour, int minute, int second, int millisecond, int microseconds)
|
||||
{
|
||||
_dateTime.assign(year, month, day, hour, minute, second, millisecond, microseconds);
|
||||
determineTzd(false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::assign(int tzd, int year, int month, int day, int hour, int minute, int second, int millisecond, int microseconds)
|
||||
{
|
||||
_dateTime.assign(year, month, day, hour, minute, second, millisecond, microseconds);
|
||||
_tzd = tzd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::assign(int tzd, double julianDay)
|
||||
{
|
||||
_tzd = tzd;
|
||||
_dateTime = julianDay;
|
||||
adjustForTzd();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void LocalDateTime::swap(LocalDateTime& dateTime)
|
||||
{
|
||||
_dateTime.swap(dateTime._dateTime);
|
||||
std::swap(_tzd, dateTime._tzd);
|
||||
}
|
||||
|
||||
|
||||
DateTime LocalDateTime::utc() const
|
||||
{
|
||||
return DateTime(_dateTime.utcTime(), -((Timestamp::TimeDiff) _tzd)*Timespan::SECONDS);
|
||||
}
|
||||
|
||||
|
||||
bool LocalDateTime::operator == (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return utcTime() == dateTime.utcTime();
|
||||
}
|
||||
|
||||
|
||||
bool LocalDateTime::operator != (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return utcTime() != dateTime.utcTime();
|
||||
}
|
||||
|
||||
|
||||
bool LocalDateTime::operator < (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return utcTime() < dateTime.utcTime();
|
||||
}
|
||||
|
||||
|
||||
bool LocalDateTime::operator <= (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return utcTime() <= dateTime.utcTime();
|
||||
}
|
||||
|
||||
|
||||
bool LocalDateTime::operator > (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return utcTime() > dateTime.utcTime();
|
||||
}
|
||||
|
||||
|
||||
bool LocalDateTime::operator >= (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return utcTime() >= dateTime.utcTime();
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime LocalDateTime::operator + (const Timespan& span) const
|
||||
{
|
||||
// First calculate the adjusted UTC time, then calculate the
|
||||
// locally adjusted time by constructing a new LocalDateTime.
|
||||
DateTime tmp(utcTime(), span.totalMicroseconds());
|
||||
return LocalDateTime(tmp);
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime LocalDateTime::operator - (const Timespan& span) const
|
||||
{
|
||||
// First calculate the adjusted UTC time, then calculate the
|
||||
// locally adjusted time by constructing a new LocalDateTime.
|
||||
DateTime tmp(utcTime(), -span.totalMicroseconds());
|
||||
return LocalDateTime(tmp);
|
||||
}
|
||||
|
||||
|
||||
Timespan LocalDateTime::operator - (const LocalDateTime& dateTime) const
|
||||
{
|
||||
return Timespan((utcTime() - dateTime.utcTime())/10);
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::operator += (const Timespan& span)
|
||||
{
|
||||
// Use the same trick as in operator+. Create a UTC time, adjust
|
||||
// it for the span, and convert back to LocalDateTime. This will
|
||||
// recalculate the tzd correctly in the case where the addition
|
||||
// crosses a DST boundary.
|
||||
*this = DateTime(utcTime(), span.totalMicroseconds());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime& LocalDateTime::operator -= (const Timespan& span)
|
||||
{
|
||||
// Use the same trick as in operator-. Create a UTC time, adjust
|
||||
// it for the span, and convert back to LocalDateTime. This will
|
||||
// recalculate the tzd correctly in the case where the subtraction
|
||||
// crosses a DST boundary.
|
||||
*this = DateTime(utcTime(), -span.totalMicroseconds());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void LocalDateTime::determineTzd(bool adjust)
|
||||
{
|
||||
if (adjust)
|
||||
{
|
||||
std::time_t epochTime = _dateTime.timestamp().epochTime();
|
||||
#if defined(_WIN32) || defined(POCO_NO_POSIX_TSF)
|
||||
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
|
||||
std::tm* broken = wceex_localtime(&epochTime);
|
||||
#else
|
||||
std::tm* broken = std::localtime(&epochTime);
|
||||
#endif
|
||||
if (!broken) throw Poco::SystemException("cannot get local time");
|
||||
_tzd = (Timezone::utcOffset() + ((broken->tm_isdst == 1) ? 3600 : 0));
|
||||
#else
|
||||
std::tm broken;
|
||||
#if defined(POCO_VXWORKS)
|
||||
if (localtime_r(&epochTime, &broken) != OK)
|
||||
throw Poco::SystemException("cannot get local time");
|
||||
#else
|
||||
if (!localtime_r(&epochTime, &broken))
|
||||
throw Poco::SystemException("cannot get local time");
|
||||
#endif
|
||||
_tzd = (Timezone::utcOffset() + ((broken.tm_isdst == 1) ? 3600 : 0));
|
||||
#endif
|
||||
adjustForTzd();
|
||||
}
|
||||
else
|
||||
{
|
||||
int dst;
|
||||
dstOffset(dst);
|
||||
_tzd = (Timezone::utcOffset() + dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::time_t LocalDateTime::dstOffset(int& dstOffset) const
|
||||
{
|
||||
std::time_t local;
|
||||
std::tm broken;
|
||||
|
||||
broken.tm_year = (_dateTime.year() - 1900);
|
||||
broken.tm_mon = (_dateTime.month() - 1);
|
||||
broken.tm_mday = _dateTime.day();
|
||||
broken.tm_hour = _dateTime.hour();
|
||||
broken.tm_min = _dateTime.minute();
|
||||
broken.tm_sec = _dateTime.second();
|
||||
broken.tm_isdst = -1;
|
||||
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
|
||||
local = wceex_mktime(&broken);
|
||||
#else
|
||||
local = std::mktime(&broken);
|
||||
#endif
|
||||
|
||||
dstOffset = (broken.tm_isdst == 1) ? 3600 : 0;
|
||||
return local;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// LogFile.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: LogFile
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LogFile.h"
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#include "LogFile_WIN32U.cpp"
|
||||
#else
|
||||
#include "LogFile_STD.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
LogFile::LogFile(const std::string& path): LogFileImpl(path)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogFile::~LogFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// LogFile_STD.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: LogFile
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LogFile_STD.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
LogFileImpl::LogFileImpl(const std::string& path):
|
||||
_path(path),
|
||||
_str(_path, std::ios::app)
|
||||
{
|
||||
if (sizeImpl() == 0)
|
||||
_creationDate = File(path).getLastModified();
|
||||
else
|
||||
_creationDate = File(path).created();
|
||||
}
|
||||
|
||||
|
||||
LogFileImpl::~LogFileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LogFileImpl::writeImpl(const std::string& text, bool flush)
|
||||
{
|
||||
_str << text;
|
||||
if (flush)
|
||||
_str << std::endl;
|
||||
else
|
||||
_str << "\n";
|
||||
if (!_str.good()) throw WriteFileException(_path);
|
||||
}
|
||||
|
||||
|
||||
UInt64 LogFileImpl::sizeImpl() const
|
||||
{
|
||||
return (UInt64) _str.tellp();
|
||||
}
|
||||
|
||||
|
||||
Timestamp LogFileImpl::creationDateImpl() const
|
||||
{
|
||||
return _creationDate;
|
||||
}
|
||||
|
||||
|
||||
const std::string& LogFileImpl::pathImpl() const
|
||||
{
|
||||
return _path;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// LogFile_WIN32U.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: LogFile
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LogFile_WIN32U.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
LogFileImpl::LogFileImpl(const std::string& path): _path(path), _hFile(INVALID_HANDLE_VALUE)
|
||||
{
|
||||
File file(path);
|
||||
if (file.exists())
|
||||
{
|
||||
if (0 == sizeImpl())
|
||||
_creationDate = file.getLastModified();
|
||||
else
|
||||
_creationDate = file.created();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LogFileImpl::~LogFileImpl()
|
||||
{
|
||||
CloseHandle(_hFile);
|
||||
}
|
||||
|
||||
|
||||
void LogFileImpl::writeImpl(const std::string& text, bool flush)
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == _hFile) createFile();
|
||||
|
||||
std::string logText;
|
||||
logText.reserve(text.size() + 16); // keep some reserve for \n -> \r\n and terminating \r\n
|
||||
for (char c: text)
|
||||
{
|
||||
if (c == '\n')
|
||||
logText += "\r\n";
|
||||
else
|
||||
logText += c;
|
||||
}
|
||||
logText += "\r\n";
|
||||
|
||||
DWORD bytesWritten;
|
||||
BOOL res = WriteFile(_hFile, logText.data(), static_cast<DWORD>(logText.size()), &bytesWritten, NULL);
|
||||
if (!res) throw WriteFileException(_path);
|
||||
if (flush)
|
||||
{
|
||||
res = FlushFileBuffers(_hFile);
|
||||
if (!res) throw WriteFileException(_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UInt64 LogFileImpl::sizeImpl() const
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == _hFile)
|
||||
{
|
||||
File file(_path);
|
||||
if (file.exists()) return file.getSize();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
LARGE_INTEGER li;
|
||||
li.HighPart = 0;
|
||||
li.LowPart = SetFilePointer(_hFile, 0, &li.HighPart, FILE_CURRENT);
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
Timestamp LogFileImpl::creationDateImpl() const
|
||||
{
|
||||
return _creationDate;
|
||||
}
|
||||
|
||||
|
||||
const std::string& LogFileImpl::pathImpl() const
|
||||
{
|
||||
return _path;
|
||||
}
|
||||
|
||||
|
||||
void LogFileImpl::createFile()
|
||||
{
|
||||
std::wstring upath;
|
||||
FileImpl::convertPath(_path, upath);
|
||||
|
||||
_hFile = CreateFileW(upath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (_hFile == INVALID_HANDLE_VALUE) throw OpenFileException(_path);
|
||||
SetFilePointer(_hFile, 0, 0, FILE_END);
|
||||
// There seems to be a strange "optimization" in the Windows NTFS
|
||||
// filesystem that causes it to reuse directory entries of deleted
|
||||
// files. Example:
|
||||
// 1. create a file named "test.dat"
|
||||
// note the file's creation date
|
||||
// 2. delete the file "test.dat"
|
||||
// 3. wait a few seconds
|
||||
// 4. create a file named "test.dat"
|
||||
// the new file will have the same creation
|
||||
// date as the old one.
|
||||
// We work around this bug by taking the file's
|
||||
// modification date as a reference when the
|
||||
// file is empty.
|
||||
if (sizeImpl() == 0)
|
||||
_creationDate = File(_path).getLastModified();
|
||||
else
|
||||
_creationDate = File(_path).created();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
//
|
||||
// LogStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: LogStream
|
||||
//
|
||||
// Copyright (c) 2006-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LogStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
//
|
||||
// LogStreamBuf
|
||||
//
|
||||
|
||||
|
||||
LogStreamBuf::LogStreamBuf(Logger& logger, Message::Priority priority, std::size_t bufferCapacity):
|
||||
_logger(logger),
|
||||
_priority(priority)
|
||||
{
|
||||
_message.reserve(bufferCapacity);
|
||||
}
|
||||
|
||||
|
||||
LogStreamBuf::~LogStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LogStreamBuf::setPriority(Message::Priority priority)
|
||||
{
|
||||
_priority = priority;
|
||||
}
|
||||
|
||||
|
||||
void LogStreamBuf::reserve(std::size_t capacity)
|
||||
{
|
||||
_message.reserve(capacity);
|
||||
}
|
||||
|
||||
|
||||
int LogStreamBuf::writeToDevice(char c)
|
||||
{
|
||||
if (c == '\n' || c == '\r')
|
||||
{
|
||||
if (_message.find_first_not_of("\r\n") != std::string::npos)
|
||||
{
|
||||
Message msg(_logger.name(), _message, _priority);
|
||||
_message.clear();
|
||||
_logger.log(msg);
|
||||
}
|
||||
}
|
||||
else _message += c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LogIOS
|
||||
//
|
||||
|
||||
|
||||
LogIOS::LogIOS(Logger& logger, Message::Priority priority, std::size_t bufferCapacity):
|
||||
_buf(logger, priority, bufferCapacity)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
LogIOS::~LogIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogStreamBuf* LogIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LogStream
|
||||
//
|
||||
|
||||
|
||||
LogStream::LogStream(Logger& logger, Message::Priority priority, std::size_t bufferCapacity):
|
||||
LogIOS(logger, priority, bufferCapacity),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogStream::LogStream(const std::string& loggerName, Message::Priority priority, std::size_t bufferCapacity):
|
||||
LogIOS(Logger::get(loggerName), priority, bufferCapacity),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogStream::~LogStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::fatal()
|
||||
{
|
||||
return priority(Message::PRIO_FATAL);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::fatal(const std::string& message)
|
||||
{
|
||||
_buf.logger().fatal(message);
|
||||
return priority(Message::PRIO_FATAL);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::critical()
|
||||
{
|
||||
return priority(Message::PRIO_CRITICAL);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::critical(const std::string& message)
|
||||
{
|
||||
_buf.logger().critical(message);
|
||||
return priority(Message::PRIO_CRITICAL);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::error()
|
||||
{
|
||||
return priority(Message::PRIO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::error(const std::string& message)
|
||||
{
|
||||
_buf.logger().error(message);
|
||||
return priority(Message::PRIO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::warning()
|
||||
{
|
||||
return priority(Message::PRIO_WARNING);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::warning(const std::string& message)
|
||||
{
|
||||
_buf.logger().warning(message);
|
||||
return priority(Message::PRIO_WARNING);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::notice()
|
||||
{
|
||||
return priority(Message::PRIO_NOTICE);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::notice(const std::string& message)
|
||||
{
|
||||
_buf.logger().notice(message);
|
||||
return priority(Message::PRIO_NOTICE);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::information()
|
||||
{
|
||||
return priority(Message::PRIO_INFORMATION);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::information(const std::string& message)
|
||||
{
|
||||
_buf.logger().information(message);
|
||||
return priority(Message::PRIO_INFORMATION);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::debug()
|
||||
{
|
||||
return priority(Message::PRIO_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::debug(const std::string& message)
|
||||
{
|
||||
_buf.logger().debug(message);
|
||||
return priority(Message::PRIO_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::trace()
|
||||
{
|
||||
return priority(Message::PRIO_TRACE);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::trace(const std::string& message)
|
||||
{
|
||||
_buf.logger().trace(message);
|
||||
return priority(Message::PRIO_TRACE);
|
||||
}
|
||||
|
||||
|
||||
LogStream& LogStream::priority(Message::Priority priority)
|
||||
{
|
||||
_buf.setPriority(priority);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+436
@@ -0,0 +1,436 @@
|
||||
//
|
||||
// Logger.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: Logger
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/Formatter.h"
|
||||
#include "Poco/LoggingRegistry.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Logger::LoggerMapPtr Logger::_pLoggerMap;
|
||||
Mutex Logger::_mapMtx;
|
||||
const std::string Logger::ROOT;
|
||||
|
||||
|
||||
Logger::Logger(const std::string& name, Channel::Ptr pChannel, int level): _name(name), _pChannel(pChannel), _level(level)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Logger::setChannel(Channel::Ptr pChannel)
|
||||
{
|
||||
_pChannel = pChannel;
|
||||
}
|
||||
|
||||
|
||||
Channel::Ptr Logger::getChannel() const
|
||||
{
|
||||
return _pChannel;
|
||||
}
|
||||
|
||||
|
||||
void Logger::setLevel(int level)
|
||||
{
|
||||
_level = level;
|
||||
}
|
||||
|
||||
|
||||
void Logger::setLevel(const std::string& level)
|
||||
{
|
||||
setLevel(parseLevel(level));
|
||||
}
|
||||
|
||||
|
||||
void Logger::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name == "channel")
|
||||
setChannel(LoggingRegistry::defaultRegistry().channelForName(value));
|
||||
else if (name == "level")
|
||||
setLevel(value);
|
||||
else
|
||||
Channel::setProperty(name, value);
|
||||
}
|
||||
|
||||
|
||||
void Logger::log(const Message& msg)
|
||||
{
|
||||
if (_level >= msg.getPriority() && _pChannel)
|
||||
{
|
||||
_pChannel->log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::log(const Exception& exc)
|
||||
{
|
||||
error(exc.displayText());
|
||||
}
|
||||
|
||||
|
||||
void Logger::log(const Exception& exc, const char* file, int line)
|
||||
{
|
||||
error(exc.displayText(), file, line);
|
||||
}
|
||||
|
||||
|
||||
void Logger::dump(const std::string& msg, const void* buffer, std::size_t length, Message::Priority prio)
|
||||
{
|
||||
if (_level >= prio && _pChannel)
|
||||
{
|
||||
std::string text(msg);
|
||||
formatDump(text, buffer, length);
|
||||
_pChannel->log(Message(_name, text, prio));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::setLevel(const std::string& name, int level)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
if (_pLoggerMap)
|
||||
{
|
||||
std::string::size_type len = name.length();
|
||||
for (auto& p: *_pLoggerMap)
|
||||
{
|
||||
if (len == 0 || (p.first.compare(0, len, name) == 0 && (p.first.length() == len || p.first[len] == '.')))
|
||||
{
|
||||
p.second->setLevel(level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::setChannel(const std::string& name, Channel::Ptr pChannel)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
if (_pLoggerMap)
|
||||
{
|
||||
std::string::size_type len = name.length();
|
||||
for (auto& p: *_pLoggerMap)
|
||||
{
|
||||
if (len == 0 || (p.first.compare(0, len, name) == 0 && (p.first.length() == len || p.first[len] == '.')))
|
||||
{
|
||||
p.second->setChannel(pChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::setProperty(const std::string& loggerName, const std::string& propertyName, const std::string& value)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
if (_pLoggerMap)
|
||||
{
|
||||
std::string::size_type len = loggerName.length();
|
||||
for (auto& p: *_pLoggerMap)
|
||||
{
|
||||
if (len == 0 || (p.first.compare(0, len, loggerName) == 0 && (p.first.length() == len || p.first[len] == '.')))
|
||||
{
|
||||
p.second->setProperty(propertyName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::format(const std::string& fmt, const std::string& arg)
|
||||
{
|
||||
std::string args[] =
|
||||
{
|
||||
arg
|
||||
};
|
||||
return format(fmt, 1, args);
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::format(const std::string& fmt, const std::string& arg0, const std::string& arg1)
|
||||
{
|
||||
std::string args[] =
|
||||
{
|
||||
arg0,
|
||||
arg1
|
||||
};
|
||||
return format(fmt, 2, args);
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2)
|
||||
{
|
||||
std::string args[] =
|
||||
{
|
||||
arg0,
|
||||
arg1,
|
||||
arg2
|
||||
};
|
||||
return format(fmt, 3, args);
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2, const std::string& arg3)
|
||||
{
|
||||
std::string args[] =
|
||||
{
|
||||
arg0,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3
|
||||
};
|
||||
return format(fmt, 4, args);
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::format(const std::string& fmt, int argc, std::string argv[])
|
||||
{
|
||||
std::string result;
|
||||
std::string::const_iterator it = fmt.begin();
|
||||
while (it != fmt.end())
|
||||
{
|
||||
if (*it == '$')
|
||||
{
|
||||
++it;
|
||||
if (*it == '$')
|
||||
{
|
||||
result += '$';
|
||||
}
|
||||
else if (*it >= '0' && *it <= '9')
|
||||
{
|
||||
int i = *it - '0';
|
||||
if (i < argc)
|
||||
result += argv[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
result += '$';
|
||||
result += *it;
|
||||
}
|
||||
}
|
||||
else result += *it;
|
||||
++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Logger::formatDump(std::string& message, const void* buffer, std::size_t length)
|
||||
{
|
||||
const int BYTES_PER_LINE = 16;
|
||||
|
||||
message.reserve(message.size() + length*6);
|
||||
if (!message.empty()) message.append("\n");
|
||||
unsigned char* base = (unsigned char*) buffer;
|
||||
int addr = 0;
|
||||
while (addr < length)
|
||||
{
|
||||
if (addr > 0) message.append("\n");
|
||||
message.append(NumberFormatter::formatHex(addr, 4));
|
||||
message.append(" ");
|
||||
int offset = 0;
|
||||
while (addr + offset < length && offset < BYTES_PER_LINE)
|
||||
{
|
||||
message.append(NumberFormatter::formatHex(base[addr + offset], 2));
|
||||
message.append(offset == 7 ? " " : " ");
|
||||
++offset;
|
||||
}
|
||||
if (offset < 7) message.append(" ");
|
||||
while (offset < BYTES_PER_LINE) { message.append(" "); ++offset; }
|
||||
message.append(" ");
|
||||
offset = 0;
|
||||
while (addr + offset < length && offset < BYTES_PER_LINE)
|
||||
{
|
||||
unsigned char c = base[addr + offset];
|
||||
message += (c >= 32 && c < 127) ? (char) c : '.';
|
||||
++offset;
|
||||
}
|
||||
addr += BYTES_PER_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Logger& Logger::get(const std::string& name)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
return unsafeGet(name);
|
||||
}
|
||||
|
||||
|
||||
Logger& Logger::unsafeGet(const std::string& name)
|
||||
{
|
||||
Ptr pLogger = find(name);
|
||||
if (!pLogger)
|
||||
{
|
||||
if (name == ROOT)
|
||||
{
|
||||
pLogger = new Logger(name, 0, Message::PRIO_INFORMATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger& par = parent(name);
|
||||
pLogger = new Logger(name, par.getChannel(), par.getLevel());
|
||||
}
|
||||
add(pLogger);
|
||||
}
|
||||
return *pLogger;
|
||||
}
|
||||
|
||||
|
||||
Logger& Logger::create(const std::string& name, Channel::Ptr pChannel, int level)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
if (find(name)) throw ExistsException();
|
||||
Ptr pLogger = new Logger(name, pChannel, level);
|
||||
add(pLogger);
|
||||
return *pLogger;
|
||||
}
|
||||
|
||||
|
||||
Logger& Logger::root()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
return unsafeGet(ROOT);
|
||||
}
|
||||
|
||||
|
||||
Logger::Ptr Logger::has(const std::string& name)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
return find(name);
|
||||
}
|
||||
|
||||
|
||||
void Logger::shutdown()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
_pLoggerMap.reset();
|
||||
}
|
||||
|
||||
|
||||
Logger::Ptr Logger::find(const std::string& name)
|
||||
{
|
||||
if (_pLoggerMap)
|
||||
{
|
||||
LoggerMap::iterator it = _pLoggerMap->find(name);
|
||||
if (it != _pLoggerMap->end()) return it->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Logger::destroy(const std::string& name)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
if (_pLoggerMap)
|
||||
{
|
||||
LoggerMap::iterator it = _pLoggerMap->find(name);
|
||||
if (it != _pLoggerMap->end()) _pLoggerMap->erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::names(std::vector<std::string>& names)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mapMtx);
|
||||
|
||||
names.clear();
|
||||
if (_pLoggerMap)
|
||||
{
|
||||
for (const auto& p: *_pLoggerMap)
|
||||
{
|
||||
names.push_back(p.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Logger& Logger::parent(const std::string& name)
|
||||
{
|
||||
std::string::size_type pos = name.rfind('.');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string pname = name.substr(0, pos);
|
||||
Ptr pParent = find(pname);
|
||||
if (pParent)
|
||||
return *pParent;
|
||||
else
|
||||
return parent(pname);
|
||||
}
|
||||
else return unsafeGet(ROOT);
|
||||
}
|
||||
|
||||
|
||||
int Logger::parseLevel(const std::string& level)
|
||||
{
|
||||
if (icompare(level, "none") == 0)
|
||||
return 0;
|
||||
else if (icompare(level, "fatal") == 0)
|
||||
return Message::PRIO_FATAL;
|
||||
else if (icompare(level, "critical") == 0)
|
||||
return Message::PRIO_CRITICAL;
|
||||
else if (icompare(level, "error") == 0)
|
||||
return Message::PRIO_ERROR;
|
||||
else if (icompare(level, "warning") == 0)
|
||||
return Message::PRIO_WARNING;
|
||||
else if (icompare(level, "notice") == 0)
|
||||
return Message::PRIO_NOTICE;
|
||||
else if (icompare(level, "information") == 0)
|
||||
return Message::PRIO_INFORMATION;
|
||||
else if (icompare(level, "debug") == 0)
|
||||
return Message::PRIO_DEBUG;
|
||||
else if (icompare(level, "trace") == 0)
|
||||
return Message::PRIO_TRACE;
|
||||
else
|
||||
{
|
||||
int numLevel;
|
||||
if (Poco::NumberParser::tryParse(level, numLevel))
|
||||
{
|
||||
if (numLevel > 0 && numLevel < 9)
|
||||
return numLevel;
|
||||
else
|
||||
throw InvalidArgumentException("Log level out of range ", level);
|
||||
}
|
||||
else
|
||||
throw InvalidArgumentException("Not a valid log level", level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::add(Ptr pLogger)
|
||||
{
|
||||
if (!_pLoggerMap) _pLoggerMap.reset(new LoggerMap);
|
||||
_pLoggerMap->insert(LoggerMap::value_type(pLogger->name(), pLogger));
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// LoggingFactory.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: LoggingFactory
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LoggingFactory.h"
|
||||
#include "Poco/SingletonHolder.h"
|
||||
#include "Poco/AsyncChannel.h"
|
||||
#include "Poco/ConsoleChannel.h"
|
||||
#include "Poco/FileChannel.h"
|
||||
#include "Poco/SimpleFileChannel.h"
|
||||
#include "Poco/FormattingChannel.h"
|
||||
#include "Poco/SplitterChannel.h"
|
||||
#include "Poco/NullChannel.h"
|
||||
#include "Poco/EventChannel.h"
|
||||
#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_NO_SYSLOGCHANNEL)
|
||||
#include "Poco/SyslogChannel.h"
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS) && !defined(_WIN32_WCE)
|
||||
#include "Poco/EventLogChannel.h"
|
||||
#include "Poco/WindowsConsoleChannel.h"
|
||||
#endif
|
||||
#include "Poco/PatternFormatter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
LoggingFactory::LoggingFactory()
|
||||
{
|
||||
registerBuiltins();
|
||||
}
|
||||
|
||||
|
||||
LoggingFactory::~LoggingFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LoggingFactory::registerChannelClass(const std::string& className, ChannelInstantiator* pFactory)
|
||||
{
|
||||
_channelFactory.registerClass(className, pFactory);
|
||||
}
|
||||
|
||||
|
||||
void LoggingFactory::registerFormatterClass(const std::string& className, FormatterFactory* pFactory)
|
||||
{
|
||||
_formatterFactory.registerClass(className, pFactory);
|
||||
}
|
||||
|
||||
|
||||
Channel::Ptr LoggingFactory::createChannel(const std::string& className) const
|
||||
{
|
||||
return _channelFactory.createInstance(className);
|
||||
}
|
||||
|
||||
|
||||
Formatter::Ptr LoggingFactory::createFormatter(const std::string& className) const
|
||||
{
|
||||
return _formatterFactory.createInstance(className);
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static SingletonHolder<LoggingFactory> sh;
|
||||
}
|
||||
|
||||
|
||||
LoggingFactory& LoggingFactory::defaultFactory()
|
||||
{
|
||||
return *sh.get();
|
||||
}
|
||||
|
||||
|
||||
void LoggingFactory::registerBuiltins()
|
||||
{
|
||||
_channelFactory.registerClass("AsyncChannel", new Instantiator<AsyncChannel, Channel>);
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS) && !defined(_WIN32_WCE)
|
||||
_channelFactory.registerClass("ConsoleChannel", new Instantiator<WindowsConsoleChannel, Channel>);
|
||||
_channelFactory.registerClass("ColorConsoleChannel", new Instantiator<WindowsColorConsoleChannel, Channel>);
|
||||
#else
|
||||
_channelFactory.registerClass("ConsoleChannel", new Instantiator<ConsoleChannel, Channel>);
|
||||
_channelFactory.registerClass("ColorConsoleChannel", new Instantiator<ColorConsoleChannel, Channel>);
|
||||
#endif
|
||||
|
||||
#ifndef POCO_NO_FILECHANNEL
|
||||
_channelFactory.registerClass("FileChannel", new Instantiator<FileChannel, Channel>);
|
||||
_channelFactory.registerClass("SimpleFileChannel", new Instantiator<SimpleFileChannel, Channel>);
|
||||
#endif
|
||||
_channelFactory.registerClass("FormattingChannel", new Instantiator<FormattingChannel, Channel>);
|
||||
#ifndef POCO_NO_SPLITTERCHANNEL
|
||||
_channelFactory.registerClass("SplitterChannel", new Instantiator<SplitterChannel, Channel>);
|
||||
#endif
|
||||
_channelFactory.registerClass("NullChannel", new Instantiator<NullChannel, Channel>);
|
||||
_channelFactory.registerClass("EventChannel", new Instantiator<EventChannel, Channel>);
|
||||
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
#ifndef POCO_NO_SYSLOGCHANNEL
|
||||
_channelFactory.registerClass("SyslogChannel", new Instantiator<SyslogChannel, Channel>);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS) && !defined(_WIN32_WCE)
|
||||
_channelFactory.registerClass("EventLogChannel", new Instantiator<EventLogChannel, Channel>);
|
||||
#endif
|
||||
|
||||
_formatterFactory.registerClass("PatternFormatter", new Instantiator<PatternFormatter, Formatter>);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// LoggingRegistry.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: LoggingRegistry
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/LoggingRegistry.h"
|
||||
#include "Poco/SingletonHolder.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
LoggingRegistry::LoggingRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LoggingRegistry::~LoggingRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Channel::Ptr LoggingRegistry::channelForName(const std::string& name) const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
ChannelMap::const_iterator it = _channelMap.find(name);
|
||||
if (it != _channelMap.end())
|
||||
return it->second;
|
||||
else
|
||||
throw NotFoundException("logging channel", name);
|
||||
}
|
||||
|
||||
|
||||
Formatter::Ptr LoggingRegistry::formatterForName(const std::string& name) const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
FormatterMap::const_iterator it = _formatterMap.find(name);
|
||||
if (it != _formatterMap.end())
|
||||
return it->second;
|
||||
else
|
||||
throw NotFoundException("logging formatter", name);
|
||||
}
|
||||
|
||||
|
||||
void LoggingRegistry::registerChannel(const std::string& name, Channel::Ptr pChannel)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_channelMap[name] = ChannelPtr(pChannel, true);
|
||||
}
|
||||
|
||||
|
||||
void LoggingRegistry::registerFormatter(const std::string& name, Formatter::Ptr pFormatter)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_formatterMap[name] = FormatterPtr(pFormatter, true);
|
||||
}
|
||||
|
||||
|
||||
void LoggingRegistry::unregisterChannel(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
ChannelMap::iterator it = _channelMap.find(name);
|
||||
if (it != _channelMap.end())
|
||||
_channelMap.erase(it);
|
||||
else
|
||||
throw NotFoundException("logging channel", name);
|
||||
}
|
||||
|
||||
|
||||
void LoggingRegistry::unregisterFormatter(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
FormatterMap::iterator it = _formatterMap.find(name);
|
||||
if (it != _formatterMap.end())
|
||||
_formatterMap.erase(it);
|
||||
else
|
||||
throw NotFoundException("logging formatter", name);
|
||||
}
|
||||
|
||||
|
||||
void LoggingRegistry::clear()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_channelMap.clear();
|
||||
_formatterMap.clear();
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static SingletonHolder<LoggingRegistry> sh;
|
||||
}
|
||||
|
||||
|
||||
LoggingRegistry& LoggingRegistry::defaultRegistry()
|
||||
{
|
||||
return *sh.get();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
//
|
||||
// MD4Engine.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Crypt
|
||||
// Module: MD4Engine
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
//
|
||||
// MD4 (RFC 1320) algorithm:
|
||||
// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
// rights reserved.
|
||||
//
|
||||
// License to copy and use this software is granted provided that it
|
||||
// is identified as the "RSA Data Security, Inc. MD4 Message-Digest
|
||||
// Algorithm" in all material mentioning or referencing this software
|
||||
// or this function.
|
||||
//
|
||||
// License is also granted to make and use derivative works provided
|
||||
// that such works are identified as "derived from the RSA Data
|
||||
// Security, Inc. MD4 Message-Digest Algorithm" in all material
|
||||
// mentioning or referencing the derived work.
|
||||
//
|
||||
// RSA Data Security, Inc. makes no representations concerning either
|
||||
// the merchantability of this software or the suitability of this
|
||||
// software for any particular purpose. It is provided "as is"
|
||||
// without express or implied warranty of any kind.
|
||||
//
|
||||
// These notices must be retained in any copies of any part of this
|
||||
// documentation and/or software.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/MD4Engine.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
MD4Engine::MD4Engine()
|
||||
{
|
||||
_digest.reserve(16);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
MD4Engine::~MD4Engine()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
void MD4Engine::updateImpl(const void* input_, std::size_t inputLen)
|
||||
{
|
||||
const unsigned char* input = (const unsigned char*) input_;
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((_context.count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((_context.count[0] += ((UInt32) inputLen << 3)) < ((UInt32) inputLen << 3))
|
||||
_context.count[1]++;
|
||||
_context.count[1] += ((UInt32) inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (inputLen >= partLen)
|
||||
{
|
||||
std::memcpy(&_context.buffer[index], input, partLen);
|
||||
transform(_context.state, _context.buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
transform(_context.state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
std::memcpy(&_context.buffer[index], &input[i], inputLen-i);
|
||||
}
|
||||
|
||||
|
||||
std::size_t MD4Engine::digestLength() const
|
||||
{
|
||||
return DIGEST_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void MD4Engine::reset()
|
||||
{
|
||||
std::memset(&_context, 0, sizeof(_context));
|
||||
_context.count[0] = _context.count[1] = 0;
|
||||
_context.state[0] = 0x67452301;
|
||||
_context.state[1] = 0xefcdab89;
|
||||
_context.state[2] = 0x98badcfe;
|
||||
_context.state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
|
||||
const DigestEngine::Digest& MD4Engine::digest()
|
||||
{
|
||||
static const unsigned char PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
encode(bits, _context.count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64. */
|
||||
index = (unsigned int)((_context.count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update(PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
update(bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
unsigned char digest[16];
|
||||
encode(digest, _context.state, 16);
|
||||
_digest.clear();
|
||||
_digest.insert(_digest.begin(), digest, digest + sizeof(digest));
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
std::memset(&_context, 0, sizeof (_context));
|
||||
reset();
|
||||
return _digest;
|
||||
}
|
||||
|
||||
|
||||
/* Constants for MD4Transform routine. */
|
||||
#define S11 3
|
||||
#define S12 7
|
||||
#define S13 11
|
||||
#define S14 19
|
||||
#define S21 3
|
||||
#define S22 5
|
||||
#define S23 9
|
||||
#define S24 13
|
||||
#define S31 3
|
||||
#define S32 9
|
||||
#define S33 11
|
||||
#define S34 15
|
||||
|
||||
|
||||
/* F, G and H are basic MD4 functions. */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
|
||||
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s) { \
|
||||
(a) += F ((b), (c), (d)) + (x); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UInt32)0x5a827999; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UInt32)0x6ed9eba1; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
|
||||
|
||||
void MD4Engine::transform (UInt32 state[4], const unsigned char block[64])
|
||||
{
|
||||
UInt32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 0], S21); /* 17 */
|
||||
GG (d, a, b, c, x[ 4], S22); /* 18 */
|
||||
GG (c, d, a, b, x[ 8], S23); /* 19 */
|
||||
GG (b, c, d, a, x[12], S24); /* 20 */
|
||||
GG (a, b, c, d, x[ 1], S21); /* 21 */
|
||||
GG (d, a, b, c, x[ 5], S22); /* 22 */
|
||||
GG (c, d, a, b, x[ 9], S23); /* 23 */
|
||||
GG (b, c, d, a, x[13], S24); /* 24 */
|
||||
GG (a, b, c, d, x[ 2], S21); /* 25 */
|
||||
GG (d, a, b, c, x[ 6], S22); /* 26 */
|
||||
GG (c, d, a, b, x[10], S23); /* 27 */
|
||||
GG (b, c, d, a, x[14], S24); /* 28 */
|
||||
GG (a, b, c, d, x[ 3], S21); /* 29 */
|
||||
GG (d, a, b, c, x[ 7], S22); /* 30 */
|
||||
GG (c, d, a, b, x[11], S23); /* 31 */
|
||||
GG (b, c, d, a, x[15], S24); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 0], S31); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32); /* 34 */
|
||||
HH (c, d, a, b, x[ 4], S33); /* 35 */
|
||||
HH (b, c, d, a, x[12], S34); /* 36 */
|
||||
HH (a, b, c, d, x[ 2], S31); /* 37 */
|
||||
HH (d, a, b, c, x[10], S32); /* 38 */
|
||||
HH (c, d, a, b, x[ 6], S33); /* 39 */
|
||||
HH (b, c, d, a, x[14], S34); /* 40 */
|
||||
HH (a, b, c, d, x[ 1], S31); /* 41 */
|
||||
HH (d, a, b, c, x[ 9], S32); /* 42 */
|
||||
HH (c, d, a, b, x[ 5], S33); /* 43 */
|
||||
HH (b, c, d, a, x[13], S34); /* 44 */
|
||||
HH (a, b, c, d, x[ 3], S31); /* 45 */
|
||||
HH (d, a, b, c, x[11], S32); /* 46 */
|
||||
HH (c, d, a, b, x[ 7], S33); /* 47 */
|
||||
HH (b, c, d, a, x[15], S34); /* 48 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
std::memset(x, 0, sizeof(x));
|
||||
}
|
||||
|
||||
|
||||
void MD4Engine::encode(unsigned char* output, const UInt32* input, std::size_t len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MD4Engine::decode(UInt32* output, const unsigned char* input, std::size_t len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UInt32)input[j]) | (((UInt32)input[j+1]) << 8) |
|
||||
(((UInt32)input[j+2]) << 16) | (((UInt32)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
//
|
||||
// MD5Engine.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Crypt
|
||||
// Module: MD5Engine
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
//
|
||||
// MD5 (RFC 1321) algorithm:
|
||||
// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
// rights reserved.
|
||||
//
|
||||
// License to copy and use this software is granted provided that it
|
||||
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
// Algorithm" in all material mentioning or referencing this software
|
||||
// or this function.
|
||||
//
|
||||
// License is also granted to make and use derivative works provided
|
||||
// that such works are identified as "derived from the RSA Data
|
||||
// Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
// mentioning or referencing the derived work.
|
||||
//
|
||||
// RSA Data Security, Inc. makes no representations concerning either
|
||||
// the merchantability of this software or the suitability of this
|
||||
// software for any particular purpose. It is provided "as is"
|
||||
// without express or implied warranty of any kind.
|
||||
//
|
||||
// These notices must be retained in any copies of any part of this
|
||||
// documentation and/or software.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/MD5Engine.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
MD5Engine::MD5Engine()
|
||||
{
|
||||
_digest.reserve(16);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
MD5Engine::~MD5Engine()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
void MD5Engine::updateImpl(const void* input_, std::size_t inputLen)
|
||||
{
|
||||
const unsigned char* input = (const unsigned char*) input_;
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((_context.count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((_context.count[0] += ((UInt32) inputLen << 3)) < ((UInt32) inputLen << 3))
|
||||
_context.count[1]++;
|
||||
_context.count[1] += ((UInt32) inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (inputLen >= partLen)
|
||||
{
|
||||
std::memcpy(&_context.buffer[index], input, partLen);
|
||||
transform(_context.state, _context.buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
transform(_context.state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
std::memcpy(&_context.buffer[index], &input[i],inputLen-i);
|
||||
}
|
||||
|
||||
|
||||
std::size_t MD5Engine::digestLength() const
|
||||
{
|
||||
return DIGEST_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void MD5Engine::reset()
|
||||
{
|
||||
std::memset(&_context, 0, sizeof(_context));
|
||||
_context.count[0] = _context.count[1] = 0;
|
||||
_context.state[0] = 0x67452301;
|
||||
_context.state[1] = 0xefcdab89;
|
||||
_context.state[2] = 0x98badcfe;
|
||||
_context.state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
|
||||
const DigestEngine::Digest& MD5Engine::digest()
|
||||
{
|
||||
static const unsigned char PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
encode(bits, _context.count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64. */
|
||||
index = (unsigned int)((_context.count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update(PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
update(bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
unsigned char digest[16];
|
||||
encode(digest, _context.state, 16);
|
||||
_digest.clear();
|
||||
_digest.insert(_digest.begin(), digest, digest + sizeof(digest));
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
std::memset(&_context, 0, sizeof (_context));
|
||||
reset();
|
||||
return _digest;
|
||||
}
|
||||
|
||||
|
||||
/* Constants for MD5Transform routine. */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
|
||||
/* F, G, H and I are basic MD5 functions. */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation. */
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (UInt32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UInt32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UInt32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (UInt32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
|
||||
void MD5Engine::transform (UInt32 state[4], const unsigned char block[64])
|
||||
{
|
||||
UInt32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
std::memset(x, 0, sizeof(x));
|
||||
}
|
||||
|
||||
|
||||
void MD5Engine::encode(unsigned char* output, const UInt32* input, std::size_t len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MD5Engine::decode(UInt32* output, const unsigned char* input, std::size_t len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UInt32)input[j]) | (((UInt32)input[j+1]) << 8) |
|
||||
(((UInt32)input[j+2]) << 16) | (((UInt32)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
BIN
Binary file not shown.
+31
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Manifest.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: SharedLibrary
|
||||
// Module: ClassLoader
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Manifest.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
ManifestBase::ManifestBase()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ManifestBase::~ManifestBase()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// MemoryPool.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: MemoryPool
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/MemoryPool.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
MemoryPool::MemoryPool(std::size_t blockSize, int preAlloc, int maxAlloc):
|
||||
_blockSize(blockSize),
|
||||
_maxAlloc(maxAlloc),
|
||||
_allocated(preAlloc)
|
||||
{
|
||||
poco_assert (maxAlloc == 0 || maxAlloc >= preAlloc);
|
||||
poco_assert (preAlloc >= 0 && maxAlloc >= 0);
|
||||
|
||||
int r = BLOCK_RESERVE;
|
||||
if (preAlloc > r)
|
||||
r = preAlloc;
|
||||
if (maxAlloc > 0 && maxAlloc < r)
|
||||
r = maxAlloc;
|
||||
_blocks.reserve(r);
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < preAlloc; ++i)
|
||||
{
|
||||
_blocks.push_back(new char[_blockSize]);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemoryPool::~MemoryPool()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void MemoryPool::clear()
|
||||
{
|
||||
for (auto p: _blocks)
|
||||
{
|
||||
delete [] p;
|
||||
}
|
||||
_blocks.clear();
|
||||
}
|
||||
|
||||
|
||||
void* MemoryPool::get()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (_blocks.empty())
|
||||
{
|
||||
if (_maxAlloc == 0 || _allocated < _maxAlloc)
|
||||
{
|
||||
++_allocated;
|
||||
return new char[_blockSize];
|
||||
}
|
||||
else throw OutOfMemoryException("MemoryPool exhausted");
|
||||
}
|
||||
else
|
||||
{
|
||||
char* ptr = _blocks.back();
|
||||
_blocks.pop_back();
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MemoryPool::release(void* ptr)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
try
|
||||
{
|
||||
_blocks.push_back(reinterpret_cast<char*>(ptr));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// MemoryStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: MemoryStream
|
||||
//
|
||||
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/MemoryStream.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
MemoryIOS::MemoryIOS(char* pBuffer, std::streamsize bufferSize):
|
||||
_buf(pBuffer, bufferSize)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
MemoryIOS::~MemoryIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MemoryInputStream::MemoryInputStream(const char* pBuffer, std::streamsize bufferSize):
|
||||
MemoryIOS(const_cast<char*>(pBuffer), bufferSize),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MemoryInputStream::~MemoryInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MemoryOutputStream::MemoryOutputStream(char* pBuffer, std::streamsize bufferSize):
|
||||
MemoryIOS(pBuffer, bufferSize),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MemoryOutputStream::~MemoryOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
//
|
||||
// Message.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Logging
|
||||
// Module: Message
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/Exception.h"
|
||||
#if !defined(POCO_VXWORKS)
|
||||
#include "Poco/Process.h"
|
||||
#endif
|
||||
#include "Poco/Thread.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
Message::Message():
|
||||
_prio(PRIO_FATAL),
|
||||
_tid(0),
|
||||
_pid(0),
|
||||
_file(0),
|
||||
_line(0),
|
||||
_pMap(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
Message::Message(const std::string& source, const std::string& text, Priority prio):
|
||||
_source(source),
|
||||
_text(text),
|
||||
_prio(prio),
|
||||
_tid(0),
|
||||
_pid(0),
|
||||
_file(0),
|
||||
_line(0),
|
||||
_pMap(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
Message::Message(const std::string& source, const std::string& text, Priority prio, const char* file, int line):
|
||||
_source(source),
|
||||
_text(text),
|
||||
_prio(prio),
|
||||
_tid(0),
|
||||
_pid(0),
|
||||
_file(file),
|
||||
_line(line),
|
||||
_pMap(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
Message::Message(const Message& msg):
|
||||
_source(msg._source),
|
||||
_text(msg._text),
|
||||
_prio(msg._prio),
|
||||
_time(msg._time),
|
||||
_tid(msg._tid),
|
||||
_thread(msg._thread),
|
||||
_pid(msg._pid),
|
||||
_file(msg._file),
|
||||
_line(msg._line)
|
||||
{
|
||||
if (msg._pMap)
|
||||
_pMap = new StringMap(*msg._pMap);
|
||||
else
|
||||
_pMap = 0;
|
||||
}
|
||||
|
||||
|
||||
Message::Message(Message&& msg) noexcept:
|
||||
_source(std::move(msg._source)),
|
||||
_text(std::move(msg._text)),
|
||||
_prio(std::move(msg._prio)),
|
||||
_time(std::move(msg._time)),
|
||||
_tid(std::move(msg._tid)),
|
||||
_thread(std::move(msg._thread)),
|
||||
_pid(std::move(msg._pid)),
|
||||
_file(std::move(msg._file)),
|
||||
_line(std::move(msg._line))
|
||||
{
|
||||
_pMap = msg._pMap;
|
||||
msg._pMap = nullptr;
|
||||
}
|
||||
|
||||
|
||||
Message::Message(const Message& msg, const std::string& text):
|
||||
_source(msg._source),
|
||||
_text(text),
|
||||
_prio(msg._prio),
|
||||
_time(msg._time),
|
||||
_tid(msg._tid),
|
||||
_thread(msg._thread),
|
||||
_pid(msg._pid),
|
||||
_file(msg._file),
|
||||
_line(msg._line)
|
||||
{
|
||||
if (msg._pMap)
|
||||
_pMap = new StringMap(*msg._pMap);
|
||||
else
|
||||
_pMap = 0;
|
||||
}
|
||||
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
delete _pMap;
|
||||
}
|
||||
|
||||
|
||||
void Message::init()
|
||||
{
|
||||
#if !defined(POCO_VXWORKS)
|
||||
_pid = Process::id();
|
||||
#endif
|
||||
Thread* pThread = Thread::current();
|
||||
if (pThread)
|
||||
{
|
||||
_tid = pThread->id();
|
||||
_thread = pThread->name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Message& Message::operator = (const Message& msg)
|
||||
{
|
||||
if (&msg != this)
|
||||
{
|
||||
Message tmp(msg);
|
||||
swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Message& Message::operator = (Message&& msg) noexcept
|
||||
{
|
||||
_source = std::move(msg._source);
|
||||
_text = std::move(msg._text);
|
||||
_prio = std::move(msg._prio);
|
||||
_time = std::move(msg._time);
|
||||
_tid = std::move(msg._tid);
|
||||
_thread = std::move(msg._thread);
|
||||
_pid = std::move(msg._pid);
|
||||
_file = std::move(msg._file);
|
||||
_line = std::move(msg._line);
|
||||
delete _pMap;
|
||||
_pMap = msg._pMap;
|
||||
msg._pMap = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Message::swap(Message& msg)
|
||||
{
|
||||
using std::swap;
|
||||
swap(_source, msg._source);
|
||||
swap(_text, msg._text);
|
||||
swap(_prio, msg._prio);
|
||||
swap(_time, msg._time);
|
||||
swap(_tid, msg._tid);
|
||||
swap(_thread, msg._thread);
|
||||
swap(_pid, msg._pid);
|
||||
swap(_file, msg._file);
|
||||
swap(_line, msg._line);
|
||||
swap(_pMap, msg._pMap);
|
||||
}
|
||||
|
||||
|
||||
void Message::setSource(const std::string& src)
|
||||
{
|
||||
_source = src;
|
||||
}
|
||||
|
||||
|
||||
void Message::setText(const std::string& text)
|
||||
{
|
||||
_text = text;
|
||||
}
|
||||
|
||||
|
||||
void Message::setPriority(Priority prio)
|
||||
{
|
||||
_prio = prio;
|
||||
}
|
||||
|
||||
|
||||
void Message::setTime(const Timestamp& t)
|
||||
{
|
||||
_time = t;
|
||||
}
|
||||
|
||||
|
||||
void Message::setThread(const std::string& thread)
|
||||
{
|
||||
_thread = thread;
|
||||
}
|
||||
|
||||
|
||||
void Message::setTid(long tid)
|
||||
{
|
||||
_tid = tid;
|
||||
}
|
||||
|
||||
|
||||
void Message::setPid(long pid)
|
||||
{
|
||||
_pid = pid;
|
||||
}
|
||||
|
||||
|
||||
void Message::setSourceFile(const char* file)
|
||||
{
|
||||
_file = file;
|
||||
}
|
||||
|
||||
|
||||
void Message::setSourceLine(int line)
|
||||
{
|
||||
_line = line;
|
||||
}
|
||||
|
||||
|
||||
bool Message::has(const std::string& param) const
|
||||
{
|
||||
return _pMap && (_pMap->find(param) != _pMap->end());
|
||||
}
|
||||
|
||||
|
||||
const std::string& Message::get(const std::string& param) const
|
||||
{
|
||||
if (_pMap)
|
||||
{
|
||||
StringMap::const_iterator it = _pMap->find(param);
|
||||
if (it != _pMap->end())
|
||||
return it->second;
|
||||
}
|
||||
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
|
||||
const std::string& Message::get(const std::string& param, const std::string& defaultValue) const
|
||||
{
|
||||
if (_pMap)
|
||||
{
|
||||
StringMap::const_iterator it = _pMap->find(param);
|
||||
if (it != _pMap->end())
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
void Message::set(const std::string& param, const std::string& value)
|
||||
{
|
||||
if (!_pMap)
|
||||
_pMap = new StringMap;
|
||||
|
||||
std::pair<StringMap::iterator, bool> result =
|
||||
_pMap->insert(std::make_pair(param, value));
|
||||
if (!result.second)
|
||||
{
|
||||
result.first->second = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const std::string& Message::operator [] (const std::string& param) const
|
||||
{
|
||||
if (_pMap)
|
||||
return (*_pMap)[param];
|
||||
else
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
|
||||
std::string& Message::operator [] (const std::string& param)
|
||||
{
|
||||
if (!_pMap)
|
||||
_pMap = new StringMap;
|
||||
return (*_pMap)[param];
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user