1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-08-12 10:57: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:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions

75
vendor/POCO/MongoDB/src/Array.cpp vendored Normal file
View File

@@ -0,0 +1,75 @@
//
// Array.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Array
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Array.h"
#include <sstream>
namespace Poco {
namespace MongoDB {
Array::Array():
Document()
{
}
Array::~Array()
{
}
Element::Ptr Array::get(int pos) const
{
std::string name = Poco::NumberFormatter::format(pos);
return Document::get(name);
}
std::string Array::toString(int indent) const
{
std::ostringstream oss;
oss << "[";
if (indent > 0) oss << std::endl;
for (ElementSet::const_iterator it = _elements.begin(); it != _elements.end(); ++it)
{
if (it != _elements.begin())
{
oss << ",";
if (indent > 0) oss << std::endl;
}
for (int i = 0; i < indent; ++i) oss << ' ';
oss << (*it)->toString(indent > 0 ? indent + 2 : 0);
}
if (indent > 0)
{
oss << std::endl;
if (indent >= 2) indent -= 2;
for (int i = 0; i < indent; ++i) oss << ' ';
}
oss << "]";
return oss.str();
}
} } // Namespace Poco::Mongo

89
vendor/POCO/MongoDB/src/Binary.cpp vendored Normal file
View File

@@ -0,0 +1,89 @@
//
// Binary.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Binary
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Binary.h"
namespace Poco {
namespace MongoDB {
Binary::Binary():
_buffer(0),
_subtype(0)
{
}
Binary::Binary(Poco::Int32 size, unsigned char subtype):
_buffer(size),
_subtype(subtype)
{
}
Binary::Binary(const UUID& uuid):
_buffer(128 / 8),
_subtype(0x04)
{
unsigned char szUUID[16];
uuid.copyTo((char*) szUUID);
_buffer.assign(szUUID, 16);
}
Binary::Binary(const std::string& data, unsigned char subtype):
_buffer(reinterpret_cast<const unsigned char*>(data.data()), data.size()),
_subtype(subtype)
{
}
Binary::Binary(const void* data, Poco::Int32 size, unsigned char subtype):
_buffer(reinterpret_cast<const unsigned char*>(data), size),
_subtype(subtype)
{
}
Binary::~Binary()
{
}
std::string Binary::toString(int indent) const
{
std::ostringstream oss;
Base64Encoder encoder(oss);
MemoryInputStream mis((const char*) _buffer.begin(), _buffer.size());
StreamCopier::copyStream(mis, encoder);
encoder.close();
return oss.str();
}
UUID Binary::uuid() const
{
if (_subtype == 0x04 && _buffer.size() == 16)
{
UUID uuid;
uuid.copyFrom((const char*) _buffer.begin());
return uuid;
}
throw BadCastException("Invalid subtype");
}
} } // namespace Poco::MongoDB

235
vendor/POCO/MongoDB/src/Connection.cpp vendored Normal file
View File

