<commit_before>/*-----------------------------------------------------------------------------

 Copyright 2017 Hopsan Group

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

 The full license is available in the file LICENSE.
 For details about the 'Hopsan Group' or information about Authors and
 Contributors see the HOPSANGROUP and AUTHORS files that are located in
 the Hopsan source code root directory.

-----------------------------------------------------------------------------*/

#include "fmu_hopsan.h"
#include "HopsanCore.h"
#include "HopsanEssentials.h"
#include "HopsanTypes.h"
#include <string>
#include "model.hpp"
#include <cassert>
#include "ComponentUtilities/num2string.hpp"

namespace {

static double fmu_time=0;
static hopsan::ComponentSystem *spCoreComponentSystem = 0;
static std::vector<std::string> sComponentNames;
hopsan::HopsanEssentials gHopsanCore;

double *dataPtrs[<<<nports>>>];

std::map<int,hopsan::HString> realParametersMap;
std::map<int,hopsan::HString> intParametersMap;
std::map<int,hopsan::HString> boolParametersMap;
std::map<int,hopsan::HString> stringParametersMap;

std::string parseResourceLocation(std::string uri)
{
    // The resource location is an URI according to rfc3986 on the following format
    // schema://authority/path or schema:/path
    // authority is expected to be empty if included
    // only the 'file' schema is supported by Hopsan
    std::string::size_type se = uri.find_first_of(':');
    std::string schema = uri.substr(0,se);
    // If the next two chars are // then authority is included (may be empty)
    std::string::size_type pb;
    if (uri.substr(se+1,2) == "//") {
        pb = uri.find_first_of('/', se+3);
    } else {
        pb = uri.find_first_of('/', se);
    }
    // Now we know were the path begins (pb), but is it a unix or windows path
    // Check windows
    if (uri.substr(pb+2,2) == ":/") {
        // Skip first /
        pb++;
    }
    std::string path = uri.substr(pb);
#ifdef _WIN32
    std::string::size_type i = path.find_first_of('/');
    while (i != std::string::npos) {
        path.replace(i, 1, 1, '\\');
        i = path.find_first_of('/');
    }
#endif
    return path;
}
}

extern "C" {

int hopsan_instantiate(const char *resourceLocation)
{
    double startT, stopT;      // Dummy variables
    spCoreComponentSystem = gHopsanCore.loadHMFModel(getModelString().c_str(), startT, stopT);
    if (spCoreComponentSystem)
    {
        std::string rl = parseResourceLocation(resourceLocation);
        spCoreComponentSystem->addSearchPath(rl.c_str());

        // Get pointers to I/O data variables
<<<setdataptrs>>>

        //Populate parameter name maps
<<<addparameterstomap>>>

        // Initialize system
        spCoreComponentSystem->setDesiredTimestep(<<<timestep>>>);
        spCoreComponentSystem->setNumLogSamples(0);
        //! @todo disableLog does not work without setNumLogsamples0
        spCoreComponentSystem->disableLog();
        if (spCoreComponentSystem->checkModelBeforeSimulation())
        {
            return 1; // C true
        }
    }
    return 0;  // C false
}

int hopsan_initialize(double startT, double stopT)
{
    return spCoreComponentSystem->initialize(startT, stopT) ? 1 : 0;
}

void hopsan_simulate(double stopTime)
{
    spCoreComponentSystem->simulate(stopTime);
}

void hopsan_finalize()
{
    spCoreComponentSystem->finalize();
}

int hopsan_has_message()
{
    return (gHopsanCore.checkMessage() > 0) ? 1 : 0;
}

void hopsan_get_message(hopsan_message_callback_t message_callback, void* userState)
{
    hopsan::HString message, type, tag;
    gHopsanCore.getMessage(message, type, tag);

    // Replace any # with ## (# is reserved by FMI for value references)
    // # is used as escape character in this case
    message.replace("#", "##");

    // Replace any single % since we do not use printf format strings inside Hopsan
    // The FMI standard assuems that message is a printf format string
    // Use %% to print %
    message.replace("%", "%%");

    message_callback(message.c_str(), type.c_str(), userState);
}

double hopsan_get_real(int vr)
{
    if(vr < <<<nports>>>) {
        return (*dataPtrs[vr]);
    }
    if(realParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(realParametersMap[vr],value);
        bool ok;
        return value.toDouble(&ok);
    }
    return -1;
}

int hopsan_get_integer(int vr)
{
    if(intParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(intParametersMap[vr],value);
        bool ok;
        return value.toLongInt(&ok);
    }
    return -1;
}

int hopsan_get_boolean(int vr)
{
    if(boolParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(boolParametersMap[vr],value);
        bool ok;
        return value.toBool(&ok);
    }
    return false;
}

const char* hopsan_get_string(int vr)
{
    if(stringParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(stringParametersMap[vr],value);
        bool ok;
        return value.c_str();
    }
    return "";
}

void hopsan_set_real(int vr, double value)
{
    if(vr < <<<nports>>>) {
        (*dataPtrs[vr]) = value;
    }
    else if(realParametersMap.count(vr)) {
        spCoreComponentSystem->setParameterValue(realParametersMap[vr], to_hstring(value));
    }
}

void hopsan_set_integer(int vr, int value)
{
    if(intParametersMap.count(vr)) {
        std::ostringstream ss;
        ss << value;
        spCoreComponentSystem->setParameterValue(intParametersMap[vr], hopsan::HString(ss.str().c_str()));
    }
}

void hopsan_set_boolean(int vr, int value)
{
    if(boolParametersMap.count(vr)) {
        hopsan::HString hvalue = "true";
        if(hvalue != 0) {
            hvalue = "false";
        }
        spCoreComponentSystem->setParameterValue(boolParametersMap[vr], hvalue);
    }
}

void hopsan_set_string(int vr, const char* value)
{
    if(stringParametersMap.count(vr)) {
        spCoreComponentSystem->setParameterValue(stringParametersMap[vr], value);
    }
}

}
<commit_msg>Fixed bool to string conversion in FMI export<commit_after>/*-----------------------------------------------------------------------------

 Copyright 2017 Hopsan Group

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

 The full license is available in the file LICENSE.
 For details about the 'Hopsan Group' or information about Authors and
 Contributors see the HOPSANGROUP and AUTHORS files that are located in
 the Hopsan source code root directory.

-----------------------------------------------------------------------------*/

#include "fmu_hopsan.h"
#include "HopsanCore.h"
#include "HopsanEssentials.h"
#include "HopsanTypes.h"
#include <string>
#include "model.hpp"
#include <cassert>
#include "ComponentUtilities/num2string.hpp"

namespace {

static double fmu_time=0;
static hopsan::ComponentSystem *spCoreComponentSystem = 0;
static std::vector<std::string> sComponentNames;
hopsan::HopsanEssentials gHopsanCore;

double *dataPtrs[<<<nports>>>];

std::map<int,hopsan::HString> realParametersMap;
std::map<int,hopsan::HString> intParametersMap;
std::map<int,hopsan::HString> boolParametersMap;
std::map<int,hopsan::HString> stringParametersMap;

std::string parseResourceLocation(std::string uri)
{
    // The resource location is an URI according to rfc3986 on the following format
    // schema://authority/path or schema:/path
    // authority is expected to be empty if included
    // only the 'file' schema is supported by Hopsan
    std::string::size_type se = uri.find_first_of(':');
    std::string schema = uri.substr(0,se);
    // If the next two chars are // then authority is included (may be empty)
    std::string::size_type pb;
    if (uri.substr(se+1,2) == "//") {
        pb = uri.find_first_of('/', se+3);
    } else {
        pb = uri.find_first_of('/', se);
    }
    // Now we know were the path begins (pb), but is it a unix or windows path
    // Check windows
    if (uri.substr(pb+2,2) == ":/") {
        // Skip first /
        pb++;
    }
    std::string path = uri.substr(pb);
#ifdef _WIN32
    std::string::size_type i = path.find_first_of('/');
    while (i != std::string::npos) {
        path.replace(i, 1, 1, '\\');
        i = path.find_first_of('/');
    }
#endif
    return path;
}
}

