<commit_before>#include <QMainWindow>
#include <QFileDialog>
#include <QString>
#include <QBoxLayout>
#include <QLabel>
#include <QMessageBox>

#include "mainwindow.h"
#include "parser/htmlreader.h"
#include "painter/paintarea.h"

#define WINDOW_HEIGHT 480

MainWindow::MainWindow()
{
    reader = new HTMLReader;
    webpage = new Document;

    //Draw main window for WebWhirr.
    setMinimumHeight(WINDOW_HEIGHT);
    setMaximumHeight(WINDOW_HEIGHT);

    positionSet = false;

    QLabel *addressBarLabel = new QLabel(tr("Current Document:"));
    addressBar = new QLineEdit;
    addressBar->setReadOnly(true);

    QHBoxLayout *addressBarLayout = new QHBoxLayout;
    addressBarLayout->addWidget(addressBarLabel);
    addressBarLayout->addWidget(addressBar);

    paintArea = new PaintArea;
    scrollArea = new QScrollArea(this);
    documentDisplay = new QLabel(scrollArea);

    documentDisplay->setAlignment(Qt::AlignTop | Qt::AlignLeft);

    scrollArea->setWidget(documentDisplay);
    scrollArea->setWidgetResizable(true);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addLayout(addressBarLayout);
    layout->addWidget(scrollArea);

    centralLayout = new QWidget;
    centralLayout->setLayout(layout);

    setCentralWidget(centralLayout);

    createActions();
    createMenus();

    setWindowTitle("WebWhirr 0.1.0 Beta");

}

void MainWindow::createActions()
{
    openAct = new QAction(tr("&Open"), this);
    openAct->setShortcut(QKeySequence::Open);

    connect(openAct, SIGNAL(triggered()), this, SLOT(setFilepath()));
}

void MainWindow::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(openAct);
}

bool MainWindow::setFilepath(std::string filepath)
{
    if (!checkFilepath(filepath))
    {
        return false;
    }
    else
    {
        //Construct a Document (contains node tree) from parsing document
        //passed from command line.
        webpage = reader->prepareDocument(filepath);
        addressBar->setText(QString::fromStdString(filepath));

        paintArea->setDocument(webpage);
    }

    return true;
}

bool MainWindow::setFilepath()
{
    //QString::toStdString() doesn't convert the filepath properly
    std::string filepath = QFileDialog::getOpenFileName(this,
                                                        tr("Open HTML Document")).toUtf8().constData();
    if (filepath.empty())
    {
        return false;
    }

    if (!checkFilepath(filepath))
    {
        QMessageBox invalidTypeErrorBox;
        invalidTypeErrorBox.setText("Error: Document type is invalid or not supported.");
        invalidTypeErrorBox.exec();
        return false;
    }

    else
    {
        //Delete any old nodes to avoid memory leaks.
        if (webpage->getFirstNode() != NULL)
        {
            webpage->clearTree();
        }

        addressBar->setText(QString::fromStdString(filepath));

        //Construct a Document (contains node tree) from parsing document
        //selected in "Open HTML Document" dialog.
        webpage = reader->prepareDocument(filepath);

        paintArea->setDocument(webpage);

        return repaintDocument();
    }
}

//This entire function is a mess. I will return and work
//on it more after the 0.1.0 release.
bool MainWindow::repaintDocument()
{
    //Paint the current document in paintArea by creating a QPixmap
    //and assigning this to the QLabel documentDisplay. Dimensions
    //are also set to avoid annoying issues with the scrollbars.
    QPixmap paintedDocument;

    //grab() has to be called twice. Otherwise, the pixmap is the wrong
    //size when the document is first displayed and the document has to
    //be opened twice in order to scroll through it properly.
    paintedDocument = paintArea->grab();
    paintedDocument.scaled(paintArea->size(), Qt::IgnoreAspectRatio);
    paintedDocument = paintArea->grab();

    documentDisplay->setMinimumWidth(paintedDocument.width());
    documentDisplay->setMaximumWidth(paintedDocument.width());
    documentDisplay->setMaximumHeight(paintArea->height());

    documentDisplay->setPixmap(paintedDocument);
    scrollArea->setMinimumWidth(documentDisplay->width() + 20);
    this->setMinimumWidth(scrollArea->width() + 20);
    this->setMaximumWidth(scrollArea->width() + 20);

    return true;
}

bool MainWindow::checkFilepath(std::string filepath)
{
    //This is a fix for the crash on opening a non-HTML document.
    //It will have to do until I write a check into the encoding,
    //because for some reason a similar check in the document text
    //itself always returns true.
    if (filepath.find(".html") != std::string::npos ||
            filepath.find(".htm") != std::string::npos)
    {
        return true;
    }

    return false;
}

Document* MainWindow::getWebpage()
{
    return webpage;
}
<commit_msg>Update name in title bar to WebWhirr 0.1.0 instead of WebWhirr 0.1.0 Beta.<commit_after>#include <QMainWindow>
#include <QFileDialog>
#include <QString>
#include <QBoxLayout>
#include <QLabel>
#include <QMessageBox>

#include "mainwindow.h"
#include "parser/htmlreader.h"
#include "painter/paintarea.h"

#define WINDOW_HEIGHT 480

MainWindow::MainWindow()
{
    reader = new HTMLReader;
    webpage = new Document;

    //Draw main window for WebWhirr.
    setMinimumHeight(WINDOW_HEIGHT);
    setMaximumHeight(WINDOW_HEIGHT);

    positionSet = false;

    QLabel *addressBarLabel = new QLabel(tr("Current Document:"));
    addressBar = new QLineEdit;
    addressBar->setReadOnly(true);

    QHBoxLayout *addressBarLayout = new QHBoxLayout;
    addressBarLayout->addWidget(addressBarLabel);
    addressBarLayout->addWidget(addressBar);

    paintArea = new PaintArea;
    scrollArea = new QScrollArea(this);
    documentDisplay = new QLabel(scrollArea);

    documentDisplay->setAlignment(Qt::AlignTop | Qt::AlignLeft);

    scrollArea->setWidget(documentDisplay);
    scrollArea->setWidgetResizable(true);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addLayout(addressBarLayout);
    layout->addWidget(scrollArea);

    centralLayout = new QWidget;
    centralLayout->setLayout(layout);

    setCentralWidget(centralLayout);

    createActions();
    createMenus();

    setWindowTitle("WebWhirr 0.1.0");

}

void MainWindow::createActions()
{
    openAct = new QAction(tr("&Open"), this);
    openAct->setShortcut(QKeySequence::Open);

    connect(openAct, SIGNAL(triggered()), this, SLOT(setFilepath()));
}

void MainWindow::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(openAct);
}

bool MainWindow::setFilepath(std::string filepath)
{
    if (!checkFilepath(filepath))
    {
        return false;
    }
    else
    {
        //Construct a Document (contains node tree) from parsing document
        //passed from command line.
        webpage = reader->prepareDocument(filepath);
        addressBar->setText(QString::fromStdString(filepath));

        paintArea->setDocument(webpage);
    }

    return true;
}

bool MainWindow::setFilepath()
{
    //QString::toStdString() doesn't convert the filepath properly
    std::string filepath = QFileDialog::getOpenFileName(this,
                                                        tr("Open HTML Document")).toUtf8().constData();
    if (filepath.empty())
    {
        return false;
    }

    if (!checkFilepath(filepath))
    {
        QMessageBox invalidTypeErrorBox;
        invalidTypeErrorBox.setText("Error: Document type is invalid or not supported.");
        invalidTypeErrorBox.exec();
        return false;
    }

    else
    {
        //Delete any old nodes to avoid memory leaks.
        if (webpage->getFirstNode() != NULL)
        {
            webpage->clearTree();
        }

        addressBar->setText(QString::fromStdString(filepath));

        //Construct a Document (contains node tree) from parsing document
        //selected in "Open HTML Document" dialog.
        webpage = reader->prepareDocument(filepath);

        paintArea->setDocument(webpage);

        return repaintDocument();
    }
}

//This entire function is a mess. I will return and work
//on it more after the 0.1.0 release.
bool MainWindow::repaintDocument()
{
    //Paint the current document in paintArea by creating a QPixmap
    //and assigning this to the QLabel documentDisplay. Dimensions
    //are also set to avoid annoying issues with the scrollbars.
    QPixmap paintedDocument;

    //grab() has to be called twice. Otherwise, the pixmap is the wrong
    //size when the document is first displayed and the document has to
    //be opened twice in order to scroll through it properly.
    paintedDocument = paintArea->grab();
    paintedDocument.scaled(paintArea->size(), Qt::IgnoreAspectRatio);
    paintedDocument = paintArea->grab();

    documentDisplay->setMinimumWidth(paintedDocument.width());
    documentDisplay->setMaximumWidth(paintedDocument.width());
    documentDisplay->setMaximumHeight(paintArea->height());

    documentDisplay->setPixmap(paintedDocument);
    scrollArea->setMinimumWidth(documentDisplay->width() + 20);
    this->setMinimumWidth(scrollArea->width() + 20);
    this->setMaximumWidth(scrollArea->width() + 20);

    return true;
}

bool MainWindow::checkFilepath(std::string filepath)
{
    //This is a fix for the crash on opening a non-HTML document.
    //It will have to do until I write a check into the encoding,
    //because for some reason a similar check in the document text
    //itself always returns true.
    if (filepath.find(".html") != std::string::npos ||
            filepath.find(".htm") != std::string::npos)
    {
        return true;
    }

    return false;
}

Document* MainWindow::getWebpage()
{
    return webpage;
}
<|endoftext|>


<commit_before>#include <io/network/tcpSocket.h>
#include <logging.h>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
static constexpr int flags = 0;

static inline int send(SOCKET s, const void* msg, size_t len, int flags)
{
    return send(s, static_cast<const char*>(msg), static_cast<int>(len), flags);
}

static inline int recv(SOCKET s, void* buf, size_t len, int flags)
{
    return recv(s, static_cast<char*>(buf), static_cast<int>(len), flags);
}

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <string.h>
static constexpr int flags = MSG_NOSIGNAL;
static constexpr intptr_t INVALID_SOCKET = -1;
#endif

extern "C" {
    struct X509;
    struct X509_STORE;
    struct SSL_CTX;
    struct SSL_METHOD;
    struct SSL;

    static X509_STORE* (*X509_STORE_new)();
    static X509* (*d2i_X509)(X509**, const unsigned char **, long);
    static int (*X509_STORE_add_cert)(X509_STORE*, X509*);
    static void (*X509_free)(X509*);
    static SSL_CTX* (*SSL_CTX_new)(const SSL_METHOD*);
    static const SSL_METHOD* (*TLSv1_2_client_method)();
    static long (*SSL_CTX_set_options)(SSL_CTX*, long);
    static int (*SSL_CTX_set_default_verify_paths)(SSL_CTX*);
    static void (*SSL_CTX_set_cert_store)(SSL_CTX*, X509_STORE*);
    static SSL* (*SSL_new)(SSL_CTX*);
    static int (*SSL_set_fd)(SSL *ssl, int fd);
    static int (*SSL_connect)(SSL *ssl);
    static long (*SSL_get_verify_result)(const SSL *ssl);
    static int (*SSL_read)(SSL *ssl, void *buf, int num);
    static int (*SSL_write)(SSL *ssl, const void *buf, int num);
    static void (*SSL_free)(SSL *ssl);

    static SSL_CTX* ssl_context;
}

# define SSL_OP_NO_SSLv2                                 0x01000000L
# define SSL_OP_NO_SSLv3                                 0x02000000L
# define SSL_OP_NO_TLSv1                                 0x04000000L
# define SSL_OP_NO_TLSv1_2                               0x08000000L
# define SSL_OP_NO_TLSv1_1                               0x10000000L