@@ -0,0 +1,235 @@
//
// Connection.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Connection
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Net/SocketStream.h"
#include "Poco/MongoDB/Connection.h"
#include "Poco/MongoDB/Database.h"
#include "Poco/URI.h"
#include "Poco/Format.h"
#include "Poco/NumberParser.h"
#include "Poco/Exception.h"
namespace Poco {
namespace MongoDB {
Connection::SocketFactory::SocketFactory()
{
}
Connection::SocketFactory::~SocketFactory()
{
}
Poco::Net::StreamSocket Connection::SocketFactory::createSocket(const std::string& host, int port, Poco::Timespan connectTimeout, bool secure)
{
if (!secure)
{
Poco::Net::SocketAddress addr(host, port);
Poco::Net::StreamSocket socket;
if (connectTimeout > 0)
socket.connect(addr, connectTimeout);
else
socket.connect(addr);
return socket;
}
else throw Poco::NotImplementedException("Default SocketFactory implementation does not support SecureStreamSocket");
}
Connection::Connection():
_address(),
_socket()
{
}
Connection::Connection(const std::string& hostAndPort):
_address(hostAndPort),
_socket()
{
connect();
}
Connection::Connection(const std::string& uri, SocketFactory& socketFactory):
_address(),
_socket()
{
connect(uri, socketFactory);
}
Connection::Connection(const std::string& host, int port):
_address(host, port),
_socket()
{
connect();
}
Connection::Connection(const Poco::Net::SocketAddress& addrs):
_address(addrs),
_socket()
{
connect();
}
Connection::Connection(const Poco::Net::StreamSocket& socket):
_address(socket.peerAddress()),
_socket(socket)
{
}
Connection::~Connection()
{
try
{
disconnect();
}
catch (...)
{
}
}
void Connection::connect()
{
_socket.connect(_address);
}
void Connection::connect(const std::string& hostAndPort)
{
_address = Poco::Net::SocketAddress(hostAndPort);
connect();
}
void Connection::connect(const std::string& host, int port)
{
_address = Poco::Net::SocketAddress(host, port);
connect();
}
void Connection::connect(const Poco::Net::SocketAddress& addrs)
{
_address = addrs;
connect();
}
void Connection::connect(const Poco::Net::StreamSocket& socket)
{
_address = socket.peerAddress();
_socket = socket;
}
void Connection::connect(const std::string& uri, SocketFactory& socketFactory)
{
Poco::URI theURI(uri);
if (theURI.getScheme() != "mongodb") throw Poco::UnknownURISchemeException(uri);
std::string userInfo = theURI.getUserInfo();
std::string host = theURI.getHost();
Poco::UInt16 port = theURI.getPort();
if (port == 0) port = 27017;
std::string databaseName = theURI.getPath();
if (!databaseName.empty() && databaseName[0] == '/') databaseName.erase(0, 1);
if (databaseName.empty()) databaseName = "admin";
bool ssl = false;
Poco::Timespan connectTimeout;
Poco::Timespan socketTimeout;
std::string authMechanism = Database::AUTH_SCRAM_SHA1;
Poco::URI::QueryParameters params = theURI.getQueryParameters();
for (Poco::URI::QueryParameters::const_iterator it = params.begin(); it != params.end(); ++it)
{
if (it->first == "ssl")
{
ssl = (it->second == "true");
}
else if (it->first == "connectTimeoutMS")
{
connectTimeout = static_cast<Poco::Timespan::TimeDiff>(1000)*Poco::NumberParser::parse(it->second);
}
else if (it->first == "socketTimeoutMS")
{
socketTimeout = static_cast<Poco::Timespan::TimeDiff>(1000)*Poco::NumberParser::parse(it->second);
}
else if (it->first == "authMechanism")
{
authMechanism = it->second;
}
}
connect(socketFactory.createSocket(host, port, connectTimeout, ssl));
if (socketTimeout > 0)
{
_socket.setSendTimeout(socketTimeout);
_socket.setReceiveTimeout(socketTimeout);
}
if (!userInfo.empty())
{
std::string username;
std::string password;
std::string::size_type pos = userInfo.find(':');
if (pos != std::string::npos)
{
username.assign(userInfo, 0, pos++);
password.assign(userInfo, pos, userInfo.size() - pos);
}
else username = userInfo;
Database database(databaseName);
if (!database.authenticate(*this, username, password, authMechanism))
throw Poco::NoPermissionException(Poco::format("Access to MongoDB database %s denied for user %s", databaseName, username));
}
}
void Connection::disconnect()
{
_socket.close();
}
void Connection::sendRequest(RequestMessage& request)
{
Poco::Net::SocketOutputStream sos(_socket);
request.send(sos);
}
void Connection::sendRequest(RequestMessage& request, ResponseMessage& response)
{
sendRequest(request);
Poco::Net::SocketInputStream sis(_socket);
response.read(sis);
}
} } // Poco::MongoDB

77
vendor/POCO/MongoDB/src/Cursor.cpp vendored Normal file
View File

@@ -0,0 +1,77 @@
//
// Cursor.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Cursor
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Cursor.h"
#include "Poco/MongoDB/GetMoreRequest.h"
#include "Poco/MongoDB/KillCursorsRequest.h"
namespace Poco {
namespace MongoDB {
Cursor::Cursor(const std::string& db, const std::string& collection, QueryRequest::Flags flags):
_query(db + '.' + collection, flags)
{
}
Cursor::Cursor(const std::string& fullCollectionName, QueryRequest::Flags flags):
_query(fullCollectionName, flags)
{
}
Cursor::~Cursor()
{
try
{
poco_assert_dbg(!_response.cursorID());
}
catch (...)
{
}
}
ResponseMessage& Cursor::next(Connection& connection)
{
if (_response.cursorID() == 0)
{
connection.sendRequest(_query, _response);
}
else
{
Poco::MongoDB::GetMoreRequest getMore(_query.fullCollectionName(), _response.cursorID());
getMore.setNumberToReturn(_query.getNumberToReturn());
_response.clear();
connection.sendRequest(getMore, _response);
}
return _response;
}
void Cursor::kill(Connection& connection)
{
if (_response.cursorID() != 0)
{
KillCursorsRequest killRequest;
killRequest.cursors().push_back(_response.cursorID());
connection.sendRequest(killRequest);
}
_response.clear();
}
} } // Namespace Poco::MongoDB

397
vendor/POCO/MongoDB/src/Database.cpp vendored Normal file
View File