extern "C" {

int hopsan_instantiate(const char *resourceLocation)
{
    double startT, stopT;      // Dummy variables
    spCoreComponentSystem = gHopsanCore.loadHMFModel(getModelString().c_str(), startT, stopT);
    if (spCoreComponentSystem)
    {
        std::string rl = parseResourceLocation(resourceLocation);
        spCoreComponentSystem->addSearchPath(rl.c_str());

        // Get pointers to I/O data variables
<<<setdataptrs>>>

        //Populate parameter name maps
<<<addparameterstomap>>>

        // Initialize system
        spCoreComponentSystem->setDesiredTimestep(<<<timestep>>>);
        spCoreComponentSystem->setNumLogSamples(0);
        //! @todo disableLog does not work without setNumLogsamples0
        spCoreComponentSystem->disableLog();
        if (spCoreComponentSystem->checkModelBeforeSimulation())
        {
            return 1; // C true
        }
    }
    return 0;  // C false
}

int hopsan_initialize(double startT, double stopT)
{
    return spCoreComponentSystem->initialize(startT, stopT) ? 1 : 0;
}

void hopsan_simulate(double stopTime)
{
    spCoreComponentSystem->simulate(stopTime);
}

void hopsan_finalize()
{
    spCoreComponentSystem->finalize();
}

int hopsan_has_message()
{
    return (gHopsanCore.checkMessage() > 0) ? 1 : 0;
}

void hopsan_get_message(hopsan_message_callback_t message_callback, void* userState)
{
    hopsan::HString message, type, tag;
    gHopsanCore.getMessage(message, type, tag);

    // Replace any # with ## (# is reserved by FMI for value references)
    // # is used as escape character in this case
    message.replace("#", "##");

    // Replace any single % since we do not use printf format strings inside Hopsan
    // The FMI standard assuems that message is a printf format string
    // Use %% to print %
    message.replace("%", "%%");

    message_callback(message.c_str(), type.c_str(), userState);
}

double hopsan_get_real(int vr)
{
    if(vr < <<<nports>>>) {
        return (*dataPtrs[vr]);
    }
    if(realParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(realParametersMap[vr],value);
        bool ok;
        return value.toDouble(&ok);
    }
    return -1;
}

int hopsan_get_integer(int vr)
{
    if(intParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(intParametersMap[vr],value);
        bool ok;
        return value.toLongInt(&ok);
    }
    return -1;
}

int hopsan_get_boolean(int vr)
{
    if(boolParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(boolParametersMap[vr],value);
        bool ok;
        return value.toBool(&ok);
    }
    return false;
}

const char* hopsan_get_string(int vr)
{
    if(stringParametersMap.count(vr)) {
        hopsan::HString value;
        spCoreComponentSystem->getParameterValue(stringParametersMap[vr],value);
        bool ok;
        return value.c_str();
    }
    return "";
}

void hopsan_set_real(int vr, double value)
{
    if(vr < <<<nports>>>) {
        (*dataPtrs[vr]) = value;
    }
    else if(realParametersMap.count(vr)) {
        spCoreComponentSystem->setParameterValue(realParametersMap[vr], to_hstring(value));
    }
}

void hopsan_set_integer(int vr, int value)
{
    if(intParametersMap.count(vr)) {
        std::ostringstream ss;
        ss << value;
        spCoreComponentSystem->setParameterValue(intParametersMap[vr], hopsan::HString(ss.str().c_str()));
    }
}

void hopsan_set_boolean(int vr, int value)
{
    if(boolParametersMap.count(vr)) {
        hopsan::HString hvalue = "true";
        if(value != 0) {
            hvalue = "false";
        }
        spCoreComponentSystem->setParameterValue(boolParametersMap[vr], hvalue);
    }
}

void hopsan_set_string(int vr, const char* value)
{
    if(stringParametersMap.count(vr)) {
        spCoreComponentSystem->setParameterValue(stringParametersMap[vr], value);
    }
}

}
<|endoftext|>


<commit_before>#include "hecl/Runtime.hpp"

#include "hecl/hecl.hpp"

#include <logvisor/logvisor.hpp>

#if _WIN32
#include <ShlObj.h>
#endif

#if WINDOWS_STORE
using namespace Windows::Storage;
#endif

namespace hecl::Runtime {
static logvisor::Module Log("FileStoreManager");

FileStoreManager::FileStoreManager(SystemStringView domain) : m_domain(domain) {
#if _WIN32
#if !WINDOWS_STORE
  WCHAR home[MAX_PATH];
  if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, home)))
    Log.report(logvisor::Fatal, fmt(_SYS_STR("unable to locate profile for file store")));

  SystemString path(home);
#else
  StorageFolder ^ cacheFolder = ApplicationData::Current->LocalCacheFolder;
  SystemString path(cacheFolder->Path->Data());
#endif
  path += _SYS_STR("/.heclrun");

  hecl::MakeDir(path.c_str());
  path += _SYS_STR('/');
  path += domain.data();

  hecl::MakeDir(path.c_str());
  m_storeRoot = path;
#else
  const char* home = getenv("HOME");
  if (!home)
    Log.report(logvisor::Fatal, fmt("unable to locate $HOME for file store"));
  std::string path(home);
  path += "/.heclrun";
  if (mkdir(path.c_str(), 0755) && errno != EEXIST)
    Log.report(logvisor::Fatal, fmt("unable to mkdir at {}"), path);
  path += '/';
  path += domain.data();
  if (mkdir(path.c_str(), 0755) && errno != EEXIST)
    Log.report(logvisor::Fatal, fmt("unable to mkdir at {}"), path);
  m_storeRoot = path;
#endif
}

} // namespace hecl::Runtime
<commit_msg>Respect the XDG base directory specification<commit_after>#include "hecl/Runtime.hpp"

#include "hecl/hecl.hpp"

#include <logvisor/logvisor.hpp>

#if _WIN32
#include <ShlObj.h>
#endif

#if WINDOWS_STORE
using namespace Windows::Storage;
#endif

namespace hecl::Runtime {
static logvisor::Module Log("FileStoreManager");

FileStoreManager::FileStoreManager(SystemStringView domain) : m_domain(domain) {
#if _WIN32
#if !WINDOWS_STORE
  WCHAR home[MAX_PATH];
  if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, home)))
    Log.report(logvisor::Fatal, fmt(_SYS_STR("unable to locate profile for file store")));

  SystemString path(home);
#else
  StorageFolder ^ cacheFolder = ApplicationData::Current->LocalCacheFolder;
  SystemString path(cacheFolder->Path->Data());
#endif
  path += _SYS_STR("/.heclrun");

  hecl::MakeDir(path.c_str());
  path += _SYS_STR('/');
  path += domain.data();

  hecl::MakeDir(path.c_str());
  m_storeRoot = path;
#else
  const char* xdg_data_home = getenv("XDG_DATA_HOME");
  std::string path;
  if (xdg_data_home) {
    if (xdg_data_home[0] != '/')
      Log.report(logvisor::Fatal, fmt("invalid $XDG_DATA_HOME for file store (must be absolute)"));
    path = xdg_data_home;
  } else {
    const char* home = getenv("HOME");
    if (!home)
      Log.report(logvisor::Fatal, fmt("unable to locate $HOME for file store"));
    path = home;
    path += "/.local/share"
  }
  path += "/hecl";
  if (mkdir(path.c_str(), 0755) && errno != EEXIST)
    Log.report(logvisor::Fatal, fmt("unable to mkdir at {}"), path);
  path += '/';
  path += domain.data();
  if (mkdir(path.c_str(), 0755) && errno != EEXIST)
    Log.report(logvisor::Fatal, fmt("unable to mkdir at {}"), path);
  m_storeRoot = path;
#endif
}

} // namespace hecl::Runtime
<|endoftext|>


<commit_before>/*
   Copyright (C) 2014-2017 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This 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.

 */

#ifndef TELEGRAMNAMESPACE_HPP
#define TELEGRAMNAMESPACE_HPP

#include "telegramqt_global.h"

#include <QObject>
#include <QFlags>
#include <QMetaType>
#include <QVector>

#ifndef Q_ENUM
#define Q_ENUM(x) Q_ENUMS(x)
#endif

namespace Telegram {

TELEGRAMQT_EXPORT QString version();
TELEGRAMQT_EXPORT QString buildVersion();

struct TELEGRAMQT_EXPORT Peer
{
    Q_GADGET
    Q_PROPERTY(Telegram::Peer::Type type MEMBER type)
    Q_PROPERTY(quint32 id MEMBER id)
public:
    enum Type {
        User,
        Chat,
        Channel,
    };
    Q_ENUM(Type)

    constexpr Peer(quint32 id = 0, Type t = User) : type(t), id(id)
    {
    }

    Type type = User;
    quint32 id = 0;

    Q_INVOKABLE constexpr bool isValid() const { return id; }

    constexpr bool operator==(const Peer &p) const
    {
        return (p.id == id) && (p.type == type);
    }

    constexpr bool operator!=(const Peer &p) const
    {
        return (p.id != id) || (p.type != type);
    }

    constexpr static Peer fromUserId(quint32 id)
    {
        return Peer(id, User);
    }

    constexpr static Peer fromChatId(quint32 id)
    {
        return Peer(id, Chat);
    }

    constexpr static Peer fromChannelId(quint32 id)
    {
        return Peer(id, Channel);
    }

    QString toString() const;
    static Peer fromString(const QString &string);
};

using PeerList = QVector<Peer>;

inline uint qHash(const Peer &key, uint seed)
{
    return ::qHash(static_cast<ulong>(key.id | (static_cast<quint64>(key.type) << (sizeof(key.id) * 8))), seed);
}

} // Telegram namespace

class TELEGRAMQT_EXPORT TelegramNamespace : public QObject
{
    Q_OBJECT
public:
    enum ContactStatus {
        ContactStatusUnknown,
        ContactStatusOffline,
        ContactStatusOnline
    };
    Q_ENUM(ContactStatus)

    enum MessageFlag {
        MessageFlagNone      = 0x0,
        MessageFlagRead      = 0x1, // Message was read
        MessageFlagOut       = 0x2, // Message is outgoing
        MessageFlagForwarded = 0x4,
        MessageFlagIsReply   = 0x8,
    };
    Q_ENUM(MessageFlag)
    Q_DECLARE_FLAGS(MessageFlags, MessageFlag)

    enum MessageType {
        MessageTypeUnsupported = 0x0000,
        MessageTypeText        = 0x0001,
        MessageTypePhoto       = 0x0002,
        MessageTypeAudio       = 0x0004,
        MessageTypeVideo       = 0x0008,
        MessageTypeContact     = 0x0010,
        MessageTypeDocument    = 0x0020,
        MessageTypeGeo         = 0x0040,
        MessageTypeWebPage     = 0x0080,
        MessageTypeSticker     = 0x0100,
        MessageTypeAnimation   = 0x0200,
        MessageTypeAll         = 0xffff,
    };
    Q_ENUM(MessageType)
    Q_DECLARE_FLAGS(MessageTypeFlags, MessageType)

    enum AuthenticationError {
        AuthenticationErrorUnknown,
        AuthenticationErrorAppIdInvalid,
        AuthenticationErrorPhoneNumberInvalid,
        AuthenticationErrorPhoneNumberOccupied,
        AuthenticationErrorPhoneNumberUnoccupied,
        AuthenticationErrorPhoneCodeInvalid,
        AuthenticationErrorPhoneCodeExpired,
        AuthenticationErrorPasswordHashInvalid,
        AuthenticationErrorFirstNameInvalid,
        AuthenticationErrorLastNameInvalid,
    };
    Q_ENUM(AuthenticationError)

