diff --git a/applications/WebConfigure/cgiCommon/opmysql.cpp b/applications/WebConfigure/cgiCommon/opmysql.cpp index 5dd9a95..88145ed 100644 --- a/applications/WebConfigure/cgiCommon/opmysql.cpp +++ b/applications/WebConfigure/cgiCommon/opmysql.cpp @@ -222,4 +222,111 @@ bool OpDatabase::queryUser(const std::string& user_id, const std::string& passwd hloge("Failed to connect to database: %s", ss.str().c_str()); return false; } +} + + +bool OpDatabase::queryInnerDevice(int dev_id, std::string& jsonResult) +{ + try + { +#if 0 + // 数据库连接配置 + std::string server = "tcp://127.0.0.1:3306"; + std::string dbuser = "root"; + std::string password = "Hj57471000"; + std::string database = "hjems"; + + // 创建连接 + sql::mysql::MySQL_Driver* driver; + driver = sql::mysql::get_mysql_driver_instance(); + //m_pDbConnection.reset(driver->connect(server, dbuser, password)); + sql::Connection* pDbConnection = driver->connect(server, dbuser, password); + + if( !pDbConnection ) + { + hloge("Failed to connect to database."); + return false; + } + + // 设置为使用指定数据库 + pDbConnection->setSchema(database); + hloge("%s : %s", user_id.c_str(), passwd_md5.c_str()); +#endif + // 准备SQL查询语句 + std::string sql = "SELECT uid,uname, upasswd,usalt,email,mobile1,mobile2,memo FROM tbl_user WHERE uid = ?"; + + // 创建预编译的prepared statement + std::unique_ptr pstmt(m_pDbConnection->prepareStatement(sql)); + + // 绑定参数 + pstmt->setString(1, user_id); // 替换为你要查询的用户名 + + // 执行查询 + std::unique_ptr res(pstmt->executeQuery()); + + bool ret = false; + OpenJson json; + auto& nodeRoot = json["user"]; + + int i = 0; + + // 处理结果集 + while( res->next() ) + { + auto& node = nodeRoot[i++]; + node["valid"] = 0; + node["uid"] = res->getString("uid"); + + // 假设username和password都是字符串类型 + std::string pass = res->getString("upasswd"); + std::string salt = res->getString("usalt"); + + //计算passwd和salt之间的关系 + //!passwd=md5(passwd_md5+salt+salt) + // passwd_md5 是大写的,需要确保一下 + std::string tmp2(passwd_md5); + std::transform(tmp2.begin(), tmp2.end(), tmp2.begin(), + [](unsigned char c) + { + return std::toupper(c); + }); + + std::string tmp = tmp2 + salt + salt; + std::string smd5 = CalculateMD5(tmp); + + if( pass == smd5 ) + { + node["valid"] = 1; + + node["uname"] = res->getString("uname"); + node["email"] = res->getString("email"); + node["mobile1"] = res->getString("mobile1"); + node["mobile2"] = res->getString("mobile2"); + node["memo"] = res->getString("memo"); + + ret = true; + break; + } + else + { + hloge("upass=[%s],calc=[%s],src=[%s]", pass.c_str(), smd5.c_str(), tmp.c_str()); + } + } + + jsonResult = json.encode(); + + //pDbConnection->close(); + //delete pDbConnection; + + return ret; + } + catch( sql::SQLException& e ) + { + std::ostringstream ss; + ss << "SQLException: " << e.what(); + ss << " (MySQL error code: " << e.getErrorCode(); + ss << ", SQLState: " << e.getSQLState() << " )"; + hloge("Failed to connect to database: %s", ss.str().c_str()); + return false; + } } \ No newline at end of file diff --git a/applications/WebConfigure/cgiCommon/opmysql.h b/applications/WebConfigure/cgiCommon/opmysql.h index 38619a8..6d73146 100644 --- a/applications/WebConfigure/cgiCommon/opmysql.h +++ b/applications/WebConfigure/cgiCommon/opmysql.h @@ -21,6 +21,9 @@ public: void InsertMessage(const std::string& ts, const std::string& msg_type, const std::string& fsu, const std::string& content, int topic, int dev_id); bool queryUser(const std::string& user_id, const std::string& passwd_md5, std::string& jsonResult); + + //查询设备,dev_id=0则返回全部 + bool queryInnerDevice(int dev_id, std::string& jsonResult); protected: //std::unique_ptr m_pDbConnection; sql::Connection* m_pDbConnection; diff --git a/applications/emsConfigurer/.gitignore b/applications/emsConfigurer/.gitignore new file mode 100644 index 0000000..4a0b530 --- /dev/null +++ b/applications/emsConfigurer/.gitignore @@ -0,0 +1,74 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* +CMakeLists.txt.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/applications/emsConfigurer/QtSingleApplication/INSTALL.TXT b/applications/emsConfigurer/QtSingleApplication/INSTALL.TXT new file mode 100644 index 0000000..bbb74a9 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/INSTALL.TXT @@ -0,0 +1,254 @@ +INSTALLATION INSTRUCTIONS + +These instructions refer to the package you are installing as +some-package.tar.gz or some-package.zip. The .zip file is intended for use +on Windows. + +The directory you choose for the installation will be referred to as +your-install-dir. + +Note to Qt Visual Studio Integration users: In the instructions below, +instead of building from command line with nmake, you can use the menu +command 'Qt->Open Solution from .pro file' on the .pro files in the +example and plugin directories, and then build from within Visual +Studio. + +Unpacking and installation +-------------------------- + +1. Unpacking the archive (if you have not done so already). + + On Unix and Mac OS X (in a terminal window): + + cd your-install-dir + gunzip some-package.tar.gz + tar xvf some-package.tar + + This creates the subdirectory some-package containing the files. + + On Windows: + + Unpack the .zip archive by right-clicking it in explorer and + choosing "Extract All...". If your version of Windows does not + have zip support, you can use the infozip tools available + from www.info-zip.org. + + If you are using the infozip tools (in a command prompt window): + cd your-install-dir + unzip some-package.zip + +2. Configuring the package. + + The configure script is called "configure" on unix/mac and + "configure.bat" on Windows. It should be run from a command line + after cd'ing to the package directory. + + You can choose whether you want to use the component by including + its source code directly into your project, or build the component + as a dynamic shared library (DLL) that is loaded into the + application at run-time. The latter may be preferable for + technical or licensing (LGPL) reasons. If you want to build a DLL, + run the configure script with the argument "-library". Also see + the note about usage below. + + (Components that are Qt plugins, e.g. styles and image formats, + are by default built as a plugin DLL.) + + The configure script will prompt you in some cases for further + information. Answer these questions and carefully read the license text + before accepting the license conditions. The package cannot be used if + you do not accept the license conditions. + +3. Building the component and examples (when required). + + If a DLL is to be built, or if you would like to build the + examples, next give the commands + + qmake + make [or nmake if your are using Microsoft Visual C++] + + The example program(s) can be found in the directory called + "examples" or "example". + + Components that are Qt plugins, e.g. styles and image formats, are + ready to be used as soon as they are built, so the rest of this + installation instruction can be skipped. + +4. Building the Qt Designer plugin (optional). + + Some of the widget components are provided with plugins for Qt + Designer. To build and install the plugin, cd into the + some-package/plugin directory and give the commands + + qmake + make [or nmake if your are using Microsoft Visual C++] + + Restart Qt Designer to make it load the new widget plugin. + + Note: If you are using the built-in Qt Designer from the Qt Visual + Studio Integration, you will need to manually copy the plugin DLL + file, i.e. copy + %QTDIR%\plugins\designer\some-component.dll + to the Qt Visual Studio Integration plugin path, typically: + C:\Program Files\Trolltech\Qt VS Integration\plugins + + Note: If you for some reason are using a Qt Designer that is built + in debug mode, you will need to build the plugin in debug mode + also. Edit the file plugin.pro in the plugin directory, changing + 'release' to 'debug' in the CONFIG line, before running qmake. + + + +Solutions components are intended to be used directly from the package +directory during development, so there is no 'make install' procedure. + + +Using a component in your project +--------------------------------- + +To use this component in your project, add the following line to the +project's .pro file (or do the equivalent in your IDE): + + include(your-install-dir/some-package/src/some-package.pri) + +This adds the package's sources and headers to the SOURCES and HEADERS +project variables respectively (or, if the component has been +configured as a DLL, it adds that library to the LIBS variable), and +updates INCLUDEPATH to contain the package's src +directory. Additionally, the .pri file may include some dependencies +needed by the package. + +To include a header file from the package in your sources, you can now +simply use: + + #include + +or alternatively, in pre-Qt 4 style: + + #include + +Refer to the documentation to see the classes and headers this +components provides. + + + +Install documentation (optional) +-------------------------------- + +The HTML documentation for the package's classes is located in the +your-install-dir/some-package/doc/html/index.html. You can open this +file and read the documentation with any web browser. + +To install the documentation into Qt Assistant (for Qt version 4.4 and +later): + +1. In Assistant, open the Edit->Preferences dialog and choose the + Documentation tab. Click the Add... button and select the file + your-install-dir/some-package/doc/html/some-package.qch + +For Qt versions prior to 4.4, do instead the following: + +1. The directory your-install-dir/some-package/doc/html contains a + file called some-package.dcf. Execute the following commands in a + shell, command prompt or terminal window: + + cd your-install-dir/some-package/doc/html/ + assistant -addContentFile some-package.dcf + +The next time you start Qt Assistant, you can access the package's +documentation. + + +Removing the documentation from assistant +----------------------------------------- + +If you have installed the documentation into Qt Assistant, and want to uninstall it, do as follows, for Qt version 4.4 and later: + +1. In Assistant, open the Edit->Preferences dialog and choose the + Documentation tab. In the list of Registered Documentation, select + the item com.nokia.qtsolutions.some-package_version, and click + the Remove button. + +For Qt versions prior to 4.4, do instead the following: + +1. The directory your-install-dir/some-package/doc/html contains a + file called some-package.dcf. Execute the following commands in a + shell, command prompt or terminal window: + + cd your-install-dir/some-package/doc/html/ + assistant -removeContentFile some-package.dcf + + + +Using the component as a DLL +---------------------------- + +1. Normal components + + The shared library (DLL) is built and placed in the + some-package/lib directory. It is intended to be used directly + from there during development. When appropriate, both debug and + release versions are built, since the run-time linker will in some + cases refuse to load a debug-built DLL into a release-built + application or vice versa. + + The following steps are taken by default to help the dynamic + linker to locate the DLL at run-time (during development): + + Unix: The some-package.pri file will add linker instructions to + add the some-package/lib directory to the rpath of the + executable. (When distributing, or if your system does not support + rpath, you can copy the shared library to another place that is + searched by the dynamic linker, e.g. the "lib" directory of your + Qt installation.) + + Mac: The full path to the library is hardcoded into the library + itself, from where it is copied into the executable at link time, + and ready by the dynamic linker at run-time. (When distributing, + you will want to edit these hardcoded paths in the same way as for + the Qt DLLs. Refer to the document "Deploying an Application on + Mac OS X" in the Qt Reference Documentation.) + + Windows: the .dll file(s) are copied into the "bin" directory of + your Qt installation. The Qt installation will already have set up + that directory to be searched by the dynamic linker. + + +2. Plugins + + For Qt Solutions plugins (e.g. image formats), both debug and + release versions of the plugin are built by default when + appropriate, since in some cases the release Qt library will not + load a debug plugin, and vice versa. The plugins are automatically + copied into the plugins directory of your Qt installation when + built, so no further setup is required. + + Plugins may also be built statically, i.e. as a library that will be + linked into your application executable, and so will not need to + be redistributed as a separate plugin DLL to end users. Static + building is required if Qt itself is built statically. To do it, + just add "static" to the CONFIG variable in the plugin/plugin.pro + file before building. Refer to the "Static Plugins" section in the + chapter "How to Create Qt Plugins" for explanation of how to use a + static plugin in your application. The source code of the example + program(s) will also typically contain the relevant instructions + as comments. + + + +Uninstalling +------------ + + The following command will remove any fils that have been + automatically placed outside the package directory itself during + installation and building + + make distclean [or nmake if your are using Microsoft Visual C++] + + If Qt Assistant documentation or Qt Designer plugins have been + installed, they can be uninstalled manually, ref. above. + + +Enjoy! :) + +- The Qt Solutions Team. diff --git a/applications/emsConfigurer/QtSingleApplication/QtLockedFile b/applications/emsConfigurer/QtSingleApplication/QtLockedFile new file mode 100644 index 0000000..16b48ba --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/QtLockedFile @@ -0,0 +1 @@ +#include "qtlockedfile.h" diff --git a/applications/emsConfigurer/QtSingleApplication/README.TXT b/applications/emsConfigurer/QtSingleApplication/README.TXT new file mode 100644 index 0000000..06abb09 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/README.TXT @@ -0,0 +1,33 @@ +Qt Solutions Component: Single Application + +The QtSingleApplication component provides support for +applications that can be only started once per user. + + + +Version history: + +2.0: - Version 1.3 ported to Qt 4. + +2.1: - Fix compilation problem on Mac. + +2.2: - Really fix the Mac compilation problem. + - Mac: fix crash due to wrong object releasing. + - Mac: Fix memory leak. + +2.3: - Windows: Force creation of internal widget to make it work + with Qt 4.2. + +2.4: - Fix the system for automatic window raising on message + reception. NOTE: minor API change. + +2.5: - Mac: Fix isRunning() to work and report correctly. + +2.6: - - initialize() is now obsolete, no longer necessary to call + it + - - Fixed race condition where multiple instances migth be started + - - QtSingleCoreApplication variant provided for non-GUI (console) + usage + - Complete reimplementation. Visible changes: + - LGPL release. + diff --git a/applications/emsConfigurer/QtSingleApplication/qtlocalpeer.cpp b/applications/emsConfigurer/QtSingleApplication/qtlocalpeer.cpp new file mode 100644 index 0000000..cc1d15f --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtlocalpeer.cpp @@ -0,0 +1,205 @@ +锘/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qtlocalpeer.h" +#include +#include +#include +#include + +#if defined(Q_OS_WIN) +#include +#include +typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); +static PProcessIdToSessionId pProcessIdToSessionId = 0; +#endif +#if defined(Q_OS_UNIX) +#include +#include +#include +#endif + +namespace QtLP_Private { +#include "qtlockedfile.cpp" +#if defined(Q_OS_WIN) +#include "qtlockedfile_win.cpp" +#else +#include "qtlockedfile_unix.cpp" +#endif +} + +const char* QtLocalPeer::ack = "ack"; + +QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) + : QObject(parent), id(appId) +{ + QString prefix = id; + if (id.isEmpty()) { + id = QCoreApplication::applicationFilePath(); +#if defined(Q_OS_WIN) + id = id.toLower(); +#endif + prefix = id.section(QLatin1Char('/'), -1); + } + prefix.remove(QRegularExpression ("[^a-zA-Z]")); + prefix.truncate(6); + + QByteArray idc = id.toUtf8(); + quint16 idNum = qChecksum(idc.constData(), idc.size()); + socketName = QLatin1String("qtsingleapp-") + prefix + + QLatin1Char('-') + QString::number(idNum, 16); + +#if defined(Q_OS_WIN) + if (!pProcessIdToSessionId) { + QLibrary lib("kernel32"); + pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); + } + if (pProcessIdToSessionId) { + DWORD sessionId = 0; + pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); + socketName += QLatin1Char('-') + QString::number(sessionId, 16); + } +#else + socketName += QLatin1Char('-') + QString::number(::getuid(), 16); +#endif + + server = new QLocalServer(this); + QString lockName = QDir(QDir::tempPath()).absolutePath() + + QLatin1Char('/') + socketName + + QLatin1String("-lockfile"); + lockFile.setFileName(lockName); + lockFile.open(QIODevice::ReadWrite); +} + + + +bool QtLocalPeer::isClient() +{ + if (lockFile.isLocked()) + return false; + + if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) + return true; + + bool res = server->listen(socketName); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) + // ### Workaround + if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { + QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); + res = server->listen(socketName); + } +#endif + if (!res) + qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); + QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); + return false; +} + + +bool QtLocalPeer::sendMessage(const QString &message, int timeout) +{ + if (!isClient()) + return false; + + QLocalSocket socket; + bool connOk = false; + for(int i = 0; i < 2; i++) { + // Try twice, in case the other instance is just starting up + socket.connectToServer(socketName); + connOk = socket.waitForConnected(timeout/2); + if (connOk || i) + break; + int ms = 250; +#if defined(Q_OS_WIN) + Sleep(DWORD(ms)); +#else + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; + nanosleep(&ts, NULL); +#endif + } + if (!connOk) + return false; + + QByteArray uMsg(message.toUtf8()); + QDataStream ds(&socket); + ds.writeBytes(uMsg.constData(), uMsg.size()); + bool res = socket.waitForBytesWritten(timeout); + if (res) { + res &= socket.waitForReadyRead(timeout); // wait for ack + if (res) + res &= (socket.read(qstrlen(ack)) == ack); + } + return res; +} + + +void QtLocalPeer::receiveConnection() +{ + QLocalSocket* socket = server->nextPendingConnection(); + if (!socket) + return; + + while (socket->bytesAvailable() < (int)sizeof(quint32)) + socket->waitForReadyRead(); + QDataStream ds(socket); + QByteArray uMsg; + quint32 remaining; + ds >> remaining; + uMsg.resize(remaining); + int got = 0; + char* uMsgBuf = uMsg.data(); + do { + got = ds.readRawData(uMsgBuf, remaining); + remaining -= got; + uMsgBuf += got; + } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); + if (got < 0) { + qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); + delete socket; + return; + } + QString message(QString::fromUtf8(uMsg)); + socket->write(ack, qstrlen(ack)); + socket->waitForBytesWritten(1000); + socket->waitForDisconnected(1000); // make sure client reads ack + delete socket; + emit messageReceived(message); //### (might take a long time to return) +} diff --git a/applications/emsConfigurer/QtSingleApplication/qtlocalpeer.h b/applications/emsConfigurer/QtSingleApplication/qtlocalpeer.h new file mode 100644 index 0000000..1b533b1 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtlocalpeer.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLOCALPEER_H +#define QTLOCALPEER_H + +#include +#include +#include + +#include "qtlockedfile.h" + +class QtLocalPeer : public QObject +{ + Q_OBJECT + +public: + QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); + bool isClient(); + bool sendMessage(const QString &message, int timeout); + QString applicationId() const + { return id; } + +Q_SIGNALS: + void messageReceived(const QString &message); + +protected Q_SLOTS: + void receiveConnection(); + +protected: + QString id; + QString socketName; + QLocalServer* server; + QtLP_Private::QtLockedFile lockFile; + +private: + static const char* ack; +}; + +#endif // QTLOCALPEER_H diff --git a/applications/emsConfigurer/QtSingleApplication/qtlockedfile.cpp b/applications/emsConfigurer/QtSingleApplication/qtlockedfile.cpp new file mode 100644 index 0000000..c142a86 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtlockedfile.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtlockedfile.h" + +/*! + \class QtLockedFile + + \brief The QtLockedFile class extends QFile with advisory locking + functions. + + A file may be locked in read or write mode. Multiple instances of + \e QtLockedFile, created in multiple processes running on the same + machine, may have a file locked in read mode. Exactly one instance + may have it locked in write mode. A read and a write lock cannot + exist simultaneously on the same file. + + The file locks are advisory. This means that nothing prevents + another process from manipulating a locked file using QFile or + file system functions offered by the OS. Serialization is only + guaranteed if all processes that access the file use + QLockedFile. Also, while holding a lock on a file, a process + must not open the same file again (through any API), or locks + can be unexpectedly lost. + + The lock provided by an instance of \e QtLockedFile is released + whenever the program terminates. This is true even when the + program crashes and no destructors are called. +*/ + +/*! \enum QtLockedFile::LockMode + + This enum describes the available lock modes. + + \value ReadLock A read lock. + \value WriteLock A write lock. + \value NoLock Neither a read lock nor a write lock. +*/ + +/*! + Constructs an unlocked \e QtLockedFile object. This constructor + behaves in the same way as \e QFile::QFile(). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile() + : QFile() +{ +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Constructs an unlocked QtLockedFile object with file \a name. This + constructor behaves in the same way as \e QFile::QFile(const + QString&). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile(const QString &name) + : QFile(name) +{ +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Opens the file in OpenMode \a mode. + + This is identical to QFile::open(), with the one exception that the + Truncate mode flag is disallowed. Truncation would conflict with the + advisory file locking, since the file would be modified before the + write lock is obtained. If truncation is required, use resize(0) + after obtaining the write lock. + + Returns true if successful; otherwise false. + + \sa QFile::open(), QFile::resize() +*/ +bool QtLockedFile::open(OpenMode mode) +{ + if (mode & QIODevice::Truncate) { + qWarning("QtLockedFile::open(): Truncate mode not allowed."); + return false; + } + return QFile::open(mode); +} + +/*! + Returns \e true if this object has a in read or write lock; + otherwise returns \e false. + + \sa lockMode() +*/ +bool QtLockedFile::isLocked() const +{ + return m_lock_mode != NoLock; +} + +/*! + Returns the type of lock currently held by this object, or \e + QtLockedFile::NoLock. + + \sa isLocked() +*/ +QtLockedFile::LockMode QtLockedFile::lockMode() const +{ + return m_lock_mode; +} + +/*! + \fn bool QtLockedFile::lock(LockMode mode, bool block = true) + + Obtains a lock of type \a mode. The file must be opened before it + can be locked. + + If \a block is true, this function will block until the lock is + aquired. If \a block is false, this function returns \e false + immediately if the lock cannot be aquired. + + If this object already has a lock of type \a mode, this function + returns \e true immediately. If this object has a lock of a + different type than \a mode, the lock is first released and then a + new lock is obtained. + + This function returns \e true if, after it executes, the file is + locked by this object, and \e false otherwise. + + \sa unlock(), isLocked(), lockMode() +*/ + +/*! + \fn bool QtLockedFile::unlock() + + Releases a lock. + + If the object has no lock, this function returns immediately. + + This function returns \e true if, after it executes, the file is + not locked by this object, and \e false otherwise. + + \sa lock(), isLocked(), lockMode() +*/ + +/*! + \fn QtLockedFile::~QtLockedFile() + + Destroys the \e QtLockedFile object. If any locks were held, they + are released. +*/ diff --git a/applications/emsConfigurer/QtSingleApplication/qtlockedfile.h b/applications/emsConfigurer/QtSingleApplication/qtlockedfile.h new file mode 100644 index 0000000..84c18e5 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtlockedfile.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLOCKEDFILE_H +#define QTLOCKEDFILE_H + +#include +#ifdef Q_OS_WIN +#include +#endif + +#if defined(Q_OS_WIN) +# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) +# define QT_QTLOCKEDFILE_EXPORT +# elif defined(QT_QTLOCKEDFILE_IMPORT) +# if defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# endif +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) +# elif defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTLOCKEDFILE_EXPORT +#endif + +namespace QtLP_Private { + +class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile +{ +public: + enum LockMode { NoLock = 0, ReadLock, WriteLock }; + + QtLockedFile(); + QtLockedFile(const QString &name); + ~QtLockedFile(); + + bool open(OpenMode mode); + + bool lock(LockMode mode, bool block = true); + bool unlock(); + bool isLocked() const; + LockMode lockMode() const; + +private: +#ifdef Q_OS_WIN + Qt::HANDLE wmutex; + Qt::HANDLE rmutex; + QVector rmutexes; + QString mutexname; + + Qt::HANDLE getMutexHandle(int idx, bool doCreate); + bool waitMutex(Qt::HANDLE mutex, bool doBlock); + +#endif + LockMode m_lock_mode; +}; +} +#endif diff --git a/applications/emsConfigurer/QtSingleApplication/qtlockedfile_unix.cpp b/applications/emsConfigurer/QtSingleApplication/qtlockedfile_unix.cpp new file mode 100644 index 0000000..976c1b9 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtlockedfile_unix.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "qtlockedfile.h" + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; + int cmd = block ? F_SETLKW : F_SETLK; + int ret = fcntl(handle(), cmd, &fl); + + if (ret == -1) { + if (errno != EINTR && errno != EAGAIN) + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + + m_lock_mode = mode; + return true; +} + + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = F_UNLCK; + int ret = fcntl(handle(), F_SETLKW, &fl); + + if (ret == -1) { + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + m_lock_mode = NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); +} + diff --git a/applications/emsConfigurer/QtSingleApplication/qtlockedfile_win.cpp b/applications/emsConfigurer/QtSingleApplication/qtlockedfile_win.cpp new file mode 100644 index 0000000..5e21262 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtlockedfile_win.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtlockedfile.h" +#include +#include + +#define MUTEX_PREFIX "QtLockedFile mutex " +// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS +#define MAX_READERS MAXIMUM_WAIT_OBJECTS + +#if QT_VERSION >= 0x050000 +#define QT_WA(unicode, ansi) unicode +#endif + +Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) +{ + if (mutexname.isEmpty()) { + QFileInfo fi(*this); + mutexname = QString::fromLatin1(MUTEX_PREFIX) + + fi.absoluteFilePath().toLower(); + } + QString mname(mutexname); + if (idx >= 0) + mname += QString::number(idx); + + Qt::HANDLE mutex; + if (doCreate) { + QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, + { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); + return 0; + } + } + else { + QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, + { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); + return 0; + } + } + return mutex; +} + +bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) +{ + Q_ASSERT(mutex); + DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); + switch (res) { + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + return true; + break; + case WAIT_TIMEOUT: + break; + default: + qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); + } + return false; +} + + + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + if (!wmutex && !(wmutex = getMutexHandle(-1, true))) + return false; + + if (!waitMutex(wmutex, block)) + return false; + + if (mode == ReadLock) { + int idx = 0; + for (; idx < MAX_READERS; idx++) { + rmutex = getMutexHandle(idx, false); + if (!rmutex || waitMutex(rmutex, false)) + break; + CloseHandle(rmutex); + } + bool ok = true; + if (idx >= MAX_READERS) { + qWarning("QtLockedFile::lock(): too many readers"); + rmutex = 0; + ok = false; + } + else if (!rmutex) { + rmutex = getMutexHandle(idx, true); + if (!rmutex || !waitMutex(rmutex, false)) + ok = false; + } + if (!ok && rmutex) { + CloseHandle(rmutex); + rmutex = 0; + } + ReleaseMutex(wmutex); + if (!ok) + return false; + } + else { + Q_ASSERT(rmutexes.isEmpty()); + for (int i = 0; i < MAX_READERS; i++) { + Qt::HANDLE mutex = getMutexHandle(i, false); + if (mutex) + rmutexes.append(mutex); + } + if (rmutexes.size()) { + DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), + TRUE, block ? INFINITE : 0); + if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { + if (res != WAIT_TIMEOUT) + qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); + m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky + unlock(); + return false; + } + } + } + + m_lock_mode = mode; + return true; +} + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + if (m_lock_mode == ReadLock) { + ReleaseMutex(rmutex); + CloseHandle(rmutex); + rmutex = 0; + } + else { + foreach(Qt::HANDLE mutex, rmutexes) { + ReleaseMutex(mutex); + CloseHandle(mutex); + } + rmutexes.clear(); + ReleaseMutex(wmutex); + } + + m_lock_mode = QtLockedFile::NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); + if (wmutex) + CloseHandle(wmutex); +} diff --git a/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.cpp b/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.cpp new file mode 100644 index 0000000..512a200 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.cpp @@ -0,0 +1,356 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qtsingleapplication.h" +#include "qtlocalpeer.h" +#include + + +/*! + \class QtSingleApplication qtsingleapplication.h + \brief The QtSingleApplication class provides an API to detect and + communicate with running instances of an application. + + This class allows you to create applications where only one + instance should be running at a time. I.e., if the user tries to + launch another instance, the already running instance will be + activated instead. Another usecase is a client-server system, + where the first started instance will assume the role of server, + and the later instances will act as clients of that server. + + By default, the full path of the executable file is used to + determine whether two processes are instances of the same + application. You can also provide an explicit identifier string + that will be compared instead. + + The application should create the QtSingleApplication object early + in the startup phase, and call isRunning() to find out if another + instance of this application is already running. If isRunning() + returns false, it means that no other instance is running, and + this instance has assumed the role as the running instance. In + this case, the application should continue with the initialization + of the application user interface before entering the event loop + with exec(), as normal. + + The messageReceived() signal will be emitted when the running + application receives messages from another instance of the same + application. When a message is received it might be helpful to the + user to raise the application so that it becomes visible. To + facilitate this, QtSingleApplication provides the + setActivationWindow() function and the activateWindow() slot. + + If isRunning() returns true, another instance is already + running. It may be alerted to the fact that another instance has + started by using the sendMessage() function. Also data such as + startup parameters (e.g. the name of the file the user wanted this + new instance to open) can be passed to the running instance with + this function. Then, the application should terminate (or enter + client mode). + + If isRunning() returns true, but sendMessage() fails, that is an + indication that the running instance is frozen. + + Here's an example that shows how to convert an existing + application to use QtSingleApplication. It is very simple and does + not make use of all QtSingleApplication's functionality (see the + examples for that). + + \code + // Original + int main(int argc, char **argv) + { + QApplication app(argc, argv); + + MyMainWidget mmw; + mmw.show(); + return app.exec(); + } + + // Single instance + int main(int argc, char **argv) + { + QtSingleApplication app(argc, argv); + + if (app.isRunning()) + return !app.sendMessage(someDataString); + + MyMainWidget mmw; + app.setActivationWindow(&mmw); + mmw.show(); + return app.exec(); + } + \endcode + + Once this QtSingleApplication instance is destroyed (normally when + the process exits or crashes), when the user next attempts to run the + application this instance will not, of course, be encountered. The + next instance to call isRunning() or sendMessage() will assume the + role as the new running instance. + + For console (non-GUI) applications, QtSingleCoreApplication may be + used instead of this class, to avoid the dependency on the QtGui + library. + + \sa QtSingleCoreApplication +*/ + + +void QtSingleApplication::sysInit(const QString &appId) +{ + actWin = 0; + peer = new QtLocalPeer(this, appId); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a GUIenabled are passed on to the QAppliation constructor. + + If you are creating a console application (i.e. setting \a + GUIenabled to false), you may consider using + QtSingleCoreApplication instead. +*/ + +QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) + : QApplication(argc, argv, GUIenabled) +{ + sysInit(); +} + + +/*! + Creates a QtSingleApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QAppliation constructor. +*/ + +QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) + : QApplication(argc, argv), + peer(nullptr) +{ + sysInit(appId); +} + +QtSingleApplication::~QtSingleApplication() +{ + if (peer) + { + delete peer; + } +} + +#if QT_VERSION < 0x050000 + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a type are passed on to the QAppliation constructor. +*/ +QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) + : QApplication(argc, argv, type) +{ + sysInit(); +} + + +# if defined(Q_WS_X11) +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, + and \a cmap are passed on to the QApplication constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, visual, cmap) +{ + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) +{ + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be \a appId. \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) +{ + sysInit(appId); +} +# endif // Q_WS_X11 +#endif // QT_VERSION < 0x050000 + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleApplication::isRunning() +{ + return peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ +bool QtSingleApplication::sendMessage(const QString &message, int timeout) +{ + return peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ +QString QtSingleApplication::id() const +{ + return peer->applicationId(); +} + + +/*! + Sets the activation window of this application to \a aw. The + activation window is the widget that will be activated by + activateWindow(). This is typically the application's main window. + + If \a activateOnMessage is true (the default), the window will be + activated automatically every time a message is received, just prior + to the messageReceived() signal being emitted. + + \sa activateWindow(), messageReceived() +*/ + +void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) +{ + actWin = aw; + if (activateOnMessage) + connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); + else + disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); +} + + +/*! + Returns the applications activation window if one has been set by + calling setActivationWindow(), otherwise returns 0. + + \sa setActivationWindow() +*/ +QWidget* QtSingleApplication::activationWindow() const +{ + return actWin; +} + + +/*! + De-minimizes, raises, and activates this application's activation window. + This function does nothing if no activation window has been set. + + This is a convenience function to show the user that this + application instance has been activated when he has tried to start + another instance. + + This function should typically be called in response to the + messageReceived() signal. By default, that will happen + automatically, if an activation window has been set. + + \sa setActivationWindow(), messageReceived(), initialize() +*/ +void QtSingleApplication::activateWindow() +{ + if (actWin) { + actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); + actWin->raise(); + actWin->activateWindow(); + } +} + + +/*! + \fn void QtSingleApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage(), setActivationWindow(), activateWindow() +*/ + + +/*! + \fn void QtSingleApplication::initialize(bool dummy = true) + + \obsolete +*/ diff --git a/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.h b/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.h new file mode 100644 index 0000000..25d3daf --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTSINGLEAPPLICATION_H +#define QTSINGLEAPPLICATION_H + +#include + +class QtLocalPeer; + +#if defined(Q_OS_WIN) +# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) +# define QT_QTSINGLEAPPLICATION_EXPORT +# elif defined(QT_QTSINGLEAPPLICATION_IMPORT) +# if defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# endif +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) +# elif defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTSINGLEAPPLICATION_EXPORT +#endif + +class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication +{ + Q_OBJECT + +public: + QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); + QtSingleApplication(const QString &id, int &argc, char **argv); + virtual ~QtSingleApplication(); + +#if QT_VERSION < 0x050000 + QtSingleApplication(int &argc, char **argv, Type type); +# if defined(Q_WS_X11) + QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); + QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); + QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); +# endif // Q_WS_X11 +#endif // QT_VERSION < 0x050000 + + bool isRunning(); + QString id() const; + + void setActivationWindow(QWidget* aw, bool activateOnMessage = true); + QWidget* activationWindow() const; + + // Obsolete: + void initialize(bool dummy = true) + { isRunning(); Q_UNUSED(dummy) } + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + void activateWindow(); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + void sysInit(const QString &appId = QString()); + QtLocalPeer *peer; + QWidget *actWin; +}; + +#endif // QTSINGLEAPPLICATION_H diff --git a/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.pri b/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.pri new file mode 100644 index 0000000..51f30cc --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtsingleapplication.pri @@ -0,0 +1,17 @@ +#include(../common.pri) +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +QT *= network +greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets + +qtsingleapplication-uselib:!qtsingleapplication-buildlib { + LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME +} else { + SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp + HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h +} + +win32 { + contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT + else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT +} diff --git a/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.cpp b/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.cpp new file mode 100644 index 0000000..5634537 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qtsinglecoreapplication.h" +#include "qtlocalpeer.h" + +/*! + \class QtSingleCoreApplication qtsinglecoreapplication.h + \brief A variant of the QtSingleApplication class for non-GUI applications. + + This class is a variant of QtSingleApplication suited for use in + console (non-GUI) applications. It is an extension of + QCoreApplication (instead of QApplication). It does not require + the QtGui library. + + The API and usage is identical to QtSingleApplication, except that + functions relating to the "activation window" are not present, for + obvious reasons. Please refer to the QtSingleApplication + documentation for explanation of the usage. + + A QtSingleCoreApplication instance can communicate to a + QtSingleApplication instance if they share the same application + id. Hence, this class can be used to create a light-weight + command-line tool that sends commands to a GUI application. + + \sa QtSingleApplication +*/ + +/*! + Creates a QtSingleCoreApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc and \a + argv are passed on to the QCoreAppliation constructor. +*/ + +QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + peer = new QtLocalPeer(this); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Creates a QtSingleCoreApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QCoreAppliation constructor. +*/ +QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + peer = new QtLocalPeer(this, appId); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleCoreApplication::isRunning() +{ + return peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleCoreApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ + +bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) +{ + return peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ + +QString QtSingleCoreApplication::id() const +{ + return peer->applicationId(); +} + + +/*! + \fn void QtSingleCoreApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage() +*/ diff --git a/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.h b/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.h new file mode 100644 index 0000000..b87fffe --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTSINGLECOREAPPLICATION_H +#define QTSINGLECOREAPPLICATION_H + +#include + +class QtLocalPeer; + +class QtSingleCoreApplication : public QCoreApplication +{ + Q_OBJECT + +public: + QtSingleCoreApplication(int &argc, char **argv); + QtSingleCoreApplication(const QString &id, int &argc, char **argv); + + bool isRunning(); + QString id() const; + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + QtLocalPeer* peer; +}; + +#endif // QTSINGLECOREAPPLICATION_H diff --git a/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.pri b/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.pri new file mode 100644 index 0000000..d2d6cc3 --- /dev/null +++ b/applications/emsConfigurer/QtSingleApplication/qtsinglecoreapplication.pri @@ -0,0 +1,10 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h +SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp + +QT *= network + +win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { + DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) +} diff --git a/applications/emsConfigurer/datafetcher.cpp b/applications/emsConfigurer/datafetcher.cpp new file mode 100644 index 0000000..4be0b91 --- /dev/null +++ b/applications/emsConfigurer/datafetcher.cpp @@ -0,0 +1,22 @@ +锘#include "datafetcher.h" +#include "globalparameters.h" + +DataFetcher::DataFetcher() +{ + +} + +DataFetcher::~DataFetcher() +{ + +} + +bool DataFetcher::Fetch(TableData& tbl_data) +{ + return true; +} + +int DataFetcher::VerifyStatus() +{ + return STATUS_NORMAL; +} diff --git a/applications/emsConfigurer/datafetcher.h b/applications/emsConfigurer/datafetcher.h new file mode 100644 index 0000000..35a07f4 --- /dev/null +++ b/applications/emsConfigurer/datafetcher.h @@ -0,0 +1,19 @@ +锘#ifndef DATAFETCHER_H +#define DATAFETCHER_H + +#include "globalparameters.h" + +class DataFetcher +{ +public: + DataFetcher(); + virtual ~DataFetcher(); + +public: + virtual bool Fetch(TableData& tbl_data); + +protected: + int VerifyStatus(); +}; + +#endif // DATAFETCHER_H diff --git a/applications/emsConfigurer/devicepropertypage.cpp b/applications/emsConfigurer/devicepropertypage.cpp new file mode 100644 index 0000000..468c761 --- /dev/null +++ b/applications/emsConfigurer/devicepropertypage.cpp @@ -0,0 +1,202 @@ +锘#include "devicepropertypage.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "globalparameters.h" +#include "mytablemodel.h" + +DevicePropertyPage::DevicePropertyPage(QWidget *parent) : + QWidget(parent),m_pTableView(nullptr),m_pButton(nullptr) +{ + InitializeTable(); + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handleTimeout())); + //m_pTimer->start(AppData::getInstance()->nTimeOut); + } + +DevicePropertyPage::~DevicePropertyPage() +{ +} + +void DevicePropertyPage::handleTimeout() +{ + if(m_pTimer->isActive()) + { + m_pTimer->stop(); + + Refresh(); + + int nInterval = 5000; + m_pTimer->start(nInterval*1000); + } +} + +void DevicePropertyPage::InitializeTableView(MyTableModel *model, QTableView *tableView) +{ + //璁剧疆tableview鐨刴odel + model->setHeadData(AppData::getInstance()->lstDataTableHeaderText); + tableView->setModel(model); + + QHeaderView* pHeaderView = tableView->horizontalHeader(); + //pHeaderView->setStyleSheet("QHeaderView::section {color: black;padding-left: 4px;border: 1px solid #6c6c6c;}"); + pHeaderView->setStyleSheet("QHeaderView::section{background:lightgray;}"); + + // pHeaderView->setSectionResizeMode(QHeaderView::Stretch); //Stretch + + pHeaderView->setHidden(false); //false 鏄剧ず琛屽彿鍒 true Hide + + //pHeaderView->setVisible(true); + //pHeaderView->setFixedHeight(40); + + //鐐瑰嚮琛ㄦ椂涓嶅琛ㄥご琛屽厜浜紙鑾峰彇鐒︾偣锛 + pHeaderView->setHighlightSections(false); + // pHeaderView->setDefaultSectionSize(200); + + // //璁剧疆琛ㄥご瀛椾綋鍔犵矖 + // QFont font = pHeaderView->font(); + // font.setBold(true); + // pHeaderView->setFont(font); + + //璁剧疆琛ㄥご瀛椾綋 + pHeaderView->setFont(QFont("Arial", 12)); + + // 璁剧疆琛ㄥご鍒楀鑷姩璋冩暣 + for (int i = 0; i < model->columnCount(); ++i) + { + pHeaderView->setSectionResizeMode(i, QHeaderView::Interactive); + } + + // 鍏佽鐢ㄦ埛閫氳繃鎷栧姩琛ㄥご杈圭紭璋冩暣鍒楀 + //pHeaderView->setSectionResizeMode(QHeaderView::Interactive); + + tableView->verticalHeader()->setDefaultSectionSize(30); //琛岄珮 + + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + + tableView->setAlternatingRowColors(true); + tableView->setTextElideMode(Qt::ElideMiddle); + + + //鎵鏈夊崟鍏冩牸鐨勫瓧浣 璁剧疆鎴愪竴鏍 + tableView->setFont(QFont("Arial", 9)); + + //璁剧疆琛ㄦ牸鏁版嵁鍖哄唴鐨勬墍鏈夊崟鍏冩牸閮戒笉鍏佽缂栬緫 + tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + +#if 1 + //璁剧疆鍒楀 + int base = 120; //w / (model->columnCount()-1); + tableView->setColumnWidth(0,base-30); + tableView->setColumnWidth(1,base*3+40); + tableView->setColumnWidth(2,base); + tableView->setColumnWidth(3,base-40); + tableView->setColumnWidth(4,base+50); +#endif + + tableView->show(); +} + +void DevicePropertyPage::InitializeTable() +{ + m_myModel = new MyTableModel(this); + m_myModel->setHeadData(AppData::getInstance()->lstDataTableHeaderText); + + m_pTableView = new QTableView(this); + m_pButton = new QPushButton(tr("Refresh"), this); + + // 鍒涘缓涓诲竷灞 + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + InitializeTableView(m_myModel,m_pTableView); + + mainLayout->addWidget(m_pTableView); + + // 鍒涘缓涓涓按骞冲竷灞鏉ュ寘鍚寜閽 + QHBoxLayout *buttonLayout = new QHBoxLayout(); + buttonLayout->addStretch(); // 璁╂寜閽繚鎸佸湪鍙充晶 + buttonLayout->addWidget(m_pButton); + buttonLayout->setContentsMargins(0, 0, 0, 0); // 鍙栨秷鎸夐挳鐨勮竟璺 + + // 灏嗚〃鏍艰鍥惧拰鎸夐挳甯冨眬娣诲姞鍒颁富甯冨眬 + mainLayout->addLayout(buttonLayout); + + mainLayout->setContentsMargins(0, 0, 0, 0); // 鍙栨秷涓诲竷灞鐨勮竟璺 + mainLayout->setSpacing(10); // 鍙栨秷甯冨眬闂寸殑闂磋窛 + + // 璁剧疆鍥哄畾澶у皬鍜屼綅缃殑鎸夐挳 + m_pButton->setFixedSize(100, 30); // 璁剧疆鎸夐挳鐨勫浐瀹氬ぇ灏 + + // 杩炴帴淇″彿鍜屾Ы + connect(m_pTableView, &QTableView::doubleClicked, this, &DevicePropertyPage::onTableViewDoubleClicked); + connect(m_pButton, &QPushButton::clicked, this, &DevicePropertyPage::onButtonClicked); + + setLayout(mainLayout); +} + +void DevicePropertyPage::Refresh() +{ + QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + TableData tbl_data; + if (Fetch(tbl_data)) + { + m_myModel->setModelData(tbl_data); + } + QGuiApplication::restoreOverrideCursor(); +} + +void DevicePropertyPage::setBaseType(unsigned int base, unsigned int mask) +{ + filterBaseType = base; + mask_code = mask; +} + + +void DevicePropertyPage::onButtonClicked() +{ + m_pTimer->stop(); + + Refresh(); +} + + +void DevicePropertyPage::onTableViewDoubleClicked(const QModelIndex &index) +{ + //QAbstractItemModel *model=ui->tableView->model(); + MyTableModel *model = (MyTableModel *)m_pTableView->model(); + QModelIndex mindex = model->index(index.row(),7); //index.row()涓虹畻閫夋嫨鐨勮鍙枫7涓烘墍閫変腑琛岀殑绗8鍒椼傘 + QVariant datatemp=model->data(mindex); +} + +void DevicePropertyPage::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); +#if 0 + // 鑾峰彇褰撳墠QTableView鐨勬诲搴 + int currentTotalWidth = m_pTableView->viewport()->width(); + + // 璁$畻鎬荤殑鍒濆瀹藉害 + int initialTotalWidth = 0; + for (int width : columnWidths) { + initialTotalWidth += width; + } + + // 璁$畻姣斾緥鍥犲瓙 + double scaleFactor = static_cast(currentTotalWidth) / initialTotalWidth; + + // 閲嶆柊璁剧疆鍒楀锛屾寜姣斾緥璋冩暣 + for (int i = 0; i < columnWidths.size(); ++i) { + int newWidth = static_cast(columnWidths[i] * scaleFactor); + m_pTableView->setColumnWidth(i, newWidth); + } +#endif +} + diff --git a/applications/emsConfigurer/devicepropertypage.h b/applications/emsConfigurer/devicepropertypage.h new file mode 100644 index 0000000..f9393c9 --- /dev/null +++ b/applications/emsConfigurer/devicepropertypage.h @@ -0,0 +1,54 @@ +锘#ifndef DEVICEPROPERTYPAGE_H +#define DEVICEPROPERTYPAGE_H + +#pragma execution_character_set("utf-8") + +#include +#include "datafetcher.h" + +class MyTableModel; +class QTimer; +class QTableView; +class QPushButton; + +class DevicePropertyPage : public QWidget,public DataFetcher +{ + Q_OBJECT + +public: + explicit DevicePropertyPage(QWidget *parent = nullptr); + ~DevicePropertyPage(); + void setBaseType(unsigned int base,unsigned int mask); + void InitializeTable(); + +public slots: + void handleTimeout(); //瓒呮椂澶勭悊鍑芥暟 + +private: + QTimer *m_pTimer; + +private: + MyTableModel* m_myModel; + +protected: + void Refresh(); + void InitializeTableView(MyTableModel *model, QTableView *tableView); + + // 閲嶅啓resizeEvent锛屽綋QTableView绐楀彛澶у皬鍙樺寲鏃舵寜姣斾緥璋冩暣鍒楀 + void resizeEvent(QResizeEvent *event) override; + +private slots: + void onButtonClicked(); + + void onTableViewDoubleClicked(const QModelIndex &index); + + +private: + unsigned int filterBaseType; + unsigned int mask_code; + QTableView* m_pTableView; + QPushButton* m_pButton; + QVector columnWidths; // 瀛樺偍鍒濆鍒楀 +}; + +#endif // DEVICEPROPERTYPAGE_H diff --git a/applications/emsConfigurer/emsConfigurer.pro b/applications/emsConfigurer/emsConfigurer.pro new file mode 100644 index 0000000..103d31c --- /dev/null +++ b/applications/emsConfigurer/emsConfigurer.pro @@ -0,0 +1,69 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +QMAKE_LFLAGS += /ignore:4099 +QMAKE_CXXFLAGS_WARN_ON += -wd4100 + +include("$$PWD/QtSingleApplication/qtsingleapplication.pri") + +DEFINES += HAVE_CONFIG_H +DEFINES += _CRT_SECURE_NO_WARNINGS + +INCLUDEPATH += $$PWD/../../SDK/include + +CONFIG(debug, debug|debug) { +INCLUDEPATH += "D:/Visual Leak Detector/include" +win32:LIBS += "D:/Visual Leak Detector/lib/Win64/vld.lib" +} + +CONFIG(debug, debug|release) { +win32:LIBS += $$PWD/..\..\SDK\lib\libdesd.lib +win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libcrypto64MDd.lib +win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libssl64MDd.lib +win32:LIBS += $$PWD/..\..\SDK\lib\hv.lib +win32:LIBS += Ws2_32.lib +}else{ +win32:LIBS += $$PWD/..\..\SDK\lib\libdes.lib +win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libcrypto64MD.lib +win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libssl64MD.lib +win32:LIBS += $$PWD/..\..\SDK\lib\hvd.lib +win32:LIBS += Ws2_32.lib +} + + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + datafetcher.cpp \ + devicepropertypage.cpp \ + globalparameters.cpp \ + main.cpp \ + maindialog.cpp \ + mainwindow.cpp \ + mytablemodel.cpp + +HEADERS += \ + datafetcher.h \ + devicepropertypage.h \ + globalparameters.h \ + maindialog.h \ + mainwindow.h \ + mytablemodel.h \ + singleton.h + +FORMS += \ + maindialog.ui \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + emscfgres.qrc diff --git a/applications/emsConfigurer/emscfgres.qrc b/applications/emsConfigurer/emscfgres.qrc new file mode 100644 index 0000000..8fe5920 --- /dev/null +++ b/applications/emsConfigurer/emscfgres.qrc @@ -0,0 +1,16 @@ + + + images/emscfg-main.ico + images/hj-net.png + images/icon.png + images/PageAir.png + images/PageBattery.png + images/PageFan.png + images/PagePower.png + images/PagePV.png + images/PageSensor.png + images/PageSetting.png + images/PageSwitch.png + images/PageUps.png + + diff --git a/applications/emsConfigurer/globalparameters.cpp b/applications/emsConfigurer/globalparameters.cpp new file mode 100644 index 0000000..b7ad80c --- /dev/null +++ b/applications/emsConfigurer/globalparameters.cpp @@ -0,0 +1,114 @@ +锘#include +#include +#include +#include +#include +#include +#include +#include + +#include "globalparameters.h" +#include "mytablemodel.h" + +AppData::~AppData() +{ +} + +AppData::AppData(token) +{ + lstDataTableHeaderText << ("Status") + << ("Parameter") + << ("Value") + << ("Unit") + << ("Time"); + + nTimeOut = 5000; + qsDestinationIp = "127.0.0.1"; + + qsLastErrorString = "OK"; + +} + +AppCommon::AppCommon(token) +{ +} + +AppCommon::~AppCommon() +{ + +} + +void AppCommon::InitializeTableView(MyTableModel *model, QTableView *tableView) +{ + //璁剧疆tableview鐨刴odel + model->setHeadData(AppData::getInstance()->lstDataTableHeaderText); + tableView->setModel(model); + + QHeaderView* pHeaderView = tableView->horizontalHeader(); + //pHeaderView->setStyleSheet("QHeaderView::section {color: black;padding-left: 4px;border: 1px solid #6c6c6c;}"); + pHeaderView->setStyleSheet("QHeaderView::section{background:lightgray;}"); + + // pHeaderView->setSectionResizeMode(QHeaderView::Stretch); //Stretch + + pHeaderView->setHidden(false); //false 鏄剧ず琛屽彿鍒 true Hide + //pHeaderView->setVisible(true); + //pHeaderView->setFixedHeight(40); + + //鐐瑰嚮琛ㄦ椂涓嶅琛ㄥご琛屽厜浜紙鑾峰彇鐒︾偣锛 + pHeaderView->setHighlightSections(false); + //pHeaderView->setDefaultSectionSize(35); + + // //璁剧疆琛ㄥご瀛椾綋鍔犵矖 + // QFont font = pHeaderView->font(); + // font.setBold(true); + // pHeaderView->setFont(font); + + //璁剧疆琛ㄥご瀛椾綋 + pHeaderView->setFont(QFont("Arial", 12)); + + // 璁剧疆琛ㄥご鍒楀鑷姩璋冩暣 + for (int i = 0; i < model->columnCount(); ++i) { + pHeaderView->setSectionResizeMode(i, QHeaderView::Stretch); + } + + // 鍏佽鐢ㄦ埛閫氳繃鎷栧姩琛ㄥご杈圭紭璋冩暣鍒楀 + pHeaderView->setSectionResizeMode(QHeaderView::Interactive); + + tableView->verticalHeader()->setDefaultSectionSize(30); //琛岄珮 + + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + + tableView->setAlternatingRowColors(true); + tableView->setTextElideMode(Qt::ElideMiddle); + + + //鎵鏈夊崟鍏冩牸鐨勫瓧浣 璁剧疆鎴愪竴鏍 + tableView->setFont(QFont("Arial", 9)); + + //璁剧疆琛ㄦ牸鏁版嵁鍖哄唴鐨勬墍鏈夊崟鍏冩牸閮戒笉鍏佽缂栬緫 + tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + +#if 0 + //璁剧疆鍒楀 + int w = tableView->width(); + int base = w /(AppData::getInstance()->lstDataTableHeaderText.count()-1); + tableView->setColumnWidth(0,base-45); + tableView->setColumnWidth(1,base-20); + tableView->setColumnWidth(2,base+30); + tableView->setColumnWidth(3,base+10); + tableView->setColumnWidth(4,base); +#endif + + tableView->show(); +} + +CWaitorCursor::CWaitorCursor() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); +} + +CWaitorCursor::~CWaitorCursor() +{ + QApplication::restoreOverrideCursor(); +} diff --git a/applications/emsConfigurer/globalparameters.h b/applications/emsConfigurer/globalparameters.h new file mode 100644 index 0000000..b28dd6f --- /dev/null +++ b/applications/emsConfigurer/globalparameters.h @@ -0,0 +1,78 @@ +锘#ifndef GLOBALPARAMETERS_H +#define GLOBALPARAMETERS_H +#pragma execution_character_set("utf-8") + +#include + +#include "singleton.h" + +class QAbstractTableModel; +class QTableView; +class MyTableModel; + +//閲囬泦璁惧鍙傛暟鎵澶勭殑鐘舵 +typedef enum _tagSignalStatus +{ + STATUS_NORMAL = 0, + STATUS_WARN = 1, + STATUS_ERROR = 2, + STATUS_INFO = 3, +}SignalStatus; + +typedef struct _ModelItem +{ + SignalStatus status; + std::string ParameterName; + std::string value; + std::string unit; + std::string sampleTime; +}ModelItem; + +typedef QList TableData; + +class CWaitorCursor +{ +public: + CWaitorCursor(); + ~CWaitorCursor(); +}; + +//鍏ㄥ眬鍙橀噺 +class AppData:public Singleton +{ +public: + AppData(token); + ~AppData(); + AppData(const AppData &other) = delete; + AppData& operator=(const AppData &other) = delete; + +public: + //鏁版嵁琛ㄦ牸鐨勮〃澶 + QStringList lstDataTableHeaderText; + + //瀹氭椂鍒锋柊闂撮殧 + int nTimeOut; + + //鐩爣鏈哄櫒IP + QString qsDestinationIp; + + //鏈鍚庣殑閿欒淇℃伅 + QString qsLastErrorString; +}; + + +//鍏ㄥ眬閫氱敤绫 +class AppCommon:public Singleton +{ +public: + AppCommon(token); + ~AppCommon(); + + AppCommon(const AppCommon&)=delete; + AppCommon& operator =(const AppCommon&)= delete; + +public: + void InitializeTableView(MyTableModel* model,QTableView* tableView); +}; + +#endif // GLOBALPARAMETERS_H diff --git a/applications/emsConfigurer/images/PageAir.png b/applications/emsConfigurer/images/PageAir.png new file mode 100644 index 0000000..6ef7023 Binary files /dev/null and b/applications/emsConfigurer/images/PageAir.png differ diff --git a/applications/emsConfigurer/images/PageBattery.png b/applications/emsConfigurer/images/PageBattery.png new file mode 100644 index 0000000..3484ae6 Binary files /dev/null and b/applications/emsConfigurer/images/PageBattery.png differ diff --git a/applications/emsConfigurer/images/PageFan.png b/applications/emsConfigurer/images/PageFan.png new file mode 100644 index 0000000..30d5176 Binary files /dev/null and b/applications/emsConfigurer/images/PageFan.png differ diff --git a/applications/emsConfigurer/images/PagePV.png b/applications/emsConfigurer/images/PagePV.png new file mode 100644 index 0000000..95735a1 Binary files /dev/null and b/applications/emsConfigurer/images/PagePV.png differ diff --git a/applications/emsConfigurer/images/PagePower.png b/applications/emsConfigurer/images/PagePower.png new file mode 100644 index 0000000..3e71b0f Binary files /dev/null and b/applications/emsConfigurer/images/PagePower.png differ diff --git a/applications/emsConfigurer/images/PageSensor.png b/applications/emsConfigurer/images/PageSensor.png new file mode 100644 index 0000000..6f0b897 Binary files /dev/null and b/applications/emsConfigurer/images/PageSensor.png differ diff --git a/applications/emsConfigurer/images/PageSetting.png b/applications/emsConfigurer/images/PageSetting.png new file mode 100644 index 0000000..e1671f6 Binary files /dev/null and b/applications/emsConfigurer/images/PageSetting.png differ diff --git a/applications/emsConfigurer/images/PageSwitch.png b/applications/emsConfigurer/images/PageSwitch.png new file mode 100644 index 0000000..d8bc768 Binary files /dev/null and b/applications/emsConfigurer/images/PageSwitch.png differ diff --git a/applications/emsConfigurer/images/PageUps.png b/applications/emsConfigurer/images/PageUps.png new file mode 100644 index 0000000..30bc5d5 Binary files /dev/null and b/applications/emsConfigurer/images/PageUps.png differ diff --git a/applications/emsConfigurer/images/emscfg-main.ico b/applications/emsConfigurer/images/emscfg-main.ico new file mode 100644 index 0000000..ced17da Binary files /dev/null and b/applications/emsConfigurer/images/emscfg-main.ico differ diff --git a/applications/emsConfigurer/images/hj-net.png b/applications/emsConfigurer/images/hj-net.png new file mode 100644 index 0000000..f4d1814 Binary files /dev/null and b/applications/emsConfigurer/images/hj-net.png differ diff --git a/applications/emsConfigurer/images/icon.png b/applications/emsConfigurer/images/icon.png new file mode 100644 index 0000000..45ced9e Binary files /dev/null and b/applications/emsConfigurer/images/icon.png differ diff --git a/applications/emsConfigurer/main.cpp b/applications/emsConfigurer/main.cpp new file mode 100644 index 0000000..f05625d --- /dev/null +++ b/applications/emsConfigurer/main.cpp @@ -0,0 +1,73 @@ +锘#ifdef _DEBUG +#include +#endif + +#include "mainwindow.h" + +#include "qtsingleapplication.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + QString app_unique_name("emsConfigurer_application_name"); + QtSingleApplication app(app_unique_name,argc, argv); + if(app.isRunning()) + { + QMessageBox::information(nullptr, "EMS Configurer", "Another instance is already running."); + app.sendMessage("raise_window_noop", 1000); //1s鍚庢縺娲诲墠涓疄渚 + + return EXIT_SUCCESS; + } + + main_ctx_init(argc, argv); + QString appDir = QCoreApplication::applicationDirPath(); + std::string logFilePath = (appDir + QString::fromStdString("/emsConfigurer.log")).toStdString(); + + hlog_set_file(logFilePath.c_str()); + hlogi("=========--- Welcome to the Earth ---========="); + hlogi("%s version: %s", argv[0], "1.1.0"); + hlog_fsync(); + + QTranslator translator; + const QStringList uiLanguages = QLocale::system().uiLanguages(); + for (const QString &locale : uiLanguages) + { + const QString baseName = "emsConfigurer_" + QLocale(locale).name(); + if (translator.load(":/i18n/" + baseName)) + { + app.installTranslator(&translator); + break; + } + } + + MainWindow w; + //闅愯棌(涓嶆樉绀)鏈澶у寲鏈灏忓寲鎸夐挳 + w.setWindowFlags(w.windowFlags()&~Qt::WindowMinMaxButtonsHint); + //w.setWindowFlags(w.windowFlags() | Qt::WindowStaysOnTopHint); + + w.setStyleSheet("{border-radius: 4px;}"); // 瀹氬埗鍦嗚 + // ".QLabel{background: gray;}.QTextEdit{background: white;}"); + + //鑾峰彇绐楀彛灏哄骞跺眳涓 + QScreen *scr = app.primaryScreen(); + int scr_w = scr->size().width(); + int scr_h = scr->size().height(); + w.move((scr_w - w.width()) / 2, (scr_h - w.height()) / 2); + + w.show(); + + int ret = app.exec(); + hlogi("=========--- I'll be back! ---========="); + return ret; +} diff --git a/applications/emsConfigurer/maindialog.cpp b/applications/emsConfigurer/maindialog.cpp new file mode 100644 index 0000000..d67b18e --- /dev/null +++ b/applications/emsConfigurer/maindialog.cpp @@ -0,0 +1,217 @@ +锘#include "maindialog.h" +#include "ui_maindialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devicepropertypage.h" + +MainDialog::MainDialog(QWidget *parent) : + QMainWindow (parent), + ui(new Ui::MainDialog) +{ + //ui->setupUi(this); + + this->setWindowIcon(QIcon(":/images/icon.png")); + + InitializeUI(); + + // Load the window state + loadWindowState(); +} + +MainDialog::~MainDialog() +{ + delete ui; +} + +void MainDialog::InitializeUI() +{ + // Create central widget and layout + this->takeCentralWidget(); + QWidget *centralWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget); + + //Create toolbar + CreateToolbar(); + + // Set up the QListWidget + m_pDeviceListWidget = new QListWidget(this); + + m_pDeviceListWidget->setStyleSheet("background-color:transparent"); + m_pDeviceListWidget->setViewMode(QListView::IconMode); + m_pDeviceListWidget->setIconSize(QSize(70, 70)); + m_pDeviceListWidget->setGridSize(QSize(145, 100)); // item 鐨勫ぇ灏 + m_pDeviceListWidget->setMovement(QListView::Static); + + m_pDeviceListWidget->setMaximumWidth(170); + m_pDeviceListWidget->setMinimumWidth(170); // Set minimum width + + m_pDeviceListWidget->setResizeMode(QListView::Fixed); + + m_pDeviceListWidget->setSpacing(25); + //m_pDeviceListWidget->setUniformItemSizes(true); // 鎵鏈夌殑 item 涓鏍峰ぇ + m_pDeviceListWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + + + CreateIcon(QIcon(":/images/PagePower.png"),tr("Power")); + CreateIcon(QIcon(":/images/PageBattery.png"),tr("Battery")); + CreateIcon(QIcon(":/images/PageSwitch.png"),tr("Switch")); + CreateIcon(QIcon(":/images/PageAir.png"),tr("Air")); + CreateIcon(QIcon(":/images/PageFan.png"),tr("Fan")); + CreateIcon(QIcon(":/images/PageSensor.png"),tr("Sensor")); + + // Set up the QStackedWidget + CreateTablePage(); + + // Set up the QSplitter to manage the resizing of QListWidget and QStackedWidget + QSplitter *splitter = new QSplitter(Qt::Horizontal, this); + splitter->addWidget(m_pDeviceListWidget); + splitter->addWidget(m_pDevicestackedWidget); + splitter->setSizes(QList({200, 600})); // Set initial sizes (200 for QListWidget, 600 for QStackedWidget) + + // Disable splitter dragging + splitter->setChildrenCollapsible(false); + + // 灏嗗伐鍏锋爮娣诲姞鍒颁富绐楀彛鐨勯《閮 + //addToolBar(Qt::TopToolBarArea, m_pMainToolBar); + + // Set up layout + mainLayout->addWidget(m_pMainToolBar); + mainLayout->addWidget(splitter); + centralWidget->setLayout(mainLayout); + + // Set central widget + setCentralWidget(centralWidget); + + // Set initial size of the dialog + setWindowTitle(tr("EMS Configurer ")); + + //resize(800, 600); + + setMinimumSize(1024, 768); + + connect(m_pDeviceListWidget, &QListWidget::currentItemChanged, this, &MainDialog::changePage); +} + + +void MainDialog::CreateToolbar() +{ + m_pMainToolBar = new QToolBar(this); + m_pMainToolBar->setIconSize(QSize(48, 48)); + + // 鍒涘缓涓涓按骞冲竷灞浠ュ绾冲浘鏍囧拰鍗犱綅绗 + QWidget *toolBarWidget = new QWidget(this); + QHBoxLayout *layout = new QHBoxLayout(toolBarWidget); + layout->setContentsMargins(0, 0, 0, 0); // 鍘婚櫎鍐呰竟璺 + + // 娣诲姞涓涓脊鎬х┖闂翠互鎺ㄩ佸浘鏍囧埌鍙充晶 + QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + layout->addItem(spacer); + + // Create actions for the toolbar + QAction *action1 = new QAction(QIcon(":/images/icon.png"), "Button 1", this); + QAction *action2 = new QAction(QIcon(":/images/icon.png"), "Button 2", this); + QAction *action3 = new QAction(QIcon(":/images/icon.png"), "About...", this); + + // Add actions to the toolbar + m_pMainToolBar->addAction(action1); + m_pMainToolBar->addAction(action2); + m_pMainToolBar->addAction(action3); + + // 灏嗗伐鍏锋爮鐨 widget 璁剧疆涓哄寘鍚浘鏍囧拰鍗犱綅绗︾殑 widget + m_pMainToolBar->addWidget(toolBarWidget); + + // Connect actions to slots + connect(action1, &QAction::triggered, this, &MainDialog::onToolButton1Clicked); + connect(action2, &QAction::triggered, this, &MainDialog::onToolButton1Clicked); + connect(action3, &QAction::triggered, this, &MainDialog::onAboutButtonClicked); +} + +void MainDialog::CreateTablePage() +{ + m_pDevicestackedWidget = new QStackedWidget(this); + + QVBoxLayout *stackedWidgetLayout = new QVBoxLayout(m_pDevicestackedWidget); + +#if 1 + //m_pDevicestackedWidget->setLayout(stackedWidgetLayout); + stackedWidgetLayout->addWidget(m_pDevicestackedWidget); + + DevicePropertyPage *page1 = new DevicePropertyPage(m_pDevicestackedWidget); + DevicePropertyPage *page2 = new DevicePropertyPage(m_pDevicestackedWidget); + + m_pDevicestackedWidget->addWidget(page1); // Add QTableView as a page + m_pDevicestackedWidget->addWidget(page2); + + m_pDevicestackedWidget->addWidget(new QPushButton("Page 3")); + m_pDevicestackedWidget->addWidget(new QPushButton("Page 4")); + m_pDevicestackedWidget->addWidget(new QPushButton("Page 5")); + m_pDevicestackedWidget->addWidget(new QPushButton("Page 6")); +#endif + // setLayout(stackedWidgetLayout); +} + +void MainDialog::CreateIcon(const QIcon& icon,QString text) +{ + QListWidgetItem *itemButton = new QListWidgetItem(m_pDeviceListWidget); + itemButton->setIcon(icon); + itemButton->setText(text); + itemButton->setTextAlignment(Qt::AlignHCenter); + itemButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); +} + +void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) +{ + if (!current) + current = previous; + + m_pDevicestackedWidget->setCurrentIndex(m_pDeviceListWidget->row(current)); +} + +void MainDialog::closeEvent(QCloseEvent *event) +{ + // Save the window state + saveWindowState(); + QMainWindow::closeEvent(event); +} + +void MainDialog::saveWindowState() +{ + QSettings settings("HJ-NET", "EMSCFG"); + settings.setValue("geometry", saveGeometry()); + settings.setValue("windowState", saveState()); +} + +void MainDialog::loadWindowState() +{ + QSettings settings("HJ-NET", "EMSCFG"); + restoreGeometry(settings.value("geometry").toByteArray()); + restoreState(settings.value("windowState").toByteArray()); +} + +void MainDialog::onToolButton1Clicked() +{ + QMessageBox::information(this, "Button Clicked", "Button 1 was clicked!"); +} + +void MainDialog::onToolButton2Clicked() +{ + QMessageBox::information(this, "Button Clicked", "Button 2 was clicked!"); +} + +void MainDialog::onAboutButtonClicked() +{ + QMessageBox::information(this, "Button Clicked", "About"); +} + diff --git a/applications/emsConfigurer/maindialog.h b/applications/emsConfigurer/maindialog.h new file mode 100644 index 0000000..885658e --- /dev/null +++ b/applications/emsConfigurer/maindialog.h @@ -0,0 +1,53 @@ +锘#ifndef MAINDIALOG_H +#define MAINDIALOG_H + +#include +#include +#include +#include +#include +#include + +namespace Ui { +class MainDialog; +} + + +class MainDialog : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainDialog(QWidget *parent = nullptr); + ~MainDialog(); + + void InitializeUI(); + void loadWindowState(); + +public slots: + void changePage(QListWidgetItem *current, QListWidgetItem *previous); + + +private slots: + void onToolButton1Clicked(); + void onToolButton2Clicked(); + void onAboutButtonClicked(); + +private: + Ui::MainDialog *ui; + QListWidget *m_pDeviceListWidget; + QStackedWidget *m_pDevicestackedWidget; + QToolBar *m_pMainToolBar; + +private: + + void CreateToolbar(); + void CreateIcon(const QIcon& icon,QString text); + void CreateTablePage(); + +protected: + void closeEvent(QCloseEvent *event) override; + void saveWindowState(); +}; + +#endif // MAINDIALOG_H diff --git a/applications/emsConfigurer/maindialog.ui b/applications/emsConfigurer/maindialog.ui new file mode 100644 index 0000000..d779f0c --- /dev/null +++ b/applications/emsConfigurer/maindialog.ui @@ -0,0 +1,25 @@ + + + MainDialog + + + Qt::NonModal + + + + 0 + 0 + 867 + 665 + + + + Qt::NoContextMenu + + + Dialog + + + + + diff --git a/applications/emsConfigurer/mainwindow.cpp b/applications/emsConfigurer/mainwindow.cpp new file mode 100644 index 0000000..cb9e0e1 --- /dev/null +++ b/applications/emsConfigurer/mainwindow.cpp @@ -0,0 +1,53 @@ +锘#include "mainwindow.h" +#include "ui_mainwindow.h" +#include +#include +#include +#include + +#include "MainDialog.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_pMainDialog(nullptr) +{ + ui->setupUi(this); + this->setWindowIcon(QIcon(":/images/icon.png")); + + QPixmap pixmap(":/images/hj-net.png"); + pixmap = pixmap.scaled(250, 75, Qt::KeepAspectRatio, Qt::SmoothTransformation); // 鎸夋瘮渚嬬缉鏀 + ui->label_logo->setPixmap(pixmap); + + QString qsLineEditStyle("QLineEdit { min-height: 20px; min-width: 120px; }"); + ui->userToken->setStyleSheet(qsLineEditStyle); + ui->serverIp->setStyleSheet(qsLineEditStyle); + + QRegularExpression rx("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$"); + QRegularExpressionValidator* ipValidator = new QRegularExpressionValidator(rx, this); + ui->serverIp->setValidator(ipValidator); + setIp("127.0.0.1"); +} + +MainWindow::~MainWindow() +{ + delete ui; + if (m_pMainDialog) + { + delete m_pMainDialog; + m_pMainDialog = nullptr; + } +} + +void MainWindow::setIp(const QString &ip) +{ + ui->serverIp->setText(ip); +} + +void MainWindow::on_pb_Logon_clicked() +{ + m_pMainDialog = new MainDialog(); + m_pMainDialog->show(); + this->close(); +} + diff --git a/applications/emsConfigurer/mainwindow.h b/applications/emsConfigurer/mainwindow.h new file mode 100644 index 0000000..3a90aaf --- /dev/null +++ b/applications/emsConfigurer/mainwindow.h @@ -0,0 +1,30 @@ +锘#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class MainDialog; + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +protected: + void setIp(const QString &ip); + +private slots: + void on_pb_Logon_clicked(); + +private: + Ui::MainWindow *ui; + MainDialog* m_pMainDialog; +}; +#endif // MAINWINDOW_H diff --git a/applications/emsConfigurer/mainwindow.ui b/applications/emsConfigurer/mainwindow.ui new file mode 100644 index 0000000..b0966c5 --- /dev/null +++ b/applications/emsConfigurer/mainwindow.ui @@ -0,0 +1,219 @@ + + + MainWindow + + + Qt::WindowModal + + + + 0 + 0 + 551 + 352 + + + + Qt::NoContextMenu + + + EMS Configurer + + + + + + 130 + 176 + 61 + 21 + + + + Host IP + + + + + + 140 + 60 + 231 + 71 + + + + + 26 + true + + + + Configurer + + + Qt::AlignCenter + + + + + + 220 + 173 + 124 + 23 + + + + + + + + + + 370 + 88 + 161 + 41 + + + + + 16 + + + + for EMU Host + + + Qt::AlignCenter + + + + + + 350 + 173 + 51 + 21 + + + + Test + + + + + + 7 + 7 + 261 + 61 + + + + WWW.HJ-NET.COM + + + + + + 140 + 280 + 251 + 31 + + + + + + + Logon + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + + + 220 + 233 + 181 + 23 + + + + Qt::NoContextMenu + + + false + + + Qt::ImhHiddenText|Qt::ImhNoAutoUppercase|Qt::ImhNoEditMenu|Qt::ImhNoPredictiveText|Qt::ImhSensitiveData + + + QLineEdit::Password + + + + + + 130 + 200 + 68 + 30 + + + + Login name + + + + + + 130 + 233 + 56 + 21 + + + + Password + + + + + + 220 + 203 + 181 + 23 + + + + + + + + diff --git a/applications/emsConfigurer/mytablemodel.cpp b/applications/emsConfigurer/mytablemodel.cpp new file mode 100644 index 0000000..1e7d268 --- /dev/null +++ b/applications/emsConfigurer/mytablemodel.cpp @@ -0,0 +1,151 @@ +锘#include +#include "mytablemodel.h" + + +MyTableModel::MyTableModel(QObject* parent) + :QAbstractTableModel(parent) +{ + for(int i=0;i<100;i++) + { + ModelItem item; + item.status = STATUS_WARN; + item.ParameterName= "Visual Leak Detector detected 1 memory leak (84 bytes)"; + item.sampleTime = "2024-9-10 11:22:33.444"; + item.unit = "C"; + item.value = "100"; + m_modelData.append(item); + } +} + +int MyTableModel::rowCount(const QModelIndex & /*parent*/) const +{ + return m_modelData.size(); +} + +int MyTableModel::columnCount(const QModelIndex & /*parent*/) const +{ + return AppData::getInstance()->lstDataTableHeaderText.count(); +} + +QVariant MyTableModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + const int row = index.row(); + switch (index.column()) + { + case 0: + { + if (m_modelData.at(row).status == STATUS_NORMAL) return tr("Normal"); + if (m_modelData.at(row).status == STATUS_INFO) return tr("INFO"); + if (m_modelData.at(row).status == STATUS_WARN) return tr("WARN"); + if (m_modelData.at(row).status == STATUS_ERROR) return tr("ERROR"); + } + case 1: + { + return m_modelData.at(row).ParameterName.c_str(); + } + case 2: return m_modelData.at(row).value.c_str(); + case 3: return m_modelData.at(row).unit.c_str(); + case 4: return m_modelData.at(row).sampleTime.c_str(); + } + } + + //瀵归綈澶勭悊 + if (role == Qt::TextAlignmentRole) + { + //const int row = index.row(); + switch (index.column()) + { + case 1: + case 2: + case 3: + return QVariant(Qt::AlignLeft|Qt::AlignVCenter); + break; + //case 4: + // return QVariant(Qt::AlignRight|Qt::AlignVCenter); + // break; + default: + return Qt::AlignCenter; + break; + } + } + + if (role == Qt::BackgroundRole) + { + const int row = index.row(); + switch (index.column()) + { + case 0: //鐘舵 + case 2: //鏁板 + { + if (m_modelData.at(row).status == STATUS_WARN) + return QVariant(QColor(Qt::yellow)); + else if (m_modelData.at(row).status == STATUS_ERROR) + return QVariant(QColor(Qt::red)); + } + } + } + + return QVariant(); +} + +QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) + { + if (section < m_headeList.size()) + { + return m_headeList[section]; + } + } + return QAbstractItemModel::headerData(section, orientation, role); +} + +const TableData *MyTableModel::getModelData() const +{ + return &m_modelData; +} + +bool MyTableModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + //beginResetModel(); + if (!index.isValid()) + return false; + + //endResetModel(); //鍦ㄧ粨鏉熷墠娣诲姞姝ゅ嚱鏁 + return QAbstractTableModel::setData(index, value, role); + +} + +Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const +{ + return Qt::ItemIsEditable | QAbstractTableModel::flags(index); +} + +void MyTableModel::setModelData(TableData data) +{ + //淇敼鏁版嵁鍓嶅悗锛岀敤beginResetModel()鍜宔ndResetModel() + beginResetModel(); //閫氳繃杩欎釜鍛婅瘔鎴戣寮濮嬩慨鏀筸odel浜 + m_modelData.clear(); + + for (int i = 0;i < data.count();++i) + { + m_modelData.append(data[i]); + } + endResetModel(); //閫氳繃杩欎釜鍛婅瘔鎴戜慨鏀筸odel缁撴潫浜 + +} + +void MyTableModel::clearModelData() +{ + m_modelData.clear(); +} + +void MyTableModel::setHeadData(QStringList i_list) +{ + m_headeList=i_list; +} diff --git a/applications/emsConfigurer/mytablemodel.h b/applications/emsConfigurer/mytablemodel.h new file mode 100644 index 0000000..6a35812 --- /dev/null +++ b/applications/emsConfigurer/mytablemodel.h @@ -0,0 +1,37 @@ +锘#pragma execution_character_set("utf-8") + +#ifndef MYTABLEMODEL_H +#define MYTABLEMODEL_H + +#include +#include +#include "globalparameters.h" + +class MyTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + MyTableModel(QObject* parent); + + int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) Q_DECL_OVERRIDE; + Qt::ItemFlags flags(const QModelIndex& index) const Q_DECL_OVERRIDE; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + const TableData *getModelData() const; + +private: + TableData m_modelData; + QStringList m_headeList; + +public: + void setHeadData(QStringList i_list); + void setModelData(TableData data); + void clearModelData(); +}; + +#endif // MYTABLEMODEL_H + diff --git a/applications/emsConfigurer/singleton.h b/applications/emsConfigurer/singleton.h new file mode 100644 index 0000000..28fb811 --- /dev/null +++ b/applications/emsConfigurer/singleton.h @@ -0,0 +1,24 @@ +锘#ifndef SINGLETON_H +#define SINGLETON_H + +#include + +template +class Singleton +{ +public: + static T* getInstance() noexcept(std::is_nothrow_constructible::value) + { + static T instance{token()}; + return &instance; + } + virtual ~Singleton() =default; + Singleton(const Singleton&)=delete; + Singleton& operator =(const Singleton&)=delete; + +protected: + struct token{}; // helper class + Singleton() noexcept=default; +}; + +#endif // SINGLETON_H diff --git a/applications/ems_datahubs/WinDataHubs.sln b/applications/ems_datahubs/WinDataHubs.sln new file mode 100644 index 0000000..7b27e53 --- /dev/null +++ b/applications/ems_datahubs/WinDataHubs.sln @@ -0,0 +1,31 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.35130.168 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinDataHubs", "WinDataHubs.vcxproj", "{2192CF4F-DE56-4896-9EA1-4C61B40590A5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x64.ActiveCfg = Debug|x64 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x64.Build.0 = Debug|x64 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x86.ActiveCfg = Debug|Win32 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x86.Build.0 = Debug|Win32 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x64.ActiveCfg = Release|x64 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x64.Build.0 = Release|x64 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x86.ActiveCfg = Release|Win32 + {2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {81B0EBA0-C45B-4F9A-B3E8-4780447CB231} + EndGlobalSection +EndGlobal diff --git a/applications/ems_datahubs/WinDataHubs.vcxproj b/applications/ems_datahubs/WinDataHubs.vcxproj new file mode 100644 index 0000000..a8a305c --- /dev/null +++ b/applications/ems_datahubs/WinDataHubs.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {2192cf4f-de56-4896-9ea1-4c61b40590a5} + WinDataHubs + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\..\..\sdk\include;$(IncludePath) + $(SolutionDir)\..\..\sdk\lib;$(LibraryPath) + + + false + + + true + $(SolutionDir)\..\..\sdk\include;$(IncludePath) + $(SolutionDir)\..\..\sdk\Lib;$(LibraryPath) + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Console + true + hv.lib;zlibd.lib;mysqlcppconn.lib;libiconvD.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/applications/ems_datahubs/datahubs.conf b/applications/ems_datahubs/datahubs.conf index 25df79c..c7beefe 100644 --- a/applications/ems_datahubs/datahubs.conf +++ b/applications/ems_datahubs/datahubs.conf @@ -8,7 +8,8 @@ log_filesize = 16M # worker_processes = auto # auto = ncpu # worker_processes = auto worker_processed = 0 -worker_threads = auto +# worker_threads = auto +worker_threads = 1 host = 0.0.0.0 port = 44242 diff --git a/applications/ems_datahubs/datahubs.vcxproj b/applications/ems_datahubs/datahubs.vcxproj index 117c3e9..e09d81c 100644 --- a/applications/ems_datahubs/datahubs.vcxproj +++ b/applications/ems_datahubs/datahubs.vcxproj @@ -76,20 +76,27 @@ - D:\My Documents\姹囩弿缃戠粶\15. EMS\projects\sdk\include;$(IncludePath) + $(SolutionDir)\..\..\sdk\include;$(IncludePath) -I/usr/local/include + $(SolutionDir)\..\..\sdk\lib; - D:\My Documents\姹囩弿缃戠粶\15. EMS\projects\emsApplication\sdk\include;$(IncludePath) + ..\..\..\emsApplication\sdk\include;$(IncludePath) + + + + + + @@ -103,6 +110,7 @@ -L/usr/local/lib hv;sqlite3;dl + %(AdditionalLibraryDirectories) diff --git a/applications/ems_datahubs/eventhandler.cpp b/applications/ems_datahubs/eventhandler.cpp new file mode 100644 index 0000000..92882c3 --- /dev/null +++ b/applications/ems_datahubs/eventhandler.cpp @@ -0,0 +1,249 @@ +#include "eventhandler.h" + +#include +#include +#include +#include +#include +#include + +#include "kdefine.h" +#include "frame_define.h" +#include "openjson.h" +#include "iconv-utils.h" +#include "kutilities.h" +#include "opmysql.h" +#include "mqtt_msg.h" + +EventHandler::EventHandler() +{ + +} + +EventHandler::~EventHandler() +{ + +} + + +void EventHandler::onRecvHandler(hio_t* io, void* buf, int readbytes) +{ + __USING_NAMESPACE_HJ__; + + char localaddrstr[SOCKADDR_STRLEN] = { 0 }; + char peeraddrstr[SOCKADDR_STRLEN] = { 0 }; + hlogi("### 1 ### on_recv fd=%d readbytes=%d [%s] <==== [%s]", hio_fd(io), readbytes, + SOCKADDR_STR(hio_localaddr(io), localaddrstr), + SOCKADDR_STR(hio_peeraddr(io), peeraddrstr)); + + MessageFrame respFrame; + if( readbytes > 0xFFFF - 1 ) + { + hloge("too large data buffer to process: %d", readbytes); + respFrame.setErrorFrame(ERR_INVALID_BUF_LEN); + hio_write(io, (void*)&respFrame, sizeof respFrame); + return; + } + + hlogi("<=== decode OK [\n%s\n]", printHex(buf, readbytes).c_str()); + + MessageFrame* pReadFrame = (MessageFrame*)buf; + hlogi("on_recv fd=%d frame_len=%d [0x%x] ", hio_fd(io), pReadFrame->frame_len, pReadFrame->frame_len); + + if( pReadFrame->frame_len > 0xFFFF - 1 ) + { + hloge("too big string buffer to process: %d, it should be less than %d", pReadFrame->frame_len, 0xFFFF); + respFrame.setErrorFrame(ERR_INVALID_LEN); + hio_write(io, (void*)&respFrame, sizeof respFrame); + return; + } + + if( Frame_DeviceData_Request == pReadFrame->frame_type ) + { + handleGatherData(io, buf, readbytes); + } + else + { + assert(false); + } +} + + +void EventHandler::handleGatherData(hio_t* io, void* buf, int readbytes) +{ + assert(buf); + + __USING_NAMESPACE_HJ__; + + MessageFrame respFrame; + MessageFrame* pReadFrame = (MessageFrame*)buf; + hlogi("<=== reveive device data request"); + + OpenJson json; + + CODING buf_code = GetCoding((unsigned char*)pReadFrame->frame_content, pReadFrame->frame_len); //判断是否是utf-8 + + hlogi("<=== recieve buffer coding is [%s]", buf_code == GBK ? "GBK" : (buf_code == UTF8 ? "UTF8" : "UNKNOWN CODING")); + + MessageData* pData = (MessageData*)pReadFrame->frame_content; + +#ifdef _DEBUG + hlogd("<=== MessageData structure [\n%s\n]", printHex(pData, pReadFrame->frame_len).c_str()); +#endif + + //这里将帧内帧的内容转换为字符串,符合json格式的字符串,详见mqtt_msg.h的MessageData结构定义 + std::string msg((char*)pReadFrame->frame_content + MSG_HEADER_LENGTH, pReadFrame->frame_len - MSG_HEADER_LENGTH); + +#ifdef _DEBUG + hlogd("<=== json content [\n%s\n]", msg.c_str()); +#endif + + if( buf_code == CODING::GBK + || buf_code == CODING::UNKOWN ) + { + std::string str_result; + //转换为UTF8 + if( !GBKToUTF8(msg, str_result) ) + { + hloge("Failed to transfer code from GBK to UTF-8"); + respFrame.setErrorFrame(ERR_INVALID_UTF8); + hio_write(io, (void*)&respFrame, sizeof respFrame); + return; + } + + hlogi("Successfuly transfer code from GBK to UTF-8!"); + msg = str_result; +} + +#ifdef _DEBUG + hlogd("<=== recieve !!VALID!! mqtt pack len =[%d] data=[%s]", msg.length(), msg.c_str()); //这里还是好的 +#endif + + unsigned int len = msg.length(); + char* pTmp = new char[len]; + memcpy(pTmp, msg.c_str(), len); + + std::shared_ptr ptr; //放个智能指针省得忘记删除 + ptr.reset(pTmp); + + //hlogi("<=== decode OK, msg=[%s]", msg.c_str()); + +#if 0 + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 17).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 18).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 19).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 20).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 21).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 22).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 23).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 24).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 25).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 26).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 27).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 28).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 29).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 30).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 31).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 32).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 33).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 34).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 61).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 62).c_str()); + hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 63).c_str()); +#endif + + //hlogd("<=== decode OK [\n%s\n]", printHex(pTmp, len).c_str()); + + try + { + if( !json.decode(msg) ) + { + hloge("Failed to decode json string pack , length=%d", readbytes); + respFrame.setErrorFrame(ERR_INVALID_JSON_FMT); + hio_write(io, (void*)&respFrame, sizeof respFrame); + return; + } + + std::string fsucode = json["FsuCode"].s(); + std::string msg_type = json["type"].s(); + std::string timestamp = get_current_timestamp(); // json["TimeStamp"].s(); + + if( fsucode.length() == 0 ) + { + //delete[] pTmp; + hlogw("!!empty fsucode recieved!"); + respFrame.setErrorFrame(ERR_INVALID_FSUCODE); + hio_write(io, (void*)&respFrame, sizeof respFrame); + return; + } + + hlogi("<=== decode OK, recieve fsucode=[%s] type=[%s] ts=[%s]", fsucode.c_str(), msg_type.c_str(), timestamp.c_str()); + + hio_write(io, (void*)&respFrame, sizeof respFrame); + +#ifdef _DEBUG + hlogd("<<<>>> \n[\n%s\n]\n", printHex(pTmp, len).c_str()); +#endif + + std::string out_compress; + + int zip_ret = 0; + if( (zip_ret = CompressString(pTmp, len, out_compress, Z_DEFAULT_COMPRESSION)) != Z_OK ) + { + hloge("Failed to compress source data, zip return value %d", zip_ret); + return; + } + + hlogd("<<<>>> \n[\n%s\n]\n", printHex(out_compress.c_str(), out_compress.size()).c_str()); +#endif + //std::string msg2(pTmp, len); + + if( msg_type == "gateway-data" + || msg_type == "gateway-alarmdata" + || msg_type == "gateway-writedata" + || msg_type == "gateway-readdata" + || msg_type == "web-write" + || msg_type == "web-alarm" ) + { + auto& IdCodeContent = json["IdCodeContent"]; + if( IdCodeContent.size() <= 0 ) + { + //delete[] pTmp; + hloge("invalid IdCodeContent's size: %d", IdCodeContent.size()); + return; + } + + auto& pNode = IdCodeContent[0]; //这是只解析第一个节点 + std::string oid = pNode["OID"].s(); + + OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id); + } + + if( msg_type == "web-read" ) + { + auto& IdCodeContent = json["IdCodes"]; + if( IdCodeContent.size() <= 0 ) + { + hloge("invalid IdCodes's size: %d", IdCodeContent.size()); + //delete[] pTmp; + return; + } + + auto& pNode = IdCodeContent[0]; //这是只解析第一个节点 + std::string oid = pNode.s(); + + OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id); + } + //delete[] pTmp; + } + catch( const char* errMsg ) + { + hloge("Failed to decode json string pack , catch error:%s", errMsg); + respFrame.setErrorFrame(ERR_INVALID_JSON_FMT); + hio_write(io, (void*)&respFrame, sizeof respFrame); + return; + } +} \ No newline at end of file diff --git a/applications/ems_datahubs/eventhandler.h b/applications/ems_datahubs/eventhandler.h new file mode 100644 index 0000000..0f8be18 --- /dev/null +++ b/applications/ems_datahubs/eventhandler.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +class EventHandler +{ +public: + EventHandler(); + virtual ~EventHandler(); + +public: + static void onRecvHandler(hio_t* io, void* buf, int readbytes); + +protected: + //处理采集程序上传的数据,以JSON数据上报 + static void handleGatherData(hio_t* io, void* buf, int readbytes); +}; + diff --git a/applications/ems_datahubs/frame_define.h b/applications/ems_datahubs/frame_define.h new file mode 100644 index 0000000..c0cbe62 --- /dev/null +++ b/applications/ems_datahubs/frame_define.h @@ -0,0 +1,54 @@ +#pragma once +#pragma pack(1) + +#include "kdefine.h" + +__NAMESPACE_BEGIN__(HJ) + +#define FRAME_HEADER_LENGTH (5) +#define FRAME_TAILE_LENGTH (4) + +typedef enum tagErrorCode : unsigned char +{ + ERR_OK = 0X00, + ERR_INVALID_LEN = 0X01, + ERR_INVALID_UTF8 = 0X02, + ERR_INVALID_BUF_LEN = 0X03, + ERR_INVALID_JSON_FMT = 0X04, + ERR_INVALID_FSUCODE = 0X05, + ERR_UNKOWN = 0XFF +}ErrorCode; + +typedef enum tagFrameType : unsigned char +{ + Frame_Response = 0x00, //返回帧 + Frame_Request = 0x01, //请求帧 + Frame_DeviceData_Request = 0x02, //来自采集程序的数据请求包,将数据保存到数据库中 +}FrameType; + +typedef struct tagFrameTail +{ + unsigned char frame_delimiter[4] = { 0xEE,0xFF,0xEE,0xFF }; +}FrameTail; + +typedef struct tagFrame +{ + FrameType frame_type; //帧类型 + unsigned int frame_len; //帧数据长度 + unsigned char frame_content[1]; //帧的内容,实际应为json字符串,由json内容自解释 + tagFrame() + { + frame_type = Frame_Response; + frame_len = 1; + frame_content[0] = ERR_OK; + } + void setErrorFrame(ErrorCode err = ERR_OK) + { + frame_len = 1; + frame_content[0] = err; + } +}MessageFrame; + +__NAMESPACE_END__(HJ) + +#pragma pack() \ No newline at end of file diff --git a/applications/ems_datahubs/iconv-utils.cpp b/applications/ems_datahubs/iconv-utils.cpp index 8d8f0ab..fc07941 100644 --- a/applications/ems_datahubs/iconv-utils.cpp +++ b/applications/ems_datahubs/iconv-utils.cpp @@ -135,8 +135,11 @@ int code_convert(const char* from_charset, const char* to_charset, char* inbuf, return -1; } iconv_close(cd); - *pout = '\0'; - +#ifndef _WIN32 + * pout = '\0'; +#else + *pout = (char*)'\0'; +#endif return 0; } diff --git a/applications/ems_datahubs/kdefine.h b/applications/ems_datahubs/kdefine.h new file mode 100644 index 0000000..5ab3434 --- /dev/null +++ b/applications/ems_datahubs/kdefine.h @@ -0,0 +1,41 @@ +#ifndef __KDEFINE_INCLUDE__ +#define __KDEFINE_INCLUDE__ + +#define K22_STR_EXP(__A) #__A +#define K22_STR(__A) K22_STR_EXP(__A) +#define K22_STRW_EXP(__A) L ## #__A +#define K22_STRW(__A) K22_STRW_EXP(__A) + +#define K22_CMS_VERSION_MAJOR 1 +#define K22_CMS_VERSION_MINOR 215 +#define K22_CMS_VERSION_REVISION 0 +#define K22_VERSION K22_STR(K22_CMS_VERSION_MAJOR) "." K22_STR(K22_CMS_VERSION_MINOR) "." K22_STR(K22_CMS_VERSION_REVISION) "" + +#ifdef __cplusplus + +# ifndef EXTERN_C +# define EXTERN_C extern "C" +# endif + +# ifndef BEGIN_EXTERN_C +# define BEGIN_EXTERN_C extern "C" { +# endif + +# ifndef END_EXTERN_C +# define END_EXTERN_C } // extern "C" +# endif + +#else + +# define EXTERN_C extern +# define BEGIN_EXTERN_C +# define END_EXTERN_C + +#endif // __cplusplus + +#define __NAMESPACE_BEGIN__(X) namespace X { +#define __NAMESPACE_END__(X) } +#define __USING_NAMESPACE__(X) using namespace X +#define __USING_NAMESPACE_HJ__ using namespace HJ + +#endif //__KDEFINE_INCLUDE__ diff --git a/applications/ems_datahubs/kutilities.cpp b/applications/ems_datahubs/kutilities.cpp new file mode 100644 index 0000000..0be5e50 --- /dev/null +++ b/applications/ems_datahubs/kutilities.cpp @@ -0,0 +1,269 @@ +#include "kutilities.h" + +#include +#include +#include +#include +#include + +#define CHUNK 16384 + +/* Compress from file source to file dest until EOF on source. +def() returns Z_OK on success, Z_MEM_ERROR if memory could not be +allocated for processing, Z_STREAM_ERROR if an invalid compression +level is supplied, Z_VERSION_ERROR if the version of zlib.h and the +version of the library linked do not match, or Z_ERRNO if there is +an error reading or writing the files. */ +int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level) +{ + if( !in_str ) + return Z_DATA_ERROR; + + int ret, flush; + unsigned have; + z_stream strm; + + unsigned char out[CHUNK]; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if( ret != Z_OK ) + return ret; + + std::shared_ptr sp_strm(&strm, [](z_stream* strm) + { + (void)deflateEnd(strm); + }); + + const char* end = in_str + in_len; + + //size_t pos_index = 0; + size_t distance = 0; + /* compress until end of file */ + do + { + distance = end - in_str; + strm.avail_in = (distance >= CHUNK) ? CHUNK : distance; + strm.next_in = (Bytef*)in_str; + + // next pos + in_str += strm.avail_in; + flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = deflate(&strm, flush); /* no bad return value */ + if( ret == Z_STREAM_ERROR ) + break; + have = CHUNK - strm.avail_out; + out_str.append((const char*)out, have); + } + while( strm.avail_out == 0 ); + + if( strm.avail_in != 0 ); /* all input will be used */ + break; + + /* done when last data in file processed */ + } + while( flush != Z_FINISH ); + + if( ret != Z_STREAM_END ) /* stream will be complete */ + return Z_STREAM_ERROR; + + /* clean up and return */ + return Z_OK; +} + +/* Decompress from file source to file dest until stream ends or EOF. +inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be +allocated for processing, Z_DATA_ERROR if the deflate data is +invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and +the version of the library linked do not match, or Z_ERRNO if there +is an error reading or writing the files. */ +int DecompressString(const char* in_str, size_t in_len, std::string& out_str) +{ + if( !in_str ) + return Z_DATA_ERROR; + + int ret; + unsigned have; + z_stream strm; + unsigned char out[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if( ret != Z_OK ) + return ret; + + std::shared_ptr sp_strm(&strm, [](z_stream* strm) + { + (void)inflateEnd(strm); + }); + + const char* end = in_str + in_len; + + //size_t pos_index = 0; + size_t distance = 0; + + int flush = 0; + /* decompress until deflate stream ends or end of file */ + do + { + distance = end - in_str; + strm.avail_in = (distance >= CHUNK) ? CHUNK : distance; + strm.next_in = (Bytef*)in_str; + + // next pos + in_str += strm.avail_in; + flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH; + + /* run inflate() on input until output buffer not full */ + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + + if( ret == Z_STREAM_ERROR ) /* state not clobbered */ + break; + + switch( ret ) + { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + return ret; + } + have = CHUNK - strm.avail_out; + out_str.append((const char*)out, have); + } + while( strm.avail_out == 0 ); + + /* done when inflate() says it's done */ + } + while( flush != Z_FINISH ); + + /* clean up and return */ + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + +// 函数用于将内存块转换为十六进制字符串 +std::string printHex(const void* data, size_t size) +{ + std::ostringstream oss; + std::ostringstream oss2; + std::ostringstream ossrow; + + const size_t lineSize = 16; // 每行输出的字节数 + const unsigned char* p = static_cast(data); + + int ic = 0; + int row = 0; + + ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : "; + oss << ossrow.str().c_str(); + + for( size_t i = 0; i < size; ++i ) + { + ic++; + + // 每个字节之间用空格分隔 + oss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << static_cast(p[i]); + + char ch = (isprint(p[i]) != 0) ? p[i] : '.'; + + oss2 << ch; + + // 每lineSize个字节换行 + if( (i + 1) % lineSize == 0 ) + { + ossrow.clear(); + ossrow.str(""); + + oss << " [" << oss2.str().c_str() << "]" << std::endl; + oss2.clear(); + oss2.str(""); + + ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : "; + oss << ossrow.str().c_str(); + + ic = 0; + } + else if( i == size - 1 ) + { + if( (i + 1) % lineSize != 0 ) + { + if( i % 2 != 0 ) + { + for( size_t j = 0; j < (lineSize - ic); j++ ) + { + oss << " --"; + } + } + else + { + for( size_t j = 0; j < (lineSize - ic); j++ ) + { + oss << " --"; + } + } + } + oss << " [" << oss2.str().c_str(); + + if( (i + 1) % lineSize != 0 ) + { + for( size_t j = 0; j < (lineSize - ic); j++ ) + { + oss << " "; + } + } + + oss << "]" << std::endl; + oss2.clear(); + oss2.str(""); + + ic = 0; + } +#if 0 + else if( (i + 1) % 8 == 0 ) + { + oss << " "; + oss2 << " "; + } +#endif + else + { + oss << " "; + } + } + return oss.str(); +} + + +std::string get_current_timestamp() +{ + auto now = std::chrono::system_clock::now(); + //通过不同精度获取相差的毫秒数 + uint64_t dis_millseconds = std::chrono::duration_cast(now.time_since_epoch()).count() + - std::chrono::duration_cast(now.time_since_epoch()).count() * 1000; + time_t tt = std::chrono::system_clock::to_time_t(now); + auto time_tm = localtime(&tt); + char strTime[25] = { 0 }; + sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d.%03d", time_tm->tm_year + 1900, + time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour, + time_tm->tm_min, time_tm->tm_sec, (int)dis_millseconds); + return std::string(strTime); +} \ No newline at end of file diff --git a/applications/ems_datahubs/kutilities.h b/applications/ems_datahubs/kutilities.h new file mode 100644 index 0000000..a3e74e9 --- /dev/null +++ b/applications/ems_datahubs/kutilities.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level); +int DecompressString(const char* in_str, size_t in_len, std::string& out_str); +std::string printHex(const void* data, size_t size); +std::string get_current_timestamp(); \ No newline at end of file diff --git a/applications/ems_datahubs/main.cpp b/applications/ems_datahubs/main.cpp index 028385e..fcbf455 100644 --- a/applications/ems_datahubs/main.cpp +++ b/applications/ems_datahubs/main.cpp @@ -1,11 +1,10 @@ 锘#include -#include #include +#ifndef _WIN32 #include +#endif #include -#include #include -#include #include #include @@ -13,180 +12,28 @@ #include #include #include -#include -#include "mqtt_msg.h" -#include "openjson.h" +#include "kdefine.h" #include "opmysql.h" +#include "eventhandler.h" -#include "iconv-utils.h" - +#ifndef TEST_UNPACK #define TEST_UNPACK 1 - -#define K22_STR_EXP(__A) #__A -#define K22_STR(__A) K22_STR_EXP(__A) -#define K22_CMS_VERSION_MAJOR 1 -#define K22_CMS_VERSION_MINOR 215 -#define K22_CMS_VERSION_REVISION 0 -#define K22_VERSION K22_STR(K22_CMS_VERSION_MAJOR) "." K22_STR(K22_CMS_VERSION_MINOR) "." K22_STR(K22_CMS_VERSION_REVISION) "" - -#define CHUNK 16384 - -/* Compress from file source to file dest until EOF on source. -def() returns Z_OK on success, Z_MEM_ERROR if memory could not be -allocated for processing, Z_STREAM_ERROR if an invalid compression -level is supplied, Z_VERSION_ERROR if the version of zlib.h and the -version of the library linked do not match, or Z_ERRNO if there is -an error reading or writing the files. */ -int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level) -{ - if (!in_str) - return Z_DATA_ERROR; - - int ret, flush; - unsigned have; - z_stream strm; - - unsigned char out[CHUNK]; - - /* allocate deflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - ret = deflateInit(&strm, level); - if (ret != Z_OK) - return ret; - - std::shared_ptr sp_strm(&strm, [](z_stream* strm) - { - (void)deflateEnd(strm); - }); - - const char* end = in_str + in_len; - - //size_t pos_index = 0; - size_t distance = 0; - /* compress until end of file */ - do - { - distance = end - in_str; - strm.avail_in = (distance >= CHUNK) ? CHUNK : distance; - strm.next_in = (Bytef*)in_str; - - // next pos - in_str += strm.avail_in; - flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH; - - /* run deflate() on input until output buffer not full, finish - compression if all of source has been read in */ - do - { - strm.avail_out = CHUNK; - strm.next_out = out; - ret = deflate(&strm, flush); /* no bad return value */ - if (ret == Z_STREAM_ERROR) - break; - have = CHUNK - strm.avail_out; - out_str.append((const char*)out, have); - } while (strm.avail_out == 0); - - if (strm.avail_in != 0); /* all input will be used */ - break; - - /* done when last data in file processed */ - } while (flush != Z_FINISH); - - if (ret != Z_STREAM_END) /* stream will be complete */ - return Z_STREAM_ERROR; - - /* clean up and return */ - return Z_OK; -} - -/* Decompress from file source to file dest until stream ends or EOF. -inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be -allocated for processing, Z_DATA_ERROR if the deflate data is -invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and -the version of the library linked do not match, or Z_ERRNO if there -is an error reading or writing the files. */ -int DecompressString(const char* in_str, size_t in_len, std::string& out_str) -{ - if (!in_str) - return Z_DATA_ERROR; - - int ret; - unsigned have; - z_stream strm; - unsigned char out[CHUNK]; - - /* allocate inflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit(&strm); - if (ret != Z_OK) - return ret; - - std::shared_ptr sp_strm(&strm, [](z_stream* strm) - { - (void)inflateEnd(strm); - }); - - const char* end = in_str + in_len; - - //size_t pos_index = 0; - size_t distance = 0; - - int flush = 0; - /* decompress until deflate stream ends or end of file */ - do - { - distance = end - in_str; - strm.avail_in = (distance >= CHUNK) ? CHUNK : distance; - strm.next_in = (Bytef*)in_str; - - // next pos - in_str += strm.avail_in; - flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH; - - /* run inflate() on input until output buffer not full */ - do - { - strm.avail_out = CHUNK; - strm.next_out = out; - ret = inflate(&strm, Z_NO_FLUSH); - - if (ret == Z_STREAM_ERROR) /* state not clobbered */ - break; - - switch (ret) - { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; /* and fall through */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - return ret; - } - have = CHUNK - strm.avail_out; - out_str.append((const char*)out, have); - } while (strm.avail_out == 0); - - /* done when inflate() says it's done */ - } while (flush != Z_FINISH); - - /* clean up and return */ - return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; -} - - -//static OpDatabase gOpDatabase; +#endif #if TEST_UNPACK static unpack_setting_t unpack_setting; #endif +//杩炴帴鍏抽棴鍥炶皟 +static void on_close(hio_t* io); +//鎺ュ叆鍥炶皟 +static void on_accept(hio_t* io); +//鎺ユ敹鍒版暟鎹 +static void on_recv(hio_t* io, void* buf, int readbytes); +//閲嶈浇鍙傛暟鍥炶皟 +static void on_reload(void* userdata); + /* * @build: make * @usage: datahubs -h @@ -212,6 +59,7 @@ typedef struct conf_ctx_s std::string dbuser; std::string dbname; } conf_ctx_t; + conf_ctx_t g_conf_ctx; inline void conf_ctx_init(conf_ctx_t* ctx) @@ -284,6 +132,7 @@ int parse_confile(const char* confile) strncpy(g_main_ctx.logfile, str.c_str(), sizeof(g_main_ctx.logfile)); } hlog_set_file(g_main_ctx.logfile); +#if 1 // loglevel str = g_conf_ctx.parser->GetValue("loglevel"); if (!str.empty()) @@ -308,14 +157,26 @@ int parse_confile(const char* confile) { logger_enable_fsync(hlog, hv_getboolean(str.c_str())); } - // first log here +#endif + // first log here hlogi("=========--- Welcome to the Earth ---========="); hlogi("%s version: %s", g_main_ctx.program_name, K22_VERSION); hlog_fsync(); +#if 0 + g_conf_ctx.worker_processes = 1; + g_conf_ctx.worker_threads = 1; + g_conf_ctx.host = "0.0.0.0"; + g_conf_ctx.port = 44242; + g_conf_ctx.dbname = "hjems"; + g_conf_ctx.dbuser = "root"; + g_conf_ctx.dbserver = "tcp://127.0.0.1:3306"; +#endif // worker_processes int worker_processes = 0; + +#if 1 #ifdef DEBUG // Disable multi-processes mode for debugging worker_processes = 0; @@ -351,6 +212,7 @@ int parse_confile(const char* confile) worker_threads = atoi(str.c_str()); } } + g_conf_ctx.worker_threads = LIMIT(0, worker_threads, 64); //host @@ -422,15 +284,10 @@ int parse_confile(const char* confile) hlogi("dbserver = ('%s')", g_conf_ctx.dbserver.c_str()); hlogi("parse_confile('%s') OK", confile); +#endif return 0; } -static void on_reload(void* userdata) -{ - hlogi("reload confile [%s]", g_main_ctx.confile); - parse_confile(g_main_ctx.confile); -} - //////1/////////////////////////////// #if 0 #define LOCKFILE "/var/lock/datahub.lock" @@ -537,6 +394,14 @@ int main(int argc, char** argv) exit(0); } + // signal + signal_init(on_reload); + const char* signal = get_arg("s"); + if( signal ) + { + signal_handle(signal); + } + // g_conf_ctx conf_ctx_init(&g_conf_ctx); const char* confile = get_arg("c"); @@ -553,13 +418,6 @@ int main(int argc, char** argv) exit(0); } - // signal - signal_init(on_reload); - const char* signal = get_arg("s"); - if (signal) - { - signal_handle(signal); - } #ifdef OS_UNIX // daemon @@ -596,294 +454,55 @@ int main(int argc, char** argv) return 0; } +void worker_fn(void* userdata) +{ + conf_ctx_t* ptrCtx = (conf_ctx_t*)(intptr_t)(userdata); + long port = ptrCtx->port; + + //initialize database connection + bool dbok = OpDatabase::getInstance()->OpenDatabase(ptrCtx->dbserver,ptrCtx->dbuser,ptrCtx->dbname); + if (!dbok) + { + hloge("failed to open database, exit now..."); + return; + } + + hlogi("database connection created!"); + + hloop_t* loop = hloop_new(0); + const char* host = ptrCtx->host.c_str(); + hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept); + + if (listenio == NULL) + { + hloge("worker process finished"); + return; + } + + hlogi("port=%ld pid=%ld tid=%ld listenfd=%d", port, hv_getpid(), hv_gettid(), hio_fd(listenio)); + + hloop_run(loop); + + hlogi("database connection close!"); + OpDatabase::getInstance()->CloseDatabase(); + + hloop_free(&loop); +} + + +/// 鍚勫洖璋冨嚱鏁板畾涔 + +static void on_reload(void* userdata) +{ + hlogi("reload confile [%s]", g_main_ctx.confile); + parse_confile(g_main_ctx.confile); +} + static void on_close(hio_t* io) { hlogi("on_close fd=%d error=%d", hio_fd(io), hio_error(io)); } -std::string get_current_timestamp() -{ - auto now = std::chrono::system_clock::now(); - //閫氳繃涓嶅悓绮惧害鑾峰彇鐩稿樊鐨勬绉掓暟 - uint64_t dis_millseconds = std::chrono::duration_cast(now.time_since_epoch()).count() - - std::chrono::duration_cast(now.time_since_epoch()).count() * 1000; - time_t tt = std::chrono::system_clock::to_time_t(now); - auto time_tm = localtime(&tt); - char strTime[25] = { 0 }; - sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d.%03d", time_tm->tm_year + 1900, - time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour, - time_tm->tm_min, time_tm->tm_sec, (int)dis_millseconds); - return std::string(strTime); -} - -// 鍑芥暟鐢ㄤ簬灏嗗唴瀛樺潡杞崲涓哄崄鍏繘鍒跺瓧绗︿覆 -std::string printHex(const void* data, size_t size) -{ - std::ostringstream oss; - std::ostringstream oss2; - std::ostringstream ossrow; - - const size_t lineSize = 16; // 姣忚杈撳嚭鐨勫瓧鑺傛暟 - const unsigned char* p = static_cast(data); - - int ic = 0; - int row = 0; - - ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : "; - oss << ossrow.str().c_str(); - - for (size_t i = 0; i < size; ++i) - { - ic++; - - // 姣忎釜瀛楄妭涔嬮棿鐢ㄧ┖鏍煎垎闅 - oss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << static_cast(p[i]); - - char ch = (isprint(p[i]) != 0) ? p[i] : '.'; - - oss2 << ch; - - // 姣弆ineSize涓瓧鑺傛崲琛 - if ((i + 1) % lineSize == 0) - { - ossrow.clear(); - ossrow.str(""); - - oss << " [" << oss2.str().c_str() << "]" << std::endl; - oss2.clear(); - oss2.str(""); - - ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : "; - oss << ossrow.str().c_str(); - - ic = 0; - } - else if (i == size - 1) - { - if ((i + 1) % lineSize != 0) - { - if (i % 2 != 0) - { - for (size_t j = 0; j < (lineSize - ic); j++) - { - oss << " --"; - } - } - else - { - for (size_t j = 0; j < (lineSize - ic); j++) - { - oss << " --"; - } - } - } - oss << " [" << oss2.str().c_str(); - - if ((i + 1) % lineSize != 0) - { - for (size_t j = 0; j < (lineSize - ic); j++) - { - oss << " "; - } - } - - oss << "]" << std::endl; - oss2.clear(); - oss2.str(""); - - ic = 0; - } -#if 0 - else if ((i + 1) % 8 == 0) - { - oss << " "; - oss2 << " "; - } -#endif - else - { - oss << " "; - } - } - return oss.str(); -} - - -//鎺ユ敹鍒版暟鎹 -static void on_recv(hio_t* io, void* buf, int readbytes) -{ - char localaddrstr[SOCKADDR_STRLEN] = { 0 }; - char peeraddrstr[SOCKADDR_STRLEN] = { 0 }; - hlogi("### 1 ### on_recv fd=%d readbytes=%d [%s] <==== [%s]", hio_fd(io), readbytes, - SOCKADDR_STR(hio_localaddr(io), localaddrstr), - SOCKADDR_STR(hio_peeraddr(io), peeraddrstr)); - - char ret[1] = { 0 }; - if (readbytes > 0xFFFF - 1) - { - hloge("too large data buffer to process: %d", readbytes); - ret[0] = 1; - hio_write(io, (void*)ret, 1); - return; - } - - MessageData* pData = (MessageData*)buf; - - OpenJson json; - - if (pData->content_len > 0xFFFF - 1) - { - hloge("too big string buffer to process: %d, it should be less than %d", pData->content_len, 0xFFFF); - ret[0] = 1; - hio_write(io, (void*)ret, 1); - return; - } - - CODING buf_code = GetCoding((unsigned char*)pData->content_data, pData->content_len); //鍒ゆ柇鏄惁鏄痷tf-8 - - hlogi("<=== recieve buffer code is [%d]", buf_code); - - std::string msg(pData->content_data, pData->content_len); - - if (buf_code == CODING::GBK - || buf_code == CODING::UNKOWN) - { - std::string str_result; - //杞崲涓篣TF8 - if (!GBKToUTF8(msg, str_result)) - { - hloge("Failed to transfer code from GBK to UTF-8"); - ret[0] = 1; - hio_write(io, (void*)ret, 1); - return; - } - - hlogi("Successfuly transfer code from GBK to UTF-8!"); - msg = str_result; - } - -#ifdef _DEBUG - hlogd("<=== recieve !!VALID!! mqtt pack len =[%d] data=[%s]", msg.length(), msg.c_str()); //杩欓噷杩樻槸濂界殑 -#endif - - unsigned int len = msg.length(); - char* pTmp = new char[len]; - memcpy(pTmp, msg.c_str(), len); - - std::shared_ptr ptr; //鏀句釜鏅鸿兘鎸囬拡鐪佸緱蹇樿鍒犻櫎 - ptr.reset(pTmp); - - //hlogi("<=== decode OK, msg=[%s]", msg.c_str()); - -#if 0 - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 17).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 18).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 19).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 20).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 21).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 22).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 23).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 24).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 25).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 26).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 27).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 28).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 29).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 30).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 31).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 32).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 33).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 34).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 61).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 62).c_str()); - hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 63).c_str()); -#endif - - //hlogd("<=== decode OK [\n%s\n]", printHex(pTmp, len).c_str()); - - if (!json.decode(msg)) - { - //delete[] pTmp; - hloge("Failed to decode json string pack , length=%d", readbytes); - ret[0] = 1; - hio_write(io, (void*)ret, 1); - return; - } - - hio_write(io, (void*)ret, 1); - - std::string fsucode = json["FsuCode"].s(); - std::string msg_type = json["type"].s(); - std::string timestamp = get_current_timestamp(); // json["TimeStamp"].s(); - - if (fsucode.length() == 0) - { - //delete[] pTmp; - hlogw("!!empty fsucode recieved!"); - return; - } - - hlogi("<=== decode OK, recieve fsucode=[%s] type=[%s] ts=[%s]", fsucode.c_str(), msg_type.c_str(), timestamp.c_str()); - -#ifdef _DEBUG - hlogd("<<<>>> \n[\n%s\n]\n", printHex(pTmp, len).c_str()); -#endif - - std::string out_compress; - - int zip_ret = 0; - if ((zip_ret = CompressString(pTmp, len, out_compress, Z_DEFAULT_COMPRESSION)) != Z_OK) - { - hloge("Failed to compress source data, zip return value %d", zip_ret); - return; - } - - hlogd("<<<>>> \n[\n%s\n]\n", printHex(out_compress.c_str(), out_compress.size()).c_str()); -#endif - //std::string msg2(pTmp, len); - - if (msg_type == "gateway-data" - || msg_type == "gateway-alarmdata" - || msg_type == "gateway-writedata" - || msg_type == "gateway-readdata" - || msg_type == "web-write" - || msg_type == "web-alarm") - { - auto& IdCodeContent = json["IdCodeContent"]; - if (IdCodeContent.size() <= 0) - { - //delete[] pTmp; - hloge("invalid IdCodeContent's size: %d", IdCodeContent.size()); - return; - } - - auto& pNode = IdCodeContent[0]; //杩欐槸鍙В鏋愮涓涓妭鐐 - std::string oid = pNode["OID"].s(); - - OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id); - } - - if (msg_type == "web-read") - { - auto& IdCodeContent = json["IdCodes"]; - if (IdCodeContent.size() <= 0) - { - hloge("invalid IdCodes's size: %d", IdCodeContent.size()); - //delete[] pTmp; - return; - } - - auto& pNode = IdCodeContent[0]; //杩欐槸鍙В鏋愮涓涓妭鐐 - std::string oid = pNode.s(); - - OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id); - } - //delete[] pTmp; -} - //鎺ュ叆鍥炶皟 static void on_accept(hio_t* io) { @@ -905,37 +524,9 @@ static void on_accept(hio_t* io) hio_read_start(io); } -void worker_fn(void* userdata) +//鎺ユ敹鍒版暟鎹 +static void on_recv(hio_t* io, void* buf, int readbytes) { - conf_ctx_t* ptrCtx = (conf_ctx_t*)(intptr_t)(userdata); - long port = ptrCtx->port; - - //initialize database connection - bool dbok = OpDatabase::getInstance()->OpenDatabase(ptrCtx->dbserver,ptrCtx->dbuser,ptrCtx->dbname); - if (!dbok) - { - hloge("failed to open database, exit now..."); - return; - } - - hlogi("database connection created!"); - - hloop_t* loop = hloop_new(0); - const char* host = ptrCtx->host.c_str(); - hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept); - - if (listenio == NULL) - { - hlogw("worker process finished"); - return; - } - - hlogi("port=%ld pid=%ld tid=%ld listenfd=%d", port, hv_getpid(), hv_gettid(), hio_fd(listenio)); - - hloop_run(loop); - - hlogi("database connection close!"); - OpDatabase::getInstance()->CloseDatabase(); - - hloop_free(&loop); + EventHandler::onRecvHandler(io, buf, readbytes); } + diff --git a/applications/ems_datahubs/mqtt_msg.h b/applications/ems_datahubs/mqtt_msg.h index 1470ac1..b00784a 100644 --- a/applications/ems_datahubs/mqtt_msg.h +++ b/applications/ems_datahubs/mqtt_msg.h @@ -1,10 +1,17 @@ #pragma once +#include "kdefine.h" + #pragma pack(1) + +__NAMESPACE_BEGIN__(HJ) + +#define MSG_HEADER_LENGTH (8) + typedef enum tagTopic : char { GateWayPublicTopic_Server = 0, ServerPublicTopic_GateWay = 1, -}MQTT_Topic; +} MQTT_Topic; typedef enum tagDataType : char { @@ -15,7 +22,9 @@ typedef enum tagDataType : char DT_GATEWAY_CTRLDATA = 4, DT_WEB_CTRL = 5, DT_WEB_WRITE = 6, - DT_GATEWAY_WRITE = 7 + DT_GATEWAY_WRITE = 7, + FRAME_REQUEST = 8, + FRAME_RESPONSE = 9, }MQTT_DataType; /* @@ -47,4 +56,6 @@ typedef struct tagMsgData char content_data[1]; //MQTT包字符串的内容 }MessageData; +__NAMESPACE_END__(HJ) + #pragma pack() \ No newline at end of file diff --git a/applications/ems_datahubs/openjson.cpp b/applications/ems_datahubs/openjson.cpp index 1e3241b..6d8f16f 100644 --- a/applications/ems_datahubs/openjson.cpp +++ b/applications/ems_datahubs/openjson.cpp @@ -20,10 +20,13 @@ #include #include +#include + #include "openjson.h" +//#define PRINTF printf +#define PRINTF hloge -#define PRINTF printf #if (defined(_MSC_VER) && (_MSC_VER >= 1400 )) inline int SNPRINTF(char* buffer, size_t size, const char* format, ...) { @@ -188,10 +191,10 @@ bool OpenJson::Box::remove(OpenJson* node) //JsonContext OpenJson::Context::Context() : - offset_(0), data_(0), - root_(0), - size_(0) + size_(0), + offset_(0), + root_(0) { } @@ -278,10 +281,10 @@ OpenJson::OpenJson(JsonType type) :type_(type), context_(0), wcontext_(0), - box_(0), idx_(0), - key_(0), len_(0), + box_(0), + key_(0), segment_(0) { } @@ -783,12 +786,16 @@ OpenJson& OpenJson::object(const char* key) { if (type_ == ARRAY) { - Log("JsonNode must be OBJECT, not ARRAY"); + PRINTF("JsonNode must be OBJECT, not ARRAY"); } type_ = OBJECT; } else { + if( !box_ ) + { + PRINTF("JsonNode must be OBJECT, not NOTHING! key:[%s]", key); + } assert(box_); } if (!box_) box_ = new Box; @@ -828,7 +835,7 @@ void OpenJson::addNode(OpenJson* node) if (!node) return; if (type_ != OBJECT && type_ != ARRAY) { - Log("JsonNode must be OBJECT or ARRAY"); + PRINTF("JsonNode must be OBJECT or ARRAY"); type_ = node->key_ ? OBJECT : ARRAY; } if (box_ == 0) box_ = new Box; diff --git a/applications/ems_datahubs/opmysql.cpp b/applications/ems_datahubs/opmysql.cpp index 0794efe..a0c249f 100644 --- a/applications/ems_datahubs/opmysql.cpp +++ b/applications/ems_datahubs/opmysql.cpp @@ -34,7 +34,8 @@ bool OpDatabase::OpenDatabase(const std::string& server, const std::string& dbus // 数据库连接配置 //std::string server = "tcp://127.0.0.1:3306"; //std::string dbuser = "root"; - std::string password = "Hj57471000"; + //std::string password = "Hj57471000"; + std::string password = "L2ysc1s1kr"; //std::string database = "hjems"; // 创建连接 diff --git a/applications/ems_datahubs/test_data/test-data-03.txt b/applications/ems_datahubs/test_data/test-data-03.txt new file mode 100644 index 0000000..e31e2cc Binary files /dev/null and b/applications/ems_datahubs/test_data/test-data-03.txt differ diff --git a/sdk/include/cppconn/build_config.h b/sdk/include/cppconn/build_config.h index f912807..a1ecbf6 100644 --- a/sdk/include/cppconn/build_config.h +++ b/sdk/include/cppconn/build_config.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_BUILD_CONFIG_H_ #define _SQL_BUILD_CONFIG_H_ diff --git a/sdk/include/cppconn/config.h b/sdk/include/cppconn/config.h index f197a02..0ddc691 100644 --- a/sdk/include/cppconn/config.h +++ b/sdk/include/cppconn/config.h @@ -1,13 +1,32 @@ /* - Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - - The MySQL Connector/C++ is licensed under the terms of the GPL - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPL as it is applied to this software, see the - FLOSS License Exception - . -*/ + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ // libmysql defines HAVE_STRTOUL (on win), so we have to follow different pattern in definitions names // to avoid annoying warnings. @@ -35,27 +54,34 @@ #define HAVE_UINT32_T 1 #define HAVE_INT64_T 1 #define HAVE_UINT64_T 1 -/* #undef HAVE_MS_INT8 */ -/* #undef HAVE_MS_UINT8 */ -/* #undef HAVE_MS_INT16 */ -/* #undef HAVE_MS_UINT16 */ -/* #undef HAVE_MS_INT32 */ -/* #undef HAVE_MS_UINT32 */ -/* #undef HAVE_MS_INT64 */ -/* #undef HAVE_MS_UINT64 */ +#define HAVE_MS_INT8 1 +#define HAVE_MS_UINT8 1 +#define HAVE_MS_INT16 1 +#define HAVE_MS_UINT16 1 +#define HAVE_MS_INT32 1 +#define HAVE_MS_UINT32 1 +#define HAVE_MS_INT64 1 +#define HAVE_MS_UINT64 1 #ifdef HAVE_STDINT_H #include #endif -#ifdef HAVE_INTTYPES_H + +#if defined(HAVE_INTTYPES_H) && !defined(_WIN32) #include #endif #if defined(_WIN32) #ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES +#if _MSC_VER >= 1600 + +#include + +#else + #if !defined(HAVE_INT8_T) && defined(HAVE_MS_INT8) typedef __int8 int8_t; #endif @@ -86,5 +112,6 @@ typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #endif +#endif // _MSC_VER >= 1600 #endif // CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES #endif // _WIN32 diff --git a/sdk/include/cppconn/connection.h b/sdk/include/cppconn/connection.h index aab4e9a..62c137d 100644 --- a/sdk/include/cppconn/connection.h +++ b/sdk/include/cppconn/connection.h @@ -1,42 +1,49 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_CONNECTION_H_ #define _SQL_CONNECTION_H_ #include -#include #include "build_config.h" #include "warning.h" #include "sqlstring.h" +#include "variant.h" namespace sql { - -typedef boost::variant ConnectPropertyVal; +typedef sql::Variant ConnectPropertyVal; typedef std::map< sql::SQLString, ConnectPropertyVal > ConnectOptionsMap; @@ -47,107 +54,121 @@ class Driver; typedef enum transaction_isolation { - TRANSACTION_NONE= 0, - TRANSACTION_READ_COMMITTED, - TRANSACTION_READ_UNCOMMITTED, - TRANSACTION_REPEATABLE_READ, - TRANSACTION_SERIALIZABLE + TRANSACTION_NONE= 0, + TRANSACTION_READ_COMMITTED, + TRANSACTION_READ_UNCOMMITTED, + TRANSACTION_REPEATABLE_READ, + TRANSACTION_SERIALIZABLE } enum_transaction_isolation; +enum ssl_mode +{ + SSL_MODE_DISABLED= 1, SSL_MODE_PREFERRED, SSL_MODE_REQUIRED, + SSL_MODE_VERIFY_CA, SSL_MODE_VERIFY_IDENTITY +}; + class Savepoint { - /* Prevent use of these */ - Savepoint(const Savepoint &); - void operator=(Savepoint &); + /* Prevent use of these */ + Savepoint(const Savepoint &); + void operator=(Savepoint &); public: - Savepoint() {}; - virtual ~Savepoint() {}; - virtual int getSavepointId() = 0; + Savepoint() {}; + virtual ~Savepoint() {}; + virtual int getSavepointId() = 0; - virtual sql::SQLString getSavepointName() = 0; + virtual sql::SQLString getSavepointName() = 0; }; class CPPCONN_PUBLIC_FUNC Connection { - /* Prevent use of these */ - Connection(const Connection &); - void operator=(Connection &); + /* Prevent use of these */ + Connection(const Connection &); + void operator=(Connection &); public: - Connection() {}; + Connection() {}; - virtual ~Connection() {}; + virtual ~Connection() {}; - virtual void clearWarnings() = 0; + virtual void clearWarnings() = 0; - virtual Statement *createStatement() = 0; + virtual Statement *createStatement() = 0; - virtual void close() = 0; + virtual void close() = 0; - virtual void commit() = 0; + virtual void commit() = 0; - virtual bool getAutoCommit() = 0; + virtual bool getAutoCommit() = 0; - virtual sql::SQLString getCatalog() = 0; + virtual sql::SQLString getCatalog() = 0; - virtual Driver *getDriver() = 0; + virtual Driver *getDriver() = 0; - virtual sql::SQLString getSchema() = 0; + virtual sql::SQLString getSchema() = 0; - virtual sql::SQLString getClientInfo() = 0; + virtual sql::SQLString getClientInfo() = 0; - virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0; + virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0; - virtual DatabaseMetaData * getMetaData() = 0; + virtual sql::SQLString getClientOption(const sql::SQLString & optionName) = 0; - virtual enum_transaction_isolation getTransactionIsolation() = 0; + virtual DatabaseMetaData * getMetaData() = 0; - virtual const SQLWarning * getWarnings() = 0; + virtual enum_transaction_isolation getTransactionIsolation() = 0; - virtual bool isClosed() = 0; + virtual const SQLWarning * getWarnings() = 0; - virtual bool isReadOnly() = 0; + virtual bool isClosed() = 0; - virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0; + virtual bool isReadOnly() = 0; - virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0; + virtual bool isValid() = 0; - virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0; + virtual bool reconnect() = 0; - virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0; + virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0; - virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0; + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0; - virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0; + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0; - virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0; + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0; - virtual void releaseSavepoint(Savepoint * savepoint) = 0; + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0; - virtual void rollback() = 0; + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0; - virtual void rollback(Savepoint * savepoint) = 0; + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0; - virtual void setAutoCommit(bool autoCommit) = 0; + virtual void releaseSavepoint(Savepoint * savepoint) = 0; - virtual void setCatalog(const sql::SQLString& catalog) = 0; + virtual void rollback() = 0; - virtual void setSchema(const sql::SQLString& catalog) = 0; + virtual void rollback(Savepoint * savepoint) = 0; - virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0; + virtual void setAutoCommit(bool autoCommit) = 0; - virtual void setHoldability(int holdability) = 0; + virtual void setCatalog(const sql::SQLString& catalog) = 0; - virtual void setReadOnly(bool readOnly) = 0; + virtual void setSchema(const sql::SQLString& catalog) = 0; - virtual Savepoint * setSavepoint() = 0; + virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0; - virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0; + virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue) = 0; - virtual void setTransactionIsolation(enum_transaction_isolation level) = 0; + virtual void setHoldability(int holdability) = 0; - /* virtual void setTypeMap(Map map) = 0; */ + virtual void setReadOnly(bool readOnly) = 0; + + virtual Savepoint * setSavepoint() = 0; + + virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0; + + virtual void setTransactionIsolation(enum_transaction_isolation level) = 0; + + /* virtual void setTypeMap(Map map) = 0; */ }; } /* namespace sql */ diff --git a/sdk/include/cppconn/datatype.h b/sdk/include/cppconn/datatype.h index b177b05..9598c37 100644 --- a/sdk/include/cppconn/datatype.h +++ b/sdk/include/cppconn/datatype.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_DATATYPE_H_ #define _SQL_DATATYPE_H_ @@ -30,35 +38,36 @@ namespace sql class DataType { - DataType(); + DataType(); public: - enum { - UNKNOWN = 0, - BIT, - TINYINT, - SMALLINT, - MEDIUMINT, - INTEGER, - BIGINT, - REAL, - DOUBLE, - DECIMAL, - NUMERIC, - CHAR, - BINARY, - VARCHAR, - VARBINARY, - LONGVARCHAR, - LONGVARBINARY, - TIMESTAMP, - DATE, - TIME, - YEAR, - GEOMETRY, - ENUM, - SET, - SQLNULL - }; + enum { + UNKNOWN = 0, + BIT, + TINYINT, + SMALLINT, + MEDIUMINT, + INTEGER, + BIGINT, + REAL, + DOUBLE, + DECIMAL, + NUMERIC, + CHAR, + BINARY, + VARCHAR, + VARBINARY, + LONGVARCHAR, + LONGVARBINARY, + TIMESTAMP, + DATE, + TIME, + YEAR, + GEOMETRY, + ENUM, + SET, + SQLNULL, + JSON + }; }; } /* namespace */ diff --git a/sdk/include/cppconn/driver.h b/sdk/include/cppconn/driver.h index 7ec7e42..d42daa7 100644 --- a/sdk/include/cppconn/driver.h +++ b/sdk/include/cppconn/driver.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_DRIVER_H_ #define _SQL_DRIVER_H_ @@ -34,35 +42,35 @@ namespace sql class CPPCONN_PUBLIC_FUNC Driver { protected: - virtual ~Driver() {} + virtual ~Driver() {} public: - // Attempts to make a database connection to the given URL. + // Attempts to make a database connection to the given URL. - virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0; + virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0; - virtual Connection * connect(ConnectOptionsMap & options) = 0; + virtual Connection * connect(ConnectOptionsMap & options) = 0; - virtual int getMajorVersion() = 0; + virtual int getMajorVersion() = 0; - virtual int getMinorVersion() = 0; + virtual int getMinorVersion() = 0; - virtual int getPatchVersion() = 0; + virtual int getPatchVersion() = 0; - virtual const sql::SQLString & getName() = 0; + virtual const sql::SQLString & getName() = 0; - virtual void threadInit() = 0; + virtual void threadInit() = 0; - virtual void threadEnd() = 0; + virtual void threadEnd() = 0; }; } /* namespace sql */ extern "C" { - CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance(); + CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance(); /* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */ - CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib); + CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib); } #endif /* _SQL_DRIVER_H_ */ diff --git a/sdk/include/cppconn/exception.h b/sdk/include/cppconn/exception.h index 0945efc..77f29d6 100644 --- a/sdk/include/cppconn/exception.h +++ b/sdk/include/cppconn/exception.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_EXCEPTION_H_ #define _SQL_EXCEPTION_H_ @@ -33,15 +41,26 @@ namespace sql { +#if (__cplusplus < 201103L) #define MEMORY_ALLOC_OPERATORS(Class) \ - void* operator new(size_t size) throw (std::bad_alloc) { return ::operator new(size); } \ - void* operator new(size_t, void*) throw(); \ - void* operator new(size_t, const std::nothrow_t&) throw(); \ - void* operator new[](size_t) throw (std::bad_alloc); \ - void* operator new[](size_t, void*) throw(); \ - void* operator new[](size_t, const std::nothrow_t&) throw(); \ - void* operator new(size_t N, std::allocator&); + void* operator new(size_t size) throw (std::bad_alloc) { return ::operator new(size); } \ + void* operator new(size_t, void*) throw(); \ + void* operator new(size_t, const std::nothrow_t&) throw(); \ + void* operator new[](size_t) throw (std::bad_alloc); \ + void* operator new[](size_t, void*) throw(); \ + void* operator new[](size_t, const std::nothrow_t&) throw(); \ + void* operator new(size_t N, std::allocator&); +#else +#define MEMORY_ALLOC_OPERATORS(Class) \ + void* operator new(size_t size){ return ::operator new(size); } \ + void* operator new(size_t, void*) noexcept; \ + void* operator new(size_t, const std::nothrow_t&) noexcept; \ + void* operator new[](size_t); \ + void* operator new[](size_t, void*) noexcept; \ + void* operator new[](size_t, const std::nothrow_t&) noexcept; \ + void* operator new(size_t N, std::allocator&); +#endif #ifdef _WIN32 #pragma warning (disable : 4290) //warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) @@ -56,71 +75,94 @@ class CPPCONN_PUBLIC_FUNC SQLException : public std::runtime_error #pragma warning(pop) #endif protected: - const std::string sql_state; - const int errNo; + const std::string sql_state; + const int errNo; public: - SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {} + SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {} - SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) : - std::runtime_error (reason ), - sql_state (SQLState ), - errNo (vendorCode) - {} + SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) : + std::runtime_error (reason ), + sql_state (SQLState ), + errNo (vendorCode) + {} - SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {} + SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {} - SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {} + SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {} - SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {} + SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {} - const std::string & getSQLState() const - { - return sql_state; - } + const std::string & getSQLState() const + { + return sql_state; + } - const char * getSQLStateCStr() const - { - return sql_state.c_str(); - } + const char * getSQLStateCStr() const + { + return sql_state.c_str(); + } - int getErrorCode() const - { - return errNo; - } + int getErrorCode() const + { + return errNo; + } - virtual ~SQLException() throw () {}; + virtual ~SQLException() throw () {}; protected: - MEMORY_ALLOC_OPERATORS(SQLException) + MEMORY_ALLOC_OPERATORS(SQLException) }; struct CPPCONN_PUBLIC_FUNC MethodNotImplementedException : public SQLException { - MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } - MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {} + MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC InvalidArgumentException : public SQLException { - InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } - InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {} + InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC InvalidInstanceException : public SQLException { - InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } - InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {} + InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC NonScrollableException : public SQLException { - NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } - NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {} + NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {} }; +struct CPPCONN_PUBLIC_FUNC SQLUnsupportedOptionException : public SQLException +{ + SQLUnsupportedOptionException(const SQLUnsupportedOptionException& e, const std::string conn_option) : + SQLException(e.what(), e.sql_state, e.errNo), + option(conn_option ) + {} + + SQLUnsupportedOptionException(const std::string& reason, const std::string conn_option) : + SQLException(reason, "", 0), + option(conn_option ) + {} + + const char *getConnectionOption() const + { + return option.c_str(); + } + + ~SQLUnsupportedOptionException() throw () {}; +protected: + const std::string option; +}; + + } /* namespace sql */ #endif /* _SQL_EXCEPTION_H_ */ diff --git a/sdk/include/cppconn/metadata.h b/sdk/include/cppconn/metadata.h index 33f381e..da9ee7a 100644 --- a/sdk/include/cppconn/metadata.h +++ b/sdk/include/cppconn/metadata.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_METADATA_H_ #define _SQL_METADATA_H_ @@ -37,438 +45,446 @@ class ResultSet; class DatabaseMetaData { protected: - virtual ~DatabaseMetaData() {} + virtual ~DatabaseMetaData() {} public: - enum - { - attributeNoNulls = 0, - attributeNullable, - attributeNullableUnknown - }; - enum - { - bestRowTemporary = 0, - bestRowTransaction, - bestRowSession - }; - enum - { - bestRowUnknown = 0, - bestRowNotPseudo, - bestRowPseudo - }; - enum - { - columnNoNulls = 0, - columnNullable, - columnNullableUnknown - }; - enum - { - importedKeyCascade = 0, - importedKeyInitiallyDeferred, - importedKeyInitiallyImmediate, - importedKeyNoAction, - importedKeyNotDeferrable, - importedKeyRestrict, - importedKeySetDefault, - importedKeySetNull - }; - enum - { - procedureColumnIn = 0, - procedureColumnInOut, - procedureColumnOut, - procedureColumnResult, - procedureColumnReturn, - procedureColumnUnknown, - procedureNoNulls, - procedureNoResult, - procedureNullable, - procedureNullableUnknown, - procedureResultUnknown, - procedureReturnsResult - }; - enum - { - sqlStateSQL99 = 0, - sqlStateXOpen - }; - enum - { - tableIndexClustered = 0, - tableIndexHashed, - tableIndexOther, - tableIndexStatistic - }; - enum - { - versionColumnUnknown = 0, - versionColumnNotPseudo = 1, - versionColumnPseudo = 2 - }; - enum - { - typeNoNulls = 0, - typeNullable = 1, - typeNullableUnknown = 2 - }; - enum - { - typePredNone = 0, - typePredChar = 1, - typePredBasic= 2, - typeSearchable = 3 - }; + enum + { + attributeNoNulls = 0, + attributeNullable, + attributeNullableUnknown + }; + enum + { + bestRowTemporary = 0, + bestRowTransaction, + bestRowSession + }; + enum + { + bestRowUnknown = 0, + bestRowNotPseudo, + bestRowPseudo + }; + enum + { + columnNoNulls = 0, + columnNullable, + columnNullableUnknown + }; + enum + { + importedKeyCascade = 0, + importedKeyInitiallyDeferred, + importedKeyInitiallyImmediate, + importedKeyNoAction, + importedKeyNotDeferrable, + importedKeyRestrict, + importedKeySetDefault, + importedKeySetNull + }; + enum + { + procedureColumnIn = 0, + procedureColumnInOut, + procedureColumnOut, + procedureColumnResult, + procedureColumnReturn, + procedureColumnUnknown, + procedureNoNulls, + procedureNoResult, + procedureNullable, + procedureNullableUnknown, + procedureResultUnknown, + procedureReturnsResult + }; + enum + { + sqlStateSQL99 = 0, + sqlStateXOpen + }; + enum + { + tableIndexClustered = 0, + tableIndexHashed, + tableIndexOther, + tableIndexStatistic + }; + enum + { + versionColumnUnknown = 0, + versionColumnNotPseudo = 1, + versionColumnPseudo = 2 + }; + enum + { + typeNoNulls = 0, + typeNullable = 1, + typeNullableUnknown = 2 + }; + enum + { + typePredNone = 0, + typePredChar = 1, + typePredBasic= 2, + typeSearchable = 3 + }; - virtual bool allProceduresAreCallable() = 0; + virtual bool allProceduresAreCallable() = 0; - virtual bool allTablesAreSelectable() = 0; + virtual bool allTablesAreSelectable() = 0; - virtual bool dataDefinitionCausesTransactionCommit() = 0; + virtual bool dataDefinitionCausesTransactionCommit() = 0; - virtual bool dataDefinitionIgnoredInTransactions() = 0; + virtual bool dataDefinitionIgnoredInTransactions() = 0; - virtual bool deletesAreDetected(int type) = 0; + virtual bool deletesAreDetected(int type) = 0; - virtual bool doesMaxRowSizeIncludeBlobs() = 0; + virtual bool doesMaxRowSizeIncludeBlobs() = 0; - virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0; + virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0; - virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0; + virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0; - virtual ResultSet * getCatalogs() = 0; + virtual ResultSet * getCatalogs() = 0; - virtual const sql::SQLString& getCatalogSeparator() = 0; + virtual const sql::SQLString& getCatalogSeparator() = 0; - virtual const sql::SQLString& getCatalogTerm() = 0; + virtual const sql::SQLString& getCatalogTerm() = 0; - virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0; + virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0; - virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0; + virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0; - virtual Connection * getConnection() = 0; + virtual Connection * getConnection() = 0; - virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0; + virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0; - virtual unsigned int getDatabaseMajorVersion() = 0; + virtual unsigned int getDatabaseMajorVersion() = 0; - virtual unsigned int getDatabaseMinorVersion() = 0; + virtual unsigned int getDatabaseMinorVersion() = 0; - virtual unsigned int getDatabasePatchVersion() = 0; + virtual unsigned int getDatabasePatchVersion() = 0; - virtual const sql::SQLString& getDatabaseProductName() = 0; + virtual const sql::SQLString& getDatabaseProductName() = 0; - virtual SQLString getDatabaseProductVersion() = 0; + virtual SQLString getDatabaseProductVersion() = 0; - virtual int getDefaultTransactionIsolation() = 0; + virtual int getDefaultTransactionIsolation() = 0; - virtual unsigned int getDriverMajorVersion() = 0; + virtual unsigned int getDriverMajorVersion() = 0; - virtual unsigned int getDriverMinorVersion() = 0; + virtual unsigned int getDriverMinorVersion() = 0; - virtual unsigned int getDriverPatchVersion() = 0; + virtual unsigned int getDriverPatchVersion() = 0; - virtual const sql::SQLString& getDriverName() = 0; + virtual const sql::SQLString& getDriverName() = 0; - virtual const sql::SQLString& getDriverVersion() = 0; + virtual const sql::SQLString& getDriverVersion() = 0; - virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; - virtual const sql::SQLString& getExtraNameCharacters() = 0; + virtual const sql::SQLString& getExtraNameCharacters() = 0; - virtual const sql::SQLString& getIdentifierQuoteString() = 0; + virtual const sql::SQLString& getIdentifierQuoteString() = 0; - virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; - virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0; + virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0; - virtual unsigned int getCDBCMajorVersion() = 0; + virtual unsigned int getCDBCMajorVersion() = 0; - virtual unsigned int getCDBCMinorVersion() = 0; + virtual unsigned int getCDBCMinorVersion() = 0; - virtual unsigned int getMaxBinaryLiteralLength() = 0; + virtual unsigned int getMaxBinaryLiteralLength() = 0; - virtual unsigned int getMaxCatalogNameLength() = 0; + virtual unsigned int getMaxCatalogNameLength() = 0; - virtual unsigned int getMaxCharLiteralLength() = 0; + virtual unsigned int getMaxCharLiteralLength() = 0; - virtual unsigned int getMaxColumnNameLength() = 0; + virtual unsigned int getMaxColumnNameLength() = 0; - virtual unsigned int getMaxColumnsInGroupBy() = 0; + virtual unsigned int getMaxColumnsInGroupBy() = 0; - virtual unsigned int getMaxColumnsInIndex() = 0; + virtual unsigned int getMaxColumnsInIndex() = 0; - virtual unsigned int getMaxColumnsInOrderBy() = 0; + virtual unsigned int getMaxColumnsInOrderBy() = 0; - virtual unsigned int getMaxColumnsInSelect() = 0; + virtual unsigned int getMaxColumnsInSelect() = 0; - virtual unsigned int getMaxColumnsInTable() = 0; + virtual unsigned int getMaxColumnsInTable() = 0; - virtual unsigned int getMaxConnections() = 0; + virtual unsigned int getMaxConnections() = 0; - virtual unsigned int getMaxCursorNameLength() = 0; + virtual unsigned int getMaxCursorNameLength() = 0; - virtual unsigned int getMaxIndexLength() = 0; + virtual unsigned int getMaxIndexLength() = 0; - virtual unsigned int getMaxProcedureNameLength() = 0; + virtual unsigned int getMaxProcedureNameLength() = 0; - virtual unsigned int getMaxRowSize() = 0; + virtual unsigned int getMaxRowSize() = 0; - virtual unsigned int getMaxSchemaNameLength() = 0; + virtual unsigned int getMaxSchemaNameLength() = 0; - virtual unsigned int getMaxStatementLength() = 0; + virtual unsigned int getMaxStatementLength() = 0; - virtual unsigned int getMaxStatements() = 0; + virtual unsigned int getMaxStatements() = 0; - virtual unsigned int getMaxTableNameLength() = 0; + virtual unsigned int getMaxTableNameLength() = 0; - virtual unsigned int getMaxTablesInSelect() = 0; + virtual unsigned int getMaxTablesInSelect() = 0; - virtual unsigned int getMaxUserNameLength() = 0; + virtual unsigned int getMaxUserNameLength() = 0; - virtual const sql::SQLString& getNumericFunctions() = 0; + virtual const sql::SQLString& getNumericFunctions() = 0; - virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; - virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0; + virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0; - virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0; + virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0; - virtual const sql::SQLString& getProcedureTerm() = 0; + virtual const sql::SQLString& getProcedureTerm() = 0; - virtual int getResultSetHoldability() = 0; + virtual int getResultSetHoldability() = 0; - virtual ResultSet * getSchemas() = 0; + virtual ResultSet * getSchemas() = 0; - virtual const sql::SQLString& getSchemaTerm() = 0; + virtual const sql::SQLString& getSchemaTerm() = 0; - virtual const sql::SQLString& getSearchStringEscape() = 0; + virtual ResultSet * getSchemaCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0; - virtual const sql::SQLString& getSQLKeywords() = 0; + virtual ResultSet * getSchemaCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0; - virtual int getSQLStateType() = 0; + virtual const sql::SQLString& getSearchStringEscape() = 0; - virtual const sql::SQLString& getStringFunctions() = 0; + virtual const sql::SQLString& getSQLKeywords() = 0; - virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; + virtual int getSQLStateType() = 0; - virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0; + virtual const sql::SQLString& getStringFunctions() = 0; - virtual const sql::SQLString& getSystemFunctions() = 0; + virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; - virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; + virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0; - virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list &types) = 0; + virtual const sql::SQLString& getSystemFunctions() = 0; - virtual ResultSet * getTableTypes() = 0; + virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; - virtual const sql::SQLString& getTimeDateFunctions() = 0; + virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list &types) = 0; - virtual ResultSet * getTypeInfo() = 0; + virtual ResultSet * getTableTypes() = 0; - virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list &types) = 0; + virtual ResultSet * getTableCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; - virtual SQLString getURL() = 0; + virtual ResultSet * getTableCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; - virtual SQLString getUserName() = 0; + virtual const sql::SQLString& getTimeDateFunctions() = 0; - virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + virtual ResultSet * getTypeInfo() = 0; - virtual bool insertsAreDetected(int type) = 0; + virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list &types) = 0; - virtual bool isCatalogAtStart() = 0; + virtual SQLString getURL() = 0; - virtual bool isReadOnly() = 0; + virtual SQLString getUserName() = 0; - virtual bool locatorsUpdateCopy() = 0; + virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; - virtual bool nullPlusNonNullIsNull() = 0; + virtual bool insertsAreDetected(int type) = 0; - virtual bool nullsAreSortedAtEnd() = 0; + virtual bool isCatalogAtStart() = 0; - virtual bool nullsAreSortedAtStart() = 0; + virtual bool isReadOnly() = 0; - virtual bool nullsAreSortedHigh() = 0; + virtual bool locatorsUpdateCopy() = 0; - virtual bool nullsAreSortedLow() = 0; + virtual bool nullPlusNonNullIsNull() = 0; - virtual bool othersDeletesAreVisible(int type) = 0; + virtual bool nullsAreSortedAtEnd() = 0; - virtual bool othersInsertsAreVisible(int type) = 0; + virtual bool nullsAreSortedAtStart() = 0; - virtual bool othersUpdatesAreVisible(int type) = 0; + virtual bool nullsAreSortedHigh() = 0; - virtual bool ownDeletesAreVisible(int type) = 0; + virtual bool nullsAreSortedLow() = 0; - virtual bool ownInsertsAreVisible(int type) = 0; + virtual bool othersDeletesAreVisible(int type) = 0; - virtual bool ownUpdatesAreVisible(int type) = 0; + virtual bool othersInsertsAreVisible(int type) = 0; - virtual bool storesLowerCaseIdentifiers() = 0; + virtual bool othersUpdatesAreVisible(int type) = 0; - virtual bool storesLowerCaseQuotedIdentifiers() = 0; + virtual bool ownDeletesAreVisible(int type) = 0; - virtual bool storesMixedCaseIdentifiers() = 0; + virtual bool ownInsertsAreVisible(int type) = 0; - virtual bool storesMixedCaseQuotedIdentifiers() = 0; + virtual bool ownUpdatesAreVisible(int type) = 0; - virtual bool storesUpperCaseIdentifiers() = 0; + virtual bool storesLowerCaseIdentifiers() = 0; - virtual bool storesUpperCaseQuotedIdentifiers() = 0; + virtual bool storesLowerCaseQuotedIdentifiers() = 0; - virtual bool supportsAlterTableWithAddColumn() = 0; + virtual bool storesMixedCaseIdentifiers() = 0; - virtual bool supportsAlterTableWithDropColumn() = 0; + virtual bool storesMixedCaseQuotedIdentifiers() = 0; - virtual bool supportsANSI92EntryLevelSQL() = 0; + virtual bool storesUpperCaseIdentifiers() = 0; - virtual bool supportsANSI92FullSQL() = 0; + virtual bool storesUpperCaseQuotedIdentifiers() = 0; - virtual bool supportsANSI92IntermediateSQL() = 0; + virtual bool supportsAlterTableWithAddColumn() = 0; - virtual bool supportsBatchUpdates() = 0; + virtual bool supportsAlterTableWithDropColumn() = 0; - virtual bool supportsCatalogsInDataManipulation() = 0; + virtual bool supportsANSI92EntryLevelSQL() = 0; - virtual bool supportsCatalogsInIndexDefinitions() = 0; + virtual bool supportsANSI92FullSQL() = 0; - virtual bool supportsCatalogsInPrivilegeDefinitions() = 0; + virtual bool supportsANSI92IntermediateSQL() = 0; - virtual bool supportsCatalogsInProcedureCalls() = 0; + virtual bool supportsBatchUpdates() = 0; - virtual bool supportsCatalogsInTableDefinitions() = 0; + virtual bool supportsCatalogsInDataManipulation() = 0; - virtual bool supportsColumnAliasing() = 0; + virtual bool supportsCatalogsInIndexDefinitions() = 0; - virtual bool supportsConvert() = 0; + virtual bool supportsCatalogsInPrivilegeDefinitions() = 0; - virtual bool supportsConvert(int fromType, int toType) = 0; + virtual bool supportsCatalogsInProcedureCalls() = 0; - virtual bool supportsCoreSQLGrammar() = 0; + virtual bool supportsCatalogsInTableDefinitions() = 0; - virtual bool supportsCorrelatedSubqueries() = 0; + virtual bool supportsColumnAliasing() = 0; - virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0; + virtual bool supportsConvert() = 0; - virtual bool supportsDataManipulationTransactionsOnly() = 0; + virtual bool supportsConvert(int fromType, int toType) = 0; - virtual bool supportsDifferentTableCorrelationNames() = 0; + virtual bool supportsCoreSQLGrammar() = 0; - virtual bool supportsExpressionsInOrderBy() = 0; + virtual bool supportsCorrelatedSubqueries() = 0; - virtual bool supportsExtendedSQLGrammar() = 0; + virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0; - virtual bool supportsFullOuterJoins() = 0; + virtual bool supportsDataManipulationTransactionsOnly() = 0; - virtual bool supportsGetGeneratedKeys() = 0; + virtual bool supportsDifferentTableCorrelationNames() = 0; - virtual bool supportsGroupBy() = 0; + virtual bool supportsExpressionsInOrderBy() = 0; - virtual bool supportsGroupByBeyondSelect() = 0; + virtual bool supportsExtendedSQLGrammar() = 0; - virtual bool supportsGroupByUnrelated() = 0; + virtual bool supportsFullOuterJoins() = 0; - virtual bool supportsIntegrityEnhancementFacility() = 0; + virtual bool supportsGetGeneratedKeys() = 0; - virtual bool supportsLikeEscapeClause() = 0; + virtual bool supportsGroupBy() = 0; - virtual bool supportsLimitedOuterJoins() = 0; + virtual bool supportsGroupByBeyondSelect() = 0; - virtual bool supportsMinimumSQLGrammar() = 0; + virtual bool supportsGroupByUnrelated() = 0; - virtual bool supportsMixedCaseIdentifiers() = 0; + virtual bool supportsIntegrityEnhancementFacility() = 0; - virtual bool supportsMixedCaseQuotedIdentifiers() = 0; + virtual bool supportsLikeEscapeClause() = 0; - virtual bool supportsMultipleOpenResults() = 0; + virtual bool supportsLimitedOuterJoins() = 0; - virtual bool supportsMultipleResultSets() = 0; + virtual bool supportsMinimumSQLGrammar() = 0; - virtual bool supportsMultipleTransactions() = 0; + virtual bool supportsMixedCaseIdentifiers() = 0; - virtual bool supportsNamedParameters() = 0; + virtual bool supportsMixedCaseQuotedIdentifiers() = 0; - virtual bool supportsNonNullableColumns() = 0; + virtual bool supportsMultipleOpenResults() = 0; - virtual bool supportsOpenCursorsAcrossCommit() = 0; + virtual bool supportsMultipleResultSets() = 0; - virtual bool supportsOpenCursorsAcrossRollback() = 0; + virtual bool supportsMultipleTransactions() = 0; - virtual bool supportsOpenStatementsAcrossCommit() = 0; + virtual bool supportsNamedParameters() = 0; - virtual bool supportsOpenStatementsAcrossRollback() = 0; + virtual bool supportsNonNullableColumns() = 0; - virtual bool supportsOrderByUnrelated() = 0; + virtual bool supportsOpenCursorsAcrossCommit() = 0; - virtual bool supportsOuterJoins() = 0; + virtual bool supportsOpenCursorsAcrossRollback() = 0; - virtual bool supportsPositionedDelete() = 0; + virtual bool supportsOpenStatementsAcrossCommit() = 0; - virtual bool supportsPositionedUpdate() = 0; + virtual bool supportsOpenStatementsAcrossRollback() = 0; - virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0; + virtual bool supportsOrderByUnrelated() = 0; - virtual bool supportsResultSetHoldability(int holdability) = 0; + virtual bool supportsOuterJoins() = 0; - virtual bool supportsResultSetType(int type) = 0; + virtual bool supportsPositionedDelete() = 0; - virtual bool supportsSavepoints() = 0; + virtual bool supportsPositionedUpdate() = 0; - virtual bool supportsSchemasInDataManipulation() = 0; + virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0; - virtual bool supportsSchemasInIndexDefinitions() = 0; + virtual bool supportsResultSetHoldability(int holdability) = 0; - virtual bool supportsSchemasInPrivilegeDefinitions() = 0; + virtual bool supportsResultSetType(int type) = 0; - virtual bool supportsSchemasInProcedureCalls() = 0; + virtual bool supportsSavepoints() = 0; - virtual bool supportsSchemasInTableDefinitions() = 0; + virtual bool supportsSchemasInDataManipulation() = 0; - virtual bool supportsSelectForUpdate() = 0; + virtual bool supportsSchemasInIndexDefinitions() = 0; - virtual bool supportsStatementPooling() = 0; + virtual bool supportsSchemasInPrivilegeDefinitions() = 0; - virtual bool supportsStoredProcedures() = 0; + virtual bool supportsSchemasInProcedureCalls() = 0; - virtual bool supportsSubqueriesInComparisons() = 0; + virtual bool supportsSchemasInTableDefinitions() = 0; - virtual bool supportsSubqueriesInExists() = 0; + virtual bool supportsSelectForUpdate() = 0; - virtual bool supportsSubqueriesInIns() = 0; + virtual bool supportsStatementPooling() = 0; - virtual bool supportsSubqueriesInQuantifieds() = 0; + virtual bool supportsStoredProcedures() = 0; - virtual bool supportsTableCorrelationNames() = 0; + virtual bool supportsSubqueriesInComparisons() = 0; - virtual bool supportsTransactionIsolationLevel(int level) = 0; + virtual bool supportsSubqueriesInExists() = 0; - virtual bool supportsTransactions() = 0; + virtual bool supportsSubqueriesInIns() = 0; - virtual bool supportsTypeConversion() = 0; /* SDBC */ + virtual bool supportsSubqueriesInQuantifieds() = 0; - virtual bool supportsUnion() = 0; + virtual bool supportsTableCorrelationNames() = 0; - virtual bool supportsUnionAll() = 0; + virtual bool supportsTransactionIsolationLevel(int level) = 0; - virtual bool updatesAreDetected(int type) = 0; + virtual bool supportsTransactions() = 0; - virtual bool usesLocalFilePerTable() = 0; + virtual bool supportsTypeConversion() = 0; /* SDBC */ - virtual bool usesLocalFiles() = 0; + virtual bool supportsUnion() = 0; - virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0; + virtual bool supportsUnionAll() = 0; - virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "", - const sql::SQLString& schemaName = "", - const sql::SQLString& objectType = "", - bool includingDdl = true, - const sql::SQLString& objectName = "", - const sql::SQLString& contextTableName = "") = 0; + virtual bool updatesAreDetected(int type) = 0; - virtual ResultSet *getSchemaObjectTypes() = 0; + virtual bool usesLocalFilePerTable() = 0; + + virtual bool usesLocalFiles() = 0; + + virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0; + + virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "", + const sql::SQLString& schemaName = "", + const sql::SQLString& objectType = "", + bool includingDdl = true, + const sql::SQLString& objectName = "", + const sql::SQLString& contextTableName = "") = 0; + + virtual ResultSet *getSchemaObjectTypes() = 0; }; diff --git a/sdk/include/cppconn/parameter_metadata.h b/sdk/include/cppconn/parameter_metadata.h index 7e97f4c..c949aef 100644 --- a/sdk/include/cppconn/parameter_metadata.h +++ b/sdk/include/cppconn/parameter_metadata.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_PARAMETER_METADATA_H_ #define _SQL_PARAMETER_METADATA_H_ @@ -34,40 +42,40 @@ namespace sql class ParameterMetaData { public: - enum - { - parameterModeIn, - parameterModeInOut, - parameterModeOut, - parameterModeUnknown - }; - enum - { - parameterNoNulls, - parameterNullable, - parameterNullableUnknown - }; + enum + { + parameterModeIn, + parameterModeInOut, + parameterModeOut, + parameterModeUnknown + }; + enum + { + parameterNoNulls, + parameterNullable, + parameterNullableUnknown + }; - virtual sql::SQLString getParameterClassName(unsigned int param) = 0; + virtual sql::SQLString getParameterClassName(unsigned int param) = 0; - virtual int getParameterCount() = 0; + virtual int getParameterCount() = 0; - virtual int getParameterMode(unsigned int param) = 0; + virtual int getParameterMode(unsigned int param) = 0; - virtual int getParameterType(unsigned int param) = 0; + virtual int getParameterType(unsigned int param) = 0; - virtual sql::SQLString getParameterTypeName(unsigned int param) = 0; + virtual sql::SQLString getParameterTypeName(unsigned int param) = 0; - virtual int getPrecision(unsigned int param) = 0; + virtual int getPrecision(unsigned int param) = 0; - virtual int getScale(unsigned int param) = 0; + virtual int getScale(unsigned int param) = 0; - virtual int isNullable(unsigned int param) = 0; + virtual int isNullable(unsigned int param) = 0; - virtual bool isSigned(unsigned int param) = 0; + virtual bool isSigned(unsigned int param) = 0; protected: - virtual ~ParameterMetaData() {} + virtual ~ParameterMetaData() {} }; diff --git a/sdk/include/cppconn/prepared_statement.h b/sdk/include/cppconn/prepared_statement.h index 5549651..33dace9 100644 --- a/sdk/include/cppconn/prepared_statement.h +++ b/sdk/include/cppconn/prepared_statement.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_PREPARED_STATEMENT_H_ @@ -41,46 +49,48 @@ class ParameterMetaData; class PreparedStatement : public Statement { public: - virtual ~PreparedStatement() {} + virtual ~PreparedStatement() {} - virtual void clearParameters() = 0; + virtual void clearParameters() = 0; - virtual bool execute(const sql::SQLString& sql) = 0; - virtual bool execute() = 0; + virtual bool execute(const sql::SQLString& sql) = 0; + virtual bool execute() = 0; - virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0; - virtual ResultSet *executeQuery() = 0; + virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0; + virtual ResultSet *executeQuery() = 0; - virtual int executeUpdate(const sql::SQLString& sql) = 0; - virtual int executeUpdate() = 0; + virtual int executeUpdate(const sql::SQLString& sql) = 0; + virtual int executeUpdate() = 0; - virtual ResultSetMetaData * getMetaData() = 0; + virtual ResultSetMetaData * getMetaData() = 0; - virtual ParameterMetaData * getParameterMetaData() = 0; + virtual ParameterMetaData * getParameterMetaData() = 0; - virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0; + virtual bool getMoreResults() = 0; - virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0; + virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0; - virtual void setBoolean(unsigned int parameterIndex, bool value) = 0; + virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0; - virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0; + virtual void setBoolean(unsigned int parameterIndex, bool value) = 0; - virtual void setDouble(unsigned int parameterIndex, double value) = 0; + virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0; - virtual void setInt(unsigned int parameterIndex, int32_t value) = 0; + virtual void setDouble(unsigned int parameterIndex, double value) = 0; - virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0; + virtual void setInt(unsigned int parameterIndex, int32_t value) = 0; - virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0; + virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0; - virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0; + virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0; - virtual void setNull(unsigned int parameterIndex, int sqlType) = 0; + virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0; - virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0; + virtual void setNull(unsigned int parameterIndex, int sqlType) = 0; - virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0; + virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0; + + virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0; }; diff --git a/sdk/include/cppconn/resultset.h b/sdk/include/cppconn/resultset.h index d4f207a..a0aa228 100644 --- a/sdk/include/cppconn/resultset.h +++ b/sdk/include/cppconn/resultset.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_RESULTSET_H_ #define _SQL_RESULTSET_H_ @@ -42,137 +50,137 @@ class Statement; class RowID { public: - virtual ~RowID() {} + virtual ~RowID() {} }; class ResultSet { public: - enum - { - CLOSE_CURSORS_AT_COMMIT, - HOLD_CURSORS_OVER_COMMIT - }; - enum - { - CONCUR_READ_ONLY, - CONCUR_UPDATABLE - }; - enum - { - FETCH_FORWARD, - FETCH_REVERSE, - FETCH_UNKNOWN - }; - typedef enum - { - TYPE_FORWARD_ONLY, - TYPE_SCROLL_INSENSITIVE, - TYPE_SCROLL_SENSITIVE - } enum_type; + enum + { + CLOSE_CURSORS_AT_COMMIT, + HOLD_CURSORS_OVER_COMMIT + }; + enum + { + CONCUR_READ_ONLY, + CONCUR_UPDATABLE + }; + enum + { + FETCH_FORWARD, + FETCH_REVERSE, + FETCH_UNKNOWN + }; + typedef enum + { + TYPE_FORWARD_ONLY, + TYPE_SCROLL_INSENSITIVE, + TYPE_SCROLL_SENSITIVE + } enum_type; - virtual ~ResultSet() {} + virtual ~ResultSet() {} - virtual bool absolute(int row) = 0; + virtual bool absolute(int row) = 0; - virtual void afterLast() = 0; + virtual void afterLast() = 0; - virtual void beforeFirst() = 0; + virtual void beforeFirst() = 0; - virtual void cancelRowUpdates() = 0; + virtual void cancelRowUpdates() = 0; - virtual void clearWarnings() = 0; + virtual void clearWarnings() = 0; - virtual void close() = 0; + virtual void close() = 0; - virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0; + virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0; - virtual bool first() = 0; + virtual bool first() = 0; - virtual std::istream * getBlob(uint32_t columnIndex) const = 0; - virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0; + virtual std::istream * getBlob(uint32_t columnIndex) const = 0; + virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0; - virtual bool getBoolean(uint32_t columnIndex) const = 0; - virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0; + virtual bool getBoolean(uint32_t columnIndex) const = 0; + virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0; - virtual int getConcurrency() = 0; - virtual SQLString getCursorName() = 0; + virtual int getConcurrency() = 0; + virtual SQLString getCursorName() = 0; - virtual long double getDouble(uint32_t columnIndex) const = 0; - virtual long double getDouble(const sql::SQLString& columnLabel) const = 0; + virtual long double getDouble(uint32_t columnIndex) const = 0; + virtual long double getDouble(const sql::SQLString& columnLabel) const = 0; - virtual int getFetchDirection() = 0; - virtual size_t getFetchSize() = 0; - virtual int getHoldability() = 0; + virtual int getFetchDirection() = 0; + virtual size_t getFetchSize() = 0; + virtual int getHoldability() = 0; - virtual int32_t getInt(uint32_t columnIndex) const = 0; - virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0; + virtual int32_t getInt(uint32_t columnIndex) const = 0; + virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0; - virtual uint32_t getUInt(uint32_t columnIndex) const = 0; - virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0; + virtual uint32_t getUInt(uint32_t columnIndex) const = 0; + virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0; - virtual int64_t getInt64(uint32_t columnIndex) const = 0; - virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0; + virtual int64_t getInt64(uint32_t columnIndex) const = 0; + virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0; - virtual uint64_t getUInt64(uint32_t columnIndex) const = 0; - virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0; + virtual uint64_t getUInt64(uint32_t columnIndex) const = 0; + virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0; - virtual ResultSetMetaData * getMetaData() const = 0; + virtual ResultSetMetaData * getMetaData() const = 0; - virtual size_t getRow() const = 0; + virtual size_t getRow() const = 0; - virtual RowID * getRowId(uint32_t columnIndex) = 0; - virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0; + virtual RowID * getRowId(uint32_t columnIndex) = 0; + virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0; - virtual const Statement * getStatement() const = 0; + virtual const Statement * getStatement() const = 0; - virtual SQLString getString(uint32_t columnIndex) const = 0; - virtual SQLString getString(const sql::SQLString& columnLabel) const = 0; + virtual SQLString getString(uint32_t columnIndex) const = 0; + virtual SQLString getString(const sql::SQLString& columnLabel) const = 0; - virtual enum_type getType() const = 0; + virtual enum_type getType() const = 0; - virtual void getWarnings() = 0; + virtual void getWarnings() = 0; - virtual void insertRow() = 0; + virtual void insertRow() = 0; - virtual bool isAfterLast() const = 0; + virtual bool isAfterLast() const = 0; - virtual bool isBeforeFirst() const = 0; + virtual bool isBeforeFirst() const = 0; - virtual bool isClosed() const = 0; + virtual bool isClosed() const = 0; - virtual bool isFirst() const = 0; + virtual bool isFirst() const = 0; - virtual bool isLast() const = 0; + virtual bool isLast() const = 0; - virtual bool isNull(uint32_t columnIndex) const = 0; - virtual bool isNull(const sql::SQLString& columnLabel) const = 0; + virtual bool isNull(uint32_t columnIndex) const = 0; + virtual bool isNull(const sql::SQLString& columnLabel) const = 0; - virtual bool last() = 0; + virtual bool last() = 0; - virtual bool next() = 0; + virtual bool next() = 0; - virtual void moveToCurrentRow() = 0; + virtual void moveToCurrentRow() = 0; - virtual void moveToInsertRow() = 0; + virtual void moveToInsertRow() = 0; - virtual bool previous() = 0; + virtual bool previous() = 0; - virtual void refreshRow() = 0; + virtual void refreshRow() = 0; - virtual bool relative(int rows) = 0; + virtual bool relative(int rows) = 0; - virtual bool rowDeleted() = 0; + virtual bool rowDeleted() = 0; - virtual bool rowInserted() = 0; + virtual bool rowInserted() = 0; - virtual bool rowUpdated() = 0; + virtual bool rowUpdated() = 0; - virtual void setFetchSize(size_t rows) = 0; + virtual void setFetchSize(size_t rows) = 0; - virtual size_t rowsCount() const = 0; + virtual size_t rowsCount() const = 0; - virtual bool wasNull() const = 0; + virtual bool wasNull() const = 0; }; } /* namespace sql */ diff --git a/sdk/include/cppconn/resultset_metadata.h b/sdk/include/cppconn/resultset_metadata.h index f23e34c..9cd7963 100644 --- a/sdk/include/cppconn/resultset_metadata.h +++ b/sdk/include/cppconn/resultset_metadata.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_RESULTSET_METADATA_H_ #define _SQL_RESULTSET_METADATA_H_ @@ -34,57 +42,63 @@ namespace sql class ResultSetMetaData { public: - enum - { - columnNoNulls, - columnNullable, - columnNullableUnknown - }; + enum + { + columnNoNulls, + columnNullable, + columnNullableUnknown + }; - virtual SQLString getCatalogName(unsigned int column) = 0; + virtual SQLString getCatalogName(unsigned int column) = 0; - virtual unsigned int getColumnCount() = 0; + virtual unsigned int getColumnCount() = 0; - virtual unsigned int getColumnDisplaySize(unsigned int column) = 0; + virtual unsigned int getColumnDisplaySize(unsigned int column) = 0; - virtual SQLString getColumnLabel(unsigned int column) = 0; + virtual SQLString getColumnLabel(unsigned int column) = 0; - virtual SQLString getColumnName(unsigned int column) = 0; + virtual SQLString getColumnName(unsigned int column) = 0; - virtual int getColumnType(unsigned int column) = 0; + virtual int getColumnType(unsigned int column) = 0; - virtual SQLString getColumnTypeName(unsigned int column) = 0; + virtual SQLString getColumnTypeName(unsigned int column) = 0; - virtual unsigned int getPrecision(unsigned int column) = 0; + virtual SQLString getColumnCharset(unsigned int columnIndex) = 0; - virtual unsigned int getScale(unsigned int column) = 0; + virtual SQLString getColumnCollation(unsigned int columnIndex) = 0; - virtual SQLString getSchemaName(unsigned int column) = 0; + virtual unsigned int getPrecision(unsigned int column) = 0; - virtual SQLString getTableName(unsigned int column) = 0; + virtual unsigned int getScale(unsigned int column) = 0; - virtual bool isAutoIncrement(unsigned int column) = 0; + virtual SQLString getSchemaName(unsigned int column) = 0; - virtual bool isCaseSensitive(unsigned int column) = 0; + virtual SQLString getTableName(unsigned int column) = 0; - virtual bool isCurrency(unsigned int column) = 0; + virtual bool isAutoIncrement(unsigned int column) = 0; - virtual bool isDefinitelyWritable(unsigned int column) = 0; + virtual bool isCaseSensitive(unsigned int column) = 0; - virtual int isNullable(unsigned int column) = 0; + virtual bool isCurrency(unsigned int column) = 0; - virtual bool isReadOnly(unsigned int column) = 0; + virtual bool isDefinitelyWritable(unsigned int column) = 0; - virtual bool isSearchable(unsigned int column) = 0; + virtual int isNullable(unsigned int column) = 0; - virtual bool isSigned(unsigned int column) = 0; + virtual bool isNumeric(unsigned int column) = 0; - virtual bool isWritable(unsigned int column) = 0; + virtual bool isReadOnly(unsigned int column) = 0; - virtual bool isZerofill(unsigned int column) = 0; + virtual bool isSearchable(unsigned int column) = 0; + + virtual bool isSigned(unsigned int column) = 0; + + virtual bool isWritable(unsigned int column) = 0; + + virtual bool isZerofill(unsigned int column) = 0; protected: - virtual ~ResultSetMetaData() {} + virtual ~ResultSetMetaData() {} }; diff --git a/sdk/include/cppconn/sqlstring.h b/sdk/include/cppconn/sqlstring.h index 24577d3..f9ea899 100644 --- a/sdk/include/cppconn/sqlstring.h +++ b/sdk/include/cppconn/sqlstring.h @@ -1,175 +1,208 @@ /* - Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_STRING_H_ #define _SQL_STRING_H_ #include +#include #include "build_config.h" #include namespace sql { - class CPPCONN_PUBLIC_FUNC SQLString - { - std::string realStr; + class CPPCONN_PUBLIC_FUNC SQLString + { + std::string realStr; - public: + public: #ifdef _WIN32 //TODO something less dirty-hackish. static const size_t npos = static_cast(-1); #else - static const size_t npos = std::string::npos; + static const size_t npos = std::string::npos; #endif - ~SQLString() {} + ~SQLString() {} - SQLString() {} + SQLString() {} - SQLString(const SQLString & other) : realStr(other.realStr) {} + SQLString(const SQLString & other) : realStr(other.realStr) {} - SQLString(const std::string & other) : realStr(other) {} + SQLString(const std::string & other) : realStr(other) {} - SQLString(const char other[]) : realStr(other) {} + SQLString(const char other[]) : realStr(other) {} - SQLString(const char * s, size_t n) : realStr(s, n) {} + SQLString(const char * s, size_t n) : realStr(s, n) {} - // Needed for stuff like SQLString str= "char * string constant" - const SQLString & operator=(const char * s) - { - realStr = s; - return *this; - } + // Needed for stuff like SQLString str= "char * string constant" + const SQLString & operator=(const char * s) + { + realStr = s; + return *this; + } - const SQLString & operator=(const std::string & rhs) - { - realStr = rhs; - return *this; - } + const SQLString & operator=(const std::string & rhs) + { + realStr = rhs; + return *this; + } - const SQLString & operator=(const SQLString & rhs) - { - realStr = rhs.realStr; - return *this; - } + const SQLString & operator=(const SQLString & rhs) + { + realStr = rhs.realStr; + return *this; + } - // Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var; - operator const std::string &() const - { - return realStr; - } + // Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var; + operator const std::string &() const + { + return realStr; + } - /** For access std::string methods. Not sure we need it. Makes it look like some smart ptr. - possibly operator* - will look even more like smart ptr */ - std::string * operator ->() - { - return & realStr; - } + /** For access std::string methods. Not sure we need it. Makes it look like some smart ptr. + possibly operator* - will look even more like smart ptr */ + std::string * operator ->() + { + return & realStr; + } - int compare(const SQLString& str) const - { - return realStr.compare(str.realStr); - } + int compare(const SQLString& str) const + { + return realStr.compare(str.realStr); + } - int compare(const char * s) const - { - return realStr.compare(s); - } + int compare(const char * s) const + { + return realStr.compare(s); + } - int compare(size_t pos1, size_t n1, const char * s) const - { - return realStr.compare(pos1, n1, s); - } + int compare(size_t pos1, size_t n1, const char * s) const + { + return realStr.compare(pos1, n1, s); + } - const std::string & asStdString() const - { - return realStr; - } + int caseCompare(const SQLString &s) const + { + std::string tmp(realStr), str(s); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + return tmp.compare(str); + } - const char * c_str() const - { - return realStr.c_str(); - } + int caseCompare(const char * s) const + { + std::string tmp(realStr), str(s); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + return tmp.compare(str); + } - size_t length() const - { - return realStr.length(); - } + int caseCompare(size_t pos1, size_t n1, const char * s) const + { + std::string tmp(realStr.c_str() + pos1, n1), str(s); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + return tmp.compare(str); + } - SQLString & append(const std::string & str) - { - realStr.append(str); - return *this; - } + const std::string & asStdString() const + { + return realStr; + } - SQLString & append(const char * s) - { - realStr.append(s); - return *this; - } + const char * c_str() const + { + return realStr.c_str(); + } - const char& operator[](size_t pos) const - { - return realStr[pos]; - } + size_t length() const + { + return realStr.length(); + } - size_t find(char c, size_t pos = 0) const - { - return realStr.find(c, pos); - } + SQLString & append(const std::string & str) + { + realStr.append(str); + return *this; + } - size_t find(const SQLString & s, size_t pos = 0) const - { - return realStr.find(s.realStr, pos); - } + SQLString & append(const char * s) + { + realStr.append(s); + return *this; + } - SQLString substr(size_t pos = 0, size_t n = npos) const - { - return realStr.substr(pos, n); - } + const char& operator[](size_t pos) const + { + return realStr[pos]; + } - const SQLString& replace(size_t pos1, size_t n1, const SQLString & s) - { - realStr.replace(pos1, n1, s.realStr); - return *this; - } + size_t find(char c, size_t pos = 0) const + { + return realStr.find(c, pos); + } - size_t find_first_of(char c, size_t pos = 0) const - { - return realStr.find_first_of(c, pos); - } + size_t find(const SQLString & s, size_t pos = 0) const + { + return realStr.find(s.realStr, pos); + } - size_t find_last_of(char c, size_t pos = npos) const - { - return realStr.find_last_of(c, pos); - } + SQLString substr(size_t pos = 0, size_t n = npos) const + { + return realStr.substr(pos, n); + } - const SQLString & operator+=(const SQLString & op2) - { - realStr += op2.realStr; - return *this; - } + const SQLString& replace(size_t pos1, size_t n1, const SQLString & s) + { + realStr.replace(pos1, n1, s.realStr); + return *this; + } + + size_t find_first_of(char c, size_t pos = 0) const + { + return realStr.find_first_of(c, pos); + } + + size_t find_last_of(char c, size_t pos = npos) const + { + return realStr.find_last_of(c, pos); + } + + const SQLString & operator+=(const SQLString & op2) + { + realStr += op2.realStr; + return *this; + } }; @@ -178,22 +211,22 @@ namespace sql */ inline const SQLString operator+(const SQLString & op1, const SQLString & op2) { - return sql::SQLString(op1.asStdString() + op2.asStdString()); + return sql::SQLString(op1.asStdString() + op2.asStdString()); } inline bool operator ==(const SQLString & op1, const SQLString & op2) { - return (op1.asStdString() == op2.asStdString()); + return (op1.asStdString() == op2.asStdString()); } inline bool operator !=(const SQLString & op1, const SQLString & op2) { - return (op1.asStdString() != op2.asStdString()); + return (op1.asStdString() != op2.asStdString()); } inline bool operator <(const SQLString & op1, const SQLString & op2) { - return op1.asStdString() < op2.asStdString(); + return op1.asStdString() < op2.asStdString(); } @@ -202,10 +235,10 @@ inline bool operator <(const SQLString & op1, const SQLString & op2) namespace std { - // operator << for SQLString output - inline ostream & operator << (ostream & os, const sql::SQLString & str ) - { - return os << str.asStdString(); - } + // operator << for SQLString output + inline ostream & operator << (ostream & os, const sql::SQLString & str ) + { + return os << str.asStdString(); + } } #endif diff --git a/sdk/include/cppconn/statement.h b/sdk/include/cppconn/statement.h index 92406a0..112794d 100644 --- a/sdk/include/cppconn/statement.h +++ b/sdk/include/cppconn/statement.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_STATEMENT_H_ #define _SQL_STATEMENT_H_ @@ -41,53 +49,53 @@ class SQLWarning; class Statement { public: - virtual ~Statement() {}; + virtual ~Statement() {}; - virtual Connection * getConnection() = 0; + virtual Connection * getConnection() = 0; - virtual void cancel() = 0; + virtual void cancel() = 0; - virtual void clearWarnings() = 0; + virtual void clearWarnings() = 0; - virtual void close() = 0; + virtual void close() = 0; - virtual bool execute(const sql::SQLString& sql) = 0; + virtual bool execute(const sql::SQLString& sql) = 0; - virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0; + virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0; - virtual int executeUpdate(const sql::SQLString& sql) = 0; + virtual int executeUpdate(const sql::SQLString& sql) = 0; - virtual size_t getFetchSize() = 0; + virtual size_t getFetchSize() = 0; - virtual unsigned int getMaxFieldSize() = 0; + virtual unsigned int getMaxFieldSize() = 0; - virtual uint64_t getMaxRows() = 0; + virtual uint64_t getMaxRows() = 0; - virtual bool getMoreResults() = 0; + virtual bool getMoreResults() = 0; - virtual unsigned int getQueryTimeout() = 0; + virtual unsigned int getQueryTimeout() = 0; - virtual ResultSet * getResultSet() = 0; + virtual ResultSet * getResultSet() = 0; - virtual sql::ResultSet::enum_type getResultSetType() = 0; + virtual sql::ResultSet::enum_type getResultSetType() = 0; - virtual uint64_t getUpdateCount() = 0; + virtual uint64_t getUpdateCount() = 0; - virtual const SQLWarning * getWarnings() = 0; + virtual const SQLWarning * getWarnings() = 0; - virtual void setCursorName(const sql::SQLString & name) = 0; + virtual void setCursorName(const sql::SQLString & name) = 0; - virtual void setEscapeProcessing(bool enable) = 0; + virtual void setEscapeProcessing(bool enable) = 0; - virtual void setFetchSize(size_t rows) = 0; + virtual void setFetchSize(size_t rows) = 0; - virtual void setMaxFieldSize(unsigned int max) = 0; + virtual void setMaxFieldSize(unsigned int max) = 0; - virtual void setMaxRows(unsigned int max) = 0; + virtual void setMaxRows(unsigned int max) = 0; - virtual void setQueryTimeout(unsigned int seconds) = 0; + virtual void setQueryTimeout(unsigned int seconds) = 0; - virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0; + virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0; }; } /* namespace sql */ diff --git a/sdk/include/cppconn/warning.h b/sdk/include/cppconn/warning.h index 05dc471..9dbd90b 100644 --- a/sdk/include/cppconn/warning.h +++ b/sdk/include/cppconn/warning.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _SQL_WARNING_H_ #define _SQL_WARNING_H_ @@ -43,26 +51,26 @@ class SQLWarning { public: - SQLWarning(){} + SQLWarning(){} - virtual const sql::SQLString & getMessage() const = 0; + virtual const sql::SQLString & getMessage() const = 0; - virtual const sql::SQLString & getSQLState() const = 0; + virtual const sql::SQLString & getSQLState() const = 0; - virtual int getErrorCode() const = 0; + virtual int getErrorCode() const = 0; - virtual const SQLWarning * getNextWarning() const = 0; + virtual const SQLWarning * getNextWarning() const = 0; - virtual void setNextWarning(const SQLWarning * _next) = 0; + virtual void setNextWarning(const SQLWarning * _next) = 0; protected: - virtual ~SQLWarning(){}; + virtual ~SQLWarning(){}; - SQLWarning(const SQLWarning& e){}; + SQLWarning(const SQLWarning&){}; private: - const SQLWarning & operator = (const SQLWarning & rhs); + const SQLWarning & operator = (const SQLWarning & rhs); }; diff --git a/sdk/include/hv/AsyncHttpClient.h b/sdk/include/hv/AsyncHttpClient.h new file mode 100644 index 0000000..38ff4fe --- /dev/null +++ b/sdk/include/hv/AsyncHttpClient.h @@ -0,0 +1,164 @@ +#ifndef HV_ASYNC_HTTP_CLIENT_H_ +#define HV_ASYNC_HTTP_CLIENT_H_ + +#include +#include + +#include "EventLoopThread.h" +#include "Channel.h" + +#include "HttpMessage.h" +#include "HttpParser.h" + +namespace hv { + +template +class ConnPool { +public: + int size() { + return conns_.size(); + } + + bool get(Conn& conn) { + if (conns_.empty()) return false; + conn = conns_.front(); + conns_.pop_front(); + return true; + } + + bool add(const Conn& conn) { + conns_.push_back(conn); + return true; + } + + bool remove(const Conn& conn) { + auto iter = conns_.begin(); + while (iter != conns_.end()) { + if (*iter == conn) { + iter = conns_.erase(iter); + return true; + } else { + ++iter; + } + } + return false; + } + +private: + std::list conns_; +}; + +struct HttpClientTask { + HttpRequestPtr req; + HttpResponseCallback cb; + uint64_t start_time; +}; +typedef std::shared_ptr HttpClientTaskPtr; + +struct HttpClientContext { + HttpClientTaskPtr task; + + HttpResponsePtr resp; + HttpParserPtr parser; + TimerID timerID; + + HttpClientContext() { + timerID = INVALID_TIMER_ID; + } + + ~HttpClientContext() { + cancelTimer(); + } + + void cancelTimer() { + if (timerID != INVALID_TIMER_ID) { + killTimer(timerID); + timerID = INVALID_TIMER_ID; + } + } + + void cancelTask() { + cancelTimer(); + task = NULL; + } + + void callback() { + cancelTimer(); + if (task && task->cb) { + task->cb(resp); + } + // NOTE: task done + task = NULL; + } + + void successCallback() { + callback(); + resp = NULL; + } + + void errorCallback() { + resp = NULL; + callback(); + } +}; + +class HV_EXPORT AsyncHttpClient : private EventLoopThread { +public: + AsyncHttpClient(EventLoopPtr loop = NULL) : EventLoopThread(loop) { + if (loop == NULL) { + EventLoopThread::start(true); + } + } + ~AsyncHttpClient() { + EventLoopThread::stop(true); + } + + // thread-safe + int send(const HttpRequestPtr& req, HttpResponseCallback resp_cb); + int send(const HttpClientTaskPtr& task) { + EventLoopThread::loop()->queueInLoop(std::bind(&AsyncHttpClient::sendInLoop, this, task)); + return 0; + } + +protected: + void sendInLoop(HttpClientTaskPtr task) { + int err = doTask(task); + if (err != 0 && task->cb) { + task->cb(NULL); + } + } + int doTask(const HttpClientTaskPtr& task); + + static int sendRequest(const SocketChannelPtr& channel); + + // channel + const SocketChannelPtr& getChannel(int fd) { + return channels[fd]; + // return fd < channels.capacity() ? channels[fd] : NULL; + } + + const SocketChannelPtr& addChannel(hio_t* io) { + auto channel = std::make_shared(io); + channel->newContext(); + int fd = channel->fd(); + channels[fd] = channel; + return channels[fd]; + } + + void removeChannel(const SocketChannelPtr& channel) { + channel->deleteContext(); + int fd = channel->fd(); + channels.erase(fd); + } + +private: + // NOTE: just one loop thread, no need mutex. + // fd => SocketChannelPtr + std::map channels; + // peeraddr => ConnPool + std::map> conn_pools; +}; + +} + +#endif // HV_ASYNC_HTTP_CLIENT_H_ diff --git a/sdk/include/hv/EventLoop.h b/sdk/include/hv/EventLoop.h index d8e7f64..40d24c2 100644 --- a/sdk/include/hv/EventLoop.h +++ b/sdk/include/hv/EventLoop.h @@ -241,7 +241,7 @@ typedef std::shared_ptr EventLoopPtr; static inline EventLoop* tlsEventLoop() { return (EventLoop*)ThreadLocalStorage::get(ThreadLocalStorage::EVENT_LOOP); } -#define currentThreadEventLoop tlsEventLoop() +#define currentThreadEventLoop ::hv::tlsEventLoop() static inline TimerID setTimer(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE) { EventLoop* loop = tlsEventLoop(); diff --git a/sdk/include/hv/EventLoopThread.h b/sdk/include/hv/EventLoopThread.h index 47f20db..51b87b9 100644 --- a/sdk/include/hv/EventLoopThread.h +++ b/sdk/include/hv/EventLoopThread.h @@ -44,6 +44,7 @@ public: Functor pre = Functor(), Functor post = Functor()) { if (status() >= kStarting && status() < kStopped) return; + if (isRunning()) return; setStatus(kStarting); thread_ = std::make_shared(&EventLoopThread::loop_thread, this, pre, post); diff --git a/sdk/include/hv/http_client.h b/sdk/include/hv/HttpClient.h similarity index 79% rename from sdk/include/hv/http_client.h rename to sdk/include/hv/HttpClient.h index d140e0e..4891bb6 100644 --- a/sdk/include/hv/http_client.h +++ b/sdk/include/hv/HttpClient.h @@ -8,7 +8,7 @@ /* #include -#include "http_client.h" +#include "HttpClient.h" int main(int argc, char* argv[]) { HttpRequest req; @@ -30,7 +30,6 @@ int main(int argc, char* argv[]) { typedef struct http_client_s http_client_t; HV_EXPORT http_client_t* http_client_new(const char* host = NULL, int port = DEFAULT_HTTP_PORT, int https = 0); -HV_EXPORT int http_client_close(http_client_t* cli); HV_EXPORT int http_client_del(http_client_t* cli); HV_EXPORT const char* http_client_strerror(int errcode); @@ -69,6 +68,15 @@ HV_EXPORT int http_client_send(HttpRequest* req, HttpResponse* resp); // http_client_send_async(&default_async_client, ...) HV_EXPORT int http_client_send_async(HttpRequestPtr req, HttpResponseCallback resp_cb = NULL); +// low-level api +// @retval >=0 connfd, <0 error +HV_EXPORT int http_client_connect(http_client_t* cli, const char* host, int port, int https, int timeout); +HV_EXPORT int http_client_send_header(http_client_t* cli, HttpRequest* req); +HV_EXPORT int http_client_send_data(http_client_t* cli, const char* data, int size); +HV_EXPORT int http_client_recv_data(http_client_t* cli, char* data, int size); +HV_EXPORT int http_client_recv_response(http_client_t* cli, HttpResponse* resp); +HV_EXPORT int http_client_close(http_client_t* cli); + namespace hv { class HttpClient { @@ -134,7 +142,22 @@ public: return http_client_send_async(_client, req, std::move(resp_cb)); } - // close + // low-level api + int connect(const char* host, int port = DEFAULT_HTTP_PORT, int https = 0, int timeout = DEFAULT_HTTP_CONNECT_TIMEOUT) { + return http_client_connect(_client, host, port, https, timeout); + } + int sendHeader(HttpRequest* req) { + return http_client_send_header(_client, req); + } + int sendData(const char* data, int size) { + return http_client_send_data(_client, data, size); + } + int recvData(char* data, int size) { + return http_client_recv_data(_client, data, size); + } + int recvResponse(HttpResponse* resp) { + return http_client_recv_response(_client, resp); + } int close() { return http_client_close(_client); } diff --git a/sdk/include/hv/HttpMessage.h b/sdk/include/hv/HttpMessage.h index cc779c3..4b8a9ef 100644 --- a/sdk/include/hv/HttpMessage.h +++ b/sdk/include/hv/HttpMessage.h @@ -46,19 +46,6 @@ #include "httpdef.h" #include "http_content.h" -namespace hv { - -struct NetAddr { - std::string ip; - int port; - - std::string ipport() { - return hv::asprintf("%s:%d", ip.c_str(), port); - } -}; - -} - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie // Cookie: sessionid=1; domain=.example.com; path=/; max-age=86400; secure; httponly struct HV_EXPORT HttpCookie { @@ -297,6 +284,7 @@ public: void* Content() { if (content == NULL && body.size() != 0) { content = (void*)body.data(); + content_length = body.size(); } return content; } diff --git a/sdk/include/hv/HttpServer.h b/sdk/include/hv/HttpServer.h index 115a5b6..79b3772 100644 --- a/sdk/include/hv/HttpServer.h +++ b/sdk/include/hv/HttpServer.h @@ -3,9 +3,11 @@ #include "hexport.h" #include "hssl.h" +// #include "EventLoop.h" #include "HttpService.h" // #include "WebSocketServer.h" namespace hv { +class EventLoop; struct WebSocketService; } using hv::HttpService; @@ -72,18 +74,16 @@ int main() { return 200; }); - HttpServer server; - server.registerHttpService(&service); - server.setPort(8080); + HttpServer server(&service); server.setThreadNum(4); - server.run(); + server.run(":8080"); return 0; } */ namespace hv { -class HttpServer : public http_server_t { +class HV_EXPORT HttpServer : public http_server_t { public: HttpServer(HttpService* service = NULL) : http_server_t() @@ -96,6 +96,8 @@ public: this->service = service; } + std::shared_ptr loop(int idx = -1); + void setHost(const char* host = "0.0.0.0") { if (host) strcpy(this->host, host); } @@ -117,6 +119,11 @@ public: this->worker_threads = num; } + void setMaxWorkerConnectionNum(uint32_t num) { + this->worker_connections = num; + } + size_t connectionNum(); + // SSL/TLS int setSslCtx(hssl_ctx_t ssl_ctx) { this->ssl_ctx = ssl_ctx; @@ -130,12 +137,20 @@ public: return setSslCtx(ssl_ctx); } - int run(bool wait = true) { + // run(":8080") + // run("0.0.0.0:8080") + // run("[::]:8080") + int run(const char* ip_port = NULL, bool wait = true) { + if (ip_port) { + hv::NetAddr listen_addr(ip_port); + if (listen_addr.ip.size() != 0) setHost(listen_addr.ip.c_str()); + if (listen_addr.port != 0) setPort(listen_addr.port); + } return http_server_run(this, wait); } - int start() { - return run(false); + int start(const char* ip_port = NULL) { + return run(ip_port, false); } int stop() { diff --git a/sdk/include/hv/TcpServer.h b/sdk/include/hv/TcpServer.h index 4c7c20f..df6a932 100644 --- a/sdk/include/hv/TcpServer.h +++ b/sdk/include/hv/TcpServer.h @@ -32,7 +32,11 @@ public: } EventLoopPtr loop(int idx = -1) { - return worker_threads.loop(idx); + EventLoopPtr worker_loop = worker_threads.loop(idx); + if (worker_loop == NULL) { + worker_loop = acceptor_loop; + } + return worker_loop; } //@retval >=0 listenfd, <0 error @@ -294,7 +298,9 @@ public: // start thread-safe void start(bool wait_threads_started = true) { TcpServerEventLoopTmpl::start(wait_threads_started); - EventLoopThread::start(wait_threads_started); + if (!isRunning()) { + EventLoopThread::start(wait_threads_started); + } } // stop thread-safe diff --git a/sdk/include/hv/UdpClient.h b/sdk/include/hv/UdpClient.h index 2aba963..1b055a9 100644 --- a/sdk/include/hv/UdpClient.h +++ b/sdk/include/hv/UdpClient.h @@ -60,6 +60,7 @@ public: if (ret != 0) { perror("bind"); } + hio_set_localaddr(channel->io(), &local_addr.sa, SOCKADDR_LEN(&local_addr)); return ret; } diff --git a/sdk/include/hv/base64.h b/sdk/include/hv/base64.h index ed24c0a..84b8a53 100644 --- a/sdk/include/hv/base64.h +++ b/sdk/include/hv/base64.h @@ -36,7 +36,11 @@ HV_INLINE std::string Base64Decode(const char* str, unsigned int len = 0) { int decoded_size = BASE64_DECODE_OUT_SIZE(len); std::string decoded_buf(decoded_size + 1, 0); decoded_size = hv_base64_decode(str, len, (unsigned char*)decoded_buf.data()); - decoded_buf.resize(decoded_size); + if (decoded_size > 0) { + decoded_buf.resize(decoded_size); + } else { + decoded_buf.clear(); + } return decoded_buf; } diff --git a/sdk/include/hv/dns.h b/sdk/include/hv/dns.h deleted file mode 100644 index 2bb9d43..0000000 --- a/sdk/include/hv/dns.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef HV_DNS_H_ -#define HV_DNS_H_ - -#include "hexport.h" -#include "hplatform.h" - -#define DNS_PORT 53 - -#define DNS_QUERY 0 -#define DNS_RESPONSE 1 - -#define DNS_TYPE_A 1 // ipv4 -#define DNS_TYPE_NS 2 -#define DNS_TYPE_CNAME 5 -#define DNS_TYPE_SOA 6 -#define DNS_TYPE_WKS 11 -#define DNS_TYPE_PTR 12 -#define DNS_TYPE_HINFO 13 -#define DNS_TYPE_MX 15 -#define DNS_TYPE_AAAA 28 // ipv6 -#define DNS_TYPE_AXFR 252 -#define DNS_TYPE_ANY 255 - -#define DNS_CLASS_IN 1 - -#define DNS_NAME_MAXLEN 256 - -// sizeof(dnshdr_t) = 12 -typedef struct dnshdr_s { - uint16_t transaction_id; - // flags -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t rd:1; - uint8_t tc:1; - uint8_t aa:1; - uint8_t opcode:4; - uint8_t qr:1; - - uint8_t rcode:4; - uint8_t cd:1; - uint8_t ad:1; - uint8_t res:1; - uint8_t ra:1; -#elif BYTE_ORDER == BIG_ENDIAN - uint8_t qr:1; // DNS_QUERY or DNS_RESPONSE - uint8_t opcode:4; - uint8_t aa:1; // authoritative - uint8_t tc:1; // truncated - uint8_t rd:1; // recursion desired - - uint8_t ra:1; // recursion available - uint8_t res:1; // reserved - uint8_t ad:1; // authenticated data - uint8_t cd:1; // checking disable - uint8_t rcode:4; -#else -#error "BYTE_ORDER undefined!" -#endif - uint16_t nquestion; - uint16_t nanswer; - uint16_t nauthority; - uint16_t naddtional; -} dnshdr_t; - -typedef struct dns_rr_s { - char name[DNS_NAME_MAXLEN]; // original domain, such as www.example.com - uint16_t rtype; - uint16_t rclass; - uint32_t ttl; - uint16_t datalen; - char* data; -} dns_rr_t; - -typedef struct dns_s { - dnshdr_t hdr; - dns_rr_t* questions; - dns_rr_t* answers; - dns_rr_t* authorities; - dns_rr_t* addtionals; -} dns_t; - -BEGIN_EXTERN_C - -// www.example.com => 3www7example3com -HV_EXPORT int dns_name_encode(const char* domain, char* buf); -// 3www7example3com => www.example.com -HV_EXPORT int dns_name_decode(const char* buf, char* domain); - -HV_EXPORT int dns_rr_pack(dns_rr_t* rr, char* buf, int len); -HV_EXPORT int dns_rr_unpack(char* buf, int len, dns_rr_t* rr, int is_question); - -HV_EXPORT int dns_pack(dns_t* dns, char* buf, int len); -HV_EXPORT int dns_unpack(char* buf, int len, dns_t* dns); -// NOTE: free dns->rrs -HV_EXPORT void dns_free(dns_t* dns); - -// dns_pack -> sendto -> recvfrom -> dns_unpack -HV_EXPORT int dns_query(dns_t* query, dns_t* response, const char* nameserver DEFAULT("127.0.1.1")); - -// domain -> dns_t query; -> dns_query -> dns_t response; -> addrs -HV_EXPORT int nslookup(const char* domain, uint32_t* addrs, int naddr, const char* nameserver DEFAULT("127.0.1.1")); - -END_EXTERN_C - -#endif // HV_DNS_H_ diff --git a/sdk/include/hv/ftp.h b/sdk/include/hv/ftp.h deleted file mode 100644 index d1b60ca..0000000 --- a/sdk/include/hv/ftp.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef HV_FTP_H_ -#define HV_FTP_H_ - -#include "hexport.h" - -#define FTP_COMMAND_PORT 21 -#define FTP_DATA_PORT 20 - -// ftp_command -// X(name) -#define FTP_COMMAND_MAP(X) \ - X(HELP) \ - X(USER) \ - X(PASS) \ - X(PWD) \ - X(CWD) \ - X(CDUP) \ - X(MKD) \ - X(RMD) \ - X(STAT) \ - X(SIZE) \ - X(DELE) \ - X(RNFR) \ - X(RNTO) \ - X(PORT) \ - X(PASV) \ - X(LIST) \ - X(NLST) \ - X(APPE) \ - X(RETR) \ - X(STOR) \ - X(QUIT) \ - -enum ftp_command { -#define X(name) FTP_##name, - FTP_COMMAND_MAP(X) -#undef X -}; - -// ftp_status -// XXX(code, name, string) -#define FTP_STATUS_MAP(XXX) \ - XXX(220, READY, Ready) \ - XXX(221, BYE, Bye) \ - XXX(226, TRANSFER_COMPLETE, Transfer complete) \ - XXX(227, PASV, Entering Passive Mode) \ - XXX(331, PASS, Password required) \ - XXX(230, LOGIN_OK, Login OK) \ - XXX(250, OK, OK) \ - XXX(500, BAD_SYNTAX, Bad syntax) \ - XXX(530, NOT_LOGIN, Not login) \ - -enum ftp_status { -#define XXX(code, name, string) FTP_STATUS_##name = code, - FTP_STATUS_MAP(XXX) -#undef XXX -}; - -// more friendly macros -#define FTP_MKDIR FTP_MKD -#define FTP_RMDIR FTP_RMD -#define FTP_APPEND FTP_APPE -#define FTP_REMOVE FTP_DELE -#define FTP_DOWNLOAD FTP_RETR -#define FTP_UPLOAD FTP_STOR - -#define FTP_RECV_BUFSIZE 8192 - -typedef struct ftp_handle_s { - int sockfd; - char recvbuf[FTP_RECV_BUFSIZE]; - void* userdata; -} ftp_handle_t; - -BEGIN_EXTERN_C - -HV_EXPORT const char* ftp_command_str(enum ftp_command cmd); -HV_EXPORT const char* ftp_status_str(enum ftp_status status); - -HV_EXPORT int ftp_connect(ftp_handle_t* hftp, const char* host, int port); -HV_EXPORT int ftp_login(ftp_handle_t* hftp, const char* username, const char* password); -HV_EXPORT int ftp_quit(ftp_handle_t* hftp); - -HV_EXPORT int ftp_exec(ftp_handle_t* hftp, const char* cmd, const char* param); - -// local => remote -HV_EXPORT int ftp_upload(ftp_handle_t* hftp, const char* local_filepath, const char* remote_filepath); -// remote => local -HV_EXPORT int ftp_download(ftp_handle_t* hftp, const char* remote_filepath, const char* local_filepath); - -typedef int (*ftp_download_cb)(ftp_handle_t* hftp, char* buf, int len); -HV_EXPORT int ftp_download_with_cb(ftp_handle_t* hftp, const char* filepath, ftp_download_cb cb); - -END_EXTERN_C - -#endif // HV_FTP_H_ diff --git a/sdk/include/hv/hbase.h b/sdk/include/hv/hbase.h index 1a9041a..c1ff0f4 100644 --- a/sdk/include/hv/hbase.h +++ b/sdk/include/hv/hbase.h @@ -82,6 +82,7 @@ HV_EXPORT char* hv_strncat(char* dest, const char* src, size_t n); #endif HV_EXPORT char* hv_strnchr(const char* s, char c, size_t n); +HV_EXPORT char* hv_strnrchr(const char* s, char c, size_t n); #define hv_strrchr_dot(str) strrchr(str, '.') HV_EXPORT char* hv_strrchr_dir(const char* filepath); diff --git a/sdk/include/hv/hconfig.h b/sdk/include/hv/hconfig.h index ecb15ab..a63861f 100644 --- a/sdk/include/hv/hconfig.h +++ b/sdk/include/hv/hconfig.h @@ -10,7 +10,7 @@ #endif #ifndef HAVE_STDATOMIC_H -#define HAVE_STDATOMIC_H 1 +#define HAVE_STDATOMIC_H 0 #endif #ifndef HAVE_SYS_TYPES_H @@ -22,7 +22,7 @@ #endif #ifndef HAVE_SYS_TIME_H -#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TIME_H 0 #endif #ifndef HAVE_FCNTL_H @@ -30,11 +30,11 @@ #endif #ifndef HAVE_PTHREAD_H -#define HAVE_PTHREAD_H 1 +#define HAVE_PTHREAD_H 0 #endif #ifndef HAVE_ENDIAN_H -#define HAVE_ENDIAN_H 1 +#define HAVE_ENDIAN_H 0 #endif #ifndef HAVE_SYS_ENDIAN_H @@ -54,46 +54,49 @@ #endif #ifndef HAVE_CLOCK_GETTIME -#define HAVE_CLOCK_GETTIME 1 +#define HAVE_CLOCK_GETTIME 0 #endif #ifndef HAVE_GETTIMEOFDAY -#define HAVE_GETTIMEOFDAY 1 +#define HAVE_GETTIMEOFDAY 0 #endif #ifndef HAVE_PTHREAD_SPIN_LOCK -#define HAVE_PTHREAD_SPIN_LOCK 1 +#define HAVE_PTHREAD_SPIN_LOCK 0 #endif #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK -#define HAVE_PTHREAD_MUTEX_TIMEDLOCK 1 +#define HAVE_PTHREAD_MUTEX_TIMEDLOCK 0 #endif #ifndef HAVE_SEM_TIMEDWAIT -#define HAVE_SEM_TIMEDWAIT 1 +#define HAVE_SEM_TIMEDWAIT 0 #endif #ifndef HAVE_PIPE -#define HAVE_PIPE 1 +#define HAVE_PIPE 0 #endif #ifndef HAVE_SOCKETPAIR -#define HAVE_SOCKETPAIR 1 +#define HAVE_SOCKETPAIR 0 #endif #ifndef HAVE_EVENTFD -#define HAVE_EVENTFD 1 +#define HAVE_EVENTFD 0 #endif #ifndef HAVE_SETPROCTITLE #define HAVE_SETPROCTITLE 0 #endif -/* #undef WITH_OPENSSL */ +#define WITH_OPENSSL 1 /* #undef WITH_GNUTLS */ /* #undef WITH_MBEDTLS */ + /* #undef ENABLE_UDS */ /* #undef USE_MULTIMAP */ + +#define WITH_WEPOLL 1 /* #undef WITH_KCP */ #endif // HV_CONFIG_H_ diff --git a/sdk/include/hv/hexport.h b/sdk/include/hv/hexport.h index 7d37016..429088f 100644 --- a/sdk/include/hv/hexport.h +++ b/sdk/include/hv/hexport.h @@ -37,32 +37,6 @@ #define HV_UNUSED #endif -// @param[IN | OUT | INOUT] -#ifndef IN -#define IN -#endif - -#ifndef OUT -#define OUT -#endif - -#ifndef INOUT -#define INOUT -#endif - -// @field[OPTIONAL | REQUIRED | REPEATED] -#ifndef OPTIONAL -#define OPTIONAL -#endif - -#ifndef REQUIRED -#define REQUIRED -#endif - -#ifndef REPEATED -#define REPEATED -#endif - #ifdef __cplusplus #ifndef EXTERN_C diff --git a/sdk/include/hv/hloop.h b/sdk/include/hv/hloop.h index be70cfd..df5e696 100644 --- a/sdk/include/hv/hloop.h +++ b/sdk/include/hv/hloop.h @@ -11,16 +11,18 @@ typedef struct hevent_s hevent_t; // NOTE: The following structures are subclasses of hevent_t, // inheriting hevent_t data members and function members. +typedef struct hio_s hio_t; typedef struct hidle_s hidle_t; typedef struct htimer_s htimer_t; typedef struct htimeout_s htimeout_t; typedef struct hperiod_s hperiod_t; -typedef struct hio_s hio_t; +typedef struct hevent_s hsignal_t; typedef void (*hevent_cb) (hevent_t* ev); +typedef void (*hio_cb) (hio_t* io); typedef void (*hidle_cb) (hidle_t* idle); typedef void (*htimer_cb) (htimer_t* timer); -typedef void (*hio_cb) (hio_t* io); +typedef void (*hsignal_cb) (hsignal_t* sig); typedef void (*haccept_cb) (hio_t* io); typedef void (*hconnect_cb) (hio_t* io); @@ -31,7 +33,8 @@ typedef void (*hclose_cb) (hio_t* io); typedef enum { HLOOP_STATUS_STOP, HLOOP_STATUS_RUNNING, - HLOOP_STATUS_PAUSE + HLOOP_STATUS_PAUSE, + HLOOP_STATUS_DESTROY } hloop_status_e; typedef enum { @@ -41,6 +44,7 @@ typedef enum { HEVENT_TYPE_PERIOD = 0x00000020, HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD, HEVENT_TYPE_IDLE = 0x00000100, + HEVENT_TYPE_SIGNAL = 0x00000200, HEVENT_TYPE_CUSTOM = 0x00000400, // 1024 } hevent_type_e; @@ -93,6 +97,7 @@ typedef enum { HIO_TYPE_STDIO = 0x0000000F, HIO_TYPE_FILE = 0x00000010, + HIO_TYPE_PIPE = 0x00000020, HIO_TYPE_IP = 0x00000100, HIO_TYPE_SOCK_RAW = 0x00000F00, @@ -182,6 +187,10 @@ HV_EXPORT void* hloop_userdata(hloop_t* loop); // NOTE: hloop_post_event is thread-safe, used to post event from other thread to loop thread. HV_EXPORT void hloop_post_event(hloop_t* loop, hevent_t* ev); +// signal +HV_EXPORT hsignal_t* hsignal_add(hloop_t* loop, hsignal_cb cb, int signo); +HV_EXPORT void hsignal_del(hsignal_t* sig); + // idle HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE)); HV_EXPORT void hidle_del(hidle_t* idle); @@ -435,6 +444,10 @@ HV_EXPORT hio_t* hloop_create_udp_server (hloop_t* loop, const char* host, int p // @see examples/nc.c HV_EXPORT hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int port); +//-----------------pipe--------------------------------------------- +// @see examples/pipe_test.c +HV_EXPORT int hio_create_pipe(hloop_t* loop, hio_t* pipeio[2]); + //-----------------upstream--------------------------------------------- // hio_read(io) // hio_read(io->upstream_io) diff --git a/sdk/include/hv/hmain.h b/sdk/include/hv/hmain.h index 3fe6598..5c7ac79 100644 --- a/sdk/include/hv/hmain.h +++ b/sdk/include/hv/hmain.h @@ -65,6 +65,7 @@ typedef struct option_s { char short_opt; const char* long_opt; int arg_type; + const char* description; } option_t; HV_EXPORT int main_ctx_init(int argc, char** argv); @@ -76,7 +77,8 @@ HV_EXPORT void main_ctx_free(void); // watch -n10 ls HV_EXPORT int parse_opt(int argc, char** argv, const char* opt); // gcc -g -Wall -O3 -std=cpp main.c -HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int size); +HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int opt_size); +HV_EXPORT int dump_opt_long(const option_t* long_options, int opt_size, char* out_str, int out_size); HV_EXPORT const char* get_arg(const char* key); HV_EXPORT const char* get_env(const char* key); diff --git a/sdk/include/hv/hplatform.h b/sdk/include/hv/hplatform.h index 5e0a290..442ba7b 100644 --- a/sdk/include/hv/hplatform.h +++ b/sdk/include/hv/hplatform.h @@ -41,6 +41,7 @@ #undef OS_UNIX #define OS_WIN #else + #undef OS_WIN #define OS_UNIX #endif @@ -142,6 +143,12 @@ // headers #ifdef OS_WIN + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 + #elif _WIN32_WINNT < 0x0600 + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 + #endif #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif diff --git a/sdk/include/hv/hsocket.h b/sdk/include/hv/hsocket.h index 8459a7b..d7ec5bf 100644 --- a/sdk/include/hv/hsocket.h +++ b/sdk/include/hv/hsocket.h @@ -82,9 +82,11 @@ HV_INLINE int nonblocking(int s) { return fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); } +#ifndef closesocket HV_INLINE int closesocket(int sockfd) { return close(sockfd); } +#endif #endif diff --git a/sdk/include/hv/hstring.h b/sdk/include/hv/hstring.h index 76cf433..8c675a1 100644 --- a/sdk/include/hv/hstring.h +++ b/sdk/include/hv/hstring.h @@ -75,6 +75,18 @@ HV_EXPORT std::string trim_pairs(const std::string& str, const char* pairs = PAI HV_EXPORT std::string replace(const std::string& str, const std::string& find, const std::string& rep); HV_EXPORT std::string replaceAll(const std::string& str, const std::string& find, const std::string& rep); +struct HV_EXPORT NetAddr { + std::string ip; + int port; + + NetAddr() : port(0) {} + NetAddr(const std::string& _ip, int _port) : ip(_ip), port(_port) {} + NetAddr(const std::string& ipport) { from_string(ipport); } + + void from_string(const std::string& ipport); + std::string to_string(); +}; + } // end namespace hv #endif // HV_STRING_H_ diff --git a/sdk/include/hv/hversion.h b/sdk/include/hv/hversion.h index d88dd42..0713065 100644 --- a/sdk/include/hv/hversion.h +++ b/sdk/include/hv/hversion.h @@ -8,7 +8,7 @@ BEGIN_EXTERN_C #define HV_VERSION_MAJOR 1 #define HV_VERSION_MINOR 3 -#define HV_VERSION_PATCH 2 +#define HV_VERSION_PATCH 3 #define HV_VERSION_STRING STRINGIFY(HV_VERSION_MAJOR) "." \ STRINGIFY(HV_VERSION_MINOR) "." \ diff --git a/sdk/include/hv/icmp.h b/sdk/include/hv/icmp.h deleted file mode 100644 index afd8349..0000000 --- a/sdk/include/hv/icmp.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef HV_ICMP_H_ -#define HV_ICMP_H_ - -#include "hexport.h" - -BEGIN_EXTERN_C - -// @param cnt: ping count -// @return: ok count -// @note: printd $CC -DPRINT_DEBUG -HV_EXPORT int ping(const char* host, int cnt DEFAULT(4)); - -END_EXTERN_C - -#endif // HV_ICMP_H_ diff --git a/sdk/include/hv/mqtt_client.h b/sdk/include/hv/mqtt_client.h index 62d5a2a..83de052 100644 --- a/sdk/include/hv/mqtt_client.h +++ b/sdk/include/hv/mqtt_client.h @@ -29,6 +29,7 @@ struct mqtt_client_s { unsigned char alloced_ssl_ctx: 1; // intern unsigned char connected : 1; unsigned short keepalive; + int ping_cnt; char client_id[64]; // will mqtt_message_t* will; @@ -47,7 +48,7 @@ struct mqtt_client_s { // privdata hloop_t* loop; hio_t* io; - htimer_t* reconn_timer; + htimer_t* timer; // SSL/TLS hssl_ctx_t ssl_ctx; // thread-safe @@ -101,6 +102,7 @@ HV_EXPORT int mqtt_client_reconnect(mqtt_client_t* cli); // on_connect -> mqtt_client_login -> // on_connack HV_EXPORT void mqtt_client_set_connect_timeout(mqtt_client_t* cli, int ms); +HV_EXPORT void mqtt_client_set_host(mqtt_client_t* cli, const char* host, int port, int ssl); HV_EXPORT int mqtt_client_connect(mqtt_client_t* cli, const char* host, int port DEFAULT(DEFAULT_MQTT_PORT), @@ -125,4 +127,214 @@ HV_EXPORT int mqtt_client_unsubscribe(mqtt_client_t* cli, END_EXTERN_C +#ifdef __cplusplus + +#include +#include +#include +#include + +namespace hv { + +// @usage examples/mqtt/mqtt_client_test.cpp +class MqttClient { +public: + mqtt_client_t* client; + // callbacks + typedef std::function MqttCallback; + typedef std::function MqttMessageCallback; + MqttCallback onConnect; + MqttCallback onClose; + MqttMessageCallback onMessage; + + MqttClient(hloop_t* loop = NULL) { + client = mqtt_client_new(loop); + } + + ~MqttClient() { + if (client) { + mqtt_client_free(client); + client = NULL; + } + } + + void run() { + mqtt_client_set_callback(client, on_mqtt); + mqtt_client_set_userdata(client, this); + mqtt_client_run(client); + } + + void stop() { + mqtt_client_stop(client); + } + + void setID(const char* id) { + mqtt_client_set_id(client, id); + } + + void setWill(mqtt_message_t* will) { + mqtt_client_set_will(client, will); + } + + void setAuth(const char* username, const char* password) { + mqtt_client_set_auth(client, username, password); + } + + void setPingInterval(int sec) { + client->keepalive = sec; + } + + int lastError() { + return mqtt_client_get_last_error(client); + } + + // SSL/TLS + int setSslCtx(hssl_ctx_t ssl_ctx) { + return mqtt_client_set_ssl_ctx(client, ssl_ctx); + } + int newSslCtx(hssl_ctx_opt_t* opt) { + return mqtt_client_new_ssl_ctx(client, opt); + } + + void setReconnect(reconn_setting_t* reconn) { + mqtt_client_set_reconnect(client, reconn); + } + + void setConnectTimeout(int ms) { + mqtt_client_set_connect_timeout(client, ms); + } + + void setHost(const char* host, int port = DEFAULT_MQTT_PORT, int ssl = 0) { + mqtt_client_set_host(client, host, port, ssl); + } + + int connect(const char* host, int port = DEFAULT_MQTT_PORT, int ssl = 0) { + return mqtt_client_connect(client, host, port, ssl); + } + + int reconnect() { + return mqtt_client_reconnect(client); + } + + int disconnect() { + return mqtt_client_disconnect(client); + } + + bool isConnected() { + return mqtt_client_is_connected(client); + } + + int publish(mqtt_message_t* msg, MqttCallback ack_cb = NULL) { + int mid = mqtt_client_publish(client, msg); + if (msg->qos > 0 && mid >= 0 && ack_cb) { + setAckCallback(mid, ack_cb); + } + return mid; + } + + int publish(const std::string& topic, const std::string& payload, int qos = 0, int retain = 0, MqttCallback ack_cb = NULL) { + mqtt_message_t msg; + memset(&msg, 0, sizeof(msg)); + msg.topic_len = topic.size(); + msg.topic = topic.c_str(); + msg.payload_len = payload.size(); + msg.payload = payload.c_str(); + msg.qos = qos; + msg.retain = retain; + return publish(&msg, ack_cb); + } + + int subscribe(const char* topic, int qos = 0, MqttCallback ack_cb = NULL) { + int mid = mqtt_client_subscribe(client, topic, qos); + if (qos > 0 && mid >= 0 && ack_cb) { + setAckCallback(mid, ack_cb); + } + return mid; + } + + int unsubscribe(const char* topic, MqttCallback ack_cb = NULL) { + int mid = mqtt_client_unsubscribe(client, topic); + if (mid >= 0 && ack_cb) { + setAckCallback(mid, ack_cb); + } + return mid; + } + +protected: + void setAckCallback(int mid, MqttCallback cb) { + ack_cbs_mutex.lock(); + ack_cbs[mid] = std::move(cb); + ack_cbs_mutex.unlock(); + } + + void invokeAckCallback(int mid) { + MqttCallback ack_cb = NULL; + ack_cbs_mutex.lock(); + auto iter = ack_cbs.find(mid); + if (iter != ack_cbs.end()) { + ack_cb = std::move(iter->second); + ack_cbs.erase(iter); + } + ack_cbs_mutex.unlock(); + if (ack_cb) ack_cb(this); + } + + static void on_mqtt(mqtt_client_t* cli, int type) { + MqttClient* client = (MqttClient*)mqtt_client_get_userdata(cli); + // printf("on_mqtt type=%d\n", type); + switch(type) { + case MQTT_TYPE_CONNECT: + // printf("mqtt connected!\n"); + break; + case MQTT_TYPE_DISCONNECT: + // printf("mqtt disconnected!\n"); + if (client->onClose) { + client->onClose(client); + } + break; + case MQTT_TYPE_CONNACK: + // printf("mqtt connack!\n"); + if (client->onConnect) { + client->onConnect(client); + } + break; + case MQTT_TYPE_PUBLISH: + if (client->onMessage) { + client->onMessage(client, &cli->message); + } + break; + case MQTT_TYPE_PUBACK: /* qos = 1 */ + // printf("mqtt puback mid=%d\n", cli->mid); + client->invokeAckCallback(cli->mid); + break; + case MQTT_TYPE_PUBREC: /* qos = 2 */ + // printf("mqtt pubrec mid=%d\n", cli->mid); + // wait MQTT_TYPE_PUBCOMP + break; + case MQTT_TYPE_PUBCOMP: /* qos = 2 */ + // printf("mqtt pubcomp mid=%d\n", cli->mid); + client->invokeAckCallback(cli->mid); + break; + case MQTT_TYPE_SUBACK: + // printf("mqtt suback mid=%d\n", cli->mid); + client->invokeAckCallback(cli->mid); + break; + case MQTT_TYPE_UNSUBACK: + // printf("mqtt unsuback mid=%d\n", cli->mid); + client->invokeAckCallback(cli->mid); + break; + default: + break; + } + } + +private: + // mid => ack callback + std::map ack_cbs; + std::mutex ack_cbs_mutex; +}; + +} +#endif + #endif // HV_MQTT_CLIENT_H_ diff --git a/sdk/include/hv/smtp.h b/sdk/include/hv/smtp.h deleted file mode 100644 index ce00399..0000000 --- a/sdk/include/hv/smtp.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef HV_SMTP_H_ -#define HV_SMTP_H_ - -#include "hexport.h" - -#define SMTP_PORT 25 -#define SMTPS_PORT 465 -#define SMTP_EOB "\r\n.\r\n" -#define SMTP_EOB_LEN 5 - -// smtp_command -// XX(name, string) -#define SMTP_COMMAND_MAP(XX)\ - XX(HELO, HELO) \ - XX(EHLO, EHLO) \ - XX(AUTH, AUTH) \ - XX(MAIL, MAIL FROM:) \ - XX(RCPT, RCPT TO:) \ - XX(DATA, DATA) \ - XX(QUIT, QUIT) \ - -enum smtp_command { -#define XX(name, string) SMTP_##name, - SMTP_COMMAND_MAP(XX) -#undef XX -}; - -// smtp_status -// XXX(code, name, string) -#define SMTP_STATUS_MAP(XXX) \ - XXX(220, READY, Ready) \ - XXX(221, BYE, Bye) \ - XXX(235, AUTH_SUCCESS, Authentication success) \ - XXX(250, OK, OK) \ - XXX(334, AUTH, Auth input) \ - XXX(354, DATA, End with .) \ - XXX(500, BAD_SYNTAX, Bad syntax) \ - XXX(502, NOT_IMPLEMENTED,Command not implemented) \ - XXX(503, BAD_SEQUENCE, Bad sequence of commands) \ - XXX(504, UNRECOGNIZED_AUTH_TYPE, Unrecognized authentication type) \ - XXX(535, AUTH_FAILED, Authentication failed) \ - XXX(553, ERR_MAIL, Mailbox name not allowed) \ - XXX(554, ERR_DATA, Transaction failed) \ - -enum smtp_status { -#define XXX(code, name, string) SMTP_STATUS_##name = code, - SMTP_STATUS_MAP(XXX) -#undef XXX -}; - -typedef struct mail_s { - char* from; - char* to; - char* subject; - char* body; -} mail_t; - -BEGIN_EXTERN_C - -HV_EXPORT const char* smtp_command_str(enum smtp_command cmd); -HV_EXPORT const char* smtp_status_str(enum smtp_status status); - -// cmd param\r\n -HV_EXPORT int smtp_build_command(enum smtp_command cmd, const char* param, char* buf, int buflen); -// status_code status_message\r\n - -HV_EXPORT int sendmail(const char* smtp_server, - const char* username, - const char* password, - mail_t* mail); - -END_EXTERN_C - -#endif // HV_SMTP_H_ diff --git a/sdk/include/iconv.h b/sdk/include/iconv.h index a844d4c..fdf3c53 100644 --- a/sdk/include/iconv.h +++ b/sdk/include/iconv.h @@ -21,7 +21,7 @@ #define _LIBICONV_H #define _LIBICONV_VERSION 0x0111 /* version number: (major<<8) + minor */ -extern int _libiconv_version; /* Likewise */ +extern __declspec (dllimport) int _libiconv_version; /* Likewise */ /* We would like to #include any system header file which could define iconv_t, 1. in order to eliminate the risk that the user gets compilation diff --git a/sdk/include/libcharset.h b/sdk/include/libcharset.h index fcf2274..1a81ced 100644 --- a/sdk/include/libcharset.h +++ b/sdk/include/libcharset.h @@ -2,22 +2,33 @@ This file is part of the GNU CHARSET Library. The GNU CHARSET Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as + modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU CHARSET Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + Library General Public License for more details. - You should have received a copy of the GNU Lesser General Public License + You should have received a copy of the GNU Library General Public License along with the GNU CHARSET Library; see the file COPYING.LIB. If not, - see . */ + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #ifndef _LIBCHARSET_H #define _LIBCHARSET_H +#ifdef LIBCHARSET_STATIC +#define LIBCHARSET_DLL_EXPORTED +#else /* LIBCHARSET_STATIC */ +#ifdef BUILDING_LIBCHARSET +#define LIBCHARSET_DLL_EXPORTED __declspec(dllexport) +#else +#define LIBCHARSET_DLL_EXPORTED __declspec(dllimport) +#endif +#endif /* LIBCHARSET_STATIC */ + #include @@ -33,8 +44,8 @@ extern "C" { by the corresponding pathname with the current prefix instead. Both prefixes should be directory names without trailing slash (i.e. use "" instead of "/"). */ -extern void libcharset_set_relocation_prefix (const char *orig_prefix, - const char *curr_prefix); +extern LIBCHARSET_DLL_EXPORTED void libcharset_set_relocation_prefix (const char *orig_prefix, + const char *curr_prefix); #ifdef __cplusplus diff --git a/sdk/include/localcharset.h b/sdk/include/localcharset.h index 34ce0ad..25d21eb 100644 --- a/sdk/include/localcharset.h +++ b/sdk/include/localcharset.h @@ -1,23 +1,34 @@ /* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2003, 2009-2019 Free Software Foundation, Inc. + Copyright (C) 2000-2003 Free Software Foundation, Inc. This file is part of the GNU CHARSET Library. This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published + under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + Library General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, see . */ + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ #ifndef _LOCALCHARSET_H #define _LOCALCHARSET_H +#ifdef LIBCHARSET_STATIC +#define LIBCHARSET_DLL_EXPORTED +#else /* LIBCHARSET_STATIC */ +#ifdef BUILDING_LIBCHARSET +#define LIBCHARSET_DLL_EXPORTED __declspec(dllexport) +#else +#define LIBCHARSET_DLL_EXPORTED __declspec(dllimport) +#endif +#endif /* LIBCHARSET_STATIC */ #ifdef __cplusplus extern "C" { @@ -25,108 +36,11 @@ extern "C" { /* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed below. - The result must not be freed; it is statically allocated. The result - becomes invalid when setlocale() is used to change the global locale, or - when the value of one of the environment variables LC_ALL, LC_CTYPE, LANG - is changed; threads in multithreaded programs should not do this. + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. If the canonical name cannot be determined, the result is a non-canonical name. */ -extern const char * locale_charset (void); - -/* About GNU canonical names for character encodings: - - Every canonical name must be supported by GNU libiconv. Support by GNU libc - is also desirable. - - The name is case insensitive. Usually an upper case MIME charset name is - preferred. - - The current list of these GNU canonical names is: - - name MIME? used by which systems - (darwin = Mac OS X, windows = native Windows) - - ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin minix cygwin - ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos - ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos - ISO-8859-3 Y glibc solaris cygwin - ISO-8859-4 Y hpux osf solaris freebsd netbsd openbsd darwin - ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos - ISO-8859-6 Y glibc aix hpux solaris cygwin - ISO-8859-7 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos - ISO-8859-8 Y glibc aix hpux osf solaris cygwin zos - ISO-8859-9 Y glibc aix hpux irix osf solaris freebsd darwin cygwin zos - ISO-8859-13 glibc hpux solaris freebsd netbsd openbsd darwin cygwin - ISO-8859-14 glibc cygwin - ISO-8859-15 glibc aix irix osf solaris freebsd netbsd openbsd darwin cygwin - KOI8-R Y glibc hpux solaris freebsd netbsd openbsd darwin - KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin - KOI8-T glibc - CP437 dos - CP775 dos - CP850 aix osf dos - CP852 dos - CP855 dos - CP856 aix - CP857 dos - CP861 dos - CP862 dos - CP864 dos - CP865 dos - CP866 freebsd netbsd openbsd darwin dos - CP869 dos - CP874 windows dos - CP922 aix - CP932 aix cygwin windows dos - CP943 aix zos - CP949 osf darwin windows dos - CP950 windows dos - CP1046 aix - CP1124 aix - CP1125 dos - CP1129 aix - CP1131 freebsd darwin - CP1250 windows - CP1251 glibc hpux solaris freebsd netbsd openbsd darwin cygwin windows - CP1252 aix windows - CP1253 windows - CP1254 windows - CP1255 glibc windows - CP1256 windows - CP1257 windows - GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin cygwin zos - EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin - EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin zos - EUC-TW glibc aix hpux irix osf solaris netbsd - BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin zos - BIG5-HKSCS glibc hpux solaris netbsd darwin - GBK glibc aix osf solaris freebsd darwin cygwin windows dos - GB18030 glibc hpux solaris freebsd netbsd darwin - SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin - JOHAB glibc solaris windows - TIS-620 glibc aix hpux osf solaris cygwin zos - VISCII Y glibc - TCVN5712-1 glibc - ARMSCII-8 glibc freebsd netbsd darwin - GEORGIAN-PS glibc cygwin - PT154 glibc netbsd cygwin - HP-ROMAN8 hpux - HP-ARABIC8 hpux - HP-GREEK8 hpux - HP-HEBREW8 hpux - HP-TURKISH8 hpux - HP-KANA8 hpux - DEC-KANJI osf - DEC-HANYU osf - UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin zos - - Note: Names which are not marked as being a MIME name should not be used in - Internet protocols for information interchange (mail, news, etc.). - - Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications - must understand both names and treat them as equivalent. - */ +extern LIBCHARSET_DLL_EXPORTED const char * locale_charset (void); #ifdef __cplusplus diff --git a/sdk/include/mysql_connection.h b/sdk/include/mysql_connection.h index 23fc4c2..6686f04 100644 --- a/sdk/include/mysql_connection.h +++ b/sdk/include/mysql_connection.h @@ -1,32 +1,41 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _MYSQL_CONNECTION_H_ #define _MYSQL_CONNECTION_H_ #include #include +#include namespace sql { @@ -35,25 +44,26 @@ namespace mysql class MySQL_Savepoint : public sql::Savepoint { - sql::SQLString name; + sql::SQLString name; public: - MySQL_Savepoint(const sql::SQLString &savepoint); - virtual ~MySQL_Savepoint() {} + MySQL_Savepoint(const sql::SQLString &savepoint); + virtual ~MySQL_Savepoint() {} - int getSavepointId(); + int getSavepointId(); - sql::SQLString getSavepointName(); + sql::SQLString getSavepointName(); private: - /* Prevent use of these */ - MySQL_Savepoint(const MySQL_Savepoint &); - void operator=(MySQL_Savepoint &); + /* Prevent use of these */ + MySQL_Savepoint(const MySQL_Savepoint &); + void operator=(MySQL_Savepoint &); }; class MySQL_DebugLogger; -class MySQL_ConnectionData; /* PIMPL */ +struct MySQL_ConnectionData; /* PIMPL */ +class MySQL_Statement; namespace NativeAPI { @@ -62,105 +72,123 @@ class NativeConnectionWrapper; class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection { + MySQL_Statement * createServiceStmt(); + public: - MySQL_Connection(Driver * _driver, - ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, - const sql::SQLString& hostName, - const sql::SQLString& userName, - const sql::SQLString& password); + MySQL_Connection(Driver * _driver, + ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, + const sql::SQLString& hostName, + const sql::SQLString& userName, + const sql::SQLString& password); - MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, - std::map< sql::SQLString, sql::ConnectPropertyVal > & options); + MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, + std::map< sql::SQLString, sql::ConnectPropertyVal > & options); - virtual ~MySQL_Connection(); + virtual ~MySQL_Connection(); - void clearWarnings(); + void clearWarnings(); - void close(); + void close(); - void commit(); + void commit(); - sql::Statement * createStatement(); + sql::Statement * createStatement(); - sql::SQLString escapeString(const sql::SQLString &); + sql::SQLString escapeString(const sql::SQLString &); - bool getAutoCommit(); + bool getAutoCommit(); - sql::SQLString getCatalog(); + sql::SQLString getCatalog(); - Driver *getDriver(); + Driver *getDriver(); - sql::SQLString getSchema(); + sql::SQLString getSchema(); - sql::SQLString getClientInfo(); + sql::SQLString getClientInfo(); - void getClientOption(const sql::SQLString & optionName, void * optionValue); + void getClientOption(const sql::SQLString & optionName, void * optionValue); - sql::DatabaseMetaData * getMetaData(); + sql::SQLString getClientOption(const sql::SQLString & optionName); - enum_transaction_isolation getTransactionIsolation(); + sql::DatabaseMetaData * getMetaData(); - const SQLWarning * getWarnings(); + enum_transaction_isolation getTransactionIsolation(); - bool isClosed(); + const SQLWarning * getWarnings(); - bool isReadOnly(); + bool isClosed(); - sql::SQLString nativeSQL(const sql::SQLString& sql); + bool isReadOnly(); - sql::PreparedStatement * prepareStatement(const sql::SQLString& sql); + bool isValid(); - sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys); + bool reconnect(); - sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int columnIndexes[]); + sql::SQLString nativeSQL(const sql::SQLString& sql); - sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency); + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql); - sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability); + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys); - sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]); + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int columnIndexes[]); - void releaseSavepoint(Savepoint * savepoint) ; + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency); - void rollback(); + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability); - void rollback(Savepoint * savepoint); + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]); - void setAutoCommit(bool autoCommit); + void releaseSavepoint(Savepoint * savepoint) ; - void setCatalog(const sql::SQLString& catalog); + void rollback(); - void setSchema(const sql::SQLString& catalog); + void rollback(Savepoint * savepoint); - sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue); + void setAutoCommit(bool autoCommit); - void setHoldability(int holdability); + void setCatalog(const sql::SQLString& catalog); - void setReadOnly(bool readOnly); + void setSchema(const sql::SQLString& catalog); - sql::Savepoint * setSavepoint(); + sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue); - sql::Savepoint * setSavepoint(const sql::SQLString& name); + sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue); - void setTransactionIsolation(enum_transaction_isolation level); + void setHoldability(int holdability); - sql::SQLString getSessionVariable(const sql::SQLString & varname); + void setReadOnly(bool readOnly); - void setSessionVariable(const sql::SQLString & varname, const sql::SQLString & value); + sql::Savepoint * setSavepoint(); -protected: - void checkClosed(); - void init(std::map< sql::SQLString, sql::ConnectPropertyVal > & properties); + sql::Savepoint * setSavepoint(const sql::SQLString& name); - Driver * driver; - boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy; + void setTransactionIsolation(enum_transaction_isolation level); - MySQL_ConnectionData * intern; /* pimpl */ + virtual sql::SQLString getSessionVariable(const sql::SQLString & varname); + + virtual void setSessionVariable(const sql::SQLString & varname, const sql::SQLString & value); + + virtual void setSessionVariable(const sql::SQLString & varname, unsigned int value); + + virtual sql::SQLString getLastStatementInfo(); private: - /* Prevent use of these */ - MySQL_Connection(const MySQL_Connection &); - void operator=(MySQL_Connection &); + /* We do not really think this class has to be subclassed*/ + void checkClosed(); + void init(std::map< sql::SQLString, sql::ConnectPropertyVal > & properties); + + Driver * driver; + boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy; + + /* statement handle to execute queries initiated by driver. Perhaps it is + a good idea to move it to a separate helper class */ + boost::scoped_ptr< ::sql::mysql::MySQL_Statement > service; + + boost::scoped_ptr< ::sql::mysql::MySQL_ConnectionData > intern; /* pimpl */ + + /* Prevent use of these */ + MySQL_Connection(const MySQL_Connection &); + void operator=(MySQL_Connection &); }; } /* namespace mysql */ diff --git a/sdk/include/mysql_driver.h b/sdk/include/mysql_driver.h index f2d4933..9a677de 100644 --- a/sdk/include/mysql_driver.h +++ b/sdk/include/mysql_driver.h @@ -1,26 +1,34 @@ /* - Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is also distributed with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, + * as designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an + * additional permission to link the program and your derivative works + * with the separately licensed software that they have included with + * MySQL. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of MySQL Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * http://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ - The MySQL Connector/C++ is licensed under the terms of the GPLv2 - , like most - MySQL Connectors. There are special exceptions to the terms and - conditions of the GPLv2 as it is applied to this software, see the - FLOSS License Exception - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ #ifndef _MYSQL_DRIVER_H_ #define _MYSQL_DRIVER_H_ @@ -40,41 +48,41 @@ namespace mysql { namespace NativeAPI { - class NativeDriverWrapper; + class NativeDriverWrapper; } //class sql::mysql::NativeAPI::NativeDriverWrapper; class CPPCONN_PUBLIC_FUNC MySQL_Driver : public sql::Driver { - boost::scoped_ptr< ::sql::mysql::NativeAPI::NativeDriverWrapper > proxy; + boost::scoped_ptr< ::sql::mysql::NativeAPI::NativeDriverWrapper > proxy; public: - MySQL_Driver(); - MySQL_Driver(const ::sql::SQLString & clientLib); + MySQL_Driver(); + MySQL_Driver(const ::sql::SQLString & clientLib); - virtual ~MySQL_Driver(); + virtual ~MySQL_Driver(); - sql::Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password); + sql::Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password); - sql::Connection * connect(sql::ConnectOptionsMap & options); + sql::Connection * connect(sql::ConnectOptionsMap & options); - int getMajorVersion(); + int getMajorVersion(); - int getMinorVersion(); + int getMinorVersion(); - int getPatchVersion(); + int getPatchVersion(); - const sql::SQLString & getName(); + const sql::SQLString & getName(); - void threadInit(); + void threadInit(); - void threadEnd(); + void threadEnd(); private: - /* Prevent use of these */ - MySQL_Driver(const MySQL_Driver &); - void operator=(MySQL_Driver &); + /* Prevent use of these */ + MySQL_Driver(const MySQL_Driver &); + void operator=(MySQL_Driver &); }; /** We do not hide the function if MYSQLCLIENT_STATIC_BINDING(or anything else) not defined diff --git a/sdk/include/zlib/zconf.h b/sdk/include/zlib/zconf.h index ede3c82..4944a4e 100644 --- a/sdk/include/zlib/zconf.h +++ b/sdk/include/zlib/zconf.h @@ -7,6 +7,8 @@ #ifndef ZCONF_H #define ZCONF_H +/* #undef Z_PREFIX */ +/* #undef Z_HAVE_UNISTD_H */ /* * If you *really* need a unique prefix for all types and library functions, @@ -433,11 +435,11 @@ typedef uLong FAR uLongf; typedef unsigned long z_crc_t; #endif -#if 1 /* was set to #if 1 by ./configure */ +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_UNISTD_H #endif -#if 1 /* was set to #if 1 by ./configure */ +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_STDARG_H #endif