#ifndef __ANDROID__
#include "dynamicLibrary.h"

static std::unique_ptr<DynamicLibrary> libcrypto;
static std::unique_ptr<DynamicLibrary> libssl;
#endif

static void initializeLibSSL()
{
    static bool initialized = false;
    if (initialized) return;
    initialized = true;

#ifndef __ANDROID__
#ifdef _WIN32
    libcrypto = DynamicLibrary::open("libcrypto-1_1.dll");
    libssl = DynamicLibrary::open("libssl-1_1.dll");
#else
    libcrypto = DynamicLibrary::open("libcrypto.so.1.1");
    libssl = DynamicLibrary::open("libssl.so.1.1");
#endif
    if (!libcrypto || !libssl)
        return;

    X509_STORE_new = libcrypto->getFunction<X509_STORE*(*)()>("X509_STORE_new");
    d2i_X509 = libcrypto->getFunction<X509* (*)(X509**, const unsigned char **, long)>("d2i_X509");
    X509_STORE_add_cert = libcrypto->getFunction<int (*)(X509_STORE*, X509*)>("X509_STORE_add_cert");
    X509_free = libcrypto->getFunction<void (*)(X509*)>("X509_free");

    SSL_CTX_new = libssl->getFunction<SSL_CTX*(*)(const SSL_METHOD*)>("SSL_CTX_new");
    TLSv1_2_client_method = libssl->getFunction<const SSL_METHOD* (*)()>("TLSv1_2_client_method");
    SSL_CTX_set_options = libssl->getFunction<long (*)(SSL_CTX*, long)>("SSL_CTX_set_options");
    SSL_CTX_set_default_verify_paths = libssl->getFunction<int (*)(SSL_CTX*)>("SSL_CTX_set_default_verify_paths");
    SSL_CTX_set_cert_store = libssl->getFunction<void (*)(SSL_CTX*, X509_STORE*)>("SSL_CTX_set_cert_store");
    SSL_new = libssl->getFunction<SSL* (*)(SSL_CTX*)>("SSL_new");
    SSL_set_fd = libssl->getFunction<int (*)(SSL *ssl, int fd)>("SSL_set_fd");
    SSL_connect = libssl->getFunction<int (*)(SSL *ssl)>("SSL_connect");
    SSL_get_verify_result = libssl->getFunction<long (*)(const SSL *ssl)>("SSL_get_verify_result");
    SSL_read = libssl->getFunction<int (*)(SSL *ssl, void *buf, int num)>("SSL_read");
    SSL_write = libssl->getFunction<int (*)(SSL *ssl, const void *buf, int num)>("SSL_write");
    SSL_free = libssl->getFunction<void (*)(SSL *ssl)>("SSL_free");

#ifdef _WIN32
    HCERTSTORE hStore;
    PCCERT_CONTEXT pContext = NULL;
    X509 *x509;
    X509_STORE *store = X509_STORE_new();

    hStore = CertOpenSystemStore(0, "ROOT");
    while((pContext = CertEnumCertificatesInStore(hStore, pContext)) != nullptr)
    {
        const unsigned char* c = pContext->pbCertEncoded;
        x509 = d2i_X509(nullptr, &c, pContext->cbCertEncoded);
        if (x509)
        {
            X509_STORE_add_cert(store, x509);
            X509_free(x509);
        }
    }
    CertFreeCertificateContext(pContext);
    CertCloseStore(hStore, 0);
#endif

    ssl_context = SSL_CTX_new(TLSv1_2_client_method());
    SSL_CTX_set_options(ssl_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#ifdef _WIN32
    SSL_CTX_set_cert_store(ssl_context, store);
#else
    SSL_CTX_set_default_verify_paths(ssl_context);
#endif
#endif
}

namespace sp {
namespace io {
namespace network {

TcpSocket::TcpSocket()
: ssl_handle(nullptr)
{
}

TcpSocket::~TcpSocket()
{
    close();
}

bool TcpSocket::connect(const Address& host, int port)
{
    if (handle != INVALID_SOCKET)
        close();

    for(const auto& addr_info : host.addr_info)
    {
        handle = ::socket(addr_info.family, SOCK_STREAM, 0);
        if (handle == INVALID_SOCKET)
            return false;
        setBlocking(blocking);
        if (addr_info.family == AF_INET && sizeof(struct sockaddr_in) == addr_info.addr.size())
        {
            struct sockaddr_in server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.size());
            server_addr.sin_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
                return true;
            if (isLastErrorNonBlocking())
            {
                connecting = true;
                return true;
            }
        }
        if (addr_info.family == AF_INET6 && sizeof(struct sockaddr_in6) == addr_info.addr.size())
        {
            struct sockaddr_in6 server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.size());
            server_addr.sin6_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
                return true;
            if (isLastErrorNonBlocking())
            {
                connecting = true;
                return true;
            }
        }
        close();
    }
    return false;
}

bool TcpSocket::connectSSL(const Address& host, int port)
{
    if (!connect(host, port))
        return false;
    initializeLibSSL();
    if (!SSL_new)
    {
        LOG(Warning, "Failed to connect SSL socket due to missing libssl/libcrypto v1.1");
        close();
        return false;
    }

    ssl_handle = SSL_new(ssl_context);
    SSL_set_fd(static_cast<SSL*>(ssl_handle), static_cast<int>(handle));
    if (!SSL_connect(static_cast<SSL*>(ssl_handle)))
    {
        LOG(Warning, "Failed to connect SSL socket due to SSL negotiation failure.");
        close();
        return false;
    }
    if (SSL_get_verify_result(static_cast<SSL*>(ssl_handle)) != 0)
    {
        LOG(Warning, "Failed to connect SSL socket due to certificate verfication failure.");
        close();
        return false;
    }
    return true;
}

void TcpSocket::setDelay(bool delay)
{
    if (handle == INVALID_SOCKET)
    {
        LOG(Warning, "Failed to setDelay due to being called on an incomplete socket");
        return;
    }
    int mode = delay ? 0 : 1;
    if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (char*)&mode, sizeof(mode)) == -1)
    {
        LOG(Warning, "Failed to setDelay on a socket");
    }
}

void TcpSocket::close()
{
    if (handle != INVALID_SOCKET)
    {
#ifdef _WIN32
        closesocket(handle);
#else
        ::close(handle);
#endif
        handle = INVALID_SOCKET;
        connecting = false;
        clearQueue();
        if (ssl_handle)
            SSL_free(static_cast<SSL*>(ssl_handle));
        ssl_handle = nullptr;
    }
}

StreamSocket::State TcpSocket::getState()
{
    if (handle == INVALID_SOCKET)
        return StreamSocket::State::Closed;
    if (connecting) {
        struct pollfd fds;
        fds.fd = handle;
        fds.events = POLLOUT;
        fds.revents = 0;
        if (WSAPoll(&fds, 1, 0))
        {
            struct sockaddr_in6 server_addr;
            int server_addr_len = sizeof(server_addr);
            if (getpeername(handle, reinterpret_cast<sockaddr*>(&server_addr), &server_addr_len))
            {
                close();
                return StreamSocket::State::Closed;
            }
            connecting = false;
            return StreamSocket::State::Connected;
        }
        return StreamSocket::State::Connecting;
    }
    return StreamSocket::State::Connected;
}

size_t TcpSocket::_send(const void* data, size_t size)
{
    int result;
    if (ssl_handle)
        result = SSL_write(static_cast<SSL*>(ssl_handle), static_cast<const char*>(data), static_cast<int>(size));
    else
        result = ::send(handle, reinterpret_cast<const void *>(static_cast<const char*>(data)), size, flags);
    if (result < 0)
    {
        if (!isLastErrorNonBlocking())
            close();
        return 0;
    }
    return result;
}

size_t TcpSocket::_receive(void* data, size_t size)
{
    int result;
    if (ssl_handle)
        result = SSL_read(static_cast<SSL*>(ssl_handle), static_cast<char*>(data), static_cast<int>(size));
    else
        result = ::recv(handle, data, size, flags);
    if (result < 0)
    {
        result = 0;
        if (!isLastErrorNonBlocking())
            close();
    }
    return result;
}

}//namespace network
}//namespace io
}//namespace sp
<commit_msg>linux build fix?<commit_after>#include <io/network/tcpSocket.h>
#include <logging.h>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
static constexpr int flags = 0;

static inline int send(SOCKET s, const void* msg, size_t len, int flags)
{
    return send(s, static_cast<const char*>(msg), static_cast<int>(len), flags);
}

static inline int recv(SOCKET s, void* buf, size_t len, int flags)
{
    return recv(s, static_cast<char*>(buf), static_cast<int>(len), flags);
}

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <string.h>
#include <poll.h>
static constexpr int flags = MSG_NOSIGNAL;
static constexpr intptr_t INVALID_SOCKET = -1;
#endif

extern "C" {
    struct X509;
    struct X509_STORE;
    struct SSL_CTX;
    struct SSL_METHOD;
    struct SSL;

    static X509_STORE* (*X509_STORE_new)();
    static X509* (*d2i_X509)(X509**, const unsigned char **, long);
    static int (*X509_STORE_add_cert)(X509_STORE*, X509*);
    static void (*X509_free)(X509*);
    static SSL_CTX* (*SSL_CTX_new)(const SSL_METHOD*);
    static const SSL_METHOD* (*TLSv1_2_client_method)();
    static long (*SSL_CTX_set_options)(SSL_CTX*, long);
    static int (*SSL_CTX_set_default_verify_paths)(SSL_CTX*);
    static void (*SSL_CTX_set_cert_store)(SSL_CTX*, X509_STORE*);
    static SSL* (*SSL_new)(SSL_CTX*);
    static int (*SSL_set_fd)(SSL *ssl, int fd);
    static int (*SSL_connect)(SSL *ssl);
    static long (*SSL_get_verify_result)(const SSL *ssl);
    static int (*SSL_read)(SSL *ssl, void *buf, int num);
    static int (*SSL_write)(SSL *ssl, const void *buf, int num);
    static void (*SSL_free)(SSL *ssl);

    static SSL_CTX* ssl_context;
}

# define SSL_OP_NO_SSLv2                                 0x01000000L
# define SSL_OP_NO_SSLv3                                 0x02000000L
# define SSL_OP_NO_TLSv1                                 0x04000000L
# define SSL_OP_NO_TLSv1_2                               0x08000000L
# define SSL_OP_NO_TLSv1_1                               0x10000000L

#ifndef __ANDROID__
#include "dynamicLibrary.h"

static std::unique_ptr<DynamicLibrary> libcrypto;
static std::unique_ptr<DynamicLibrary> libssl;
#endif