    enum UnauthorizedError {
        UnauthorizedUnknownError,
        UnauthorizedErrorKeyUnregistered,
        UnauthorizedErrorKeyInvalid,
        UnauthorizedErrorUserDeactivated,
        UnauthorizedErrorUserSessionRevoked,
        UnauthorizedErrorUserSessionExpired,
        UnauthorizedErrorActiveUserRequired,
        UnauthorizedErrorNeedPermanentKey,
        UnauthorizedSessionPasswordNeeded,
    };
    Q_ENUM(UnauthorizedError)

    enum UserNameStatus {
        UserNameStatusUnknown,
        UserNameStatusIsInvalid,
        UserNameStatusIsOccupied,
        UserNameStatusIsNotModified,
        UserNameStatusCanBeUsed,
        UserNameStatusCanNotBeUsed,
        UserNameStatusResolved,
        UserNameStatusAccepted
    };
    Q_ENUM(UserNameStatus)

    enum ContactLastOnline {
        ContactLastOnlineUnknown,
        ContactLastOnlineRecently,
        ContactLastOnlineLastWeek,
        ContactLastOnlineLastMonth,
        ContactLastOnlineMask = 0xf
    };

    enum MessageAction {
        MessageActionNone, // Cancel
        MessageActionTyping,
        MessageActionRecordVideo,
        MessageActionRecordAudio,
        MessageActionUploadVideo,
        MessageActionUploadAudio,
        MessageActionUploadPhoto,
        MessageActionUploadDocument,
        MessageActionGeoLocation,
        MessageActionChooseContact
    };
    Q_ENUM(MessageAction)

    static void registerTypes();
    Q_INVOKABLE static Telegram::Peer emptyPeer();
    Q_INVOKABLE static Telegram::Peer peerFromChatId(quint32 id);
    Q_INVOKABLE static Telegram::Peer peerFromChannelId(quint32 id);
    Q_INVOKABLE static Telegram::Peer peerFromUserId(quint32 id);
};

namespace Telegram {

TELEGRAMQT_EXPORT void initialize();

class UserInfo;
class RemoteFile;
class MessageMediaInfo;

enum class PeerPictureSize {
    Small,
    Big,
};

struct TELEGRAMQT_EXPORT DcOption
{
    enum Flags {
        Ipv6 = 1 << 0,
        MediaOnly = 1 << 1,
        TcpOnly = 1 << 2,
        Cdn = 1 << 3,
        IsStatic = 1 << 4,
    };

    DcOption() = default;
    DcOption(const QString &a, quint16 p, quint32 dcId = 0) : address(a), id(dcId), port(p) { }
    bool operator==(const DcOption &option) const;
    bool isValid() const { return id && port && !address.isEmpty(); }

    QString address;
    quint32 id = 0;
    quint16 port = 0;
    quint16 flags = 0;
};

inline bool DcOption::operator==(const DcOption &option) const
{
    return (option.id == id) && (option.port == port) && (option.address == address) && (option.flags == flags);
}

struct TELEGRAMQT_EXPORT Message
{
    Message() = default;
    const Peer peer() const { return m_peer; }
    void setPeer(const Peer &peer) { m_peer = peer; }

    const Peer forwardFromPeer() const { return m_forwardPeer; }
    void setForwardFromPeer(const Peer &peer) { m_forwardPeer = peer; }

    QString text;
    quint32 id = 0;
    quint32 fromId = 0; // Telegram user id
    quint32 timestamp = 0;
    quint32 fwdTimestamp = 0;
    quint32 forwardContactId = 0;
    quint32 replyToMessageId = 0;
    TelegramNamespace::MessageType type = TelegramNamespace::MessageTypeUnsupported;
    TelegramNamespace::MessageFlags flags = TelegramNamespace::MessageFlagNone;

private:
    Peer m_peer;
    Peer m_forwardPeer;
};

class TELEGRAMQT_EXPORT MessageMediaInfo
{
public:
    MessageMediaInfo();
    MessageMediaInfo(const MessageMediaInfo &info);
    ~MessageMediaInfo();

    MessageMediaInfo &operator=(const MessageMediaInfo &info);

    void setUploadFile(TelegramNamespace::MessageType type, const RemoteFile &file);

    bool getRemoteFileInfo(RemoteFile *file) const;

    TelegramNamespace::MessageType type() const;

    quint32 size() const;

    quint32 duration() const;
    bool setDuration(quint32 duration);

    QString documentFileName() const;
    bool setDocumentFileName(const QString &fileName);

    // Photo, Video
    QString caption() const;
    void setCaption(const QString &caption);

    QByteArray getCachedPhoto() const;

    // Valid for Document and Audio
    QString mimeType() const;
    bool setMimeType(const QString &mimeType);

    // Contact
    bool getContactInfo(UserInfo *info) const;
    void setContactInfo(const UserInfo *info);

    // Valid for GeoPoint and Document/Sticker
    QString alt() const;

    // GeoPoint
    double latitude() const;
    double longitude() const;
    void setGeoPoint(double latitude, double longitude);

    QString url() const;
    QString displayUrl() const;
    QString siteName() const;
    QString title() const;
    QString description() const;

    struct Private;

protected:
    Private *d;
};

class TELEGRAMQT_EXPORT RemoteFile
{
public:
    enum Type {
        Undefined,
        Download,
        Upload
    };
    RemoteFile();
    RemoteFile(const RemoteFile &file);
    ~RemoteFile();

    RemoteFile &operator=(const RemoteFile &file);

    Type type() const;

    bool isValid() const;
    QString getUniqueId() const;
    static RemoteFile fromUniqueId(const QString &uniqueId);

    QString fileName() const;
    quint32 size() const;
    QString md5Sum() const;

    struct Private;
protected:
    Private *d;
};

class TELEGRAMQT_EXPORT DialogInfo
{
public:
    DialogInfo();
    DialogInfo(const DialogInfo &info);
    virtual ~DialogInfo();

    DialogInfo &operator=(const DialogInfo &info);

    quint32 unreadCount() const;
    QString draft() const;
    quint32 lastMessageId() const;
    quint32 readInboxMaxId() const;
    quint32 readOutboxMaxId() const;

    Peer peer() const;
    quint32 muteUntil() const;
    bool isStillMuted() const;

    struct Private;
protected:
    Private *d;
};

class TELEGRAMQT_EXPORT UserInfo
{
public:
    UserInfo();
    UserInfo(const UserInfo &info);
    ~UserInfo();

    UserInfo &operator=(const UserInfo &info);

    QString getBestDisplayName() const;

    quint32 id() const;
    QString firstName() const;
    QString lastName() const;
    QString userName() const;
    QString phone() const;
    TelegramNamespace::ContactStatus status() const;
    quint32 wasOnline() const;
    bool isBot() const;
    bool isSelf() const;
    bool isContact() const;
    bool isMutualContact() const;
    bool isDeleted() const;

    quint32 botVersion() const;
    bool getPeerPicture(RemoteFile *file, PeerPictureSize size = PeerPictureSize::Small) const;

    // See TelegramNamespace::ContactLastOnline enum and a documentation for the contactLastOnline() method in the cpp file.

    struct Private;
protected:
    Private *d;
};

class TELEGRAMQT_EXPORT ChatInfo
{
public:
    ChatInfo();
    ChatInfo(const ChatInfo &info);
    ~ChatInfo();

    ChatInfo &operator=(const ChatInfo &info);

    Peer peer() const;

    QString title() const;
    quint32 participantsCount() const;
    quint32 date() const;
    bool left() const;
    bool broadcast() const;
    Peer migratedTo() const;

    bool getPeerPicture(RemoteFile *file, PeerPictureSize size = PeerPictureSize::Small) const;

    struct Private;
protected:
    Private *d;
};

namespace Utils
{

quint64 maskNumber(quint64 number);
TELEGRAMQT_EXPORT QString maskString(const QString &string);
TELEGRAMQT_EXPORT QByteArray maskByteArray(const QByteArray &data);
QString maskPhoneNumber(const QString &identifier);
QStringList maskPhoneNumber(const QStringList &list);

template <typename T>
T maskPhoneNumber(T container, const QString &key)
{
    if (container.contains(key)) {
        container.insert(key, maskPhoneNumber(container.value(key).toString()));
    }
    return container;
}

TELEGRAMQT_EXPORT QVector<quint32> toIdList(const Telegram::PeerList &peerList);

} // Utils namespace

} // Telegram namespace

Q_DECLARE_METATYPE(Telegram::Peer)
Q_DECLARE_METATYPE(Telegram::Peer::Type)
Q_DECLARE_METATYPE(Telegram::PeerList)
Q_DECLARE_METATYPE(Telegram::DcOption)
Q_DECLARE_METATYPE(Telegram::Message)
Q_DECLARE_METATYPE(Telegram::ChatInfo)
Q_DECLARE_METATYPE(Telegram::RemoteFile)
Q_DECLARE_METATYPE(Telegram::UserInfo)

Q_DECLARE_TYPEINFO(Telegram::DcOption, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::Message, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::ChatInfo, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::RemoteFile, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::UserInfo, Q_MOVABLE_TYPE);