@@ -0,0 +1,397 @@
//
// Database.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Database
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Database.h"
#include "Poco/MongoDB/Binary.h"
#include "Poco/MD5Engine.h"
#include "Poco/SHA1Engine.h"
#include "Poco/PBKDF2Engine.h"
#include "Poco/HMACEngine.h"
#include "Poco/Base64Decoder.h"
#include "Poco/MemoryStream.h"
#include "Poco/StreamCopier.h"
#include "Poco/Exception.h"
#include "Poco/RandomStream.h"
#include "Poco/Random.h"
#include "Poco/Format.h"
#include "Poco/NumberParser.h"
#include <sstream>
#include <map>
namespace Poco {
namespace MongoDB {
const std::string Database::AUTH_MONGODB_CR("MONGODB-CR");
const std::string Database::AUTH_SCRAM_SHA1("SCRAM-SHA-1");
namespace
{
std::map<std::string, std::string> parseKeyValueList(const std::string& str)
{
std::map<std::string, std::string> kvm;
std::string::const_iterator it = str.begin();
std::string::const_iterator end = str.end();
while (it != end)
{
std::string k;
std::string v;
while (it != end && *it != '=') k += *it++;
if (it != end) ++it;
while (it != end && *it != ',') v += *it++;
if (it != end) ++it;
kvm[k] = v;
}
return kvm;
}
std::string decodeBase64(const std::string& base64)
{
Poco::MemoryInputStream istr(base64.data(), base64.size());
Poco::Base64Decoder decoder(istr);
std::string result;
Poco::StreamCopier::copyToString(decoder, result);
return result;
}
std::string encodeBase64(const std::string& data)
{
std::ostringstream ostr;
Poco::Base64Encoder encoder(ostr);
encoder.rdbuf()->setLineLength(0);
encoder << data;
encoder.close();
return ostr.str();
}
std::string digestToBinaryString(Poco::DigestEngine& engine)
{
Poco::DigestEngine::Digest d = engine.digest();
return std::string(reinterpret_cast<const char*>(&d[0]), d.size());
}
std::string digestToHexString(Poco::DigestEngine& engine)
{
Poco::DigestEngine::Digest d = engine.digest();
return Poco::DigestEngine::digestToHex(d);
}
std::string digestToBase64(Poco::DigestEngine& engine)
{
return encodeBase64(digestToBinaryString(engine));
}
std::string hashCredentials(const std::string& username, const std::string& password)
{
Poco::MD5Engine md5;
md5.update(username);
md5.update(std::string(":mongo:"));
md5.update(password);
return digestToHexString(md5);
}
std::string createNonce()
{
Poco::MD5Engine md5;
Poco::RandomInputStream randomStream;
Poco::Random random;
for (int i = 0; i < 4; i++)
{
md5.update(randomStream.get());
md5.update(random.nextChar());
}
return digestToHexString(md5);
}
}
Database::Database(const std::string& db):
_dbname(db)
{
}
Database::~Database()
{
}
bool Database::authenticate(Connection& connection, const std::string& username, const std::string& password, const std::string& method)
{
if (username.empty()) throw Poco::InvalidArgumentException("empty username");
if (password.empty()) throw Poco::InvalidArgumentException("empty password");
if (method == AUTH_MONGODB_CR)
return authCR(connection, username, password);
else if (method == AUTH_SCRAM_SHA1)
return authSCRAM(connection, username, password);
else
throw Poco::InvalidArgumentException("authentication method", method);
}
bool Database::authCR(Connection& connection, const std::string& username, const std::string& password)
{
std::string nonce;
Poco::SharedPtr<QueryRequest> pCommand = createCommand();
pCommand->selector().add<Poco::Int32>("getnonce", 1);
ResponseMessage response;
connection.sendRequest(*pCommand, response);
if (response.documents().size() > 0)
{
Document::Ptr pDoc = response.documents()[0];
if (pDoc->getInteger("ok") != 1) return false;
nonce = pDoc->get<std::string>("nonce", "");
if (nonce.empty()) throw Poco::ProtocolException("no nonce received");
}
else throw Poco::ProtocolException("empty response for getnonce");
std::string credsDigest = hashCredentials(username, password);
Poco::MD5Engine md5;
md5.update(nonce);
md5.update(username);
md5.update(credsDigest);
std::string key = digestToHexString(md5);
pCommand = createCommand();
pCommand->selector()
.add<Poco::Int32>("authenticate", 1)
.add<std::string>("user", username)
.add<std::string>("nonce", nonce)
.add<std::string>("key", key);
connection.sendRequest(*pCommand, response);
if (response.documents().size() > 0)
{
Document::Ptr pDoc = response.documents()[0];
return pDoc->getInteger("ok") == 1;
}
else throw Poco::ProtocolException("empty response for authenticate");
}
bool Database::authSCRAM(Connection& connection, const std::string& username, const std::string& password)
{
std::string clientNonce(createNonce());
std::string clientFirstMsg = Poco::format("n=%s,r=%s", username, clientNonce);
Poco::SharedPtr<QueryRequest> pCommand = createCommand();
pCommand->selector()
.add<Poco::Int32>("saslStart", 1)
.add<std::string>("mechanism", AUTH_SCRAM_SHA1)
.add<Binary::Ptr>("payload", new Binary(Poco::format("n,,%s", clientFirstMsg)))
.add<bool>("authAuthorize", true);
ResponseMessage response;
connection.sendRequest(*pCommand, response);
Int32 conversationId = 0;
std::string serverFirstMsg;
if (response.documents().size() > 0)
{
Document::Ptr pDoc = response.documents()[0];
if (pDoc->getInteger("ok") == 1)
{
Binary::Ptr pPayload = pDoc->get<Binary::Ptr>("payload");
serverFirstMsg = pPayload->toRawString();
conversationId = pDoc->get<Int32>("conversationId");
}
else return false;
}
else throw Poco::ProtocolException("empty response for saslStart");
std::map<std::string, std::string> kvm = parseKeyValueList(serverFirstMsg);
const std::string serverNonce = kvm["r"];
const std::string salt = decodeBase64(kvm["s"]);
const unsigned iterations = Poco::NumberParser::parseUnsigned(kvm["i"]);
const Poco::UInt32 dkLen = 20;
std::string hashedPassword = hashCredentials(username, password);
Poco::PBKDF2Engine<Poco::HMACEngine<Poco::SHA1Engine> > pbkdf2(salt, iterations, dkLen);
pbkdf2.update(hashedPassword);
std::string saltedPassword = digestToBinaryString(pbkdf2);
std::string clientFinalNoProof = Poco::format("c=biws,r=%s", serverNonce);
std::string authMessage = Poco::format("%s,%s,%s", clientFirstMsg, serverFirstMsg, clientFinalNoProof);
Poco::HMACEngine<Poco::SHA1Engine> hmacKey(saltedPassword);
hmacKey.update(std::string("Client Key"));
std::string clientKey = digestToBinaryString(hmacKey);
Poco::SHA1Engine sha1;
sha1.update(clientKey);
std::string storedKey = digestToBinaryString(sha1);
Poco::HMACEngine<Poco::SHA1Engine> hmacSig(storedKey);
hmacSig.update(authMessage);
std::string clientSignature = digestToBinaryString(hmacSig);
std::string clientProof(clientKey);
for (std::size_t i = 0; i < clientProof.size(); i++)
{
clientProof[i] ^= clientSignature[i];
}
std::string clientFinal = Poco::format("%s,p=%s", clientFinalNoProof, encodeBase64(clientProof));
pCommand = createCommand();
pCommand->selector()
.add<Poco::Int32>("saslContinue", 1)
.add<Poco::Int32>("conversationId", conversationId)
.add<Binary::Ptr>("payload", new Binary(clientFinal));
std::string serverSecondMsg;
connection.sendRequest(*pCommand, response);
if (response.documents().size() > 0)
{
Document::Ptr pDoc = response.documents()[0];
if (pDoc->getInteger("ok") == 1)
{
Binary::Ptr pPayload = pDoc->get<Binary::Ptr>("payload");
serverSecondMsg = pPayload->toRawString();
}
else return false;
}
else throw Poco::ProtocolException("empty response for saslContinue");
Poco::HMACEngine<Poco::SHA1Engine> hmacSKey(saltedPassword);
hmacSKey.update(std::string("Server Key"));
std::string serverKey = digestToBinaryString(hmacSKey);
Poco::HMACEngine<Poco::SHA1Engine> hmacSSig(serverKey);
hmacSSig.update(authMessage);
std::string serverSignature = digestToBase64(hmacSSig);
kvm = parseKeyValueList(serverSecondMsg);
std::string serverSignatureReceived = kvm["v"];
if (serverSignature != serverSignatureReceived)
throw Poco::ProtocolException("server signature verification failed");
pCommand = createCommand();
pCommand->selector()
.add<Poco::Int32>("saslContinue", 1)
.add<Poco::Int32>("conversationId", conversationId)
.add<Binary::Ptr>("payload", new Binary);
connection.sendRequest(*pCommand, response);
if (response.documents().size() > 0)
{
Document::Ptr pDoc = response.documents()[0];
return pDoc->getInteger("ok") == 1;
}
else throw Poco::ProtocolException("empty response for saslContinue");
}
Int64 Database::count(Connection& connection, const std::string& collectionName) const
{
Poco::SharedPtr<Poco::MongoDB::QueryRequest> countRequest = createCountRequest(collectionName);
Poco::MongoDB::ResponseMessage response;
connection.sendRequest(*countRequest, response);
if (response.documents().size() > 0)
{
Poco::MongoDB::Document::Ptr doc = response.documents()[0];
return doc->getInteger("n");
}
return -1;
}
Poco::MongoDB::Document::Ptr Database::ensureIndex(Connection& connection, const std::string& collection, const std::string& indexName, Poco::MongoDB::Document::Ptr keys, bool unique, bool background, int version, int ttl)
{
Poco::MongoDB::Document::Ptr index = new Poco::MongoDB::Document();
index->add("ns", _dbname + "." + collection);
index->add("name", indexName);
index->add("key", keys);
if (version > 0)
{
index->add("version", version);
}
if (unique)
{
index->add("unique", true);
}
if (background)
{
index->add("background", true);
}
if (ttl > 0)
{
index->add("expireAfterSeconds", ttl);
}
Poco::SharedPtr<Poco::MongoDB::InsertRequest> insertRequest = createInsertRequest("system.indexes");
insertRequest->documents().push_back(index);
connection.sendRequest(*insertRequest);
return getLastErrorDoc(connection);
}
Document::Ptr Database::getLastErrorDoc(Connection& connection) const
{
Document::Ptr errorDoc;
Poco::SharedPtr<Poco::MongoDB::QueryRequest> request = createQueryRequest("$cmd");
request->setNumberToReturn(1);
request->selector().add("getLastError", 1);
Poco::MongoDB::ResponseMessage response;
connection.sendRequest(*request, response);
if (response.documents().size() > 0)
{
errorDoc = response.documents()[0];
}
return errorDoc;
}
std::string Database::getLastError(Connection& connection) const
{
Document::Ptr errorDoc = getLastErrorDoc(connection);
if (!errorDoc.isNull() && errorDoc->isType<std::string>("err"))
{
return errorDoc->get<std::string>("err");
}
return "";
}
Poco::SharedPtr<Poco::MongoDB::QueryRequest> Database::createCountRequest(const std::string& collectionName) const
{
Poco::SharedPtr<Poco::MongoDB::QueryRequest> request = createQueryRequest("$cmd");
request->setNumberToReturn(1);
request->selector().add("count", collectionName);
return request;
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,54 @@
//
// DeleteRequest.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: DeleteRequest
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/DeleteRequest.h"
namespace Poco {
namespace MongoDB {
DeleteRequest::DeleteRequest(const std::string& collectionName, DeleteRequest::Flags flags):
RequestMessage(MessageHeader::OP_DELETE),
_flags(flags),
_fullCollectionName(collectionName),
_selector()
{
}
DeleteRequest::DeleteRequest(const std::string& collectionName, bool justOne):
RequestMessage(MessageHeader::OP_DELETE),
_flags(justOne ? DELETE_SINGLE_REMOVE : DELETE_DEFAULT),
_fullCollectionName(collectionName),
_selector()
{
}
DeleteRequest::~DeleteRequest()
{
}
void DeleteRequest::buildRequest(BinaryWriter& writer)
{
writer << 0; // 0 - reserved for future use
BSONWriter(writer).writeCString(_fullCollectionName);
writer << _flags;
_selector.write(writer);
}
} } // namespace Poco::MongoDB

219
vendor/POCO/MongoDB/src/Document.cpp vendored Normal file
View File

@@ -0,0 +1,219 @@
//
// Document.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Document
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Document.h"
#include "Poco/MongoDB/Binary.h"
#include "Poco/MongoDB/ObjectId.h"
#include "Poco/MongoDB/Array.h"
#include "Poco/MongoDB/RegularExpression.h"
#include "Poco/MongoDB/JavaScriptCode.h"
#include <sstream>
namespace Poco {
namespace MongoDB {
Document::Document()
{
}
Document::~Document()
{
}
Element::Ptr Document::get(const std::string& name) const
{
Element::Ptr element;
ElementSet::const_iterator it = std::find_if(_elements.begin(), _elements.end(), ElementFindByName(name));
if (it != _elements.end())
{
return *it;
}
return element;
}
Int64 Document::getInteger(const std::string& name) const
{
Element::Ptr element = get(name);
if (element.isNull()) throw Poco::NotFoundException(name);
if (ElementTraits<double>::TypeId == element->type())
{
ConcreteElement<double>* concrete = dynamic_cast<ConcreteElement<double>*>(element.get());
if (concrete) return static_cast<Int64>(concrete->value());
}
else if (ElementTraits<Int32>::TypeId == element->type())
{
ConcreteElement<Int32>* concrete = dynamic_cast<ConcreteElement<Int32>*>(element.get());
if (concrete) return concrete->value();
}
else if (ElementTraits<Int64>::TypeId == element->type())
{
ConcreteElement<Int64>* concrete = dynamic_cast<ConcreteElement<Int64>*>(element.get());
if (concrete) return concrete->value();
}
throw Poco::BadCastException("Invalid type mismatch!");
}
void Document::read(BinaryReader& reader)
{
int size;
reader >> size;
unsigned char type;
reader >> type;
while (type != '\0')
{
Element::Ptr element;
std::string name = BSONReader(reader).readCString();
switch (type)
{
case ElementTraits<double>::TypeId:
element = new ConcreteElement<double>(name, 0);
break;
case ElementTraits<Int32>::TypeId:
element = new ConcreteElement<Int32>(name, 0);
break;
case ElementTraits<std::string>::TypeId:
element = new ConcreteElement<std::string>(name, "");
break;
case ElementTraits<Document::Ptr>::TypeId:
element = new ConcreteElement<Document::Ptr>(name, new Document);
break;
case ElementTraits<Array::Ptr>::TypeId:
element = new ConcreteElement<Array::Ptr>(name, new Array);
break;
case ElementTraits<Binary::Ptr>::TypeId:
element = new ConcreteElement<Binary::Ptr>(name, new Binary);
break;
case ElementTraits<ObjectId::Ptr>::TypeId:
element = new ConcreteElement<ObjectId::Ptr>(name, new ObjectId);
break;
case ElementTraits<bool>::TypeId:
element = new ConcreteElement<bool>(name, false);
break;
case ElementTraits<Poco::Timestamp>::TypeId:
element = new ConcreteElement<Poco::Timestamp>(name, Poco::Timestamp());
break;
case ElementTraits<BSONTimestamp>::TypeId:
element = new ConcreteElement<BSONTimestamp>(name, BSONTimestamp());
break;
case ElementTraits<NullValue>::TypeId:
element = new ConcreteElement<NullValue>(name, NullValue(0));
break;
case ElementTraits<RegularExpression::Ptr>::TypeId:
element = new ConcreteElement<RegularExpression::Ptr>(name, new RegularExpression());
break;
case ElementTraits<JavaScriptCode::Ptr>::TypeId:
element = new ConcreteElement<JavaScriptCode::Ptr>(name, new JavaScriptCode());
break;
case ElementTraits<Int64>::TypeId:
element = new ConcreteElement<Int64>(name, 0);
break;
default:
{
std::stringstream ss;
ss << "Element " << name << " contains an unsupported type 0x" << std::hex << (int) type;
throw Poco::NotImplementedException(ss.str());
}
//TODO: x0F -> JavaScript code with scope
// xFF -> Min Key
// x7F -> Max Key
}
element->read(reader);
_elements.push_back(element);
reader >> type;
}
}
std::string Document::toString(int indent) const
{
std::ostringstream oss;
oss << '{';
if (indent > 0) oss << std::endl;
for (ElementSet::const_iterator it = _elements.begin(); it != _elements.end(); ++it)
{
if (it != _elements.begin())
{
oss << ',';
if (indent > 0) oss << std::endl;
}
for (int i = 0; i < indent; ++i) oss << ' ';
oss << '"' << (*it)->name() << '"';
oss << (indent > 0 ? " : " : ":");
oss << (*it)->toString(indent > 0 ? indent + 2 : 0);
}
if (indent > 0)
{
oss << std::endl;
if (indent >= 2) indent -= 2;
for (int i = 0; i < indent; ++i) oss << ' ';
}
oss << '}';
return oss.str();
}
void Document::write(BinaryWriter& writer)
{
if (_elements.empty())
{
writer << 5;
}
else
{
std::stringstream sstream;
Poco::BinaryWriter tempWriter(sstream, BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER);
for (ElementSet::iterator it = _elements.begin(); it != _elements.end(); ++it)
{
tempWriter << static_cast<unsigned char>((*it)->type());
BSONWriter(tempWriter).writeCString((*it)->name());
Element::Ptr element = *it;
element->write(tempWriter);
}
tempWriter.flush();
Poco::Int32 len = static_cast<Poco::Int32>(5 + sstream.tellp()); /* 5 = sizeof(len) + 0-byte */
writer << len;
writer.writeRaw(sstream.str());
}
writer << '\0';
}
} } // namespace Poco::MongoDB

32
vendor/POCO/MongoDB/src/Element.cpp vendored Normal file
View File

@@ -0,0 +1,32 @@
//
// Element.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Element
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Element.h"
namespace Poco {
namespace MongoDB {
Element::Element(const std::string& name) : _name(name)
{
}
Element::~Element()
{
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,46 @@
//
// GetMoreRequest.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: GetMoreRequest
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/GetMoreRequest.h"
#include "Poco/MongoDB/Element.h"
namespace Poco {
namespace MongoDB {
GetMoreRequest::GetMoreRequest(const std::string& collectionName, Int64 cursorID):
RequestMessage(MessageHeader::OP_GET_MORE),
_fullCollectionName(collectionName),
_numberToReturn(100),
_cursorID(cursorID)
{
}
GetMoreRequest::~GetMoreRequest()
{
}
void GetMoreRequest::buildRequest(BinaryWriter& writer)
{
writer << 0; // 0 - reserved for future use
BSONWriter(writer).writeCString(_fullCollectionName);
writer << _numberToReturn;
writer << _cursorID;
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,49 @@
//
// InsertRequest.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: InsertRequest
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/InsertRequest.h"
namespace Poco {
namespace MongoDB {
InsertRequest::InsertRequest(const std::string& collectionName, Flags flags):
RequestMessage(MessageHeader::OP_INSERT),
_flags(flags),
_fullCollectionName(collectionName)
{
}
InsertRequest::~InsertRequest()
{
}
void InsertRequest::buildRequest(BinaryWriter& writer)
{
poco_assert (!_documents.empty());
writer << _flags;
BSONWriter bsonWriter(writer);
bsonWriter.writeCString(_fullCollectionName);
for (Document::Vector::iterator it = _documents.begin(); it != _documents.end(); ++it)
{
bsonWriter.write(*it);
}
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,33 @@
//
// JavaScriptCode.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: JavaScriptCode
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/JavaScriptCode.h"
namespace Poco {
namespace MongoDB {
JavaScriptCode::JavaScriptCode()
{
}
JavaScriptCode::~JavaScriptCode()
{
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,44 @@
//
// KillCursorsRequest.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: KillCursorsRequest
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/KillCursorsRequest.h"
namespace Poco {
namespace MongoDB {
KillCursorsRequest::KillCursorsRequest():
RequestMessage(MessageHeader::OP_KILL_CURSORS)
{
}
KillCursorsRequest::~KillCursorsRequest()
{
}
void KillCursorsRequest::buildRequest(BinaryWriter& writer)
{
writer << 0; // 0 - reserved for future use
writer << static_cast<Poco::UInt64>(_cursors.size());
for (std::vector<Int64>::iterator it = _cursors.begin(); it != _cursors.end(); ++it)
{
writer << *it;
}
}
} } // namespace Poco::MongoDB

33
vendor/POCO/MongoDB/src/Message.cpp vendored Normal file
View File

@@ -0,0 +1,33 @@
//
// Message.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: Message
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Message.h"
namespace Poco {
namespace MongoDB {
Message::Message(MessageHeader::OpCode opcode):
_header(opcode)
{
}
Message::~Message()
{
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,63 @@
//
// MessageHeader.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: MessageHeader
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/Message.h"
#include "Poco/Exception.h"
namespace Poco {
namespace MongoDB {
MessageHeader::MessageHeader(OpCode opCode):
_messageLength(0),
_requestID(0),
_responseTo(0),
_opCode(opCode)
{
}
MessageHeader::~MessageHeader()
{
}
void MessageHeader::read(BinaryReader& reader)
{
reader >> _messageLength;
reader >> _requestID;
reader >> _responseTo;
Int32 opCode;
reader >> opCode;
_opCode = (OpCode) opCode;
if (!reader.good())
{
throw IOException("Failed to read from socket");
}
}
void MessageHeader::write(BinaryWriter& writer)
{
writer << _messageLength;
writer << _requestID;
writer << _responseTo;
writer << (Int32) _opCode;
}
} } // namespace Poco::MongoDB

66
vendor/POCO/MongoDB/src/ObjectId.cpp vendored Normal file
View File

@@ -0,0 +1,66 @@
//
// ObjectId.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: ObjectId
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/ObjectId.h"
#include "Poco/Format.h"
#include <cstring>
namespace Poco {
namespace MongoDB {
ObjectId::ObjectId()
{
std::memset(_id, 0, sizeof(_id));
}
ObjectId::ObjectId(const std::string& id)
{
poco_assert_dbg(id.size() == 24);
const char* p = id.c_str();
for (std::size_t i = 0; i < 12; ++i)
{
_id[i] = fromHex(p);
p += 2;
}
}
ObjectId::ObjectId(const ObjectId& copy)
{
std::memcpy(_id, copy._id, sizeof(_id));
}
ObjectId::~ObjectId()
{
}
std::string ObjectId::toString(const std::string& fmt) const
{
std::string s;
for (int i = 0; i < 12; ++i)
{
s += format(fmt, (unsigned int) _id[i]);
}
return s;
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,54 @@
//
// QueryRequest.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: QueryRequest
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/QueryRequest.h"
namespace Poco {
namespace MongoDB {
QueryRequest::QueryRequest(const std::string& collectionName, QueryRequest::Flags flags):
RequestMessage(MessageHeader::OP_QUERY),
_flags(flags),
_fullCollectionName(collectionName),
_numberToSkip(0),
_numberToReturn(100),
_selector(),
_returnFieldSelector()
{
}
QueryRequest::~QueryRequest()
{
}
void QueryRequest::buildRequest(BinaryWriter& writer)
{
writer << _flags;
BSONWriter(writer).writeCString(_fullCollectionName);
writer << _numberToSkip;
writer << _numberToReturn;
_selector.write(writer);
if (!_returnFieldSelector.empty())
{
_returnFieldSelector.write(writer);
}
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,71 @@
//
// RegularExpression.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: RegularExpression
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/RegularExpression.h"
#include <sstream>
namespace Poco {
namespace MongoDB {
RegularExpression::RegularExpression()
{
}
RegularExpression::RegularExpression(const std::string& pattern, const std::string& options):
_pattern(pattern),
_options(options)
{
}
RegularExpression::~RegularExpression()
{
}
SharedPtr<Poco::RegularExpression> RegularExpression::createRE() const
{
int options = 0;
for (std::string::const_iterator optIt = _options.begin(); optIt != _options.end(); ++optIt)
{
switch (*optIt)
{
case 'i': // Case Insensitive
options |= Poco::RegularExpression::RE_CASELESS;
break;
case 'm': // Multiline matching
options |= Poco::RegularExpression::RE_MULTILINE;
break;
case 'x': // Verbose mode
//No equivalent in Poco
break;
case 'l': // \w \W Locale dependent
//No equivalent in Poco
break;
case 's': // Dotall mode
options |= Poco::RegularExpression::RE_DOTALL;
break;
case 'u': // \w \W Unicode
//No equivalent in Poco
break;
}
}
return new Poco::RegularExpression(_pattern, options);
}
} } // namespace Poco::MongoDB

89
vendor/POCO/MongoDB/src/ReplicaSet.cpp vendored Normal file
View File

@@ -0,0 +1,89 @@
//
// ReplicaSet.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: ReplicaSet
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/ReplicaSet.h"
#include "Poco/MongoDB/QueryRequest.h"
#include "Poco/MongoDB/ResponseMessage.h"
namespace Poco {
namespace MongoDB {
ReplicaSet::ReplicaSet(const std::vector<Net::SocketAddress> &addresses):
_addresses(addresses)
{
}
ReplicaSet::~ReplicaSet()
{
}
Connection::Ptr ReplicaSet::findMaster()
{
Connection::Ptr master;
for (std::vector<Net::SocketAddress>::iterator it = _addresses.begin(); it != _addresses.end(); ++it)
{
master = isMaster(*it);
if (!master.isNull())
{
break;
}
}
return master;
}
Connection::Ptr ReplicaSet::isMaster(const Net::SocketAddress& address)
{
Connection::Ptr conn = new Connection();
try
{
conn->connect(address);
QueryRequest request("admin.$cmd");
request.setNumberToReturn(1);
request.selector().add("isMaster", 1);
ResponseMessage response;
conn->sendRequest(request, response);
if (response.documents().size() > 0)
{
Document::Ptr doc = response.documents()[0];
if (doc->get<bool>("ismaster"))
{
return conn;
}
else if (doc->exists("primary"))
{
return isMaster(Net::SocketAddress(doc->get<std::string>("primary")));
}
}
}
catch (...)
{
conn = 0;
}
return 0;
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,51 @@
//
// RequestMessage.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: RequestMessage
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/RequestMessage.h"
#include "Poco/Net/SocketStream.h"
#include "Poco/StreamCopier.h"
namespace Poco {
namespace MongoDB {
RequestMessage::RequestMessage(MessageHeader::OpCode opcode):
Message(opcode)
{
}
RequestMessage::~RequestMessage()
{
}
void RequestMessage::send(std::ostream& ostr)
{
std::stringstream ss;
BinaryWriter requestWriter(ss, BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER);
buildRequest(requestWriter);
requestWriter.flush();
messageLength(static_cast<Poco::Int32>(ss.tellp()));
BinaryWriter socketWriter(ostr, BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER);
_header.write(socketWriter);
StreamCopier::copyStream(ss, ostr);
ostr.flush();
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,70 @@
//
// ResponseMessage.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: ResponseMessage
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/ResponseMessage.h"
#include "Poco/Net/SocketStream.h"
namespace Poco {
namespace MongoDB {
ResponseMessage::ResponseMessage():
Message(MessageHeader::OP_REPLY),
_responseFlags(0),
_cursorID(0),
_startingFrom(0),
_numberReturned(0)
{
}
ResponseMessage::~ResponseMessage()
{
}
void ResponseMessage::clear()
{
_responseFlags = 0;
_startingFrom = 0;
_cursorID = 0;
_numberReturned = 0;
_documents.clear();
}
void ResponseMessage::read(std::istream& istr)
{
clear();
BinaryReader reader(istr, BinaryReader::LITTLE_ENDIAN_BYTE_ORDER);
_header.read(reader);
reader >> _responseFlags;
reader >> _cursorID;
reader >> _startingFrom;
reader >> _numberReturned;
for (int i = 0; i < _numberReturned; ++i)
{
Document::Ptr doc = new Document();
doc->read(reader);
_documents.push_back(doc);
}
}
} } // namespace Poco::MongoDB

View File

@@ -0,0 +1,47 @@
//
// UpdateRequest.cpp
//
// Library: MongoDB
// Package: MongoDB
// Module: UpdateRequest
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/MongoDB/UpdateRequest.h"
namespace Poco {
namespace MongoDB {
UpdateRequest::UpdateRequest(const std::string& collectionName, UpdateRequest::Flags flags):
RequestMessage(MessageHeader::OP_UPDATE),
_flags(flags),
_fullCollectionName(collectionName),
_selector(),
_update()
{
}
UpdateRequest::~UpdateRequest()
{
}
void UpdateRequest::buildRequest(BinaryWriter& writer)
{
writer << 0; // 0 - reserved for future use
BSONWriter(writer).writeCString(_fullCollectionName);
writer << _flags;
_selector.write(writer);
_update.write(writer);
}
} } // namespace Poco::MongoDB