static void initializeLibSSL()
{
    static bool initialized = false;
    if (initialized) return;
    initialized = true;

#ifndef __ANDROID__
#ifdef _WIN32
    libcrypto = DynamicLibrary::open("libcrypto-1_1.dll");
    libssl = DynamicLibrary::open("libssl-1_1.dll");
#else
    libcrypto = DynamicLibrary::open("libcrypto.so.1.1");
    libssl = DynamicLibrary::open("libssl.so.1.1");
#endif
    if (!libcrypto || !libssl)
        return;

    X509_STORE_new = libcrypto->getFunction<X509_STORE*(*)()>("X509_STORE_new");
    d2i_X509 = libcrypto->getFunction<X509* (*)(X509**, const unsigned char **, long)>("d2i_X509");
    X509_STORE_add_cert = libcrypto->getFunction<int (*)(X509_STORE*, X509*)>("X509_STORE_add_cert");
    X509_free = libcrypto->getFunction<void (*)(X509*)>("X509_free");

    SSL_CTX_new = libssl->getFunction<SSL_CTX*(*)(const SSL_METHOD*)>("SSL_CTX_new");
    TLSv1_2_client_method = libssl->getFunction<const SSL_METHOD* (*)()>("TLSv1_2_client_method");
    SSL_CTX_set_options = libssl->getFunction<long (*)(SSL_CTX*, long)>("SSL_CTX_set_options");
    SSL_CTX_set_default_verify_paths = libssl->getFunction<int (*)(SSL_CTX*)>("SSL_CTX_set_default_verify_paths");
    SSL_CTX_set_cert_store = libssl->getFunction<void (*)(SSL_CTX*, X509_STORE*)>("SSL_CTX_set_cert_store");
    SSL_new = libssl->getFunction<SSL* (*)(SSL_CTX*)>("SSL_new");
    SSL_set_fd = libssl->getFunction<int (*)(SSL *ssl, int fd)>("SSL_set_fd");
    SSL_connect = libssl->getFunction<int (*)(SSL *ssl)>("SSL_connect");
    SSL_get_verify_result = libssl->getFunction<long (*)(const SSL *ssl)>("SSL_get_verify_result");
    SSL_read = libssl->getFunction<int (*)(SSL *ssl, void *buf, int num)>("SSL_read");
    SSL_write = libssl->getFunction<int (*)(SSL *ssl, const void *buf, int num)>("SSL_write");
    SSL_free = libssl->getFunction<void (*)(SSL *ssl)>("SSL_free");

#ifdef _WIN32
    HCERTSTORE hStore;
    PCCERT_CONTEXT pContext = NULL;
    X509 *x509;
    X509_STORE *store = X509_STORE_new();

    hStore = CertOpenSystemStore(0, "ROOT");
    while((pContext = CertEnumCertificatesInStore(hStore, pContext)) != nullptr)
    {
        const unsigned char* c = pContext->pbCertEncoded;
        x509 = d2i_X509(nullptr, &c, pContext->cbCertEncoded);
        if (x509)
        {
            X509_STORE_add_cert(store, x509);
            X509_free(x509);
        }
    }
    CertFreeCertificateContext(pContext);
    CertCloseStore(hStore, 0);
#endif

    ssl_context = SSL_CTX_new(TLSv1_2_client_method());
    SSL_CTX_set_options(ssl_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#ifdef _WIN32
    SSL_CTX_set_cert_store(ssl_context, store);
#else
    SSL_CTX_set_default_verify_paths(ssl_context);
#endif
#endif
}

namespace sp {
namespace io {
namespace network {

TcpSocket::TcpSocket()
: ssl_handle(nullptr)
{
}

TcpSocket::~TcpSocket()
{
    close();
}

bool TcpSocket::connect(const Address& host, int port)
{
    if (handle != INVALID_SOCKET)
        close();

    for(const auto& addr_info : host.addr_info)
    {
        handle = ::socket(addr_info.family, SOCK_STREAM, 0);
        if (handle == INVALID_SOCKET)
            return false;
        setBlocking(blocking);
        if (addr_info.family == AF_INET && sizeof(struct sockaddr_in) == addr_info.addr.size())
        {
            struct sockaddr_in server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.size());
            server_addr.sin_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
                return true;
            if (isLastErrorNonBlocking())
            {
                connecting = true;
                return true;
            }
        }
        if (addr_info.family == AF_INET6 && sizeof(struct sockaddr_in6) == addr_info.addr.size())
        {
            struct sockaddr_in6 server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.size());
            server_addr.sin6_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
                return true;
            if (isLastErrorNonBlocking())
            {
                connecting = true;
                return true;
            }
        }
        close();
    }
    return false;
}

bool TcpSocket::connectSSL(const Address& host, int port)
{
    if (!connect(host, port))
        return false;
    initializeLibSSL();
    if (!SSL_new)
    {
        LOG(Warning, "Failed to connect SSL socket due to missing libssl/libcrypto v1.1");
        close();
        return false;
    }

    ssl_handle = SSL_new(ssl_context);
    SSL_set_fd(static_cast<SSL*>(ssl_handle), static_cast<int>(handle));
    if (!SSL_connect(static_cast<SSL*>(ssl_handle)))
    {
        LOG(Warning, "Failed to connect SSL socket due to SSL negotiation failure.");
        close();
        return false;
    }
    if (SSL_get_verify_result(static_cast<SSL*>(ssl_handle)) != 0)
    {
        LOG(Warning, "Failed to connect SSL socket due to certificate verfication failure.");
        close();
        return false;
    }
    return true;
}

void TcpSocket::setDelay(bool delay)
{
    if (handle == INVALID_SOCKET)
    {
        LOG(Warning, "Failed to setDelay due to being called on an incomplete socket");
        return;
    }
    int mode = delay ? 0 : 1;
    if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (char*)&mode, sizeof(mode)) == -1)
    {
        LOG(Warning, "Failed to setDelay on a socket");
    }
}

void TcpSocket::close()
{
    if (handle != INVALID_SOCKET)
    {
#ifdef _WIN32
        closesocket(handle);
#else
        ::close(handle);
#endif
        handle = INVALID_SOCKET;
        connecting = false;
        clearQueue();
        if (ssl_handle)
            SSL_free(static_cast<SSL*>(ssl_handle));
        ssl_handle = nullptr;
    }
}

StreamSocket::State TcpSocket::getState()
{
    if (handle == INVALID_SOCKET)
        return StreamSocket::State::Closed;
    if (connecting) {
        struct pollfd fds;
        fds.fd = handle;
        fds.events = POLLOUT;
        fds.revents = 0;
#ifdef WIN32
        if (WSAPoll(&fds, 1, 0))
#else
        if (poll(&fds, 1, 0))
#endif
        {
            struct sockaddr_in6 server_addr;
            int server_addr_len = sizeof(server_addr);
            if (getpeername(handle, reinterpret_cast<sockaddr*>(&server_addr), &server_addr_len))
            {
                close();
                return StreamSocket::State::Closed;
            }
            connecting = false;
            return StreamSocket::State::Connected;
        }
        return StreamSocket::State::Connecting;
    }
    return StreamSocket::State::Connected;
}

size_t TcpSocket::_send(const void* data, size_t size)
{
    int result;
    if (ssl_handle)
        result = SSL_write(static_cast<SSL*>(ssl_handle), static_cast<const char*>(data), static_cast<int>(size));
    else
        result = ::send(handle, reinterpret_cast<const void *>(static_cast<const char*>(data)), size, flags);
    if (result < 0)
    {
        if (!isLastErrorNonBlocking())
            close();
        return 0;
    }
    return result;
}

size_t TcpSocket::_receive(void* data, size_t size)
{
    int result;
    if (ssl_handle)
        result = SSL_read(static_cast<SSL*>(ssl_handle), static_cast<char*>(data), static_cast<int>(size));
    else
        result = ::recv(handle, data, size, flags);
    if (result < 0)
    {
        result = 0;
        if (!isLastErrorNonBlocking())
            close();
    }
    return result;
}

}//namespace network
}//namespace io
}//namespace sp
<|endoftext|>


<commit_before>/*
 * Asynchronous local file access.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "istream_file.hxx"
#include "istream.hxx"
#include "io/Buffered.hxx"
#include "io/UniqueFileDescriptor.hxx"
#include "gerrno.h"
#include "pool.hxx"
#include "fb_pool.hxx"
#include "SliceFifoBuffer.hxx"
#include "event/TimerEvent.hxx"

#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

/**
 * If EAGAIN occurs (on NFS), we try again after 100ms.  We can't
 * check EV_READ, because the kernel always indicates VFS files as
 * "readable without blocking".
 */
static const struct timeval file_retry_timeout = {
    .tv_sec = 0,
    .tv_usec = 100000,
};

struct FileIstream final : public Istream {
    int fd;

    FdType fd_type;

    /**
     * A timer to retry reading after EAGAIN.
     */
    TimerEvent event;

    off_t rest;
    SliceFifoBuffer buffer;
    const char *path;

    FileIstream(struct pool &p, EventLoop &event_loop,
                int _fd, FdType _fd_type, off_t _length,
                const char *_path)
        :Istream(p),
         fd(_fd), fd_type(_fd_type),
         event(event_loop, BIND_THIS_METHOD(EventCallback)),
         rest(_length),
         path(_path) {}

    ~FileIstream() {
        event.Cancel();
    }

    void CloseHandle() {
        if (fd < 0)
            return;

        event.Cancel();

        close(fd);
        fd = -1;

        buffer.FreeIfDefined(fb_pool_get());
    }

    void Abort(GError *error) {
        CloseHandle();
        DestroyError(error);
    }

    /**
     * @return the number of bytes still in the buffer
     */
    size_t SubmitBuffer() {
        return ConsumeFromBuffer(buffer);
    }

    void EofDetected() {
        assert(fd >= 0);

        CloseHandle();
        DestroyEof();
    }

    gcc_pure
    size_t GetMaxRead() const {
        if (rest != (off_t)-1 && rest < (off_t)INT_MAX)
            return (size_t)rest;
        else
            return INT_MAX;
    }

    void TryData();
    void TryDirect();

    void TryRead() {
        if (CheckDirect(fd_type))
            TryDirect();
        else
            TryData();
    }

    void EventCallback() {
        TryRead();
    }

    /* virtual methods from class Istream */

    off_t _GetAvailable(bool partial) override;
    off_t _Skip(gcc_unused off_t length) override;

    void _Read() override {
        event.Cancel();
        TryRead();
    }

    int _AsFd() override;
    void _Close() override {
        CloseHandle();
        Destroy();
    }
};

inline void
FileIstream::TryData()
{
    size_t buffer_rest = 0;

    if (buffer.IsNull()) {
        if (rest != 0)
            buffer.Allocate(fb_pool_get());
    } else {
        const size_t available = buffer.GetAvailable();
        if (available > 0) {
            buffer_rest = SubmitBuffer();
            if (buffer_rest == available)
                /* not a single byte was consumed: we may have been
                   closed, and we must bail out now */
                return;
        }
    }

    if (rest == 0) {
        if (buffer_rest == 0)
            EofDetected();
        return;
    }

    ssize_t nbytes = read_to_buffer(fd, buffer, GetMaxRead());
    if (nbytes == 0) {
        if (rest == (off_t)-1) {
            rest = 0;
            if (buffer_rest == 0)
                EofDetected();
        } else {
            GError *error =
                g_error_new(g_file_error_quark(), 0,
                            "premature end of file in '%s'", path);
            Abort(error);
        }
        return;
    } else if (nbytes == -1) {
        GError *error =
            g_error_new(errno_quark(), errno,
                        "failed to read from '%s': %s",
                        path, strerror(errno));
        Abort(error);
        return;
    } else if (nbytes > 0 && rest != (off_t)-1) {
        rest -= (off_t)nbytes;
        assert(rest >= 0);
    }

    assert(!buffer.IsEmpty());

    buffer_rest = SubmitBuffer();
    if (buffer_rest == 0 && rest == 0)
        EofDetected();
}

inline void
FileIstream::TryDirect()
{
    /* first consume the rest of the buffer */
    if (SubmitBuffer() > 0)
        return;

    if (rest == 0) {
        EofDetected();
        return;
    }

    ssize_t nbytes = InvokeDirect(fd_type, fd, GetMaxRead());
    if (nbytes == ISTREAM_RESULT_CLOSED)
        /* this stream was closed during the direct() callback */
        return;

    if (nbytes > 0 || nbytes == ISTREAM_RESULT_BLOCKING) {
        /* -2 means the callback wasn't able to consume any data right
           now */
        if (nbytes > 0 && rest != (off_t)-1) {
            rest -= (off_t)nbytes;
            assert(rest >= 0);
            if (rest == 0)
                EofDetected();
        }
    } else if (nbytes == ISTREAM_RESULT_EOF) {
        if (rest == (off_t)-1) {
            EofDetected();
        } else {
            GError *error =
                g_error_new(g_file_error_quark(), 0,
                            "premature end of file in '%s'", path);
            Abort(error);
        }
    } else if (errno == EAGAIN) {
        /* this should only happen for splice(SPLICE_F_NONBLOCK) from
           NFS files - unfortunately we cannot use EV_READ here, so we
           just install a timer which retries after 100ms */

        event.Add(file_retry_timeout);
    } else {
        /* XXX */
        GError *error =
            g_error_new(errno_quark(), errno,
                        "failed to read from '%s': %s",
                        path, strerror(errno));
        Abort(error);
    }
}