Q_DECLARE_OPERATORS_FOR_FLAGS(TelegramNamespace::MessageFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(TelegramNamespace::MessageTypeFlags)

#endif // TELEGRAMNAMESPACE_HPP
<commit_msg>TelegramNamespace: Add an alias for vector of messages (MessageIdList)<commit_after>/*
   Copyright (C) 2014-2017 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This 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.

 */

#ifndef TELEGRAMNAMESPACE_HPP
#define TELEGRAMNAMESPACE_HPP

#include "telegramqt_global.h"

#include <QObject>
#include <QFlags>
#include <QMetaType>
#include <QVector>

#ifndef Q_ENUM
#define Q_ENUM(x) Q_ENUMS(x)
#endif

namespace Telegram {

TELEGRAMQT_EXPORT QString version();
TELEGRAMQT_EXPORT QString buildVersion();

struct TELEGRAMQT_EXPORT Peer
{
    Q_GADGET
    Q_PROPERTY(Telegram::Peer::Type type MEMBER type)
    Q_PROPERTY(quint32 id MEMBER id)
public:
    enum Type {
        User,
        Chat,
        Channel,
    };
    Q_ENUM(Type)

    constexpr Peer(quint32 id = 0, Type t = User) : type(t), id(id)
    {
    }

    Type type = User;
    quint32 id = 0;

    Q_INVOKABLE constexpr bool isValid() const { return id; }

    constexpr bool operator==(const Peer &p) const
    {
        return (p.id == id) && (p.type == type);
    }

    constexpr bool operator!=(const Peer &p) const
    {
        return (p.id != id) || (p.type != type);
    }

    constexpr static Peer fromUserId(quint32 id)
    {
        return Peer(id, User);
    }

    constexpr static Peer fromChatId(quint32 id)
    {
        return Peer(id, Chat);
    }

    constexpr static Peer fromChannelId(quint32 id)
    {
        return Peer(id, Channel);
    }

    QString toString() const;
    static Peer fromString(const QString &string);
};

using PeerList = QVector<Peer>;
using MessageIdList = QVector<quint32>;

inline uint qHash(const Peer &key, uint seed)
{
    return ::qHash(static_cast<ulong>(key.id | (static_cast<quint64>(key.type) << (sizeof(key.id) * 8))), seed);
}

} // Telegram namespace

class TELEGRAMQT_EXPORT TelegramNamespace : public QObject
{
    Q_OBJECT
public:
    enum ContactStatus {
        ContactStatusUnknown,
        ContactStatusOffline,
        ContactStatusOnline
    };
    Q_ENUM(ContactStatus)

    enum MessageFlag {
        MessageFlagNone      = 0x0,
        MessageFlagRead      = 0x1, // Message was read
        MessageFlagOut       = 0x2, // Message is outgoing
        MessageFlagForwarded = 0x4,
        MessageFlagIsReply   = 0x8,
    };
    Q_ENUM(MessageFlag)
    Q_DECLARE_FLAGS(MessageFlags, MessageFlag)

    enum MessageType {
        MessageTypeUnsupported = 0x0000,
        MessageTypeText        = 0x0001,
        MessageTypePhoto       = 0x0002,
        MessageTypeAudio       = 0x0004,
        MessageTypeVideo       = 0x0008,
        MessageTypeContact     = 0x0010,
        MessageTypeDocument    = 0x0020,
        MessageTypeGeo         = 0x0040,
        MessageTypeWebPage     = 0x0080,
        MessageTypeSticker     = 0x0100,
        MessageTypeAnimation   = 0x0200,
        MessageTypeAll         = 0xffff,
    };
    Q_ENUM(MessageType)
    Q_DECLARE_FLAGS(MessageTypeFlags, MessageType)

    enum AuthenticationError {
        AuthenticationErrorUnknown,
        AuthenticationErrorAppIdInvalid,
        AuthenticationErrorPhoneNumberInvalid,
        AuthenticationErrorPhoneNumberOccupied,
        AuthenticationErrorPhoneNumberUnoccupied,
        AuthenticationErrorPhoneCodeInvalid,
        AuthenticationErrorPhoneCodeExpired,
        AuthenticationErrorPasswordHashInvalid,
        AuthenticationErrorFirstNameInvalid,
        AuthenticationErrorLastNameInvalid,
    };
    Q_ENUM(AuthenticationError)

    enum UnauthorizedError {
        UnauthorizedUnknownError,
        UnauthorizedErrorKeyUnregistered,
        UnauthorizedErrorKeyInvalid,
        UnauthorizedErrorUserDeactivated,
        UnauthorizedErrorUserSessionRevoked,
        UnauthorizedErrorUserSessionExpired,
        UnauthorizedErrorActiveUserRequired,
        UnauthorizedErrorNeedPermanentKey,
        UnauthorizedSessionPasswordNeeded,
    };
    Q_ENUM(UnauthorizedError)

    enum UserNameStatus {
        UserNameStatusUnknown,
        UserNameStatusIsInvalid,
        UserNameStatusIsOccupied,
        UserNameStatusIsNotModified,
        UserNameStatusCanBeUsed,
        UserNameStatusCanNotBeUsed,
        UserNameStatusResolved,
        UserNameStatusAccepted
    };
    Q_ENUM(UserNameStatus)

    enum ContactLastOnline {
        ContactLastOnlineUnknown,
        ContactLastOnlineRecently,
        ContactLastOnlineLastWeek,
        ContactLastOnlineLastMonth,
        ContactLastOnlineMask = 0xf
    };

    enum MessageAction {
        MessageActionNone, // Cancel
        MessageActionTyping,
        MessageActionRecordVideo,
        MessageActionRecordAudio,
        MessageActionUploadVideo,
        MessageActionUploadAudio,
        MessageActionUploadPhoto,
        MessageActionUploadDocument,
        MessageActionGeoLocation,
        MessageActionChooseContact
    };
    Q_ENUM(MessageAction)

    static void registerTypes();
    Q_INVOKABLE static Telegram::Peer emptyPeer();
    Q_INVOKABLE static Telegram::Peer peerFromChatId(quint32 id);
    Q_INVOKABLE static Telegram::Peer peerFromChannelId(quint32 id);
    Q_INVOKABLE static Telegram::Peer peerFromUserId(quint32 id);
};

namespace Telegram {

TELEGRAMQT_EXPORT void initialize();

class UserInfo;
class RemoteFile;
class MessageMediaInfo;

enum class PeerPictureSize {
    Small,
    Big,
};

struct TELEGRAMQT_EXPORT DcOption
{
    enum Flags {
        Ipv6 = 1 << 0,
        MediaOnly = 1 << 1,
        TcpOnly = 1 << 2,
        Cdn = 1 << 3,
        IsStatic = 1 << 4,
    };

    DcOption() = default;
    DcOption(const QString &a, quint16 p, quint32 dcId = 0) : address(a), id(dcId), port(p) { }
    bool operator==(const DcOption &option) const;
    bool isValid() const { return id && port && !address.isEmpty(); }

    QString address;
    quint32 id = 0;
    quint16 port = 0;
    quint16 flags = 0;
};

inline bool DcOption::operator==(const DcOption &option) const
{
    return (option.id == id) && (option.port == port) && (option.address == address) && (option.flags == flags);
}

struct TELEGRAMQT_EXPORT Message
{
    Message() = default;
    const Peer peer() const { return m_peer; }
    void setPeer(const Peer &peer) { m_peer = peer; }

    const Peer forwardFromPeer() const { return m_forwardPeer; }
    void setForwardFromPeer(const Peer &peer) { m_forwardPeer = peer; }

    QString text;
    quint32 id = 0;
    quint32 fromId = 0; // Telegram user id
    quint32 timestamp = 0;
    quint32 fwdTimestamp = 0;
    quint32 forwardContactId = 0;
    quint32 replyToMessageId = 0;
    TelegramNamespace::MessageType type = TelegramNamespace::MessageTypeUnsupported;
    TelegramNamespace::MessageFlags flags = TelegramNamespace::MessageFlagNone;

private:
    Peer m_peer;
    Peer m_forwardPeer;
};

class TELEGRAMQT_EXPORT MessageMediaInfo
{
public:
    MessageMediaInfo();
    MessageMediaInfo(const MessageMediaInfo &info);
    ~MessageMediaInfo();

    MessageMediaInfo &operator=(const MessageMediaInfo &info);

    void setUploadFile(TelegramNamespace::MessageType type, const RemoteFile &file);

    bool getRemoteFileInfo(RemoteFile *file) const;

    TelegramNamespace::MessageType type() const;

    quint32 size() const;

    quint32 duration() const;
    bool setDuration(quint32 duration);

    QString documentFileName() const;
    bool setDocumentFileName(const QString &fileName);

    // Photo, Video
    QString caption() const;
    void setCaption(const QString &caption);

    QByteArray getCachedPhoto() const;

    // Valid for Document and Audio
    QString mimeType() const;
    bool setMimeType(const QString &mimeType);

    // Contact
    bool getContactInfo(UserInfo *info) const;
    void setContactInfo(const UserInfo *info);

    // Valid for GeoPoint and Document/Sticker
    QString alt() const;

    // GeoPoint
    double latitude() const;
    double longitude() const;
    void setGeoPoint(double latitude, double longitude);

    QString url() const;
    QString displayUrl() const;
    QString siteName() const;
    QString title() const;
    QString description() const;

    struct Private;

protected:
    Private *d;
};

class TELEGRAMQT_EXPORT RemoteFile
{
public:
    enum Type {
        Undefined,
        Download,
        Upload
    };
    RemoteFile();
    RemoteFile(const RemoteFile &file);
    ~RemoteFile();

    RemoteFile &operator=(const RemoteFile &file);

    Type type() const;

    bool isValid() const;
    QString getUniqueId() const;
    static RemoteFile fromUniqueId(const QString &uniqueId);

    QString fileName() const;
    quint32 size() const;
    QString md5Sum() const;

    struct Private;
protected:
    Private *d;
};

class TELEGRAMQT_EXPORT DialogInfo
{
public:
    DialogInfo();
    DialogInfo(const DialogInfo &info);
    virtual ~DialogInfo();

    DialogInfo &operator=(const DialogInfo &info);

    quint32 unreadCount() const;
    QString draft() const;
    quint32 lastMessageId() const;
    quint32 readInboxMaxId() const;
    quint32 readOutboxMaxId() const;

    Peer peer() const;
    quint32 muteUntil() const;
    bool isStillMuted() const;

    struct Private;
protected:
    Private *d;
};

class TELEGRAMQT_EXPORT UserInfo
{
public:
    UserInfo();
    UserInfo(const UserInfo &info);
    ~UserInfo();

    UserInfo &operator=(const UserInfo &info);

    QString getBestDisplayName() const;

    quint32 id() const;
    QString firstName() const;
    QString lastName() const;
    QString userName() const;
    QString phone() const;
    TelegramNamespace::ContactStatus status() const;
    quint32 wasOnline() const;
    bool isBot() const;
    bool isSelf() const;
    bool isContact() const;
    bool isMutualContact() const;
    bool isDeleted() const;

    quint32 botVersion() const;
    bool getPeerPicture(RemoteFile *file, PeerPictureSize size = PeerPictureSize::Small) const;

    // See TelegramNamespace::ContactLastOnline enum and a documentation for the contactLastOnline() method in the cpp file.

    struct Private;
protected:
    Private *d;
};

class TELEGRAMQT_EXPORT ChatInfo
{
public:
    ChatInfo();
    ChatInfo(const ChatInfo &info);
    ~ChatInfo();

    ChatInfo &operator=(const ChatInfo &info);

    Peer peer() const;

    QString title() const;
    quint32 participantsCount() const;
    quint32 date() const;
    bool left() const;
    bool broadcast() const;
    Peer migratedTo() const;

    bool getPeerPicture(RemoteFile *file, PeerPictureSize size = PeerPictureSize::Small) const;

    struct Private;
protected:
    Private *d;
};

namespace Utils
{

quint64 maskNumber(quint64 number);
TELEGRAMQT_EXPORT QString maskString(const QString &string);
TELEGRAMQT_EXPORT QByteArray maskByteArray(const QByteArray &data);
QString maskPhoneNumber(const QString &identifier);
QStringList maskPhoneNumber(const QStringList &list);

template <typename T>
T maskPhoneNumber(T container, const QString &key)
{
    if (container.contains(key)) {
        container.insert(key, maskPhoneNumber(container.value(key).toString()));
    }
    return container;
}

TELEGRAMQT_EXPORT QVector<quint32> toIdList(const Telegram::PeerList &peerList);

} // Utils namespace

} // Telegram namespace

Q_DECLARE_METATYPE(Telegram::Peer)
Q_DECLARE_METATYPE(Telegram::Peer::Type)
Q_DECLARE_METATYPE(Telegram::PeerList)
Q_DECLARE_METATYPE(Telegram::DcOption)
Q_DECLARE_METATYPE(Telegram::Message)
Q_DECLARE_METATYPE(Telegram::ChatInfo)
Q_DECLARE_METATYPE(Telegram::RemoteFile)
Q_DECLARE_METATYPE(Telegram::UserInfo)

Q_DECLARE_TYPEINFO(Telegram::DcOption, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::Message, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::ChatInfo, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::RemoteFile, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Telegram::UserInfo, Q_MOVABLE_TYPE);

Q_DECLARE_OPERATORS_FOR_FLAGS(TelegramNamespace::MessageFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(TelegramNamespace::MessageTypeFlags)

#endif // TELEGRAMNAMESPACE_HPP
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Visualization Toolkit
Module:    TestSQLDatabaseSchema.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
  Copyright (c) Sandia Corporation
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
  ----------------------------------------------------------------------------*/
// .SECTION Thanks
// Thanks to Philippe Pebay and David Thompson from Sandia National Laboratories
// for implementing this test.

#include "vtkSQLDatabaseSchema.h"

#include "vtkStdString.h"

#include <vtkstd/set>

int TestSQLDatabaseSchema( int /*argc*/, char* /*argv*/[] )
{
  bool status = true;
  int tblHandle = 0;
  vtkSQLDatabaseSchema* schema = vtkSQLDatabaseSchema::New();

  schema->SetName( "TestSchema" );
  tblHandle = schema->AddTableMultipleArguments( "StrangeTable",
                                                 vtkSQLDatabaseSchema::COLUMN_TOKEN, vtkSQLDatabaseSchema::SERIAL,  "TableKey",  0, "",
                                                 vtkSQLDatabaseSchema::COLUMN_TOKEN, vtkSQLDatabaseSchema::VARCHAR, "SomeName", 11, "NOT NULL",
                                                 vtkSQLDatabaseSchema::COLUMN_TOKEN, vtkSQLDatabaseSchema::BIGINT,  "SomeNmbr", 17, "DEFAULT 0",
                                                 vtkSQLDatabaseSchema::INDEX_TOKEN,  vtkSQLDatabaseSchema::PRIMARY_KEY, "BigKey",
                                                 vtkSQLDatabaseSchema::INDEX_COLUMN_TOKEN, "TableKey",
                                                 vtkSQLDatabaseSchema::END_INDEX_TOKEN,
                                                 vtkSQLDatabaseSchema::INDEX_TOKEN,  vtkSQLDatabaseSchema::UNIQUE, "ReverseLookup",
                                                 vtkSQLDatabaseSchema::INDEX_COLUMN_TOKEN, "SomeName",
                                                 vtkSQLDatabaseSchema::INDEX_COLUMN_TOKEN, "SomeNmbr",
                                                 vtkSQLDatabaseSchema::END_INDEX_TOKEN,
                                                 vtkSQLDatabaseSchema::TRIGGER_TOKEN,  vtkSQLDatabaseSchema::AFTER_INSERT, "InsertTrigger", "INSERT INTO OtherTable ( Value ) VALUES NEW.SomeNmbr",
                                                 vtkSQLDatabaseSchema::END_TABLE_TOKEN
                                                 );

  if ( tblHandle < 0 )
    {
    cerr << "Could not create test schema.\n";
    status = false;
    }

  // Define the correct (reference) columns and types
  vtkstd::set<vtkStdString> colNames;
  colNames.insert( vtkStdString ( "SomeNmbr" ) );
  colNames.insert( vtkStdString ( "SomeName" ) );
  colNames.insert( vtkStdString ( "TableKey" ) );
  vtkstd::set<int> colTypes;
  colTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::BIGINT ) );
  colTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::SERIAL ) );
  colTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::VARCHAR ) );

  // Loop over all columns of the previously created table
  int numCol = schema->GetNumberOfColumnsInTable( tblHandle );
  if ( numCol != 3 )
    {
    cerr << "Read " << numCol << " != 3 columns in test schema.\n";
    status = false;
    }

  for ( int colHandle = 0; colHandle < numCol; ++ colHandle )
    {
    vtkStdString colName = schema->GetColumnNameFromHandle( tblHandle, colHandle );
    cerr << "Column name: "
         << colName
         << "\n";

    vtkstd::set<vtkStdString>::iterator sit = colNames.find( colName );
    if ( sit != colNames.end() )
      {
      colNames.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve column name " << colName  << " from test schema.\n";
      status = false;
      }

    int colType = schema->GetColumnTypeFromHandle( tblHandle, colHandle );
    cerr << "Column type: "
         << colType
         << "\n";

    vtkstd::set<int>::iterator iit = colTypes.find( colType );
    if ( iit != colTypes.end() )
      {
      colTypes.erase ( iit );
      }
    else
      {
      cerr << "Could not retrieve column type " << colType  << " from test schema.\n";
      status = false;
      }
    }

  // Define the correct (reference) indices and types
  vtkstd::set<vtkStdString> idxNames;
  idxNames.insert( vtkStdString ( "BigKey" ) );
  idxNames.insert( vtkStdString ( "ReverseLookup" ) );
  vtkstd::set<int> idxTypes;
  idxTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::PRIMARY_KEY ) );
  idxTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::UNIQUE ) );

  // Loop over all indices of the previously created table
  int numIdx = schema->GetNumberOfIndicesInTable( tblHandle );
  if ( numIdx != 2 )
    {
    cerr << "Read " << numIdx << " != 2 indices in test schema.\n";
    status = false;
    }

  for ( int idxHandle = 0; idxHandle < numIdx; ++ idxHandle )
    {
    vtkStdString idxName = schema->GetIndexNameFromHandle( tblHandle, idxHandle );
    cerr << "Index name: "
         << idxName
         << "\n";

    vtkstd::set<vtkStdString>::iterator sit = idxNames.find( idxName );
    if ( sit != idxNames.end() )
      {
      idxNames.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve index name " << idxName  << " from test schema.\n";
      status = false;
      }

    int idxType = schema->GetIndexTypeFromHandle( tblHandle, idxHandle );
    cerr << "Index type: "
         << idxType
         << "\n";

    vtkstd::set<int>::iterator iit = idxTypes.find( idxType );
    if ( iit != idxTypes.end() )
      {
      idxTypes.erase ( iit );
      }
    else
      {
      cerr << "Could not retrieve index type " << idxType  << " from test schema.\n";
      status = false;
      }
    }

  // Define the correct (reference) triggers and types
  vtkstd::set<vtkStdString> trgNames;
  trgNames.insert( vtkStdString ( "InsertTrigger" ) );
  vtkstd::set<int> trgTypes;
  trgTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::AFTER_INSERT ) );

  // Loop over all triggers of the previously created table
  int numTrg = schema->GetNumberOfTriggersInTable( tblHandle );
  if ( numTrg != 1 )
    {
    cerr << "Read " << numTrg << " != 2 triggers in test schema.\n";
    status = false;
    }

  for ( int trgHandle = 0; trgHandle < numTrg; ++ trgHandle )
    {
    vtkStdString trgName = schema->GetTriggerNameFromHandle( tblHandle, trgHandle );
    cerr << "Trigger name: "
         << trgName
         << "\n";

    vtkstd::set<vtkStdString>::iterator sit = trgNames.find( trgName );
    if ( sit != trgNames.end() )
      {
      trgNames.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve trigger name " << trgName  << " from test schema.\n";
      status = false;
      }

    int trgType = schema->GetTriggerTypeFromHandle( tblHandle, trgHandle );
    cerr << "Trigger type: "
         << trgType
         << "\n";

    vtkstd::set<int>::iterator iit = trgTypes.find( trgType );
    if ( iit != trgTypes.end() )
      {
      trgTypes.erase ( iit );
      }
    else
      {
      cerr << "Could not retrieve trigger type " << trgType  << " from test schema.\n";
      status = false;
      }
    }

  schema->Delete();

  return status ? 0 : 1;
  return 0;
}
<commit_msg>ENH: test trigger actions as well.<commit_after>/*=========================================================================

Program:   Visualization Toolkit
Module:    TestSQLDatabaseSchema.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
  Copyright (c) Sandia Corporation
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
  ----------------------------------------------------------------------------*/