/*
 * istream implementation
 *
 */

off_t
FileIstream::_GetAvailable(bool partial)
{
    off_t available;
    if (rest != (off_t)-1)
        available = rest;
    else if (!partial)
        return (off_t)-1;
    else
        available = 0;

    available += buffer.GetAvailable();
    return available;
}

off_t
FileIstream::_Skip(off_t length)
{
    event.Cancel();

    if (rest == (off_t)-1)
        return (off_t)-1;

    if (length == 0)
        return 0;

    const size_t buffer_available = buffer.GetAvailable();
    if (length < off_t(buffer_available)) {
        buffer.Consume(length);
        Consumed(length);
        return length;
    }

    length -= buffer_available;
    buffer.Clear();

    if (length >= rest) {
        /* skip beyond EOF */

        length = rest;
        rest = 0;
    } else {
        /* seek the file descriptor */

        off_t ret = lseek(fd, length, SEEK_CUR);
        if (ret < 0)
            return -1;
        rest -= length;
    }

    off_t result = buffer_available + length;
    Consumed(result);
    return result;
}

int
FileIstream::_AsFd()
{
    int result_fd = fd;

    Destroy();

    return result_fd;
}

/*
 * constructor and public methods
 *
 */

Istream *
istream_file_fd_new(EventLoop &event_loop, struct pool &pool,
                    const char *path,
                    int fd, FdType fd_type, off_t length)
{
    assert(fd >= 0);
    assert(length >= -1);

    return NewIstream<FileIstream>(pool, event_loop, fd, fd_type, length, path);
}

Istream *
istream_file_stat_new(EventLoop &event_loop, struct pool &pool,
                      const char *path, struct stat &st,
                      GError **error_r)
{
    assert(path != nullptr);

    UniqueFileDescriptor fd;
    if (!fd.OpenReadOnly(path)) {
        set_error_errno(error_r);
        g_prefix_error(error_r, "Failed to open %s: ", path);
        return nullptr;
    }

    if (fstat(fd.Get(), &st) < 0) {
        set_error_errno(error_r);
        g_prefix_error(error_r, "Failed to stat %s: ", path);
        return nullptr;
    }

    FdType fd_type = FdType::FD_FILE;
    off_t size = st.st_size;

    if (S_ISCHR(st.st_mode)) {
        fd_type = FdType::FD_CHARDEV;
        size = -1;
    }

    return istream_file_fd_new(event_loop, pool, path,
                               fd.Steal(), fd_type, size);
}

Istream *
istream_file_new(EventLoop &event_loop, struct pool &pool,
                 const char *path, off_t length,
                 GError **error_r)
{
    assert(length >= -1);

    UniqueFileDescriptor fd;
    if (!fd.OpenReadOnly(path)) {
        set_error_errno(error_r);
        g_prefix_error(error_r, "Failed to open %s: ", path);
        return nullptr;
    }

    return istream_file_fd_new(event_loop, pool, path,
                               fd.Steal(), FdType::FD_FILE, length);
}

int
istream_file_fd(Istream &istream)
{
    auto &file = (FileIstream &)istream;
    assert(file.fd >= 0);
    return file.fd;
}

bool
istream_file_set_range(Istream &istream, off_t start, off_t end)
{
    assert(start >= 0);
    assert(end >= start);

    auto &file = (FileIstream &)istream;
    assert(file.fd >= 0);
    assert(file.rest >= 0);
    assert(file.buffer.IsNull());
    assert(end <= file.rest);

    if (start > 0 && lseek(file.fd, start, SEEK_CUR) < 0)
        return false;

    file.rest = end - start;
    return true;
}
<commit_msg>istream/file: rename "event" to "retry_event"<commit_after>/*
 * Asynchronous local file access.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "istream_file.hxx"
#include "istream.hxx"
#include "io/Buffered.hxx"
#include "io/UniqueFileDescriptor.hxx"
#include "gerrno.h"
#include "pool.hxx"
#include "fb_pool.hxx"
#include "SliceFifoBuffer.hxx"
#include "event/TimerEvent.hxx"

#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

/**
 * If EAGAIN occurs (on NFS), we try again after 100ms.  We can't
 * check EV_READ, because the kernel always indicates VFS files as
 * "readable without blocking".
 */
static const struct timeval file_retry_timeout = {
    .tv_sec = 0,
    .tv_usec = 100000,
};

struct FileIstream final : public Istream {
    int fd;

    FdType fd_type;

    /**
     * A timer to retry reading after EAGAIN.
     */
    TimerEvent retry_event;

    off_t rest;
    SliceFifoBuffer buffer;
    const char *path;

    FileIstream(struct pool &p, EventLoop &event_loop,
                int _fd, FdType _fd_type, off_t _length,
                const char *_path)
        :Istream(p),
         fd(_fd), fd_type(_fd_type),
         retry_event(event_loop, BIND_THIS_METHOD(EventCallback)),
         rest(_length),
         path(_path) {}

    ~FileIstream() {
        retry_event.Cancel();
    }

    void CloseHandle() {
        if (fd < 0)
            return;

        retry_event.Cancel();

        close(fd);
        fd = -1;

        buffer.FreeIfDefined(fb_pool_get());
    }

    void Abort(GError *error) {
        CloseHandle();
        DestroyError(error);
    }

    /**
     * @return the number of bytes still in the buffer
     */
    size_t SubmitBuffer() {
        return ConsumeFromBuffer(buffer);
    }

    void EofDetected() {
        assert(fd >= 0);

        CloseHandle();
        DestroyEof();
    }

    gcc_pure
    size_t GetMaxRead() const {
        if (rest != (off_t)-1 && rest < (off_t)INT_MAX)
            return (size_t)rest;
        else
            return INT_MAX;
    }

    void TryData();
    void TryDirect();

    void TryRead() {
        if (CheckDirect(fd_type))
            TryDirect();
        else
            TryData();
    }

    void EventCallback() {
        TryRead();
    }

    /* virtual methods from class Istream */

    off_t _GetAvailable(bool partial) override;
    off_t _Skip(gcc_unused off_t length) override;

    void _Read() override {
        retry_event.Cancel();
        TryRead();
    }

    int _AsFd() override;
    void _Close() override {
        CloseHandle();
        Destroy();
    }
};

inline void
FileIstream::TryData()
{
    size_t buffer_rest = 0;

    if (buffer.IsNull()) {
        if (rest != 0)
            buffer.Allocate(fb_pool_get());
    } else {
        const size_t available = buffer.GetAvailable();
        if (available > 0) {
            buffer_rest = SubmitBuffer();
            if (buffer_rest == available)
                /* not a single byte was consumed: we may have been
                   closed, and we must bail out now */
                return;
        }
    }

    if (rest == 0) {
        if (buffer_rest == 0)
            EofDetected();
        return;
    }

    ssize_t nbytes = read_to_buffer(fd, buffer, GetMaxRead());
    if (nbytes == 0) {
        if (rest == (off_t)-1) {
            rest = 0;
            if (buffer_rest == 0)
                EofDetected();
        } else {
            GError *error =
                g_error_new(g_file_error_quark(), 0,
                            "premature end of file in '%s'", path);
            Abort(error);
        }
        return;
    } else if (nbytes == -1) {
        GError *error =
            g_error_new(errno_quark(), errno,
                        "failed to read from '%s': %s",
                        path, strerror(errno));
        Abort(error);
        return;
    } else if (nbytes > 0 && rest != (off_t)-1) {
        rest -= (off_t)nbytes;
        assert(rest >= 0);
    }

    assert(!buffer.IsEmpty());

    buffer_rest = SubmitBuffer();
    if (buffer_rest == 0 && rest == 0)
        EofDetected();
}

inline void
FileIstream::TryDirect()
{
    /* first consume the rest of the buffer */
    if (SubmitBuffer() > 0)
        return;

    if (rest == 0) {
        EofDetected();
        return;
    }

    ssize_t nbytes = InvokeDirect(fd_type, fd, GetMaxRead());
    if (nbytes == ISTREAM_RESULT_CLOSED)
        /* this stream was closed during the direct() callback */
        return;

    if (nbytes > 0 || nbytes == ISTREAM_RESULT_BLOCKING) {
        /* -2 means the callback wasn't able to consume any data right
           now */
        if (nbytes > 0 && rest != (off_t)-1) {
            rest -= (off_t)nbytes;
            assert(rest >= 0);
            if (rest == 0)
                EofDetected();
        }
    } else if (nbytes == ISTREAM_RESULT_EOF) {
        if (rest == (off_t)-1) {
            EofDetected();
        } else {
            GError *error =
                g_error_new(g_file_error_quark(), 0,
                            "premature end of file in '%s'", path);
            Abort(error);
        }
    } else if (errno == EAGAIN) {
        /* this should only happen for splice(SPLICE_F_NONBLOCK) from
           NFS files - unfortunately we cannot use EV_READ here, so we
           just install a timer which retries after 100ms */

        retry_event.Add(file_retry_timeout);
    } else {
        /* XXX */
        GError *error =
            g_error_new(errno_quark(), errno,
                        "failed to read from '%s': %s",
                        path, strerror(errno));
        Abort(error);
    }
}

/*
 * istream implementation
 *
 */

off_t
FileIstream::_GetAvailable(bool partial)
{
    off_t available;
    if (rest != (off_t)-1)
        available = rest;
    else if (!partial)
        return (off_t)-1;
    else
        available = 0;

    available += buffer.GetAvailable();
    return available;
}

off_t
FileIstream::_Skip(off_t length)
{
    retry_event.Cancel();

    if (rest == (off_t)-1)
        return (off_t)-1;

    if (length == 0)
        return 0;

    const size_t buffer_available = buffer.GetAvailable();
    if (length < off_t(buffer_available)) {
        buffer.Consume(length);
        Consumed(length);
        return length;
    }

    length -= buffer_available;
    buffer.Clear();

    if (length >= rest) {
        /* skip beyond EOF */

        length = rest;
        rest = 0;
    } else {
        /* seek the file descriptor */

        off_t ret = lseek(fd, length, SEEK_CUR);
        if (ret < 0)
            return -1;
        rest -= length;
    }

    off_t result = buffer_available + length;
    Consumed(result);
    return result;
}

int
FileIstream::_AsFd()
{
    int result_fd = fd;

    Destroy();

    return result_fd;
}

/*
 * constructor and public methods
 *
 */

Istream *
istream_file_fd_new(EventLoop &event_loop, struct pool &pool,
                    const char *path,
                    int fd, FdType fd_type, off_t length)
{
    assert(fd >= 0);
    assert(length >= -1);

    return NewIstream<FileIstream>(pool, event_loop, fd, fd_type, length, path);
}