// .SECTION Thanks
// Thanks to Philippe Pebay and David Thompson from Sandia National Laboratories
// for implementing this test.

#include "vtkSQLDatabaseSchema.h"

#include "vtkStdString.h"

#include <vtkstd/set>

int TestSQLDatabaseSchema( int /*argc*/, char* /*argv*/[] )
{
  bool status = true;
  int tblHandle = 0;
  vtkSQLDatabaseSchema* schema = vtkSQLDatabaseSchema::New();

  schema->SetName( "TestSchema" );
  tblHandle = schema->AddTableMultipleArguments( "StrangeTable",
                                                 vtkSQLDatabaseSchema::COLUMN_TOKEN, vtkSQLDatabaseSchema::SERIAL,  "TableKey",  0, "",
                                                 vtkSQLDatabaseSchema::COLUMN_TOKEN, vtkSQLDatabaseSchema::VARCHAR, "SomeName", 11, "NOT NULL",
                                                 vtkSQLDatabaseSchema::COLUMN_TOKEN, vtkSQLDatabaseSchema::BIGINT,  "SomeNmbr", 17, "DEFAULT 0",
                                                 vtkSQLDatabaseSchema::INDEX_TOKEN,  vtkSQLDatabaseSchema::PRIMARY_KEY, "BigKey",
                                                 vtkSQLDatabaseSchema::INDEX_COLUMN_TOKEN, "TableKey",
                                                 vtkSQLDatabaseSchema::END_INDEX_TOKEN,
                                                 vtkSQLDatabaseSchema::INDEX_TOKEN,  vtkSQLDatabaseSchema::UNIQUE, "ReverseLookup",
                                                 vtkSQLDatabaseSchema::INDEX_COLUMN_TOKEN, "SomeName",
                                                 vtkSQLDatabaseSchema::INDEX_COLUMN_TOKEN, "SomeNmbr",
                                                 vtkSQLDatabaseSchema::END_INDEX_TOKEN,
                                                 vtkSQLDatabaseSchema::TRIGGER_TOKEN,  vtkSQLDatabaseSchema::AFTER_INSERT, "InsertTrigger", "INSERT INTO OtherTable ( Value ) VALUES NEW.SomeNmbr",
                                                 vtkSQLDatabaseSchema::END_TABLE_TOKEN
                                                 );

  if ( tblHandle < 0 )
    {
    cerr << "Could not create test schema.\n";
    status = false;
    }

  // Define the correct (reference) columns and types
  vtkstd::set<vtkStdString> colNames;
  colNames.insert( vtkStdString ( "SomeNmbr" ) );
  colNames.insert( vtkStdString ( "SomeName" ) );
  colNames.insert( vtkStdString ( "TableKey" ) );
  vtkstd::set<int> colTypes;
  colTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::BIGINT ) );
  colTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::SERIAL ) );
  colTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::VARCHAR ) );

  // Loop over all columns of the previously created table
  int numCol = schema->GetNumberOfColumnsInTable( tblHandle );
  if ( numCol != 3 )
    {
    cerr << "Read " << numCol << " != 3 columns in test schema.\n";
    status = false;
    }

  for ( int colHandle = 0; colHandle < numCol; ++ colHandle )
    {
    vtkStdString colName = schema->GetColumnNameFromHandle( tblHandle, colHandle );
    cerr << "Column name: "
         << colName
         << "\n";

    vtkstd::set<vtkStdString>::iterator sit = colNames.find( colName );
    if ( sit != colNames.end() )
      {
      colNames.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve column name " << colName  << " from test schema.\n";
      status = false;
      }

    int colType = schema->GetColumnTypeFromHandle( tblHandle, colHandle );
    cerr << "Column type: "
         << colType
         << "\n";

    vtkstd::set<int>::iterator iit = colTypes.find( colType );
    if ( iit != colTypes.end() )
      {
      colTypes.erase ( iit );
      }
    else
      {
      cerr << "Could not retrieve column type " << colType  << " from test schema.\n";
      status = false;
      }
    }

  // Define the correct (reference) indices and types
  vtkstd::set<vtkStdString> idxNames;
  idxNames.insert( vtkStdString ( "BigKey" ) );
  idxNames.insert( vtkStdString ( "ReverseLookup" ) );
  vtkstd::set<int> idxTypes;
  idxTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::PRIMARY_KEY ) );
  idxTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::UNIQUE ) );

  // Loop over all indices of the previously created table
  int numIdx = schema->GetNumberOfIndicesInTable( tblHandle );
  if ( numIdx != 2 )
    {
    cerr << "Read " << numIdx << " != 2 indices in test schema.\n";
    status = false;
    }

  for ( int idxHandle = 0; idxHandle < numIdx; ++ idxHandle )
    {
    vtkStdString idxName = schema->GetIndexNameFromHandle( tblHandle, idxHandle );
    cerr << "Index name: "
         << idxName
         << "\n";

    vtkstd::set<vtkStdString>::iterator sit = idxNames.find( idxName );
    if ( sit != idxNames.end() )
      {
      idxNames.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve index name " << idxName  << " from test schema.\n";
      status = false;
      }

    int idxType = schema->GetIndexTypeFromHandle( tblHandle, idxHandle );
    cerr << "Index type: "
         << idxType
         << "\n";

    vtkstd::set<int>::iterator iit = idxTypes.find( idxType );
    if ( iit != idxTypes.end() )
      {
      idxTypes.erase ( iit );
      }
    else
      {
      cerr << "Could not retrieve index type " << idxType  << " from test schema.\n";
      status = false;
      }
    }

  // Define the correct (reference) triggers and types
  vtkstd::set<vtkStdString> trgNames;
  trgNames.insert( vtkStdString ( "InsertTrigger" ) );
  vtkstd::set<int> trgTypes;
  trgTypes.insert( static_cast<int>( vtkSQLDatabaseSchema::AFTER_INSERT ) );
  vtkstd::set<vtkStdString> trgActions;
  trgActions.insert( vtkStdString( "INSERT INTO OtherTable ( Value ) VALUES NEW.SomeNmbr" ) );

  // Loop over all triggers of the previously created table
  int numTrg = schema->GetNumberOfTriggersInTable( tblHandle );
  if ( numTrg != 1 )
    {
    cerr << "Read " << numTrg << " != 2 triggers in test schema.\n";
    status = false;
    }

  for ( int trgHandle = 0; trgHandle < numTrg; ++ trgHandle )
    {
    vtkStdString trgName = schema->GetTriggerNameFromHandle( tblHandle, trgHandle );
    cerr << "Trigger name: "
         << trgName
         << "\n";

    vtkstd::set<vtkStdString>::iterator sit = trgNames.find( trgName );
    if ( sit != trgNames.end() )
      {
      trgNames.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve trigger name " << trgName  << " from test schema.\n";
      status = false;
      }

    int trgType = schema->GetTriggerTypeFromHandle( tblHandle, trgHandle );
    cerr << "Trigger type: "
         << trgType
         << "\n";

    vtkstd::set<int>::iterator iit = trgTypes.find( trgType );
    if ( iit != trgTypes.end() )
      {
      trgTypes.erase ( iit );
      }
    else
      {
      cerr << "Could not retrieve trigger type " << trgType  << " from test schema.\n";
      status = false;
      }

    vtkStdString trgAction = schema->GetTriggerActionFromHandle( tblHandle, trgHandle );
    cerr << "Trigger action: "
         << trgAction
         << "\n";

    sit = trgActions.find( trgAction );
    if ( sit != trgActions.end() )
      {
      trgActions.erase ( sit );
      }
    else
      {
      cerr << "Could not retrieve trigger action " << trgAction  << " from test schema.\n";
      status = false;
      }
    }

  schema->Delete();

  return status ? 0 : 1;
  return 0;
}
<|endoftext|>