Istream *
istream_file_stat_new(EventLoop &event_loop, struct pool &pool,
                      const char *path, struct stat &st,
                      GError **error_r)
{
    assert(path != nullptr);

    UniqueFileDescriptor fd;
    if (!fd.OpenReadOnly(path)) {
        set_error_errno(error_r);
        g_prefix_error(error_r, "Failed to open %s: ", path);
        return nullptr;
    }

    if (fstat(fd.Get(), &st) < 0) {
        set_error_errno(error_r);
        g_prefix_error(error_r, "Failed to stat %s: ", path);
        return nullptr;
    }

    FdType fd_type = FdType::FD_FILE;
    off_t size = st.st_size;

    if (S_ISCHR(st.st_mode)) {
        fd_type = FdType::FD_CHARDEV;
        size = -1;
    }

    return istream_file_fd_new(event_loop, pool, path,
                               fd.Steal(), fd_type, size);
}

Istream *
istream_file_new(EventLoop &event_loop, struct pool &pool,
                 const char *path, off_t length,
                 GError **error_r)
{
    assert(length >= -1);

    UniqueFileDescriptor fd;
    if (!fd.OpenReadOnly(path)) {
        set_error_errno(error_r);
        g_prefix_error(error_r, "Failed to open %s: ", path);
        return nullptr;
    }

    return istream_file_fd_new(event_loop, pool, path,
                               fd.Steal(), FdType::FD_FILE, length);
}

int
istream_file_fd(Istream &istream)
{
    auto &file = (FileIstream &)istream;
    assert(file.fd >= 0);
    return file.fd;
}

bool
istream_file_set_range(Istream &istream, off_t start, off_t end)
{
    assert(start >= 0);
    assert(end >= start);

    auto &file = (FileIstream &)istream;
    assert(file.fd >= 0);
    assert(file.rest >= 0);
    assert(file.buffer.IsNull());
    assert(end <= file.rest);

    if (start > 0 && lseek(file.fd, start, SEEK_CUR) < 0)
        return false;

    file.rest = end - start;
    return true;
}
<|endoftext|>


<commit_before>#include "Manager.hpp"

#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm>

#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

int
smain(int argc, char *argv[]) {
    namespace po = boost::program_options;
    namespace fs = boost::filesystem;

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "help message")
        ("config-path,c", po::value< std::vector<std::string> >(), "configuration path")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if(vm.count("help")) {
        std::cerr << desc << "\n";
        return 1;
    }

    std::vector<std::string> files;

    if(vm.count("config-path")) {
        auto conf_path = vm["config-path"].as< std::vector<std::string> >();
        for(std::string &dir : conf_path) {
            fs::path p(dir);
            if(fs::is_regular_file(p) && 0 == p.extension().compare(".lua") && file_size(p) > 0) {
                files.push_back(p.native());
            }
            else if (fs::is_directory(p)) {
                std::for_each(fs::directory_iterator(p), fs::directory_iterator(),
                    [&](fs::directory_entry &de) {
                        fs::path p2 = de.path();
                        if(fs::is_regular_file(p2) && 0 == p2.extension().compare(".lua") && file_size(p2) > 0) {
                            files.push_back(p2.native());
                        }
                    }
                );
            }
        }
    }
    else {
        std::cerr << desc << "\n";
        return 1;
    }

    // run it...
    lutop::Manager m;

    m.loadFiles(files);

    return 0;
}

int
main(int argc, char *argv[]) {
    try {
        return smain(argc, argv);
    }
    catch(std::exception const &e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return 1;
    }
    catch(...) {
        std::cerr << "Unknown exception" << std::endl;
        return 1;
    }
}
<commit_msg>boost::filesystem api in not stable...<commit_after>#include "Manager.hpp"

#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm>

#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

int
smain(int argc, char *argv[]) {
    namespace po = boost::program_options;
    namespace fs = boost::filesystem;

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "help message")
        ("config-path,c", po::value< std::vector<std::string> >(), "configuration path")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if(vm.count("help")) {
        std::cerr << desc << "\n";
        return 1;
    }

    std::vector<std::string> files;

    if(vm.count("config-path")) {
        auto conf_path = vm["config-path"].as< std::vector<std::string> >();
        for(std::string &dir : conf_path) {
            fs::path p(dir);
            if(fs::is_regular_file(p) && (p.extension() == ".lua") && file_size(p) > 0) {
                files.push_back(p.native());
            }
            else if (fs::is_directory(p)) {
                std::for_each(fs::directory_iterator(p), fs::directory_iterator(),
                    [&](fs::directory_entry &de) {
                        fs::path p2 = de.path();
                        if(fs::is_regular_file(p2) && (p2.extension() == ".lua") && file_size(p2) > 0) {
                            files.push_back(p2.native());
                        }
                    }
                );
            }
        }
    }
    else {
        std::cerr << desc << "\n";
        return 1;
    }

    // run it...
    lutop::Manager m;

    m.loadFiles(files);

    return 0;
}

int
main(int argc, char *argv[]) {
    try {
        return smain(argc, argv);
    }
    catch(std::exception const &e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return 1;
    }
    catch(...) {
        std::cerr << "Unknown exception" << std::endl;
        return 1;
    }
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * E.S.O. - ACS project
 *
 * "@(#) $Id: acsdaemonStopContainer.cpp,v 1.9 2008/06/27 11:41:07 msekoran Exp $"
 *
 * who       when        what
 * --------  ----------  ----------------------------------------------
 */

/** @file acsdaemonStopContainer.cpp
 *  acsdaemonStopContainer is used to remotely stop container via ACS Deamon.
 *  @htmlonly
 *

 *  @endhtmlonly
 */

#include <acsutilPorts.h>
#include <logging.h>
#include <acsdaemonC.h>
#include <ACSErrTypeCommon.h>
#include <acsdaemonErrType.h>
#include <getopt.h>

static struct option long_options[] = {
        {"help",        no_argument,       0, 'h'},
        {"container",   required_argument, 0, 'c'},
        {"instance",    required_argument, 0, 'i'},
        {"host",        required_argument, 0, 'H'},
        {"daemon",      required_argument, 0, 'd'},
        {"additional",   required_argument, 0, 'a'},
        {0, 0, 0, '\0'}};

void
usage(const char *argv)
{
    ACE_OS::printf ("\n\tusage: %s {-h} -i INSTANCE -t TYPE -c CONTAINER [-d DAEMONREF] [-H HOST] [-a more options]", argv);
    ACE_OS::printf ("\t   -h, --help         show this help message\n");
    ACE_OS::printf ("\t   -c, --container     container name\n");
    ACE_OS::printf ("\t   -i, --instance     ACS instance to use\n");
    ACE_OS::printf ("\t   -H, --host         Host where to stop the container\n");
    ACE_OS::printf ("\t   -d, --daemon       Daemon reference\n");
    ACE_OS::printf ("\t   -a, --additional    passthrough options for stopContaner. Put options between \"\"\n");
}

int
main (int argc, char *argv[])
{
    int c, instance = -1;
    ACE_CString daemonRef;
    ACE_CString hostName;
    ACE_CString containerName;
    ACE_CString additional;
    for(;;)
        {
        int option_index = 0;
        c = getopt_long (argc, argv, "hc:i:d:H:a:",
                         long_options, &option_index);
        if (c==-1) break;
        switch(c)
            {
                case 'h':
                    usage(argv[0]);
                    return 0;
                case 'i':
                    instance = ACE_OS::atoi(optarg);
                    break;
                case 'd':
                    daemonRef = optarg;
                    break;
                case 'H':
                    hostName = optarg;
                    break;
                case 'c':
                    containerName = optarg;
                    break;
                case 'a':
                    additional = optarg;
                    break;
            }
        }
    if (instance == -1)
        {
        ACE_OS::printf("Error: instance is a mandatory option try %s -h\n", argv[0]);
        return -1;
        }

    if (containerName.length() == 0)
        {
        ACE_OS::printf("Error: container name is a mandatory option try %s -h\n", argv[0]);
        return -1;
        }

	LoggingProxy * logger = new LoggingProxy(0, 0, 31);
	if (logger)
	{
		LoggingProxy::init(logger);
		LoggingProxy::ProcessName(argv[0]);
		LoggingProxy::ThreadName("main");
	}
	else
		ACS_SHORT_LOG((LM_INFO, "Failed to initialize logging."));

	try
	{
		// Initialize the ORB.
		CORBA::ORB_var orb = CORBA::ORB_init (argc,argv,"TAO");

		// construct default one
      if (daemonRef.length() == 0)
	  {
          if(hostName.length() == 0)
          {
	      hostName = ACSPorts::getIP();
          }
	  daemonRef = "corbaloc::";
	  daemonRef = daemonRef + hostName + ":" + ACSPorts::getContainerDaemonPort().c_str() + "/" + ::acsdaemon::containerDaemonServiceName;
	  ACS_SHORT_LOG((LM_INFO, "Using local Container Daemon reference: '%s'", daemonRef.c_str()));

	  }
      else
          {
          ACS_SHORT_LOG((LM_INFO, "Container Daemon reference obtained via command line: '%s'", daemonRef.c_str()));
          }

		CORBA::Object_var obj = orb->string_to_object(daemonRef.c_str());
		if (CORBA::is_nil(obj.in()))
		{
			ACS_SHORT_LOG((LM_INFO, "Failed to resolve reference '%s'.", daemonRef.c_str()));
			return -1;
		}

		acsdaemon::ContainerDaemon_var daemon = acsdaemon::ContainerDaemon::_narrow(obj.in());
		if (CORBA::is_nil(daemon.in()))
		{
			ACS_SHORT_LOG((LM_INFO, "Failed to narrow reference '%s'.", daemonRef.c_str()));
			return -1;
		}

                ACS_SHORT_LOG((LM_INFO, "Calling stop_container(%s, %d, %s).", containerName.c_str(), instance, additional.c_str()));

                daemon->stop_container(containerName.c_str(), instance, additional.c_str());

                ACS_SHORT_LOG((LM_INFO, "Container stop message issued."));

	}
	catch (ACSErrTypeCommon::BadParameterEx &ex)
	{
		ACSErrTypeCommon::BadParameterExImpl exImpl(ex);
		exImpl.log();
		return -1;
	}
	catch (acsdaemonErrType::FailedToStopContainerEx &ex)
	{
		acsdaemonErrType::FailedToStopContainerExImpl exImpl(ex);
		exImpl.log();
		return -1;
	}
	catch( CORBA::Exception &ex )
	{
		ACS_SHORT_LOG((LM_INFO, "Failed."));
		ACE_PRINT_EXCEPTION (ex, ACE_TEXT ("Caught unexpected exception:"));
		return -1;
	}

	return 0;
}

<commit_msg>Added --synchronous (-s) option to invoke stop_container_sync() method instead of stop_container()<commit_after>/*******************************************************************************
 * E.S.O. - ACS project
 *
 * "@(#) $Id: acsdaemonStopContainer.cpp,v 1.9 2008/06/27 11:41:07 msekoran Exp $"
 *
 * who       when        what
 * --------  ----------  ----------------------------------------------
 */

/** @file acsdaemonStopContainer.cpp
 *  acsdaemonStopContainer is used to remotely stop container via ACS Deamon.
 *  @htmlonly
 *

 *  @endhtmlonly
 */

#include <acsutilPorts.h>
#include <logging.h>
#include <acsdaemonC.h>
#include <ACSErrTypeCommon.h>
#include <acsdaemonErrType.h>
#include <getopt.h>

static struct option long_options[] = {
        {"help",        no_argument,       0, 'h'},
        {"container",   required_argument, 0, 'c'},
        {"instance",    required_argument, 0, 'i'},
        {"host",        required_argument, 0, 'H'},
        {"daemon",      required_argument, 0, 'd'},
        {"additional",   required_argument, 0, 'a'},
		{"synchronous", no_argument,       0, 's'},
        {0, 0, 0, '\0'}};

void
usage(const char *argv)
{
    ACE_OS::printf ("\n\tusage: %s {-h} -i INSTANCE -t TYPE -c CONTAINER [-d DAEMONREF] [-H HOST] [-a more options]", argv);
    ACE_OS::printf ("\t   -h, --help         show this help message\n");
    ACE_OS::printf ("\t   -c, --container     container name\n");
    ACE_OS::printf ("\t   -i, --instance     ACS instance to use\n");
    ACE_OS::printf ("\t   -H, --host         Host where to stop the container\n");
    ACE_OS::printf ("\t   -d, --daemon       Daemon reference\n");
    ACE_OS::printf ("\t   -a, --additional    passthrough options for stopContaner. Put options between \"\"\n");
	ACE_OS::printf ("\t   -s, --synchronous  Send the command to stop the container synchronously\n");
	ACE_OS::printf ("\t                      The script will exit only when the container will have been fully stopped or if an error occurred\n");
}

int
main (int argc, char *argv[])
{
    int c, instance = -1;
    ACE_CString daemonRef;
    ACE_CString hostName;
    ACE_CString containerName;
    ACE_CString additional;
	int sync_flag = 0;
    for(;;)
        {
        int option_index = 0;
        c = getopt_long (argc, argv, "hc:i:d:H:a:s",
                         long_options, &option_index);
        if (c==-1) break;
        switch(c)
            {
                case 'h':
                    usage(argv[0]);
                    return 0;
                case 'i':
                    instance = ACE_OS::atoi(optarg);
                    break;
                case 'd':
                    daemonRef = optarg;
                    break;
                case 'H':
                    hostName = optarg;
                    break;
                case 'c':
                    containerName = optarg;
                    break;
                case 'a':
                    additional = optarg;
                    break;
                case 's':
                    sync_flag = 1;
                    break;
            }
        }
    if (instance == -1)
        {
        ACE_OS::printf("Error: instance is a mandatory option try %s -h\n", argv[0]);
        return -1;
        }

    if (containerName.length() == 0)
        {
        ACE_OS::printf("Error: container name is a mandatory option try %s -h\n", argv[0]);
        return -1;
        }

	LoggingProxy * logger = new LoggingProxy(0, 0, 31);
	if (logger)
	{
		LoggingProxy::init(logger);
		LoggingProxy::ProcessName(argv[0]);
		LoggingProxy::ThreadName("main");
	}
	else
		ACS_SHORT_LOG((LM_INFO, "Failed to initialize logging."));

	try
	{
		// Initialize the ORB.
		CORBA::ORB_var orb = CORBA::ORB_init (argc,argv,"TAO");

		// construct default one
      if (daemonRef.length() == 0)
	  {
          if(hostName.length() == 0)
          {
	      hostName = ACSPorts::getIP();
          }
	  daemonRef = "corbaloc::";
	  daemonRef = daemonRef + hostName + ":" + ACSPorts::getContainerDaemonPort().c_str() + "/" + ::acsdaemon::containerDaemonServiceName;
	  ACS_SHORT_LOG((LM_INFO, "Using local Container Daemon reference: '%s'", daemonRef.c_str()));

	  }
      else
          {
          ACS_SHORT_LOG((LM_INFO, "Container Daemon reference obtained via command line: '%s'", daemonRef.c_str()));
          }

		CORBA::Object_var obj = orb->string_to_object(daemonRef.c_str());
		if (CORBA::is_nil(obj.in()))
		{
			ACS_SHORT_LOG((LM_INFO, "Failed to resolve reference '%s'.", daemonRef.c_str()));
			return -1;
		}

		acsdaemon::ContainerDaemon_var daemon = acsdaemon::ContainerDaemon::_narrow(obj.in());
		if (CORBA::is_nil(daemon.in()))
		{
			ACS_SHORT_LOG((LM_INFO, "Failed to narrow reference '%s'.", daemonRef.c_str()));
			return -1;
		}

		ACS_SHORT_LOG((LM_INFO, "Calling stop_container(%s, %d, %s).", containerName.c_str(), instance, additional.c_str()));
		if (sync_flag)
		{
			daemon->stop_container_sync(containerName.c_str(), instance, additional.c_str());
		}
		else
		{
			daemon->stop_container(containerName.c_str(), instance, additional.c_str());
		}
		ACS_SHORT_LOG((LM_INFO, "Container stop message issued."));

	}
	catch (ACSErrTypeCommon::BadParameterEx &ex)
	{
		ACSErrTypeCommon::BadParameterExImpl exImpl(ex);
		exImpl.log();
		return -1;
	}
	catch (acsdaemonErrType::FailedToStopContainerEx &ex)
	{
		acsdaemonErrType::FailedToStopContainerExImpl exImpl(ex);
		exImpl.log();
		return -1;
	}
	catch( CORBA::Exception &ex )
	{
		ACS_SHORT_LOG((LM_INFO, "Failed."));
		ACE_PRINT_EXCEPTION (ex, ACE_TEXT ("Caught unexpected exception:"));
		return -1;
	}

	return 0;
}

<|endoftext|>


<commit_before>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2011
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: bulkDataNTWriterListener.cpp,v 1.3 2011/10/14 17:30:28 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* almadev  2011-10-14  created
*/

#include "bulkDataNTWriterListener.h"

#include <ACS_DDS_Errors.h>
#include <iostream>

using namespace std;

BulkDataNTWriterListener::BulkDataNTWriterListener(const char *name) :
		topicName_m(name)
{
	ACS_TRACE(__PRETTY_FUNCTION__);
	sum_unacknowledged_sample = 0;
	max_unacknowledged_sample =0;
	iter=0;
}

// Implementation skeleton destructor
BulkDataNTWriterListener::~BulkDataNTWriterListener ()
{
	ACS_TRACE(__PRETTY_FUNCTION__);
}

void BulkDataNTWriterListener::on_offered_deadline_missed (
		::DDS::DataWriter* writer,
		const ::DDS::OfferedDeadlineMissedStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_offered_deadline_missed" << endl;
}

void BulkDataNTWriterListener::on_offered_incompatible_qos (
		::DDS::DataWriter* writer,
		const ::DDS::OfferedIncompatibleQosStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_offered_incompatible_qos" << endl;
}

void BulkDataNTWriterListener::on_liveliness_lost (
		::DDS::DataWriter* writer,
		const ::DDS::LivelinessLostStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_liveliness_lost" << endl;
}

void BulkDataNTWriterListener::on_publication_matched (
		::DDS::DataWriter* writer,
		const ::DDS::PublicationMatchedStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_publication_match" << endl;
}

void BulkDataNTWriterListener::on_reliable_writer_cache_changed(DDSDataWriter* writer,
		const DDS_ReliableWriterCacheChangedStatus& status)
{
	sum_unacknowledged_sample += status.unacknowledged_sample_count;
	if( status.unacknowledged_sample_count > max_unacknowledged_sample)
		max_unacknowledged_sample = status.unacknowledged_sample_count;
	iter++;
/*
	cerr << "==========> BDDDSWriterListenerImpl::on_reliable_writer_cache_changed" << endl;
	cerr << "==========> unacknowledged_sample_count: " << status.unacknowledged_sample_count;
	cerr << " unacknowledged_sample_count_peak: " << status.unacknowledged_sample_count_peak << endl;
*/
}

void BulkDataNTWriterListener::on_reliable_reader_activity_changed(DDSDataWriter* writer,
		const DDS::ReliableReaderActivityChangedStatus& status)
{
	cerr <<  topicName_m << " ==========> BulkDataNTWriterListener::on_reliable_reader_activity_changed:" << endl;
	cerr <<  topicName_m << "   ==========>	status.active_count:" << status.active_count << endl;
	cerr <<  topicName_m << "   ==========>	status.active_count_change:" << status.active_count_change << endl;
	cerr <<  topicName_m << "   ==========>	status.inactive_count:" << status.inactive_count << endl;
	cerr <<  topicName_m << "   ==========>	status.inactive_count_change:" << status.inactive_count_change << endl;
}

void BulkDataNTWriterListener::on_destination_unreachable(DDSDataWriter* writer,
		const DDS_InstanceHandle_t& handle,
		const DDS_Locator_t& destination)
{
	cerr <<  topicName_m << " BulkDataNTWriterListener::on_destination_unreachable" << endl;
}

/*___oOo___*/
<commit_msg>implementd on_publication_matched<commit_after>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2011
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: bulkDataNTWriterListener.cpp,v 1.4 2012/01/12 11:41:38 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* almadev  2011-10-14  created
*/

#include "bulkDataNTWriterListener.h"

#include <ACS_DDS_Errors.h>
#include <iostream>

using namespace std;

BulkDataNTWriterListener::BulkDataNTWriterListener(const char *name) :
		topicName_m(name)
{
	ACS_TRACE(__PRETTY_FUNCTION__);
	sum_unacknowledged_sample = 0;
	max_unacknowledged_sample =0;
	iter=0;
}

// Implementation skeleton destructor
BulkDataNTWriterListener::~BulkDataNTWriterListener ()
{
	ACS_TRACE(__PRETTY_FUNCTION__);
}

void BulkDataNTWriterListener::on_offered_deadline_missed (
		::DDS::DataWriter* writer,
		const ::DDS::OfferedDeadlineMissedStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_offered_deadline_missed" << endl;
}

void BulkDataNTWriterListener::on_offered_incompatible_qos (
		::DDS::DataWriter* writer,
		const ::DDS::OfferedIncompatibleQosStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_offered_incompatible_qos" << endl;
}

void BulkDataNTWriterListener::on_liveliness_lost (
		::DDS::DataWriter* writer,
		const ::DDS::LivelinessLostStatus & status)
{
	cerr << topicName_m << " BulkDataNTWriterListener::on_liveliness_lost" << endl;
}

void BulkDataNTWriterListener::on_publication_matched (DDS::DataWriter* writer,	const DDS::PublicationMatchedStatus & status)
{
	ACS_TRACE(__FUNCTION__);
}//on_publication_matched

void BulkDataNTWriterListener::on_reliable_writer_cache_changed(DDSDataWriter* writer,
		const DDS_ReliableWriterCacheChangedStatus& status)
{
	sum_unacknowledged_sample += status.unacknowledged_sample_count;
	if( status.unacknowledged_sample_count > max_unacknowledged_sample)
		max_unacknowledged_sample = status.unacknowledged_sample_count;
	iter++;
/*
	cerr << "==========> BDDDSWriterListenerImpl::on_reliable_writer_cache_changed" << endl;
	cerr << "==========> unacknowledged_sample_count: " << status.unacknowledged_sample_count;
	cerr << " unacknowledged_sample_count_peak: " << status.unacknowledged_sample_count_peak << endl;
*/
}

void BulkDataNTWriterListener::on_reliable_reader_activity_changed(DDSDataWriter* writer,
		const DDS::ReliableReaderActivityChangedStatus& status)
{
	cerr <<  topicName_m << " ==========> BulkDataNTWriterListener::on_reliable_reader_activity_changed:" << endl;
	cerr <<  topicName_m << "   ==========>	status.active_count:" << status.active_count << endl;
	cerr <<  topicName_m << "   ==========>	status.active_count_change:" << status.active_count_change << endl;
	cerr <<  topicName_m << "   ==========>	status.inactive_count:" << status.inactive_count << endl;
	cerr <<  topicName_m << "   ==========>	status.inactive_count_change:" << status.inactive_count_change << endl;
}

void BulkDataNTWriterListener::on_destination_unreachable(DDSDataWriter* writer,
		const DDS_InstanceHandle_t& handle,
		const DDS_Locator_t& destination)
{
	cerr <<  topicName_m << " BulkDataNTWriterListener::on_destination_unreachable" << endl;
}

/*___oOo___*/
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    "../Characters/Format.h"
#include    "../Execution/Logger.h"
#include    "../IO/FileSystem/FileInputStream.h"
#include    "../IO/FileSystem/FileOutputStream.h"
#include    "../IO/FileSystem/PathName.h"
#include    "../IO/FileSystem/ThroughTmpFileWriter.h"
#include    "../IO/FileSystem/WellKnownLocations.h"
#include    "../Streams/MemoryStream.h"

#include    "JSON/Reader.h"
#include    "JSON/Writer.h"
#include    "XML/Reader.h"
#include    "XML/Writer.h"
#include    "VariantValue.h"

#include    "OptionsFile.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::Streams;

using   Memory::BLOB;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 ***************** DataExchange::OptionsFile::LoggerMessage *********************
 ********************************************************************************
 */
OptionsFile::LoggerMessage::LoggerMessage (Msg msg, String fn)
    : fMsg (msg)
    , fFileName (fn)
{
}

String  OptionsFile::LoggerMessage::FormatMessage () const
{
    switch (fMsg) {
        case Msg::eFailedToWriteFile:
            return Characters::Format (L"Failed to write file: %s", fFileName.Value ().c_str ());
        case Msg::eFailedToReadFile:
            return Characters::Format (L"Failed to read file: %s", fFileName.Value ().c_str ());
        case Msg::eFailedToParseReadFile:
            return Characters::Format (L"Error analyzing configuration file '%s' - using defaults.", fFileName.Value ().c_str ());
        case Msg::eFailedToParseReadFileBadFormat:
            return Characters::Format (L"Error analyzing configuration file (because bad format) '%s' - using defaults.", fFileName.Value ().c_str ());
        case Msg::eFailedToCompareReadFile:
            return Characters::Format (L"Failed to compare configuration file: %s", fFileName.Value ().c_str ());
        case Msg::eWritingConfigFile_SoDefaultsEditable:
            return Characters::Format (L"Writing configuration file '%s' because not found (and so defaults are more easily seen and editable).", fFileName.Value ().c_str ());
        case Msg::eWritingConfigFile_BecauseUpgraded:
            return Characters::Format (L"Writing configuration file '%s' in a new location because the software has been upgraded.", fFileName.Value ().c_str ());
        case Msg::eWritingConfigFile_BecauseSomethingChanged:
            return Characters::Format (L"Writing configuration file '%s' because something changed (e.g. a default, or field added/removed).", fFileName.Value ().c_str ());
        case Msg::eFailedToWriteInUseValues:
            return Characters::Format (L"Failed to write default (in use) values to file: %s", fFileName.Value ().c_str ());
        default:
            RequireNotReached ();
            return String ();
    }
}

/*
 ********************************************************************************
 ************************** DataExchange::OptionsFile ***************************
 ********************************************************************************
 */
const   OptionsFile::ModuleDataUpgraderType  OptionsFile::kDefaultUpgrader = [] (const Memory::Optional<Configuration::Version>& version, const VariantValue& rawVariantValue) -> VariantValue {
    return rawVariantValue;
};

const   OptionsFile::LoggerType OptionsFile::kDefaultLogger =
    [] (const LoggerMessage& message)
{
    using   Execution::Logger;
    Logger::Priority priority = Logger::Priority::eError;
    using Msg = OptionsFile::LoggerMessage::Msg;
    switch (message.fMsg) {
        case Msg::eFailedToReadFile:
            priority = Logger::Priority::eWarning;   // could be just because new system, no file
            break;
        case Msg::eWritingConfigFile_SoDefaultsEditable:
        case Msg::eWritingConfigFile_BecauseUpgraded:
        case Msg::eWritingConfigFile_BecauseSomethingChanged:
            priority = Logger::Priority::eInfo;
            break;

        case Msg::eFailedToParseReadFile:
        case Msg::eFailedToParseReadFileBadFormat:
            // Most likely very bad - as critical configuration data will be lost, and overwritten with 'defaults'
            priority = Logger::Priority::eCriticalError;
            break;
    }
    Logger::Get ().Log (priority, L"%s", message.FormatMessage ().c_str ());
};

const   OptionsFile::ModuleNameToFileNameMapperType  OptionsFile::mkFilenameMapper (const String& appName)
{
    String useAppName = appName;
    return
    [useAppName] (const String & moduleName, const String & fileSuffix) -> String {
        return IO::FileSystem::WellKnownLocations::GetApplicationData() + useAppName + String (IO::FileSystem::kPathComponentSeperator) + moduleName + fileSuffix;
    }
    ;
}

const   OptionsFile::ModuleNameToFileVersionMapperType  OptionsFile::kDefaultModuleNameToFileVersionMapper = [] (const String& moduleName) -> Optional<Configuration::Version> {
    return Optional<Configuration::Version> (); // default to dont know
};

// Consider using XML by default when more mature
const   VariantReader  OptionsFile::kDefaultReader =   JSON::Reader ();
const   VariantWriter  OptionsFile::kDefaultWriter =   JSON::Writer ();

OptionsFile::OptionsFile (
    const String& modName,
    const ObjectVariantMapper& mapper,
    ModuleDataUpgraderType moduleUpgrader,
    ModuleNameToFileNameMapperType moduleNameToFileNameMapper,
    ModuleNameToFileVersionMapperType moduleNameToReadFileVersion,
    LoggerType logger,
    VariantReader reader,
    VariantWriter writer
)
    : OptionsFile (modName, mapper, moduleUpgrader, moduleNameToFileNameMapper, moduleNameToFileNameMapper, moduleNameToReadFileVersion, logger, reader, writer, reader.GetDefaultFileSuffix ())
{
}

OptionsFile::OptionsFile (
    const String& modName,
    const ObjectVariantMapper& mapper,
    ModuleDataUpgraderType moduleUpgrader,
    ModuleNameToFileNameMapperType moduleNameToReadFileNameMapper,
    ModuleNameToFileNameMapperType moduleNameToWriteFileNameMapper,
    ModuleNameToFileVersionMapperType moduleNameToReadFileVersion,
    LoggerType logger,
    VariantReader reader,
    VariantWriter writer
)
    : OptionsFile (modName, mapper, moduleUpgrader, moduleNameToReadFileNameMapper, moduleNameToWriteFileNameMapper, moduleNameToReadFileVersion, logger, reader, writer, reader.GetDefaultFileSuffix ())
{
}

OptionsFile::OptionsFile (
    const String& modName,
    const ObjectVariantMapper& mapper,
    ModuleDataUpgraderType moduleUpgrader,
    ModuleNameToFileNameMapperType moduleNameToReadFileNameMapper,
    ModuleNameToFileNameMapperType moduleNameToWriteFileNameMapper,
    ModuleNameToFileVersionMapperType moduleNameToReadFileVersion,
    LoggerType logger,
    VariantReader reader,
    VariantWriter writer,
    const String& fileSuffix
)
    : fModuleName_ (modName)
    , fMapper_ (mapper)
    , fModuleDataUpgrader_ (moduleUpgrader)
    , fModuleNameToReadFileNameMapper_ (moduleNameToReadFileNameMapper)
    , fModuleNameToWriteFileNameMapper_ (moduleNameToWriteFileNameMapper)
    , fModuleNameToFileVersionMapper_ (moduleNameToReadFileVersion)
    , fLogger_ (logger)
    , fReader_ (reader)
    , fWriter_ (writer)
    , fFileSuffix_ (fileSuffix)
{
}

BLOB    OptionsFile::ReadRaw () const
{
    Debug::TraceContextBumper  ctx ("OptionsFile::ReadRaw");
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"(readfilename=%s)", GetReadFilePath_ ().c_str ());
#endif
    return IO::FileSystem::FileInputStream::mk (GetReadFilePath_ ()).ReadAll ();
}