<commit_before>#include "bufferAgent.h"

using boost::shared_ptr;
using boost::thread;
using boost::bind;

using std::string;

namespace veil {
namespace helpers {

BufferAgent::BufferAgent(write_fun w, read_fun r)
  : m_agentActive(false),
    doWrite(w),
    doRead(r)
{
    agentStart();
}
BufferAgent::~BufferAgent()
{
    agentStop();
}

int BufferAgent::onOpen(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);

    buffer_ptr lCache(new LockableCache());
    lCache->fileName = path;
    lCache->buffer = newFileCache();
    lCache->ffi = *ffi;

    m_cacheMap[ffi->fh] = lCache;

    return 0;
}

int BufferAgent::onWrite(std::string path, const std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->byteSize() > 1024 * 1024 * 10) {
        wrapper->cond.wait(buff_guard);
    }

    wrapper->buffer->writeData(offset, buf);

    guard.lock();
    m_jobQueue.push_back(ffi->fh);

    return size;
}

int BufferAgent::onRead(std::string path, std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    return EOPNOTSUPP;
}

int BufferAgent::onFlush(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->blockCount() > 0)
    {
        block_ptr block = wrapper->buffer->removeOldestBlock();
        int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);
        if(res < 0)
        {
            while(wrapper->buffer->blockCount() > 0)
            {
                (void) wrapper->buffer->removeOldestBlock();
            }
            return res;
        }
    }

    guard.lock();
    m_jobQueue.remove(ffi->fh);

    return 0;
}

int BufferAgent::onRelease(std::string path, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);

    return 0;
}

void BufferAgent::agentStart(int worker_count)
{
    m_workers.clear();
    m_agentActive = true;

    while(worker_count--)
    {
        m_workers.push_back(shared_ptr<thread>(new thread(bind(&BufferAgent::workerLoop, this))));
    }
}

void BufferAgent::agentStop()
{
    m_agentActive = false;
    m_loopCond.notify_all();
    while(m_workers.size() > 0)
    {
        m_workers.back()->join();
        m_workers.pop_back();
    }
}

void BufferAgent::workerLoop()
{
    unique_lock guard(m_loopMutex);
    while(m_agentActive)
    {
        while(m_jobQueue.empty() && m_agentActive)
            m_loopCond.wait(guard);

        if(!m_agentActive)
            return;

        fd_type file = m_jobQueue.front();
        buffer_ptr wrapper = m_cacheMap[file];
        m_jobQueue.pop_front();
        m_loopCond.notify_all();

        if(!wrapper)
            continue;

        {
            guard.unlock();

            unique_lock buff_guard(wrapper->mutex);

            block_ptr block = wrapper->buffer->removeOldestBlock();
            int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);

            wrapper->cond.notify_all();

            guard.lock();
            if(wrapper->buffer->blockCount() > 0)
            {
                m_jobQueue.push_back(file);
            }
        }

    }
}

boost::shared_ptr<FileCache> BufferAgent::newFileCache()
{
    return boost::shared_ptr<FileCache>(new FileCache(100 * 1024));
}

} // namespace helpers
} // namespace veil

<commit_msg>VFS-292: debug<commit_after>#include "bufferAgent.h"

using boost::shared_ptr;
using boost::thread;
using boost::bind;

using std::string;

namespace veil {
namespace helpers {

BufferAgent::BufferAgent(write_fun w, read_fun r)
  : m_agentActive(false),
    doWrite(w),
    doRead(r)
{
    agentStart();
}
BufferAgent::~BufferAgent()
{
    agentStop();
}

int BufferAgent::onOpen(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);

    buffer_ptr lCache(new LockableCache());
    lCache->fileName = path;
    lCache->buffer = newFileCache();
    lCache->ffi = *ffi;

    m_cacheMap[ffi->fh] = lCache;

    return 0;
}

int BufferAgent::onWrite(std::string path, const std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->byteSize() > 1024 * 1024 * 10) {
        wrapper->cond.wait(buff_guard);
    }

    wrapper->buffer->writeData(offset, buf);

    guard.lock();
    m_jobQueue.push_back(ffi->fh);

    return size;
}

int BufferAgent::onRead(std::string path, std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    return EOPNOTSUPP;
}

int BufferAgent::onFlush(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->blockCount() > 0)
    {
        block_ptr block = wrapper->buffer->removeOldestBlock();
        int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);
        if(res < 0)
        {
            while(wrapper->buffer->blockCount() > 0)
            {
                (void) wrapper->buffer->removeOldestBlock();
            }
            return res;
        }
    }

    guard.lock();
    m_jobQueue.remove(ffi->fh);

    return 0;
}

int BufferAgent::onRelease(std::string path, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);

    return 0;
}

void BufferAgent::agentStart(int worker_count)
{
    m_workers.clear();
    m_agentActive = true;

    while(worker_count--)
    {
        m_workers.push_back(shared_ptr<thread>(new thread(bind(&BufferAgent::workerLoop, this))));
    }
}

void BufferAgent::agentStop()
{
    m_agentActive = false;
    m_loopCond.notify_all();
    while(m_workers.size() > 0)
    {
        m_workers.back()->join();
        m_workers.pop_back();
    }
}

void BufferAgent::workerLoop()
{
    unique_lock guard(m_loopMutex);
    while(m_agentActive)
    {
        guard.lock();

        while(m_jobQueue.empty() && m_agentActive)
            m_loopCond.wait(guard);

        if(!m_agentActive)
            return;

        fd_type file = m_jobQueue.front();
        buffer_ptr wrapper = m_cacheMap[file];
        m_jobQueue.pop_front();
        m_loopCond.notify_all();

        if(!wrapper)
            continue;

        {
            guard.unlock();

            unique_lock buff_guard(wrapper->mutex);

            block_ptr block = wrapper->buffer->removeOldestBlock();
            if(!block)
                continue;

            int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);

            wrapper->cond.notify_all();

            guard.lock();
            if(wrapper->buffer->blockCount() > 0)
            {
                m_jobQueue.push_back(file);
            }
        }

    }
}

boost::shared_ptr<FileCache> BufferAgent::newFileCache()
{
    return boost::shared_ptr<FileCache>(new FileCache(100 * 1024));
}

} // namespace helpers
} // namespace veil

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "PostConstructTest.h"
#include "Autowired.h"
#include "ContextMember.h"

using namespace std;

class ContextExposer:
  public CoreContext
{
public:
  size_t DeferredCount(void) const {return CoreContext::m_deferred.size();}
};

// Two classes to make up the cyclic dependency:
class A:
  public ContextMember
{
public:
  A(void):
    m_value(2)
  {}

  int m_value;

  int GetValue(void) const {return m_value;}
};

class Naive:
  public ContextMember
{
public:
  Naive(void) {
    if(!m_a)
      throw exception();
  }

  Autowired<A> m_a;
};

class Smarter:
  public ContextMember
{
public:
  Smarter(void):
    value(1)
  {
#if LAMBDAS_AVAILABLE
    m_a.NotifyWhenAutowired([this] () {
      this->value = m_a->GetValue();
    });
#endif
  }

  int value;
  Autowired<A> m_a;
};

TEST_F(PostConstructTest, VerifyNaiveBehavior) {
  // Create a context and add just the naive class, to verify the problematic behavior:
  cpp11::shared_ptr<CoreContext> subContext = CoreContext::CurrentContext()->Create();
  EXPECT_THROW(subContext->Add<Naive>(), std::exception) << "Naive class didn't throw an exception as expected";
}

TEST_F(PostConstructTest, VerifyExpectedDeferrmentCount) {
  cpp11::shared_ptr<CoreContext> subContext = CoreContext::CurrentContext()->Create();
  CurrentContextPusher cur(subContext);

  // Add the smart class, which should introduce a single deferred count:
  subContext->Add<Smarter>();

  // Now test the count:
  EXPECT_EQ(
    1,
    ((ContextExposer&)*subContext).DeferredCount()
  ) << "Unexpected number of deferred initializers";
}

TEST_F(PostConstructTest, VerifySmartBehavior) {
  // These tests are only eabled where C++11 is present, because they are somewhat complicated to implement without it.
  if(!LAMBDAS_AVAILABLE)
    return;

  cpp11::shared_ptr<CoreContext> subContext = CoreContext::CurrentContext()->Create();
  CurrentContextPusher cur(subContext);

  // Add the smart class, which should allow
  subContext->Add<Smarter>();

  // Initially, value should be one, which is the default
  Autowired<Smarter> smarter;
  EXPECT_EQ(1, smarter->value) << "Unexpected initial value of Smarter instance";

  // Now we add A and check the wiring
  subContext->Add<A>();
  EXPECT_FALSE(!smarter->m_a.get()) << "Autowired member was not wired as expected";

  // Verify the value was updated by the notification routine
  EXPECT_EQ(2, smarter->value) << "Post-construction notification routine wasn't invoked as expected";
}
<commit_msg>Corrected signed/unsigned comparison on MSVC<commit_after>#include "stdafx.h"
#include "PostConstructTest.h"
#include "Autowired.h"
#include "ContextMember.h"

using namespace std;

class ContextExposer:
  public CoreContext
{
public:
  size_t DeferredCount(void) const {return CoreContext::m_deferred.size();}
};

// Two classes to make up the cyclic dependency:
class A:
  public ContextMember
{
public:
  A(void):
    m_value(2)
  {}

  int m_value;

  int GetValue(void) const {return m_value;}
};

class Naive:
  public ContextMember
{
public:
  Naive(void) {
    if(!m_a)
      throw exception();
  }

  Autowired<A> m_a;
};

class Smarter:
  public ContextMember
{
public:
  Smarter(void):
    value(1)
  {
#if LAMBDAS_AVAILABLE
    m_a.NotifyWhenAutowired([this] () {
      this->value = m_a->GetValue();
    });
#endif
  }

  int value;
  Autowired<A> m_a;
};

TEST_F(PostConstructTest, VerifyNaiveBehavior) {
  // Create a context and add just the naive class, to verify the problematic behavior:
  cpp11::shared_ptr<CoreContext> subContext = CoreContext::CurrentContext()->Create();
  EXPECT_THROW(subContext->Add<Naive>(), std::exception) << "Naive class didn't throw an exception as expected";
}

TEST_F(PostConstructTest, VerifyExpectedDeferrmentCount) {
  cpp11::shared_ptr<CoreContext> subContext = CoreContext::CurrentContext()->Create();
  CurrentContextPusher cur(subContext);

  // Add the smart class, which should introduce a single deferred count:
  subContext->Add<Smarter>();

  // Now test the count:
  EXPECT_EQ(
    1UL,
    ((ContextExposer&)*subContext).DeferredCount()
  ) << "Unexpected number of deferred initializers";
}

TEST_F(PostConstructTest, VerifySmartBehavior) {
  // These tests are only eabled where C++11 is present, because they are somewhat complicated to implement without it.
  if(!LAMBDAS_AVAILABLE)
    return;

  cpp11::shared_ptr<CoreContext> subContext = CoreContext::CurrentContext()->Create();
  CurrentContextPusher cur(subContext);

  // Add the smart class, which should allow
  subContext->Add<Smarter>();

  // Initially, value should be one, which is the default
  Autowired<Smarter> smarter;
  EXPECT_EQ(1, smarter->value) << "Unexpected initial value of Smarter instance";

  // Now we add A and check the wiring
  subContext->Add<A>();
  EXPECT_FALSE(!smarter->m_a.get()) << "Autowired member was not wired as expected";

  // Verify the value was updated by the notification routine
  EXPECT_EQ(2, smarter->value) << "Post-construction notification routine wasn't invoked as expected";
}
<|endoftext|>


<commit_before>#ifndef INCLUDE_AL_OPENGL_HPP
#define INCLUDE_AL_OPENGL_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	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 the University of California 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 HOLDER 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.

	File description:
	Platform-specific header includes for OpenGL

	File author(s):
	Lance Putnam, 2011, putnam.lance@gmail.com
*/

#include "allocore/system/al_Config.h"

#if !(defined(AL_GRAPHICS_USE_DEFAULT_BACKEND) || defined(AL_GRAPHICS_USE_OPENGL) || defined(AL_GRAPHICS_USE_OPENGLES1) || defined(AL_GRAPHICS_USE_OPENGLES2))
	#define AL_GRAPHICS_USE_DEFAULT_BACKEND
#endif