void    OptionsFile::WriteRaw (const BLOB& blob)
{
    Debug::TraceContextBumper  ctx ("OptionsFile::WriteRaw");
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"(writefilename=%s)", GetWriteFilePath_ ().c_str ());
#endif
    if (GetReadFilePath_ () == GetWriteFilePath_ ()) {
        try {
            if (ReadRaw () == blob) {
                return;
            }
        }
        catch (...) {
            // No matter why we fail, nevermind. Just fall through and write.
        }
    }
    try {
        IO::FileSystem::ThroughTmpFileWriter    tmpFile (GetWriteFilePath_ ());
        IO::FileSystem::FileOutputStream        outStream (tmpFile.GetFilePath ());
        outStream.Write (blob);
        outStream.Flush ();
        outStream.clear ();     // so any errors can be displayed as exceptions, and so closed before commit/rename
        tmpFile.Commit ();
    }
    catch (...) {
        fLogger_ (LoggerMessage (LoggerMessage::Msg::eFailedToWriteFile, GetWriteFilePath_ ()));
    }
}

template    <>
Optional<VariantValue>  OptionsFile::Read ()
{
    Debug::TraceContextBumper  ctx ("OptionsFile::Read");
    try {
        Optional<VariantValue>  r   =   fReader_.Read (MemoryStream<Byte> (ReadRaw ()));
        if (r.IsPresent ()) {
            r = fModuleDataUpgrader_ (fModuleNameToFileVersionMapper_ (fModuleName_), *r);
        }
        return r;
    }
    catch (...) {
        // @todo - check different exception cases and for some - like file not found - just no warning...
        fLogger_ (LoggerMessage (LoggerMessage::Msg::eFailedToReadFile, GetReadFilePath_ ()));
        return Optional<VariantValue> ();
    }
}

template    <>
void        OptionsFile::Write (const VariantValue& optionsObject)
{
    Debug::TraceContextBumper  ctx ("OptionsFile::Write");
    MemoryStream<Byte> tmp;
    fWriter_.Write (optionsObject, tmp);
    WriteRaw (tmp.As<BLOB> ());
}

String  OptionsFile::GetReadFilePath_ () const
{
    return fModuleNameToReadFileNameMapper_(fModuleName_, fFileSuffix_);
}

String  OptionsFile::GetWriteFilePath_ () const
{
    return fModuleNameToWriteFileNameMapper_(fModuleName_, fFileSuffix_);
}
<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    "../Characters/Format.h"
#include    "../Execution/Logger.h"
#include    "../IO/FileSystem/FileInputStream.h"
#include    "../IO/FileSystem/FileOutputStream.h"
#include    "../IO/FileSystem/PathName.h"
#include    "../IO/FileSystem/ThroughTmpFileWriter.h"
#include    "../IO/FileSystem/WellKnownLocations.h"
#include    "../Streams/MemoryStream.h"

#include    "JSON/Reader.h"
#include    "JSON/Writer.h"
#include    "XML/Reader.h"
#include    "XML/Writer.h"
#include    "VariantValue.h"

#include    "OptionsFile.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::Streams;

using   Memory::BLOB;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 ***************** DataExchange::OptionsFile::LoggerMessage *********************
 ********************************************************************************
 */
OptionsFile::LoggerMessage::LoggerMessage (Msg msg, String fn)
    : fMsg (msg)
    , fFileName (fn)
{
}

String  OptionsFile::LoggerMessage::FormatMessage () const
{
    switch (fMsg) {
        case Msg::eFailedToWriteFile:
            return Characters::Format (L"Failed to write file: %s", fFileName.Value ().c_str ());
        case Msg::eFailedToReadFile:
            return Characters::Format (L"Failed to read file: %s", fFileName.Value ().c_str ());
        case Msg::eFailedToParseReadFile:
            return Characters::Format (L"Error analyzing configuration file '%s' - using defaults.", fFileName.Value ().c_str ());
        case Msg::eFailedToParseReadFileBadFormat:
            return Characters::Format (L"Error analyzing configuration file (because bad format) '%s' - using defaults.", fFileName.Value ().c_str ());
        case Msg::eFailedToCompareReadFile:
            return Characters::Format (L"Failed to compare configuration file: %s", fFileName.Value ().c_str ());
        case Msg::eWritingConfigFile_SoDefaultsEditable:
            return Characters::Format (L"Writing configuration file '%s' because not found (and so defaults are more easily seen and editable).", fFileName.Value ().c_str ());
        case Msg::eWritingConfigFile_BecauseUpgraded:
            return Characters::Format (L"Writing configuration file '%s' in a new location because the software has been upgraded.", fFileName.Value ().c_str ());
        case Msg::eWritingConfigFile_BecauseSomethingChanged:
            return Characters::Format (L"Writing configuration file '%s' because something changed (e.g. a default, or field added/removed).", fFileName.Value ().c_str ());
        case Msg::eFailedToWriteInUseValues:
            return Characters::Format (L"Failed to write default (in use) values to file: %s", fFileName.Value ().c_str ());
        default:
            RequireNotReached ();
            return String ();
    }
}

/*
 ********************************************************************************
 ************************** DataExchange::OptionsFile ***************************
 ********************************************************************************
 */
const   OptionsFile::ModuleDataUpgraderType  OptionsFile::kDefaultUpgrader = [] (const Memory::Optional<Configuration::Version>& version, const VariantValue& rawVariantValue) -> VariantValue {
    return rawVariantValue;
};

const   OptionsFile::LoggerType OptionsFile::kDefaultLogger =
    [] (const LoggerMessage& message)
{
    using   Execution::Logger;
    Logger::Priority priority = Logger::Priority::eError;
    using Msg = OptionsFile::LoggerMessage::Msg;
    switch (message.fMsg) {
        case Msg::eFailedToReadFile:
            priority = Logger::Priority::eWarning;   // could be just because new system, no file
            break;
        case Msg::eWritingConfigFile_SoDefaultsEditable:
        case Msg::eWritingConfigFile_BecauseUpgraded:
        case Msg::eWritingConfigFile_BecauseSomethingChanged:
            priority = Logger::Priority::eInfo;
            break;

        case Msg::eFailedToParseReadFile:
        case Msg::eFailedToParseReadFileBadFormat:
            // Most likely very bad - as critical configuration data will be lost, and overwritten with 'defaults'
            priority = Logger::Priority::eCriticalError;
            break;
    }
    Logger::Get ().Log (priority, L"%s", message.FormatMessage ().c_str ());
};

const   OptionsFile::ModuleNameToFileNameMapperType  OptionsFile::mkFilenameMapper (const String& appName)
{
    String useAppName = appName;
    return
    [useAppName] (const String & moduleName, const String & fileSuffix) -> String {
        return IO::FileSystem::WellKnownLocations::GetApplicationData() + useAppName + String (IO::FileSystem::kPathComponentSeperator) + moduleName + fileSuffix;
    }
    ;
}

const   OptionsFile::ModuleNameToFileVersionMapperType  OptionsFile::kDefaultModuleNameToFileVersionMapper = [] (const String& moduleName) -> Optional<Configuration::Version> {
    return Optional<Configuration::Version> (); // default to dont know
};

// Consider using XML by default when more mature
const   VariantReader  OptionsFile::kDefaultReader =   JSON::Reader ();
const   VariantWriter  OptionsFile::kDefaultWriter =   JSON::Writer ();

OptionsFile::OptionsFile (
    const String& modName,
    const ObjectVariantMapper& mapper,
    ModuleDataUpgraderType moduleUpgrader,
    ModuleNameToFileNameMapperType moduleNameToFileNameMapper,
    ModuleNameToFileVersionMapperType moduleNameToReadFileVersion,
    LoggerType logger,
    VariantReader reader,
    VariantWriter writer
)
    : OptionsFile (modName, mapper, moduleUpgrader, moduleNameToFileNameMapper, moduleNameToFileNameMapper, moduleNameToReadFileVersion, logger, reader, writer, reader.GetDefaultFileSuffix ())
{
}

OptionsFile::OptionsFile (
    const String& modName,
    const ObjectVariantMapper& mapper,
    ModuleDataUpgraderType moduleUpgrader,
    ModuleNameToFileNameMapperType moduleNameToReadFileNameMapper,
    ModuleNameToFileNameMapperType moduleNameToWriteFileNameMapper,
    ModuleNameToFileVersionMapperType moduleNameToReadFileVersion,
    LoggerType logger,
    VariantReader reader,
    VariantWriter writer
)
    : OptionsFile (modName, mapper, moduleUpgrader, moduleNameToReadFileNameMapper, moduleNameToWriteFileNameMapper, moduleNameToReadFileVersion, logger, reader, writer, reader.GetDefaultFileSuffix ())
{
}

OptionsFile::OptionsFile (
    const String& modName,
    const ObjectVariantMapper& mapper,
    ModuleDataUpgraderType moduleUpgrader,
    ModuleNameToFileNameMapperType moduleNameToReadFileNameMapper,
    ModuleNameToFileNameMapperType moduleNameToWriteFileNameMapper,
    ModuleNameToFileVersionMapperType moduleNameToReadFileVersion,
    LoggerType logger,
    VariantReader reader,
    VariantWriter writer,
    const String& fileSuffix
)
    : fModuleName_ (modName)
    , fMapper_ (mapper)
    , fModuleDataUpgrader_ (moduleUpgrader)
    , fModuleNameToReadFileNameMapper_ (moduleNameToReadFileNameMapper)
    , fModuleNameToWriteFileNameMapper_ (moduleNameToWriteFileNameMapper)
    , fModuleNameToFileVersionMapper_ (moduleNameToReadFileVersion)
    , fLogger_ (logger)
    , fReader_ (reader)
    , fWriter_ (writer)
    , fFileSuffix_ (fileSuffix)
{
}

BLOB    OptionsFile::ReadRaw () const
{
    Debug::TraceContextBumper  ctx ("OptionsFile::ReadRaw");
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"(readfilename=%s)", GetReadFilePath_ ().c_str ());
#endif
    return IO::FileSystem::FileInputStream::mk (GetReadFilePath_ ()).ReadAll ();
}

void    OptionsFile::WriteRaw (const BLOB& blob)
{
    Debug::TraceContextBumper  ctx ("OptionsFile::WriteRaw");
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"(writefilename=%s)", GetWriteFilePath_ ().c_str ());
#endif
    if (GetReadFilePath_ () == GetWriteFilePath_ ()) {
        try {
            if (ReadRaw () == blob) {
                return;
            }
        }
        catch (...) {
            // No matter why we fail, nevermind. Just fall through and write.
        }
    }
    try {
        IO::FileSystem::ThroughTmpFileWriter    tmpFile (GetWriteFilePath_ ());
        IO::FileSystem::FileOutputStream        outStream (tmpFile.GetFilePath ());
        outStream.Write (blob);
        outStream.Flush ();
        outStream.clear ();     // so any errors can be displayed as exceptions, and so closed before commit/rename
        tmpFile.Commit ();
    }
    catch (...) {
        fLogger_ (LoggerMessage (LoggerMessage::Msg::eFailedToWriteFile, GetWriteFilePath_ ()));
    }
}

template    <>
Optional<VariantValue>  OptionsFile::Read ()
{
    Debug::TraceContextBumper  ctx ("OptionsFile::Read");
    try {
        Optional<VariantValue>  r   =   fReader_.Read (MemoryStream<Byte> (ReadRaw ()));
        if (r.IsPresent ()) {
            r = fModuleDataUpgrader_ (fModuleNameToFileVersionMapper_ (fModuleName_), *r);
        }
        return r;
    }
    catch (...) {
        // @todo - check different exception cases and for some - like file not found - just no warning...
        fLogger_ (LoggerMessage (LoggerMessage::Msg::eFailedToReadFile, GetReadFilePath_ ()));
        return Optional<VariantValue> ();
    }
}

template    <>
void        OptionsFile::Write (const VariantValue& optionsObject)
{
    Debug::TraceContextBumper  ctx ("OptionsFile::Write");
    MemoryStream<Byte> tmp;
    fWriter_.Write (optionsObject, tmp);
    WriteRaw (tmp.As<BLOB> ());
}

String  OptionsFile::GetReadFilePath_ () const
{
    return fModuleNameToReadFileNameMapper_ (fModuleName_, fFileSuffix_);
}

String  OptionsFile::GetWriteFilePath_ () const
{
    return fModuleNameToWriteFileNameMapper_ (fModuleName_, fFileSuffix_);
}
<|endoftext|>


<commit_before>#include "TM0Cylindrical.h"

template<>
InputParameters validParams<TM0Cylindrical>()
{
  InputParameters params = validParams<Kernel>();
  // params.addRequiredParam<Real>("position_units", "Units of position.");
  params.addRequiredParam<Real>("f", "The drive frequency.");
  params.addParam<Real>("eps_r", 1., "The relative permittivity of the medium.");
  return params;
}

TM0Cylindrical::TM0Cylindrical(const InputParameters & parameters) :
    Kernel(parameters),

    // _r_units(1. / getParam<Real>("position_units")),
    _omega(2. * libMesh::pi * getParam<Real>("f")),
    _eps_r(getParam<Real>("eps_r")),
    _mu0(4. * libMesh::pi * 1e-7),
    _eps0(8.85e-12)
{
}

TM0Cylindrical::~TM0Cylindrical()
{
}

Real
TM0Cylindrical::computeQpResidual()
{
  return -_grad_test[_i][_qp] * _grad_u[_qp] - _test[_i][_qp] * _u[_qp] / std::pow(_q_point[_qp](0), 2) + _test[_i][_qp] * std::pow(_omega, 2) * _mu0 * _eps_r * _eps0 * _u[_qp];
}

Real
TM0Cylindrical::computeQpJacobian()
{
  return -_grad_test[_i][_qp] * _grad_phi[_j][_qp] - _test[_i][_qp] * _phi[_j][_qp] / std::pow(_q_point[_qp](0), 2) + _test[_i][_qp] * std::pow(_omega, 2) * _mu0 * _eps_r * _eps0 * _phi[_j][_qp];
}
<commit_msg>Possible error in dielectric formulation.<commit_after>#include "TM0Cylindrical.h"

template<>
InputParameters validParams<TM0Cylindrical>()
{
  InputParameters params = validParams<Kernel>();
  // params.addRequiredParam<Real>("position_units", "Units of position.");
  params.addRequiredParam<Real>("f", "The drive frequency.");
  params.addParam<Real>("eps_r", 1., "The relative permittivity of the medium.");
  return params;
}

TM0Cylindrical::TM0Cylindrical(const InputParameters & parameters) :
    Kernel(parameters),

    // _r_units(1. / getParam<Real>("position_units")),
    _omega(2. * libMesh::pi * getParam<Real>("f")),
    _eps_r(getParam<Real>("eps_r")),
    _mu0(4. * libMesh::pi * 1e-7),
    _eps0(8.85e-12)
{
}

TM0Cylindrical::~TM0Cylindrical()
{
}

Real
TM0Cylindrical::computeQpResidual()
{
  return -_grad_test[_i][_qp] * _grad_u[_qp] / _eps_r - _test[_i][_qp] * _u[_qp] / std::pow(_q_point[_qp](0), 2) / _eps_r + _test[_i][_qp] * std::pow(_omega, 2) * _mu0 * _eps_r * _eps0 * _u[_qp];
}

Real
TM0Cylindrical::computeQpJacobian()
{
  return -_grad_test[_i][_qp] * _grad_phi[_j][_qp] / _eps_r - _test[_i][_qp] * _phi[_j][_qp] / std::pow(_q_point[_qp](0), 2) / _eps_r + _test[_i][_qp] * std::pow(_omega, 2) * _mu0 * _eps_r * _eps0 * _phi[_j][_qp];
}
<|endoftext|>