#if defined AL_OSX
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGL
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGL
		#include <OpenGL/OpenGL.h>
		#include <OpenGL/gl.h>
		#include <OpenGL/glext.h>
		#define AL_GRAPHICS_INIT_CONTEXT
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined AL_LINUX
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGL
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGL
		#include <GL/glew.h> // needed for certain parts of OpenGL API
		#include <GL/gl.h>
		#include <GL/glext.h>
		#include <time.h>
		#define AL_GRAPHICS_INIT_CONTEXT\
			{	GLenum err = glewInit();\
				if (GLEW_OK != err){\
					/* Problem: glewInit failed, something is seriously wrong. */\
					fprintf(stderr, "GLEW Init Error: %s\n", glewGetErrorString(err));\
				}\
			}
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined AL_WINDOWS
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGL
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGL
		#include <GL/glew.h> // needed for certain parts of OpenGL API
		#include <GL/gl.h>
		#pragma comment( lib, "winmm.lib")
		#pragma comment( lib, "opengl32.lib" )
		#define AL_GRAPHICS_IsNIT_CONTEXT\
			{	GLenum err = glewInit();\
				if (GLEW_OK != err){\
					/* Problem: glewInit failed, something is seriously wrong. */\
					fprintf(stderr, "GLEW Init Error: %s\n", glewGetErrorString(err));\
				}\
			}
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined AL_EMSCRIPTEN
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGLES2
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGLES2
		//#define GL_GLEXT_PROTOTYPES 1
		#include <GLES2/gl2.h>
		//#include <GLES2/gl2ext.h> // just include core API for now
		#define AL_GRAPHICS_INIT_CONTEXT
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined __IPHONE_2_0
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGLES1
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGLES1
		#import <OpenGLES/ES1/gl.h>
		#import <OpenGLES/ES1/glext.h>
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined __IPHONE_3_0
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGLES2
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGLES2
		#import <OpenGLES/ES2/gl.h>
		#import <OpenGLES/ES2/glext.h>
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#endif // platform-specific

#endif /* include guard */
<commit_msg>Fix typo<commit_after>#ifndef INCLUDE_AL_OPENGL_HPP
#define INCLUDE_AL_OPENGL_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	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 the University of California 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 HOLDER 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.

	File description:
	Platform-specific header includes for OpenGL

	File author(s):
	Lance Putnam, 2011, putnam.lance@gmail.com
*/

#include "allocore/system/al_Config.h"

#if !(defined(AL_GRAPHICS_USE_DEFAULT_BACKEND) || defined(AL_GRAPHICS_USE_OPENGL) || defined(AL_GRAPHICS_USE_OPENGLES1) || defined(AL_GRAPHICS_USE_OPENGLES2))
	#define AL_GRAPHICS_USE_DEFAULT_BACKEND
#endif

#if defined AL_OSX
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGL
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGL
		#include <OpenGL/OpenGL.h>
		#include <OpenGL/gl.h>
		#include <OpenGL/glext.h>
		#define AL_GRAPHICS_INIT_CONTEXT
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined AL_LINUX
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGL
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGL
		#include <GL/glew.h> // needed for certain parts of OpenGL API
		#include <GL/gl.h>
		#include <GL/glext.h>
		#include <time.h>
		#define AL_GRAPHICS_INIT_CONTEXT\
			{	GLenum err = glewInit();\
				if (GLEW_OK != err){\
					/* Problem: glewInit failed, something is seriously wrong. */\
					fprintf(stderr, "GLEW Init Error: %s\n", glewGetErrorString(err));\
				}\
			}
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined AL_WINDOWS
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGL
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGL
		#include <GL/glew.h> // needed for certain parts of OpenGL API
		#include <GL/gl.h>
		#pragma comment( lib, "winmm.lib")
		#pragma comment( lib, "opengl32.lib" )
		#define AL_GRAPHICS_INIT_CONTEXT\
			{	GLenum err = glewInit();\
				if (GLEW_OK != err){\
					/* Problem: glewInit failed, something is seriously wrong. */\
					fprintf(stderr, "GLEW Init Error: %s\n", glewGetErrorString(err));\
				}\
			}
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined AL_EMSCRIPTEN
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGLES2
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGLES2
		//#define GL_GLEXT_PROTOTYPES 1
		#include <GLES2/gl2.h>
		//#include <GLES2/gl2ext.h> // just include core API for now
		#define AL_GRAPHICS_INIT_CONTEXT
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined __IPHONE_2_0
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGLES1
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGLES1
		#import <OpenGLES/ES1/gl.h>
		#import <OpenGLES/ES1/glext.h>
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#elif defined __IPHONE_3_0
	#ifdef AL_GRAPHICS_USE_DEFAULT_BACKEND
		#define AL_GRAPHICS_USE_OPENGLES2
	#endif
	#ifdef AL_GRAPHICS_USE_OPENGLES2
		#import <OpenGLES/ES2/gl.h>
		#import <OpenGLES/ES2/glext.h>
	#else
		#error "Specified graphics backend not supported on this platform"
	#endif

#endif // platform-specific

#endif /* include guard */
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"

/*
  Format a date expressed in "UNIX time" into "month/day hour:minute".
*/
char *
format_date( time_t date )
{
    static char buf[ 12 ];
    struct tm   *tm;

	if (date<0) {
		strcpy(buf,"    ???    ");
		return buf;
	}

    tm = localtime( &date );
    sprintf( buf, "%2d/%-2d %02d:%02d",
        (tm->tm_mon)+1, tm->tm_mday, tm->tm_hour, tm->tm_min
    );
    return buf;
}

/*
  Format a date expressed in "UNIX time" into "month/day/year hour:minute".
*/
char *
format_date_year( time_t date )
{
    static char buf[ 15 ];
    struct tm   *tm;

	if (date<0) {
		strcpy(buf,"    ???    ");
		return buf;
	}

    tm = localtime( &date );
    sprintf( buf, "%2d/%02d/%-4d %02d:%02d",
        (tm->tm_mon)+1, tm->tm_mday, (tm->tm_year + 1900), tm->tm_hour, tm->tm_min
    );
    return buf;
}

/*
  Format a time value which is encoded as seconds since the UNIX
  "epoch".  We return a string in the format dd+hh:mm:ss, indicating
  days, hours, minutes, and seconds.  The string is in static data
  space, and will be overwritten by the next call to this function.
*/
char    *
format_time( int tot_secs )
{
    int     days;
    int     hours;
    int     min;
    int     secs;
    static char answer[25];

	if ( tot_secs < 0 ) {
		sprintf(answer,"[?????]");
		return answer;
	}

    days = tot_secs / DAY;
    tot_secs %= DAY;
    hours = tot_secs / HOUR;
    tot_secs %= HOUR;
    min = tot_secs / MINUTE;
    secs = tot_secs % MINUTE;

    (void)sprintf( answer, "%3d+%02d:%02d:%02d", days, hours, min, secs );
    return answer;
}

/*
  Same as format_time above but don't print seconds field.
*/
char    *
format_time_nosecs( int tot_secs )
{
    int     days;
    int     hours;
    int     min;
    static char answer[25];

	if ( tot_secs < 0 ) {
		sprintf(answer,"[?????]");
		return answer;
	}

    days = tot_secs / DAY;
    tot_secs %= DAY;
    hours = tot_secs / HOUR;
    tot_secs %= HOUR;
    min = tot_secs / MINUTE;

    (void)sprintf( answer, "%3d+%02d:%02d", days, hours, min );
    return answer;
}

<commit_msg>There was a buffer overflow when printing the time into a small char array. I upped the size of the array.<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"

/*
  Format a date expressed in "UNIX time" into "month/day hour:minute".
*/
char *
format_date( time_t date )
{
    static char buf[ 12 ];
    struct tm   *tm;

	if (date<0) {
		strcpy(buf,"    ???    ");
		return buf;
	}

    tm = localtime( &date );
    sprintf( buf, "%2d/%-2d %02d:%02d",
        (tm->tm_mon)+1, tm->tm_mday, tm->tm_hour, tm->tm_min
    );
    return buf;
}

/*
  Format a date expressed in "UNIX time" into "month/day/year hour:minute".
*/
char *
format_date_year( time_t date )
{
    static char buf[ 18 ];
    struct tm   *tm;

	if (date<0) {
		strcpy(buf,"    ???    ");
		return buf;
	}

    tm = localtime( &date );
    sprintf( buf, "%2d/%02d/%-4d %02d:%02d",
        (tm->tm_mon)+1, tm->tm_mday, (tm->tm_year + 1900), tm->tm_hour, tm->tm_min
    );
    return buf;
}

/*
  Format a time value which is encoded as seconds since the UNIX
  "epoch".  We return a string in the format dd+hh:mm:ss, indicating
  days, hours, minutes, and seconds.  The string is in static data
  space, and will be overwritten by the next call to this function.
*/
char    *
format_time( int tot_secs )
{
    int     days;
    int     hours;
    int     min;
    int     secs;
    static char answer[25];

	if ( tot_secs < 0 ) {
		sprintf(answer,"[?????]");
		return answer;
	}

    days = tot_secs / DAY;
    tot_secs %= DAY;
    hours = tot_secs / HOUR;
    tot_secs %= HOUR;
    min = tot_secs / MINUTE;
    secs = tot_secs % MINUTE;

    (void)sprintf( answer, "%3d+%02d:%02d:%02d", days, hours, min, secs );
    return answer;
}

/*
  Same as format_time above but don't print seconds field.
*/
char    *
format_time_nosecs( int tot_secs )
{
    int     days;
    int     hours;
    int     min;
    static char answer[25];

	if ( tot_secs < 0 ) {
		sprintf(answer,"[?????]");
		return answer;
	}

    days = tot_secs / DAY;
    tot_secs %= DAY;
    hours = tot_secs / HOUR;
    tot_secs %= HOUR;
    min = tot_secs / MINUTE;

    (void)sprintf( answer, "%3d+%02d:%02d", days, hours, min );
    return answer;
}

<|endoftext|>