<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <hintids.hxx>
#include <uitool.hxx>
#include <svl/urihelper.hxx>
#include <svl/PasswordHelper.hxx>
#include <vcl/msgbox.hxx>
#include <svl/stritem.hxx>
#include <svl/eitem.hxx>
#include <sot/formats.hxx>
#include <sfx2/passwd.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/request.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/linkmgr.hxx>
#include <editeng/sizeitem.hxx>
#include <svtools/htmlcfg.hxx>
#include <section.hxx>
#include <docary.hxx>
#include <regionsw.hxx>
#include <basesh.hxx>
#include <wdocsh.hxx>
#include <view.hxx>
#include <swmodule.hxx>
#include <wrtsh.hxx>
#include <swundo.hxx>                   // for Undo-Ids
#include <column.hxx>
#include <fmtfsize.hxx>
#include <shellio.hxx>
#include <helpid.h>
#include <cmdid.h>
#include <regionsw.hrc>
#include <comcore.hrc>
#include <globals.hrc>
#include <sfx2/bindings.hxx>
#include <svx/htmlmode.hxx>
#include <svx/dlgutil.hxx>
#include "swabstdlg.hxx"
#include <boost/scoped_ptr.hpp>

void SwBaseShell::InsertRegionDialog(SfxRequest& rReq)
{
    SwWrtShell& rSh = GetShell();
    const SfxItemSet *pSet = rReq.GetArgs();

    SfxItemSet aSet(GetPool(),
            RES_COL, RES_COL,
            RES_LR_SPACE, RES_LR_SPACE,
            RES_COLUMNBALANCE, RES_FRAMEDIR,
            RES_BACKGROUND, RES_BACKGROUND,
            RES_FRM_SIZE, RES_FRM_SIZE,
            RES_FTN_AT_TXTEND, RES_END_AT_TXTEND,
            SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
            0);

    if (!pSet || pSet->Count()==0)
    {
        SwRect aRect;
        rSh.CalcBoundRect(aRect, FLY_AS_CHAR);

        long nWidth = aRect.Width();
        aSet.Put(SwFmtFrmSize(ATT_VAR_SIZE, nWidth));

        // height=width for more consistent preview (analog to edit region)
        aSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(nWidth, nWidth)));
        SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
        OSL_ENSURE(pFact, "Dialogdiet fail!");
        AbstractInsertSectionTabDialog* aTabDlg = pFact->CreateInsertSectionTabDialog( DLG_INSERT_SECTION,
                                                        &GetView().GetViewFrame()->GetWindow(), aSet , rSh);
        OSL_ENSURE(aTabDlg, "Dialogdiet fail!");
        aTabDlg->Execute();
        rReq.Ignore();
        delete aTabDlg;
    }
    else
    {
        const SfxPoolItem *pItem = 0;
        String aTmpStr;
        if ( SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_REGION_NAME, sal_True, &pItem) )
            aTmpStr = rSh.GetUniqueSectionName(
                    &((const SfxStringItem *)pItem)->GetValue() );
        else
            aTmpStr = rSh.GetUniqueSectionName();

        SwSectionData aSection(CONTENT_SECTION, aTmpStr);
        rReq.SetReturnValue(SfxStringItem(FN_INSERT_REGION, aTmpStr));

        aSet.Put( *pSet );
        if(SFX_ITEM_SET == pSet->GetItemState(SID_ATTR_COLUMNS, sal_False, &pItem)||
            SFX_ITEM_SET == pSet->GetItemState(FN_INSERT_REGION, sal_False, &pItem))
        {
            SwFmtCol aCol;
            SwRect aRect;
            rSh.CalcBoundRect(aRect, FLY_AS_CHAR);
            long nWidth = aRect.Width();

            sal_uInt16 nCol = ((SfxUInt16Item *)pItem)->GetValue();
            if(nCol)
            {
                aCol.Init( nCol, 0, static_cast< sal_uInt16 >(nWidth) );
                aSet.Put(aCol);
            }
        }
        else if(SFX_ITEM_SET == pSet->GetItemState(RES_COL, sal_False, &pItem))
        {
            aSet.Put(*pItem);
        }

        const sal_Bool bHidden = SFX_ITEM_SET ==
            pSet->GetItemState(FN_PARAM_REGION_HIDDEN, sal_True, &pItem)?
            (sal_Bool)((const SfxBoolItem *)pItem)->GetValue():sal_False;
        const sal_Bool bProtect = SFX_ITEM_SET ==
            pSet->GetItemState(FN_PARAM_REGION_PROTECT, sal_True, &pItem)?
            (sal_Bool)((const SfxBoolItem *)pItem)->GetValue():sal_False;
        // #114856# edit in readonly sections
        const sal_Bool bEditInReadonly = SFX_ITEM_SET ==
            pSet->GetItemState(FN_PARAM_REGION_EDIT_IN_READONLY, sal_True, &pItem)?
            (sal_Bool)((const SfxBoolItem *)pItem)->GetValue():sal_False;

        aSection.SetProtectFlag(bProtect);
        aSection.SetHidden(bHidden);
        // #114856# edit in readonly sections
        aSection.SetEditInReadonlyFlag(bEditInReadonly);

        if(SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_REGION_CONDITION, sal_True, &pItem))
            aSection.SetCondition(((const SfxStringItem *)pItem)->GetValue());

        String aFile, aSub;
        if(SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_1, sal_True, &pItem))
            aFile = ((const SfxStringItem *)pItem)->GetValue();

        if(SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_3, sal_True, &pItem))
            aSub = ((const SfxStringItem *)pItem)->GetValue();

        if(aFile.Len() || aSub.Len())
        {
            String sLinkFileName = rtl::OUString(sfx2::cTokenSeperator);
            sLinkFileName += sfx2::cTokenSeperator;
            sLinkFileName.SetToken(0, sfx2::cTokenSeperator,aFile);

            if(SFX_ITEM_SET ==
                    pSet->GetItemState(FN_PARAM_2, sal_True, &pItem))
                sLinkFileName.SetToken(1, sfx2::cTokenSeperator,
                    ((const SfxStringItem *)pItem)->GetValue());

            sLinkFileName += aSub;
            aSection.SetType( FILE_LINK_SECTION );
            aSection.SetLinkFileName(sLinkFileName);
        }
        rSh.InsertSection(aSection, aSet.Count() ? &aSet : 0);
        rReq.Done();
    }
}

IMPL_STATIC_LINK( SwWrtShell, InsertRegionDialog, SwSectionData*, pSect )
{
    boost::scoped_ptr<SwSectionData> xSectionData(pSect);
    if (xSectionData.get())
    {
        SfxItemSet aSet(pThis->GetView().GetPool(),
                RES_COL, RES_COL,
                RES_BACKGROUND, RES_BACKGROUND,
                RES_FRM_SIZE, RES_FRM_SIZE,
                SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
                0);
        SwRect aRect;
        pThis->CalcBoundRect(aRect, FLY_AS_CHAR);
        long nWidth = aRect.Width();
        aSet.Put(SwFmtFrmSize(ATT_VAR_SIZE, nWidth));
        // height=width for more consistent preview (analog to edit region)
        aSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(nWidth, nWidth)));
        SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
        OSL_ENSURE(pFact, "Dialogdiet fail!");
        AbstractInsertSectionTabDialog* aTabDlg = pFact->CreateInsertSectionTabDialog( DLG_INSERT_SECTION,
                                                        &pThis->GetView().GetViewFrame()->GetWindow(),aSet , *pThis);
        OSL_ENSURE(aTabDlg, "Dialogdiet fail!");
        aTabDlg->SetSectionData(*xSectionData);
        aTabDlg->Execute();

        delete aTabDlg;
    }
    return 0;
}

void SwBaseShell::EditRegionDialog(SfxRequest& rReq)
{
    const SfxItemSet* pArgs = rReq.GetArgs();
    sal_uInt16 nSlot = rReq.GetSlot();
    const SfxPoolItem* pItem = 0;
    if(pArgs)
        pArgs->GetItemState(nSlot, sal_False, &pItem);
    SwWrtShell& rWrtShell = GetShell();

    switch ( nSlot )
    {
        case FN_EDIT_REGION:
        {
            Window* pParentWin = &GetView().GetViewFrame()->GetWindow();
            sal_Bool bStart = sal_True;
            if(bStart)
            {
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
                OSL_ENSURE(pFact, "Dialogdiet fail!");
                AbstractEditRegionDlg* pEditRegionDlg = pFact->CreateEditRegionDlg( MD_EDIT_REGION,
                                                        pParentWin, rWrtShell);
                OSL_ENSURE(pEditRegionDlg, "Dialogdiet fail!");
                if(pItem && pItem->ISA(SfxStringItem))
                {
                    pEditRegionDlg->SelectSection(((const SfxStringItem*)pItem)->GetValue());
                }
                pEditRegionDlg->Execute();
                delete pEditRegionDlg;
            }
            else
                InfoBox(pParentWin, SW_RES(REG_WRONG_PASSWORD)).Execute();
        }
        break;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Drop unreachable branch<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <hintids.hxx>
#include <uitool.hxx>
#include <svl/urihelper.hxx>
#include <svl/PasswordHelper.hxx>
#include <vcl/msgbox.hxx>
#include <svl/stritem.hxx>
#include <svl/eitem.hxx>
#include <sot/formats.hxx>
#include <sfx2/passwd.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/request.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/linkmgr.hxx>
#include <editeng/sizeitem.hxx>
#include <svtools/htmlcfg.hxx>
#include <section.hxx>
#include <docary.hxx>
#include <regionsw.hxx>
#include <basesh.hxx>
#include <wdocsh.hxx>
#include <view.hxx>
#include <swmodule.hxx>
#include <wrtsh.hxx>
#include <swundo.hxx>                   // for Undo-Ids
#include <column.hxx>
#include <fmtfsize.hxx>
#include <shellio.hxx>
#include <helpid.h>
#include <cmdid.h>
#include <regionsw.hrc>
#include <comcore.hrc>
#include <globals.hrc>
#include <sfx2/bindings.hxx>
#include <svx/htmlmode.hxx>
#include <svx/dlgutil.hxx>
#include "swabstdlg.hxx"
#include <boost/scoped_ptr.hpp>

void SwBaseShell::InsertRegionDialog(SfxRequest& rReq)
{
    SwWrtShell& rSh = GetShell();
    const SfxItemSet *pSet = rReq.GetArgs();

    SfxItemSet aSet(GetPool(),
            RES_COL, RES_COL,
            RES_LR_SPACE, RES_LR_SPACE,
            RES_COLUMNBALANCE, RES_FRAMEDIR,
            RES_BACKGROUND, RES_BACKGROUND,
            RES_FRM_SIZE, RES_FRM_SIZE,
            RES_FTN_AT_TXTEND, RES_END_AT_TXTEND,
            SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
            0);

    if (!pSet || pSet->Count()==0)
    {
        SwRect aRect;
        rSh.CalcBoundRect(aRect, FLY_AS_CHAR);

        long nWidth = aRect.Width();
        aSet.Put(SwFmtFrmSize(ATT_VAR_SIZE, nWidth));

        // height=width for more consistent preview (analog to edit region)
        aSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(nWidth, nWidth)));
        SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
        OSL_ENSURE(pFact, "Dialogdiet fail!");
        AbstractInsertSectionTabDialog* aTabDlg = pFact->CreateInsertSectionTabDialog( DLG_INSERT_SECTION,
                                                        &GetView().GetViewFrame()->GetWindow(), aSet , rSh);
        OSL_ENSURE(aTabDlg, "Dialogdiet fail!");
        aTabDlg->Execute();
        rReq.Ignore();
        delete aTabDlg;
    }
    else
    {
        const SfxPoolItem *pItem = 0;
        String aTmpStr;
        if ( SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_REGION_NAME, sal_True, &pItem) )
            aTmpStr = rSh.GetUniqueSectionName(
                    &((const SfxStringItem *)pItem)->GetValue() );
        else
            aTmpStr = rSh.GetUniqueSectionName();

        SwSectionData aSection(CONTENT_SECTION, aTmpStr);
        rReq.SetReturnValue(SfxStringItem(FN_INSERT_REGION, aTmpStr));

        aSet.Put( *pSet );
        if(SFX_ITEM_SET == pSet->GetItemState(SID_ATTR_COLUMNS, sal_False, &pItem)||
            SFX_ITEM_SET == pSet->GetItemState(FN_INSERT_REGION, sal_False, &pItem))
        {
            SwFmtCol aCol;
            SwRect aRect;
            rSh.CalcBoundRect(aRect, FLY_AS_CHAR);
            long nWidth = aRect.Width();

            sal_uInt16 nCol = ((SfxUInt16Item *)pItem)->GetValue();
            if(nCol)
            {
                aCol.Init( nCol, 0, static_cast< sal_uInt16 >(nWidth) );
                aSet.Put(aCol);
            }
        }
        else if(SFX_ITEM_SET == pSet->GetItemState(RES_COL, sal_False, &pItem))
        {
            aSet.Put(*pItem);
        }

        const sal_Bool bHidden = SFX_ITEM_SET ==
            pSet->GetItemState(FN_PARAM_REGION_HIDDEN, sal_True, &pItem)?
            (sal_Bool)((const SfxBoolItem *)pItem)->GetValue():sal_False;
        const sal_Bool bProtect = SFX_ITEM_SET ==
            pSet->GetItemState(FN_PARAM_REGION_PROTECT, sal_True, &pItem)?
            (sal_Bool)((const SfxBoolItem *)pItem)->GetValue():sal_False;
        // #114856# edit in readonly sections
        const sal_Bool bEditInReadonly = SFX_ITEM_SET ==
            pSet->GetItemState(FN_PARAM_REGION_EDIT_IN_READONLY, sal_True, &pItem)?
            (sal_Bool)((const SfxBoolItem *)pItem)->GetValue():sal_False;

        aSection.SetProtectFlag(bProtect);
        aSection.SetHidden(bHidden);
        // #114856# edit in readonly sections
        aSection.SetEditInReadonlyFlag(bEditInReadonly);

        if(SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_REGION_CONDITION, sal_True, &pItem))
            aSection.SetCondition(((const SfxStringItem *)pItem)->GetValue());

        String aFile, aSub;
        if(SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_1, sal_True, &pItem))
            aFile = ((const SfxStringItem *)pItem)->GetValue();

        if(SFX_ITEM_SET ==
                pSet->GetItemState(FN_PARAM_3, sal_True, &pItem))
            aSub = ((const SfxStringItem *)pItem)->GetValue();

        if(aFile.Len() || aSub.Len())
        {
            String sLinkFileName = rtl::OUString(sfx2::cTokenSeperator);
            sLinkFileName += sfx2::cTokenSeperator;
            sLinkFileName.SetToken(0, sfx2::cTokenSeperator,aFile);

            if(SFX_ITEM_SET ==
                    pSet->GetItemState(FN_PARAM_2, sal_True, &pItem))
                sLinkFileName.SetToken(1, sfx2::cTokenSeperator,
                    ((const SfxStringItem *)pItem)->GetValue());

            sLinkFileName += aSub;
            aSection.SetType( FILE_LINK_SECTION );
            aSection.SetLinkFileName(sLinkFileName);
        }
        rSh.InsertSection(aSection, aSet.Count() ? &aSet : 0);
        rReq.Done();
    }
}

IMPL_STATIC_LINK( SwWrtShell, InsertRegionDialog, SwSectionData*, pSect )
{
    boost::scoped_ptr<SwSectionData> xSectionData(pSect);
    if (xSectionData.get())
    {
        SfxItemSet aSet(pThis->GetView().GetPool(),
                RES_COL, RES_COL,
                RES_BACKGROUND, RES_BACKGROUND,
                RES_FRM_SIZE, RES_FRM_SIZE,
                SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
                0);
        SwRect aRect;
        pThis->CalcBoundRect(aRect, FLY_AS_CHAR);
        long nWidth = aRect.Width();
        aSet.Put(SwFmtFrmSize(ATT_VAR_SIZE, nWidth));
        // height=width for more consistent preview (analog to edit region)
        aSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(nWidth, nWidth)));
        SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
        OSL_ENSURE(pFact, "Dialogdiet fail!");
        AbstractInsertSectionTabDialog* aTabDlg = pFact->CreateInsertSectionTabDialog( DLG_INSERT_SECTION,
                                                        &pThis->GetView().GetViewFrame()->GetWindow(),aSet , *pThis);
        OSL_ENSURE(aTabDlg, "Dialogdiet fail!");
        aTabDlg->SetSectionData(*xSectionData);
        aTabDlg->Execute();

        delete aTabDlg;
    }
    return 0;
}

void SwBaseShell::EditRegionDialog(SfxRequest& rReq)
{
    const SfxItemSet* pArgs = rReq.GetArgs();
    sal_uInt16 nSlot = rReq.GetSlot();
    const SfxPoolItem* pItem = 0;
    if(pArgs)
        pArgs->GetItemState(nSlot, sal_False, &pItem);
    SwWrtShell& rWrtShell = GetShell();

    switch ( nSlot )
    {
        case FN_EDIT_REGION:
        {
            Window* pParentWin = &GetView().GetViewFrame()->GetWindow();
            {
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
                OSL_ENSURE(pFact, "Dialogdiet fail!");
                AbstractEditRegionDlg* pEditRegionDlg = pFact->CreateEditRegionDlg( MD_EDIT_REGION,
                                                        pParentWin, rWrtShell);
                OSL_ENSURE(pEditRegionDlg, "Dialogdiet fail!");
                if(pItem && pItem->ISA(SfxStringItem))
                {
                    pEditRegionDlg->SelectSection(((const SfxStringItem*)pItem)->GetValue());
                }
                pEditRegionDlg->Execute();
                delete pEditRegionDlg;
            }
        }
        break;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#ifndef HTTP_CLIENT_HH
#define HTTP_CLIENT_HH

#include "ten/http/http_message.hh"
#include "ten/shared_pool.hh"
#include "ten/buffer.hh"

namespace ten {

//! thrown on http network errors
class http_error : public errorx {
public:
    http_error(const std::string &msg) : errorx(msg) {}
};

//! basic http client
class http_client {
private:
    std::shared_ptr<netsock> s;
    buffer buf;
    std::string host;
    uint16_t port;

    void ensure_connection() {
        if (s && s->valid()) return;
        s.reset(new netsock(AF_INET, SOCK_STREAM));
        if (s->dial(host.c_str(), port) != 0) {
            throw http_error("dial");
        }
    }

public:
    size_t max_content_length;

    http_client(const std::string &host_, uint16_t port_=80)
        : buf(4*1024), host(host_), port(port_), max_content_length(~(size_t)0)
    {
        parse_host_port(host, port);
    }

    http_response perform(const std::string &method, const std::string &path, const std::string &data="") {
        uri u;
        u.scheme = "http";
        u.host = host;
        u.port = port;
        u.path = path;
        u.normalize();

        http_request r(method, u.compose_path());
        // HTTP/1.1 requires host header
        r.set("Host", u.host);
        r.body = data;
        return perform(r);
    }

    http_response perform(http_request &r) {
        if (r.body.size()) {
            r.set("Content-Length", r.body.size());
        }

        try {
            ensure_connection();

            std::string hdata = r.data();
            ssize_t nw = s->send(hdata.c_str(), hdata.size());
            if (r.body.size()) {
                nw = s->send(r.body.c_str(), r.body.size());
            }

            http_parser parser;
            http_response resp;
            resp.parser_init(&parser);

            buf.clear();

            while (!resp.complete) {
                buf.reserve(4*1024);
                ssize_t nr = s->recv(buf.back(), buf.available());
                if (nr <= 0) { throw http_error("recv"); }
                buf.commit(nr);
                size_t len = buf.size();
                resp.parse(&parser, buf.front(), len);
                buf.remove(len);
                if (resp.body.size() >= max_content_length) {
                    s.reset(); // close this socket, we won't read anymore
                    return resp;
                }
            }
            // should not be any data left over in buf
            CHECK(buf.size() == 0);

            return resp;
        } catch (errorx &e) {
            s.reset();
            throw;
        }
    }

    http_response get(const std::string &path) {
        return perform("GET", path);
    }

    http_response post(const std::string &path, const std::string &data) {
        return perform("POST", path, data);
    }

};

class http_pool : public shared_pool<http_client> {
public:
    http_pool(const std::string &host_, uint16_t port_, ssize_t max_conn)
        : shared_pool<http_client>("http://" + host_,
            std::bind(&http_pool::new_resource, this),
            max_conn
        ),
        host(host_), port(port_) {}

protected:
    std::string host;
    uint16_t port;

    std::shared_ptr<http_client> new_resource() {
        VLOG(3) << "new http_client resource " << host << ":" << port;
        return std::make_shared<http_client>(host, port);
    }
};

} // end namespace ten
#endif // HTTP_CLIENT_HH

<commit_msg>conform to coding style<commit_after>#ifndef HTTP_CLIENT_HH
#define HTTP_CLIENT_HH

#include "ten/http/http_message.hh"
#include "ten/shared_pool.hh"
#include "ten/buffer.hh"

namespace ten {

//! thrown on http network errors
class http_error : public errorx {
public:
    http_error(const std::string &msg) : errorx(msg) {}
};

//! basic http client
class http_client {
private:
    std::shared_ptr<netsock> _s;
    buffer _buf;
    std::string _host;
    uint16_t _port;

    void ensure_connection() {
        if (_s && _s->valid()) return;
        _s.reset(new netsock(AF_INET, SOCK_STREAM));
        if (_s->dial(_host.c_str(), _port) != 0) {
            throw http_error("dial");
        }
    }

public:
    size_t max_content_length;

    http_client(const std::string &host_, uint16_t port_=80)
        : _buf(4*1024), _host(host_), _port(port_), max_content_length(~(size_t)0)
    {
        parse_host_port(_host, _port);
    }

    std::string host() const { return _host; }
    uint16_t port() const { return _port; }

    http_response perform(const std::string &method, const std::string &path, const std::string &data="") {
        uri u;
        u.scheme = "http";
        u.host = _host;
        u.port = _port;
        u.path = path;
        u.normalize();

        http_request r(method, u.compose_path());
        // HTTP/1.1 requires host header
        r.set("Host", u.host);
        r.body = data;
        return perform(r);
    }

    http_response perform(http_request &r) {
        if (r.body.size()) {
            r.set("Content-Length", r.body.size());
        }

        try {
            ensure_connection();

            std::string hdata = r.data();
            ssize_t nw = _s->send(hdata.c_str(), hdata.size());
            if (r.body.size()) {
                nw = _s->send(r.body.c_str(), r.body.size());
            }

            http_parser parser;
            http_response resp;
            resp.parser_init(&parser);

            _buf.clear();

            while (!resp.complete) {
                _buf.reserve(4*1024);
                ssize_t nr = _s->recv(_buf.back(), _buf.available());
                if (nr <= 0) { throw http_error("recv"); }
                _buf.commit(nr);
                size_t len = _buf.size();
                resp.parse(&parser, _buf.front(), len);
                _buf.remove(len);
                if (resp.body.size() >= max_content_length) {
                    _s.reset(); // close this socket, we won't read anymore
                    return resp;
                }
            }
            // should not be any data left over in _buf
            CHECK(_buf.size() == 0);

            return resp;
        } catch (errorx &e) {
            _s.reset();
            throw;
        }
    }

    http_response get(const std::string &path) {
        return perform("GET", path);
    }

    http_response post(const std::string &path, const std::string &data) {
        return perform("POST", path, data);
    }

};

class http_pool : public shared_pool<http_client> {
public:
    http_pool(const std::string &host_, uint16_t port_, ssize_t max_conn)
        : shared_pool<http_client>("http://" + host_,
            std::bind(&http_pool::new_resource, this),
            max_conn
        ),
        _host(host_), _port(port_) {}

protected:
    std::string _host;
    uint16_t _port;

    std::shared_ptr<http_client> new_resource() {
        VLOG(3) << "new http_client resource " << _host << ":" << _port;
        return std::make_shared<http_client>(_host, _port);
    }
};

} // end namespace ten
#endif // HTTP_CLIENT_HH

<|endoftext|>


<commit_before>// (C) 2016 Marvin Sielenkemper

#include "db.hpp"

#include <mysql.h>

#include <boost/any.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/foreach.hpp>

#include <sstream>
#include <vector>

namespace {
  char const* const db_host("192.168.2.51");
  char const* const db_user("furnace");
  char const* const db_name("furnace");
  unsigned int const db_port(3306);

  class MySql : boost::noncopyable {
  public:
    MySql(char const* passwd) : m_mysqlPtr(mysql_init(nullptr)) {
      if (!mysql_real_connect(
              m_mysqlPtr, passwd ? db_host : "localhost", db_user,
              passwd, db_name, db_port, nullptr, CLIENT_COMPRESS)) {
        std::ostringstream buffer;

        buffer << "failed to connect to database: '"
               << mysql_error(m_mysqlPtr) << '\'';

        mysql_close(m_mysqlPtr);

        throw std::runtime_error(buffer.str());
      }
    }

    ~MySql() {
      mysql_close(m_mysqlPtr);
    }

    operator MYSQL*() const {
      return m_mysqlPtr;
    }

  private:
    MYSQL* const m_mysqlPtr;
  };

  class Statement;

  class Result {
  public:
    template <class T>
    T get(std::string const& columnName) const;
  };

  class ResultSet : boost::noncopyable {
  public:
    struct const_iterator
        : boost::iterator_facade<const_iterator, Result const,
                                 boost::single_pass_traversal_tag> {
    private:
      friend boost::iterator_core_access;

      reference dereference() const;
      void increment() {
      }
      bool equal(const_iterator const& other) const {
        return true;
      }
    };

    ResultSet(ResultSet&& other)
        : m_statement(other.m_statement), m_resultMetaData(nullptr) {
      std::swap(m_resultMetaData, other.m_resultMetaData);
    }

    ResultSet(Statement const& statement)
        : m_statement(statement), m_resultMetaData(nullptr) {
    }

    ~ResultSet() {
      if (m_resultMetaData) {
        mysql_free_result(m_resultMetaData);
      }
    }

    const_iterator begin() const {
      return const_iterator();
    }

    const_iterator end() const {
      return const_iterator();
    }

  private:
    Statement const& m_statement;
    MYSQL_RES* m_resultMetaData;

    MYSQL_RES* getResultMetaData();
  };

  class Statement : boost::noncopyable {
  public:
    Statement(MySql& mysql, std::string const& statement)
        : m_statementPtr(mysql_stmt_init(mysql))
        , m_bindings(nullptr)
        , m_buffers() {
      if (mysql_stmt_prepare(m_statementPtr, statement.data(),
                             statement.length())) {
        std::ostringstream buffer;

        buffer << "failed to prepare statement '" << statement
               << "': '" << mysql_stmt_error(m_statementPtr) << '\'';

        throw std::runtime_error(buffer.str());
      }

      if (auto const paramCount =
              mysql_stmt_param_count(m_statementPtr)) {
        m_bindings = new MYSQL_BIND[paramCount];
        m_buffers.resize(paramCount);
      }
    }

    void set(int index, std::string const& param) {
      typedef std::pair<std::string, unsigned long> Buffer;

      auto& anyBuffer(m_buffers.at(index));
      auto& mysqlBinding(m_bindings[index]);

      anyBuffer = Buffer(param, param.length());

      auto& buffer(boost::any_cast<Buffer&>(anyBuffer));

      mysqlBinding.buffer_type   = MYSQL_TYPE_STRING;
      mysqlBinding.buffer        = const_cast<char*>(buffer.first.data());
      mysqlBinding.buffer_length = buffer.second;
      mysqlBinding.is_null       = nullptr;
      mysqlBinding.length        = &buffer.second;
    }

    ResultSet execute() {
      if (mysql_stmt_bind_param(m_statementPtr, m_bindings)) {
        std::ostringstream buffer;

        buffer << "failed to bind parameters: '"
               << mysql_stmt_error(m_statementPtr) << '\'';

        throw std::runtime_error(buffer.str());
      }

      if (mysql_stmt_execute(m_statementPtr)) {
        std::ostringstream buffer;

        buffer << "failed to execute prepared statement: '"
               << mysql_stmt_error(m_statementPtr) << '\'';

        throw std::runtime_error(buffer.str());
      }

      return ResultSet(*this);
    }

    ~Statement() {
      if (m_statementPtr) {
        mysql_stmt_close(m_statementPtr);
      }

      if (m_bindings) {
        delete[] m_bindings;
      }
    }

    operator MYSQL_STMT*() const {
      return m_statementPtr;
    }

  private:
    MYSQL_STMT* const m_statementPtr;
    MYSQL_BIND* m_bindings;
    std::vector<boost::any> m_buffers;
  };

  MYSQL_RES* ResultSet::getResultMetaData() {
    if (!m_resultMetaData) {
      m_resultMetaData = mysql_stmt_result_metadata(m_statement);

      auto const fieldCount(mysql_num_fields(m_resultMetaData));
      auto const fields(mysql_fetch_fields(m_resultMetaData));

      for (auto const& field :
           boost::make_iterator_range(fields, fields + fieldCount)) {
        (void)field.length;
      }
    }

    return m_resultMetaData;
  }
}

struct Db::Impl : boost::noncopyable {
  MySql mysql;
  Statement insert;
  Statement query;

  Impl(char const* password)
      : mysql(password)
      , insert(mysql, "INSERT INTO serial_log(line) VALUES(?)")
      , query(mysql, "SELECT id, time, line FROM serial_log") {
  }
};

Db::Db() : m_implPtr(new Impl(nullptr)) {
}

Db::Db(std::string const& password)
    : m_implPtr(new Impl(password.c_str())) {
}

Db::~Db() {
}

void Db::addSerialLine(std::string const& line) {
  auto& insert(m_implPtr->insert);

  insert.set(0, line);
  insert.execute();
}

void Db::getLines(
    std::function<void(int, int, std::string const&)> const&
        callback) {
  auto& query(m_implPtr->query);
  auto const resultSet(query.execute());

  BOOST_FOREACH (auto const& row, resultSet) {
    callback(row.get<int>("id"), row.get<int>("time"),
             row.get<std::string>("line"));
  }
}
<commit_msg>move destructor closer to constructor, added dummy implementations<commit_after>// (C) 2016 Marvin Sielenkemper

#include "db.hpp"

#include <mysql.h>

#include <boost/any.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/foreach.hpp>

#include <sstream>
#include <vector>

namespace {
  char const* const db_host("192.168.2.51");
  char const* const db_user("furnace");
  char const* const db_name("furnace");
  unsigned int const db_port(3306);

  class MySql : boost::noncopyable {
  public:
    MySql(char const* passwd) : m_mysqlPtr(mysql_init(nullptr)) {
      if (!mysql_real_connect(
              m_mysqlPtr, passwd ? db_host : "localhost", db_user,
              passwd, db_name, db_port, nullptr, CLIENT_COMPRESS)) {
        std::ostringstream buffer;

        buffer << "failed to connect to database: '"
               << mysql_error(m_mysqlPtr) << '\'';

        mysql_close(m_mysqlPtr);

        throw std::runtime_error(buffer.str());
      }
    }

    ~MySql() {
      mysql_close(m_mysqlPtr);
    }

    operator MYSQL*() const {
      return m_mysqlPtr;
    }

  private:
    MYSQL* const m_mysqlPtr;
  };

  class Statement;

  class Result {
  public:
    template <class T>
    T get(std::string const& columnName) const {
      return T();
    }
  };

  class ResultSet : boost::noncopyable {
  public:
    struct const_iterator
        : boost::iterator_facade<const_iterator, Result const,
                                 boost::single_pass_traversal_tag> {
    private:
      friend boost::iterator_core_access;

      reference dereference() const {
        throw std::runtime_error("dereference() not implemented");
      }

      void increment() {
        throw std::runtime_error("increment() not implemented");
      }

      bool equal(const_iterator const& other) const {
        throw std::runtime_error("equal(...) not implemented");
      }
    };

    ResultSet(ResultSet&& other)
        : m_statement(other.m_statement), m_resultMetaData(nullptr) {
      std::swap(m_resultMetaData, other.m_resultMetaData);
    }

    ResultSet(Statement const& statement)
        : m_statement(statement), m_resultMetaData(nullptr) {
    }

    ~ResultSet() {
      if (m_resultMetaData) {
        mysql_free_result(m_resultMetaData);
      }
    }

    const_iterator begin() const {
      return const_iterator();
    }

    const_iterator end() const {
      return const_iterator();
    }

  private:
    Statement const& m_statement;
    MYSQL_RES* m_resultMetaData;

    MYSQL_RES* getResultMetaData();
  };

  class Statement : boost::noncopyable {
  public:
    Statement(MySql& mysql, std::string const& statement)
        : m_statementPtr(mysql_stmt_init(mysql))
        , m_bindings(nullptr)
        , m_buffers() {
      if (mysql_stmt_prepare(m_statementPtr, statement.data(),
                             statement.length())) {
        std::ostringstream buffer;

        buffer << "failed to prepare statement '" << statement
               << "': '" << mysql_stmt_error(m_statementPtr) << '\'';

        throw std::runtime_error(buffer.str());
      }

      if (auto const paramCount =
              mysql_stmt_param_count(m_statementPtr)) {
        m_bindings = new MYSQL_BIND[paramCount];
        m_buffers.resize(paramCount);
      }
    }

    ~Statement() {
      if (m_statementPtr) {
        mysql_stmt_close(m_statementPtr);
      }

      if (m_bindings) {
        delete[] m_bindings;
      }
    }

    void set(int index, std::string const& param) {
      typedef std::pair<std::string, unsigned long> Buffer;

      auto& anyBuffer(m_buffers.at(index));
      auto& mysqlBinding(m_bindings[index]);

      anyBuffer = Buffer(param, param.length());

      auto& buffer(boost::any_cast<Buffer&>(anyBuffer));

      mysqlBinding.buffer_type   = MYSQL_TYPE_STRING;
      mysqlBinding.buffer        = const_cast<char*>(buffer.first.data());
      mysqlBinding.buffer_length = buffer.second;
      mysqlBinding.is_null       = nullptr;
      mysqlBinding.length        = &buffer.second;
    }

    ResultSet execute() {
      if (mysql_stmt_bind_param(m_statementPtr, m_bindings)) {
        std::ostringstream buffer;

        buffer << "failed to bind parameters: '"
               << mysql_stmt_error(m_statementPtr) << '\'';

        throw std::runtime_error(buffer.str());
      }

      if (mysql_stmt_execute(m_statementPtr)) {
        std::ostringstream buffer;

        buffer << "failed to execute prepared statement: '"
               << mysql_stmt_error(m_statementPtr) << '\'';

        throw std::runtime_error(buffer.str());
      }

      return ResultSet(*this);
    }

    operator MYSQL_STMT*() const {
      return m_statementPtr;
    }

  private:
    MYSQL_STMT* const m_statementPtr;
    MYSQL_BIND* m_bindings;
    std::vector<boost::any> m_buffers;
  };

  MYSQL_RES* ResultSet::getResultMetaData() {
    if (!m_resultMetaData) {
      m_resultMetaData = mysql_stmt_result_metadata(m_statement);

      auto const fieldCount(mysql_num_fields(m_resultMetaData));
      auto const fields(mysql_fetch_fields(m_resultMetaData));

      for (auto const& field :
           boost::make_iterator_range(fields, fields + fieldCount)) {
        (void)field.length;
      }
    }

    return m_resultMetaData;
  }
}

struct Db::Impl : boost::noncopyable {
  MySql mysql;
  Statement insert;
  Statement query;

  Impl(char const* password)
      : mysql(password)
      , insert(mysql, "INSERT INTO serial_log(line) VALUES(?)")
      , query(mysql, "SELECT id, time, line FROM serial_log") {
  }
};

Db::Db() : m_implPtr(new Impl(nullptr)) {
}

Db::Db(std::string const& password)
    : m_implPtr(new Impl(password.c_str())) {
}

Db::~Db() {
}

void Db::addSerialLine(std::string const& line) {
  auto& insert(m_implPtr->insert);

  insert.set(0, line);
  insert.execute();
}

void Db::getLines(
    std::function<void(int, int, std::string const&)> const&
        callback) {
  auto& query(m_implPtr->query);
  auto const resultSet(query.execute());

  BOOST_FOREACH (auto const& row, resultSet) {
    callback(row.get<int>("id"), row.get<int>("time"),
             row.get<std::string>("line"));
  }
}
<|endoftext|>


<commit_before>/*
 * This file is part of the Multivariate Splines library.
 * Copyright (C) 2012 Bjarne Grimstad (bjarne.grimstad@gmail.com)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <datatable.h>
#include <datasample.h>
#include <serialize.h>
#include "testingutilities.h"
#include <iostream>

using namespace std;
using namespace MultivariateSplines;

bool serializeDataTable1()
{
    DataTable table;

    auto x = std::vector<double>(1);
    double y;
    for (double i = -0.3; i <= 0.3; i += 0.04)
    {
        x.at(0) = i;
        y = 2 * i;
        table.addSample(x, y);
    }

    table.save("test1.datatable");

    DataTable loadedTable("test1.datatable");

    remove("test1.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable2()
{
    DataTable table;

    auto x = std::vector<double>(2);
    double y;
    for (double i = -0.3; i <= 0.3; i += 0.04)
    {
        for (double j = -0.4; j <= 1.0; j += 0.08)
        {
            x.at(0) = i;
            x.at(1) = j;
            y = i * j;
            table.addSample(x, y);
        }
    }

    table.save("test2.datatable");

    DataTable loadedTable("test2.datatable");

    remove("test2.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable3()
{
    DataTable table;

    auto x = std::vector<double>(2);
    double y;
    for (double i = -0.3; i <= 0.3; i += 0.04)
    {
        for(double j = -0.4; j <= 1.0; j += 0.03)
        {
            x.at(0) = i;
            x.at(1) = j;
            y = i * j;
            table.addSample(x, y);
        }
    }

    table.save("test3.datatable");

    DataTable loadedTable("test3.datatable");

    remove("test3.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable4()
{
    DataTable table;

    auto x = std::vector<double>(4);
    double y;
    int j = 0;
    for (double i = std::numeric_limits<double>::lowest(), k = std::numeric_limits<double>::max();
        j < 10000;
        i = nextafter(i, std::numeric_limits<double>::max()), k = nextafter(k, std::numeric_limits<double>::lowest()))
    {
        x.at(0) = i;
        y = k;
        table.addSample(x, y);
        j++;
    }

    table.save("test4.datatable");

    DataTable loadedTable("test4.datatable");

    remove("test4.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable5()
{
    DataTable table;

    auto x = std::vector<double>(3);
    double y;
    for (double i = -0.0001; i <= 0.0001; i += 0.000001)
    {
        for (double j = -0.01; j <= 0.01; j += 0.001)
        {
            for (double k = -0.01; k <= 0.01; k += 0.001)
            {
                x.at(0) = i;
                x.at(1) = j;
                x.at(2) = k;
                y = i * j;
                table.addSample(x, y);
            }
        }
    }

    table.save("test5.datatable");

    DataTable loadedTable("test5.datatable");

    remove("test5.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable6()
{
    DataTable table;

    auto x = std::vector<double>(4);
    double y;
    for (double i = -0.0001; i <= 0.0001; i += 0.000001)
    {
        for (double j = -0.01; j <= 0.01; j += 0.001)
        {
            for (double k = -0.01; k <= 0.01; k += 0.001)
            {
                for (double l = -100000.0; l < 0.0; l += 13720.0)
                {
                    x.at(0) = i;
                    x.at(1) = j;
                    x.at(2) = k;
                    x.at(3) = l;
                    y = i * j;
                    table.addSample(x, y);
                }
            }
        }
    }

    table.save("test6.datatable");

    DataTable loadedTable("test6.datatable");

    remove("test6.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeBSpline1()
{
    // Create new DataTable to manage samples
    DataTable samples;
    // Sample function
    auto x0_vec = linspace(0, 2, 20);
    auto x1_vec = linspace(0, 2, 20);
    DenseVector x(2);
    double y;
    for (auto x0 : x0_vec)
    {
        for (auto x1 : x1_vec)
        {
            // Sample function at x
            x(0) = x0;
            x(1) = x1;
            y = sixHumpCamelBack(x);
            // Store sample
            samples.addSample(x,y);
        }
    }
    // Build B-splines that interpolate the samples
    BSpline bspline(samples, BSplineType::LINEAR);
    bspline.save("saveTest1.bspline");
    BSpline loadedBspline("saveTest1.bspline");
    remove("saveTest1.bspline");
    return compareBSplines(bspline, loadedBspline);
}

int main()
{
    cout << endl << endl;
    cout << "Testing load and save functionality:                                   "   << endl;
    cout << "-----------------------------------------------------------------------"   << endl;
    cout << "DataTables:                                                            "   << endl;
    cout << "serializeDataTable1(): " << (serializeDataTable1() ? "success" : "fail")   << endl;
    cout << "serializeDataTable2(): " << (serializeDataTable2() ? "success" : "fail")   << endl;
    cout << "serializeDataTable3(): " << (serializeDataTable3() ? "success" : "fail")   << endl;
    cout << "serializeDataTable4(): " << (serializeDataTable4() ? "success" : "fail")   << endl;
    cout << "serializeDataTable5(): " << (serializeDataTable5() ? "success" : "fail")   << endl;
    cout << "serializeDataTable6(): " << (serializeDataTable6() ? "success" : "fail")   << endl;
    cout << "BSplines:                                                              "   << endl;
    cout << "serializeBSpline1():   " << (serializeBSpline1()   ? "success" : "fail")   << endl;

    return 0;
}
<commit_msg>Made save/load test of datatables #6 somewhat shorter by reducing the grid.<commit_after>/*
 * This file is part of the Multivariate Splines library.
 * Copyright (C) 2012 Bjarne Grimstad (bjarne.grimstad@gmail.com)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <datatable.h>
#include <datasample.h>
#include <serialize.h>
#include "testingutilities.h"
#include <iostream>

using namespace std;
using namespace MultivariateSplines;

bool serializeDataTable1()
{
    DataTable table;

    auto x = std::vector<double>(1);
    double y;
    for (double i = -0.3; i <= 0.3; i += 0.04)
    {
        x.at(0) = i;
        y = 2 * i;
        table.addSample(x, y);
    }

    table.save("test1.datatable");

    DataTable loadedTable("test1.datatable");

    remove("test1.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable2()
{
    DataTable table;

    auto x = std::vector<double>(2);
    double y;
    for (double i = -0.3; i <= 0.3; i += 0.04)
    {
        for (double j = -0.4; j <= 1.0; j += 0.08)
        {
            x.at(0) = i;
            x.at(1) = j;
            y = i * j;
            table.addSample(x, y);
        }
    }

    table.save("test2.datatable");

    DataTable loadedTable("test2.datatable");

    remove("test2.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable3()
{
    DataTable table;

    auto x = std::vector<double>(2);
    double y;
    for (double i = -0.3; i <= 0.3; i += 0.04)
    {
        for(double j = -0.4; j <= 1.0; j += 0.03)
        {
            x.at(0) = i;
            x.at(1) = j;
            y = i * j;
            table.addSample(x, y);
        }
    }

    table.save("test3.datatable");

    DataTable loadedTable("test3.datatable");

    remove("test3.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable4()
{
    DataTable table;

    auto x = std::vector<double>(4);
    double y;
    int j = 0;
    for (double i = std::numeric_limits<double>::lowest(), k = std::numeric_limits<double>::max();
        j < 10000;
        i = nextafter(i, std::numeric_limits<double>::max()), k = nextafter(k, std::numeric_limits<double>::lowest()))
    {
        x.at(0) = i;
        y = k;
        table.addSample(x, y);
        j++;
    }

    table.save("test4.datatable");

    DataTable loadedTable("test4.datatable");

    remove("test4.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable5()
{
    DataTable table;

    auto x = std::vector<double>(3);
    double y;
    for (double i = -0.0001; i <= 0.0001; i += 0.000001)
    {
        for (double j = -0.01; j <= 0.01; j += 0.001)
        {
            for (double k = -0.01; k <= 0.01; k += 0.001)
            {
                x.at(0) = i;
                x.at(1) = j;
                x.at(2) = k;
                y = i * j;
                table.addSample(x, y);
            }
        }
    }

    table.save("test5.datatable");

    DataTable loadedTable("test5.datatable");

    remove("test5.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeDataTable6()
{
    DataTable table;

    auto x = std::vector<double>(4);
    double y;
    for (double i = -0.0001; i <= 0.0001; i += 0.000001)
    {
        for (double j = -0.01; j <= 0.01; j += 0.001)
        {
            for (double k = -0.01; k <= 0.01; k += 0.001)
            {
                for (double l = -100000.0; l < -60000.0; l += 13720.0)
                {
                    x.at(0) = i;
                    x.at(1) = j;
                    x.at(2) = k;
                    x.at(3) = l;
                    y = i * j;
                    table.addSample(x, y);
                }
            }
        }
    }

    table.save("test6.datatable");

    DataTable loadedTable("test6.datatable");

    remove("test6.datatable");

    return compareDataTables(table, loadedTable);
}

bool serializeBSpline1()
{
    // Create new DataTable to manage samples
    DataTable samples;
    // Sample function
    auto x0_vec = linspace(0, 2, 20);
    auto x1_vec = linspace(0, 2, 20);
    DenseVector x(2);
    double y;
    for (auto x0 : x0_vec)
    {
        for (auto x1 : x1_vec)
        {
            // Sample function at x
            x(0) = x0;
            x(1) = x1;
            y = sixHumpCamelBack(x);
            // Store sample
            samples.addSample(x,y);
        }
    }
    // Build B-splines that interpolate the samples
    BSpline bspline(samples, BSplineType::LINEAR);
    bspline.save("saveTest1.bspline");
    BSpline loadedBspline("saveTest1.bspline");
    remove("saveTest1.bspline");
    return compareBSplines(bspline, loadedBspline);
}

int main()
{
    cout << endl << endl;
    cout << "Testing load and save functionality:                                   "   << endl;
    cout << "-----------------------------------------------------------------------"   << endl;
    cout << "DataTables:                                                            "   << endl;
    cout << "serializeDataTable1(): " << (serializeDataTable1() ? "success" : "fail")   << endl;
    cout << "serializeDataTable2(): " << (serializeDataTable2() ? "success" : "fail")   << endl;
    cout << "serializeDataTable3(): " << (serializeDataTable3() ? "success" : "fail")   << endl;
    cout << "serializeDataTable4(): " << (serializeDataTable4() ? "success" : "fail")   << endl;
    cout << "serializeDataTable5(): " << (serializeDataTable5() ? "success" : "fail")   << endl;
    cout << "serializeDataTable6(): " << (serializeDataTable6() ? "success" : "fail")   << endl;
    cout << "BSplines:                                                              "   << endl;
    cout << "serializeBSpline1():   " << (serializeBSpline1()   ? "success" : "fail")   << endl;

    return 0;
}
<|endoftext|>


<commit_before>#include <string>
#include <memory>
#include <cmath>
#include <map>
#include <functional>
#include <EASTL/vector.h>
#include <EASTL/array.h>

using eastl::vector;
using eastl::array;

#include "Vec2i.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CItem.h"
#include "CActor.h"
#include "CCharacterArchetype.h"
#include "CCharacter.h"
#include "CMonster.h"
#include "CGameDelegate.h"
#include "CMap.h"

namespace Knights {

	CMonster::CMonster(std::shared_ptr<CCharacterArchetype> aArchetype, std::shared_ptr<CTeam> aTeam, ActorId aId, int aViewRange, CMonsterUpdateCallback updateCallback)
			: CCharacter(aArchetype, aTeam, aId), mUpdateCallback( updateCallback ), mViewRange( aViewRange) {
	}

    CMonster::CMonster(std::shared_ptr<CCharacterArchetype> aArchetype, std::shared_ptr<CTeam> aTeam, ActorId aId, int aViewRange )
            : CCharacter(aArchetype, aTeam, aId), mUpdateCallback( [](std::shared_ptr <CMap> map, std::shared_ptr<CActor> me){} ), mViewRange( aViewRange){
    }

	bool CMonster::dealWith(std::shared_ptr<CMap> map, int x, int y) {
		int dx = x - mPosition.x;
		int dy = y - mPosition.y;

		auto sharedThis = shared_from_this();

		if (std::abs(dx) >= std::abs(dy)) {

			if ( std::abs(dx) == 1) {
				map->attack( sharedThis, {x, y}, false);
				onMove();
				return true;
			}

			if (dx <= 0) {

                if (!map->move(EDirection::kWest, sharedThis)) {
					if (!map->move(EDirection::kSouth, sharedThis)) {
						return map->move(EDirection::kNorth, sharedThis);
					}
                }

                return true;
			} else if (dx > 0) {

                if (!map->move(EDirection::kEast, sharedThis)) {
					if (!map->move(EDirection::kNorth, sharedThis)) {
						return map->move(EDirection::kSouth, sharedThis);
					}
				}

                return true;
			}
		} else {
			if ( std::abs(dy) == 1) {
                map->attack( sharedThis, {x, y}, false);
                onMove();
				return true;
			}

			if (dy <= 0) {

                if (!map->move(EDirection::kNorth, sharedThis)) {
					if (!map->move(EDirection::kWest, sharedThis)) {
						return map->move(EDirection::kEast, sharedThis);
					}
                }

				return true;
			} else if (dy > 0) {

                if (!map->move(EDirection::kSouth, sharedThis)) {
					if (!map->move(EDirection::kEast, sharedThis)) {
						return map->move(EDirection::kWest, sharedThis);
					}
				}
                return true;
			}
		}

		return false;
	}

	bool CMonster::actOn(int newX, int newY, std::shared_ptr<CMap> map) {
		if (map->isValid({newX, newY})) {

			auto otherActor = map->getActorAt(Vec2i{newX, newY});

			if (otherActor != nullptr
			    && otherActor->getTeam() != getTeam()) {

				setTarget(otherActor);

				if (dealWith(map, newX, newY)) {
					return true;
				}
			}

			if (map->isBlockMovementAt({newX, newY})) {
				return false;
			}

		}
		return false;
	}

	void CMonster::update(std::shared_ptr<CMap> map) {

		CCharacter::update(map);
        mUpdateCallback(map, shared_from_this() );

		if ( mTarget != nullptr && getAP() > 0 && isAlive() ) {
			auto pos = mTarget->getPosition();
			actOn(pos.x, pos.y, map);
		} else {
			int newX;
			int newY;

			for (int x = -mViewRange / 2; x <= mViewRange / 2; ++x) {

				for (int y = -mViewRange / 2; y <= mViewRange / 2; ++y) {

					if (x == 0 && y == 0) {
						continue;
					}

					newX = std::min<int>(kMapSize - 1, std::max<int>(0, (x + mPosition.x)));
					newY = std::min<int>(kMapSize - 1, std::max<int>(0, (y + mPosition.y)));

					if (actOn(newX, newY, map)) {
						return;
					}
				}
			}
		}
	}
}<commit_msg>Fix Emscripten compilation<commit_after>#include <string>
#include <memory>
#include <math.h>
#include <map>
#include <functional>
#include <EASTL/vector.h>
#include <EASTL/array.h>

using eastl::vector;
using eastl::array;

#include "Vec2i.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CItem.h"
#include "CActor.h"
#include "CCharacterArchetype.h"
#include "CCharacter.h"
#include "CMonster.h"
#include "CGameDelegate.h"
#include "CMap.h"

namespace Knights {

	CMonster::CMonster(std::shared_ptr<CCharacterArchetype> aArchetype, std::shared_ptr<CTeam> aTeam, ActorId aId, int aViewRange, CMonsterUpdateCallback updateCallback)
			: CCharacter(aArchetype, aTeam, aId), mUpdateCallback( updateCallback ), mViewRange( aViewRange) {
	}

    CMonster::CMonster(std::shared_ptr<CCharacterArchetype> aArchetype, std::shared_ptr<CTeam> aTeam, ActorId aId, int aViewRange )
            : CCharacter(aArchetype, aTeam, aId), mUpdateCallback( [](std::shared_ptr <CMap> map, std::shared_ptr<CActor> me){} ), mViewRange( aViewRange){
    }

	bool CMonster::dealWith(std::shared_ptr<CMap> map, int x, int y) {
		int dx = x - mPosition.x;
		int dy = y - mPosition.y;

		auto sharedThis = shared_from_this();

		if (abs(dx) >= abs(dy)) {

			if ( abs(dx) == 1) {
				map->attack( sharedThis, {x, y}, false);
				onMove();
				return true;
			}

			if (dx <= 0) {

                if (!map->move(EDirection::kWest, sharedThis)) {
					if (!map->move(EDirection::kSouth, sharedThis)) {
						return map->move(EDirection::kNorth, sharedThis);
					}
                }

                return true;
			} else if (dx > 0) {

                if (!map->move(EDirection::kEast, sharedThis)) {
					if (!map->move(EDirection::kNorth, sharedThis)) {
						return map->move(EDirection::kSouth, sharedThis);
					}
				}

                return true;
			}
		} else {
			if ( abs(dy) == 1) {
                map->attack( sharedThis, {x, y}, false);
                onMove();
				return true;
			}

			if (dy <= 0) {

                if (!map->move(EDirection::kNorth, sharedThis)) {
					if (!map->move(EDirection::kWest, sharedThis)) {
						return map->move(EDirection::kEast, sharedThis);
					}
                }

				return true;
			} else if (dy > 0) {

                if (!map->move(EDirection::kSouth, sharedThis)) {
					if (!map->move(EDirection::kEast, sharedThis)) {
						return map->move(EDirection::kWest, sharedThis);
					}
				}
                return true;
			}
		}

		return false;
	}

	bool CMonster::actOn(int newX, int newY, std::shared_ptr<CMap> map) {
		if (map->isValid({newX, newY})) {

			auto otherActor = map->getActorAt(Vec2i{newX, newY});

			if (otherActor != nullptr
			    && otherActor->getTeam() != getTeam()) {

				setTarget(otherActor);

				if (dealWith(map, newX, newY)) {
					return true;
				}
			}

			if (map->isBlockMovementAt({newX, newY})) {
				return false;
			}

		}
		return false;
	}

	void CMonster::update(std::shared_ptr<CMap> map) {

		CCharacter::update(map);
        mUpdateCallback(map, shared_from_this() );

		if ( mTarget != nullptr && getAP() > 0 && isAlive() ) {
			auto pos = mTarget->getPosition();
			actOn(pos.x, pos.y, map);
		} else {
			int newX;
			int newY;

			for (int x = -mViewRange / 2; x <= mViewRange / 2; ++x) {

				for (int y = -mViewRange / 2; y <= mViewRange / 2; ++y) {

					if (x == 0 && y == 0) {
						continue;
					}

					newX = std::min<int>(kMapSize - 1, std::max<int>(0, (x + mPosition.x)));
					newY = std::min<int>(kMapSize - 1, std::max<int>(0, (y + mPosition.y)));

					if (actOn(newX, newY, map)) {
						return;
					}
				}
			}
		}
	}
}<|endoftext|>


<commit_before>#include "Canvas.h"
#include "Mesh.h"
#include "GLTask.h"
#include "kit/log/log.h"
#include "kit/log/errors.h"
using namespace std;
using namespace glm;

Canvas :: Canvas(unsigned w, unsigned h):
    m_Surface(Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, w, h)),
    m_Context(Cairo::Context::create(m_Surface)),
    //m_PangoContext(Glib::wrap(pango_x_get_context())),
    m_Layout(Pango::Layout::create(m_Context))
{
    int last_id;
    unsigned id;

    GL_TASK_START()

        glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_id);
        glGenTextures(1,&id);
        try{
            m_Texture = make_shared<Texture>(id); // take ownership
        }catch(...){
            //GL_TASK_ASYNC_START()
                glDeleteTextures(1,&id);
            //GL_TASK_ASYNC_END()
            throw;
        }
        m_Texture->size(w, h);

        glBindTexture(GL_TEXTURE_2D, id);
        BOOST_SCOPE_EXIT_ALL(last_id) {
            glBindTexture(GL_TEXTURE_2D, last_id);
        };

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        {
            auto err = glGetError();
            if(err != GL_NO_ERROR)
                ERRORf(GENERAL, "OpenGL Error: %s", err);
        }

        glTexImage2D(GL_TEXTURE_2D, 0, 4,
            m_Texture->size().x, m_Texture->size().y,
            0, GL_BGRA, GL_UNSIGNED_BYTE, m_Surface->get_data());

        {
            auto err = glGetError();
            if(err != GL_NO_ERROR)
                ERRORf(GENERAL, "OpenGL Error: %s", err);
        }

    GL_TASK_END()

    add(make_shared<Mesh>(
        make_shared<MeshGeometry>(Prefab::quad(vec2(1.0f*w, 1.0f*h))),
        vector<shared_ptr<IMeshModifier>>{
            make_shared<Wrap>(Prefab::quad_wrap(
                glm::vec2(1.0f,1.0f), glm::vec2()
            ))
        },
        make_shared<MeshMaterial>(m_Texture)
    ));

}

Canvas :: ~Canvas()
{

}

void Canvas :: render_self(Pass* pass) const
{
    if(!m_Texture || !*m_Texture)
        return;

    //GL_TASK_START()
        //if(m_bDirty)
        //{
            //if(pass->flags() & Pass::BASE)
            //{
                m_Texture->bind(pass);
                glTexImage2D(GL_TEXTURE_2D, 0, 4,
                    m_Texture->size().x, m_Texture->size().y,
                    0, GL_BGRA, GL_UNSIGNED_BYTE, m_Surface->get_data());

                //glTexSubImage2D(GL_TEXTURE_2D, 0, 4,
                //    m_Texture->size().x, m_Texture->size().y,
                //    0, GL_BGRA, GL_UNSIGNED_BYTE, m_Surface->get_data());
                //m_bDirty = false;
                {
                    auto err = glGetError();
                    if(err != GL_NO_ERROR)
                        ERRORf(GENERAL, "OpenGL Error: %s", err);
                }
            //}

        //}

        // TODO: render quad

    //GL_TASK_END()
}

<commit_msg>canvas needs to clamp here<commit_after>#include "Canvas.h"
#include "Mesh.h"
#include "GLTask.h"
#include "kit/log/log.h"
#include "kit/log/errors.h"
using namespace std;
using namespace glm;

Canvas :: Canvas(unsigned w, unsigned h):
    m_Surface(Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, w, h)),
    m_Context(Cairo::Context::create(m_Surface)),
    //m_PangoContext(Glib::wrap(pango_x_get_context())),
    m_Layout(Pango::Layout::create(m_Context))
{
    int last_id;
    unsigned id;

    GL_TASK_START()

        glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_id);
        glGenTextures(1,&id);
        try{
            m_Texture = make_shared<Texture>(id); // take ownership
        }catch(...){
            //GL_TASK_ASYNC_START()
                glDeleteTextures(1,&id);
            //GL_TASK_ASYNC_END()
            throw;
        }
        m_Texture->size(w, h);

        glBindTexture(GL_TEXTURE_2D, id);
        BOOST_SCOPE_EXIT_ALL(last_id) {
            glBindTexture(GL_TEXTURE_2D, last_id);
        };

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        {
            auto err = glGetError();
            if(err != GL_NO_ERROR)
                ERRORf(GENERAL, "OpenGL Error: %s", err);
        }

        glTexImage2D(GL_TEXTURE_2D, 0, 4,
            m_Texture->size().x, m_Texture->size().y,
            0, GL_BGRA, GL_UNSIGNED_BYTE, m_Surface->get_data());

        {
            auto err = glGetError();
            if(err != GL_NO_ERROR)
                ERRORf(GENERAL, "OpenGL Error: %s", err);
        }

    GL_TASK_END()

    add(make_shared<Mesh>(
        make_shared<MeshGeometry>(Prefab::quad(vec2(1.0f*w, 1.0f*h))),
        vector<shared_ptr<IMeshModifier>>{
            make_shared<Wrap>(Prefab::quad_wrap(
                glm::vec2(1.0f,1.0f), glm::vec2()
            ))
        },
        make_shared<MeshMaterial>(m_Texture)
    ));

}

Canvas :: ~Canvas()
{

}

void Canvas :: render_self(Pass* pass) const
{
    if(!m_Texture || !*m_Texture)
        return;

    //GL_TASK_START()
        //if(m_bDirty)
        //{
            //if(pass->flags() & Pass::BASE)
            //{
                m_Texture->bind(pass);
                glTexImage2D(GL_TEXTURE_2D, 0, 4,
                    m_Texture->size().x, m_Texture->size().y,
                    0, GL_BGRA, GL_UNSIGNED_BYTE, m_Surface->get_data());

                //glTexSubImage2D(GL_TEXTURE_2D, 0, 4,
                //    m_Texture->size().x, m_Texture->size().y,
                //    0, GL_BGRA, GL_UNSIGNED_BYTE, m_Surface->get_data());
                //m_bDirty = false;
                {
                    auto err = glGetError();
                    if(err != GL_NO_ERROR)
                        ERRORf(GENERAL, "OpenGL Error: %s", err);
                }
            //}

        //}

        // TODO: render quad

    //GL_TASK_END()
}

<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include <cstddef>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "caf/byte.hpp"
#include "caf/byte_buffer.hpp"
#include "caf/error_code.hpp"
#include "caf/fwd.hpp"
#include "caf/read_inspector.hpp"
#include "caf/sec.hpp"
#include "caf/span.hpp"

namespace caf {

/// Serializes objects into a sequence of bytes.
class binary_serializer : public read_inspector<binary_serializer> {
public:
  // -- member types -----------------------------------------------------------

  using result_type = error_code<sec>;

  using container_type = byte_buffer;

  using value_type = byte;

  // -- constructors, destructors, and assignment operators --------------------

  binary_serializer(actor_system& sys, byte_buffer& buf) noexcept;

  binary_serializer(execution_unit* ctx, byte_buffer& buf) noexcept
    : buf_(buf), write_pos_(buf.size()), context_(ctx) {
    // nop
  }

  binary_serializer(const binary_serializer&) = delete;

  binary_serializer& operator=(const binary_serializer&) = delete;

  // -- properties -------------------------------------------------------------

  /// Returns the current execution unit.
  execution_unit* context() const noexcept {
    return context_;
  }

  byte_buffer& buf() noexcept {
    return buf_;
  }

  const byte_buffer& buf() const noexcept {
    return buf_;
  }

  size_t write_pos() const noexcept {
    return write_pos_;
  }

  // -- position management ----------------------------------------------------

  /// Sets the write position to `offset`.
  /// @pre `offset <= buf.size()`
  void seek(size_t offset) noexcept {
    write_pos_ = offset;
  }

  /// Jumps `num_bytes` forward. Resizes the buffer (filling it with zeros)
  /// when skipping past the end.
  void skip(size_t num_bytes);

  // -- interface functions ----------------------------------------------------

  error_code<sec> begin_object(uint16_t nr, string_view name);

  error_code<sec> end_object();

  error_code<sec> begin_sequence(size_t list_size);

  error_code<sec> end_sequence();

  void apply(byte x);

  void apply(uint8_t x);

  void apply(uint16_t x);

  void apply(uint32_t x);

  void apply(uint64_t x);

  void apply(float x);

  void apply(double x);

  void apply(long double x);

  void apply(string_view x);

  void apply(const std::u16string& x);

  void apply(const std::u32string& x);

  void apply(span<const byte> x);

  template <class T>
  std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value>
  apply(T x) {
    return apply(static_cast<std::make_unsigned_t<T>>(x));
  }

  template <class Enum>
  std::enable_if_t<std::is_enum<Enum>::value> apply(Enum x) {
    return apply(static_cast<std::underlying_type_t<Enum>>(x));
  }

  void apply(const std::vector<bool>& x);

private:
  /// Stores the serialized output.
  byte_buffer& buf_;

  /// Stores the current offset for writing.
  size_t write_pos_;

  /// Provides access to the ::proxy_registry and to the ::actor_system.
  execution_unit* context_;
};

} // namespace caf
<commit_msg>Fix ambiguous call to apply on FreeBSD<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include <cstddef>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "caf/byte.hpp"
#include "caf/byte_buffer.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/error_code.hpp"
#include "caf/fwd.hpp"
#include "caf/read_inspector.hpp"
#include "caf/sec.hpp"
#include "caf/span.hpp"

namespace caf {

/// Serializes objects into a sequence of bytes.
class binary_serializer : public read_inspector<binary_serializer> {
public:
  // -- member types -----------------------------------------------------------

  using result_type = error_code<sec>;

  using container_type = byte_buffer;

  using value_type = byte;

  // -- constructors, destructors, and assignment operators --------------------

  binary_serializer(actor_system& sys, byte_buffer& buf) noexcept;

  binary_serializer(execution_unit* ctx, byte_buffer& buf) noexcept
    : buf_(buf), write_pos_(buf.size()), context_(ctx) {
    // nop
  }

  binary_serializer(const binary_serializer&) = delete;

  binary_serializer& operator=(const binary_serializer&) = delete;

  // -- properties -------------------------------------------------------------

  /// Returns the current execution unit.
  execution_unit* context() const noexcept {
    return context_;
  }

  byte_buffer& buf() noexcept {
    return buf_;
  }

  const byte_buffer& buf() const noexcept {
    return buf_;
  }

  size_t write_pos() const noexcept {
    return write_pos_;
  }

  // -- position management ----------------------------------------------------

  /// Sets the write position to `offset`.
  /// @pre `offset <= buf.size()`
  void seek(size_t offset) noexcept {
    write_pos_ = offset;
  }

  /// Jumps `num_bytes` forward. Resizes the buffer (filling it with zeros)
  /// when skipping past the end.
  void skip(size_t num_bytes);

  // -- interface functions ----------------------------------------------------

  error_code<sec> begin_object(uint16_t nr, string_view name);

  error_code<sec> end_object();

  error_code<sec> begin_sequence(size_t list_size);

  error_code<sec> end_sequence();

  void apply(byte x);

  void apply(uint8_t x);

  void apply(uint16_t x);

  void apply(uint32_t x);

  void apply(uint64_t x);

  void apply(float x);

  void apply(double x);

  void apply(long double x);

  void apply(string_view x);

  void apply(const std::u16string& x);

  void apply(const std::u32string& x);

  void apply(span<const byte> x);

  template <class T>
  std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value>
  apply(T x) {
    using unsigned_type = std::make_unsigned_t<T>;
    using squashed_unsigned_type = detail::squashed_int_t<unsigned_type>;
    return apply(static_cast<squashed_unsigned_type>(x));
  }

  template <class Enum>
  std::enable_if_t<std::is_enum<Enum>::value> apply(Enum x) {
    return apply(static_cast<std::underlying_type_t<Enum>>(x));
  }

  void apply(const std::vector<bool>& x);

private:
  /// Stores the serialized output.
  byte_buffer& buf_;

  /// Stores the current offset for writing.
  size_t write_pos_;

  /// Provides access to the ::proxy_registry and to the ::actor_system.
  execution_unit* context_;
};

} // namespace caf
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2021 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "bp/session/Lease.hxx"
#include "bp/session/Session.hxx"
#include "bp/session/Manager.hxx"
#include "event/Loop.hxx"

#include <gtest/gtest.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

TEST(SessionTest, Basic)
{
	EventLoop event_loop;

	SessionManager session_manager(event_loop, std::chrono::minutes(30),
				       0, 0);

	const auto session_id = session_manager.CreateSession()->id;

	SessionLease session{session_manager, session_id};
	ASSERT_TRUE(session);
	ASSERT_EQ(session->id, session_id);
}
<commit_msg>test/t_session: allocate a RealmSession and a WidgetSession<commit_after>/*
 * Copyright 2007-2021 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "bp/session/Lease.hxx"
#include "bp/session/Session.hxx"
#include "bp/session/Manager.hxx"
#include "event/Loop.hxx"

#include <gtest/gtest.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

TEST(SessionTest, Basic)
{
	EventLoop event_loop;

	SessionManager session_manager(event_loop, std::chrono::minutes(30),
				       0, 0);

	const auto session_id = session_manager.CreateSession()->id;

	SessionLease session{session_manager, session_id};
	ASSERT_TRUE(session);
	ASSERT_EQ(session->id, session_id);

	auto *realm = session->GetRealm("a_realm_name");
	ASSERT_NE(realm, nullptr);

	auto *widget = realm->GetWidget("a_widget_name", false);
	ASSERT_EQ(widget, nullptr);

	widget = realm->GetWidget("a_widget_name", true);
	ASSERT_NE(widget, nullptr);
}
<|endoftext|>


<commit_before>#include <esn/esn.h>
#include <iomanip>
#include <iostream>
#include <random>

static const unsigned kNeuronCount = 100;
static const float kStep = 0.01f;
static const float kIntervalMin = 0.1f;
static const float kIntervalMax = 1.0f;

int main()
{
    ESN::NetworkParamsNSLI params;
    params.neuronCount = kNeuronCount;
    params.inputCount = 1;
    params.outputCount = 1;
    auto network = ESN::CreateNetwork( params );

    bool inputState = false;
    std::vector< float > input( 1 );
    float nextInterval = 0.0f;
    std::default_random_engine randomEngine;
    std::uniform_real_distribution< float > random(
        kIntervalMin, kIntervalMax );
    for ( float time = 0.0f; true; time += kStep )
    {
        if ( time > nextInterval )
        {
            inputState = !inputState;
            input[0] = inputState ? 1.0f : 0.0f;
            nextInterval += random( randomEngine );
        }

        std::cout <<
            std::setw( 3 ) << inputState <<
            std::endl;
    }

    return 0;
}
<commit_msg>samples : pulse : rename variables kIntervalMax -> kIntervalWidthMax, kIntervalMin -> kIntervalWidthMin<commit_after>#include <esn/esn.h>
#include <iomanip>
#include <iostream>
#include <random>

static const unsigned kNeuronCount = 100;
static const float kStep = 0.01f;
static const float kIntervalWidthMin = 0.1f;
static const float kIntervalWidthMax = 1.0f;

int main()
{
    ESN::NetworkParamsNSLI params;
    params.neuronCount = kNeuronCount;
    params.inputCount = 1;
    params.outputCount = 1;
    auto network = ESN::CreateNetwork( params );

    bool inputState = false;
    std::vector< float > input( 1 );
    float nextInterval = 0.0f;
    std::default_random_engine randomEngine;
    std::uniform_real_distribution< float > random(
        kIntervalWidthMin, kIntervalWidthMax );
    for ( float time = 0.0f; true; time += kStep )
    {
        if ( time > nextInterval )
        {
            inputState = !inputState;
            input[0] = inputState ? 1.0f : 0.0f;
            nextInterval += random( randomEngine );
        }

        std::cout <<
            std::setw( 3 ) << inputState <<
            std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>Replace fch{mod,own} with straight ch{mod,own} as the former cannot be used on socket file descriptors.<commit_after><|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include "src/Common.h"
#include <folly/io/IOBuf.h>
#include <random>
#include "src/AbstractStreamAutomaton.h"

namespace reactivesocket {

namespace {

const char* HEX_CHARS = {"0123456789abcdef"};
}

static const char* getTerminatingSignalErrorMessage(int terminatingSignal) {
  switch ((StreamCompletionSignal)terminatingSignal) {
    case StreamCompletionSignal::CONNECTION_END:
      return "connection closed";
    case StreamCompletionSignal::CONNECTION_ERROR:
      return "connection error";
    case StreamCompletionSignal::ERROR:
      return "socket error";
    case StreamCompletionSignal::SOCKET_CLOSED:
      return "reactive socket closed";
    case StreamCompletionSignal::GRACEFUL:
      DCHECK(false) << "throwing exception for GRACEFUL termination?";
      return "graceful termination";
    default:
      return "stream interrupted";
  }
}

std::ostream& operator<<(std::ostream& os, StreamCompletionSignal signal) {
  switch (signal) {
    case StreamCompletionSignal::GRACEFUL:
      return os << "GRACEFUL";
    case StreamCompletionSignal::ERROR:
      return os << "ERROR";
    case StreamCompletionSignal::INVALID_SETUP:
      return os << "INVALID_SETUP";
    case StreamCompletionSignal::UNSUPPORTED_SETUP:
      return os << "UNSUPPORTED_SETUP";
    case StreamCompletionSignal::REJECTED_SETUP:
      return os << "REJECTED_SETUP";
    case StreamCompletionSignal::CONNECTION_ERROR:
      return os << "CONNECTION_ERROR";
    case StreamCompletionSignal::CONNECTION_END:
      return os << "CONNECTION_END";
    case StreamCompletionSignal::SOCKET_CLOSED:
      return os << "SOCKET_CLOSED";
  }
  // this should be never hit because the switch is over all cases
  LOG(FATAL) << "unknown StreamCompletionSignal=" << (int)signal;
}

StreamInterruptedException::StreamInterruptedException(int _terminatingSignal)
    : std::runtime_error(getTerminatingSignalErrorMessage(_terminatingSignal)),
      terminatingSignal(_terminatingSignal) {}

ResumeIdentificationToken::ResumeIdentificationToken()
    : ResumeIdentificationToken(
          Data() = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}) {}

ResumeIdentificationToken ResumeIdentificationToken::generateNew() {
  // TODO: this will be replaced with a variable length bit array and the value
  // will be generated outside of reactivesocket
  // for now we will use temporary number generator
  std::mt19937 rng;
  rng.seed(std::random_device()());
  auto num = rng();

  static_assert(sizeof(num) <= sizeof(Data), "FIXME");

  Data data;
  for (size_t i = 0; i < sizeof(num); i++) {
    data[i] = ((uint8_t*)&num)[i];
  }
  return ResumeIdentificationToken(std::move(data));
}

ResumeIdentificationToken ResumeIdentificationToken::fromString(
    const std::string& /*str*/) {
  CHECK(false) << "not implemented";
  return ResumeIdentificationToken();
}

std::string ResumeIdentificationToken::toString() const {
  std::string str;
  for (auto b : bits_) {
    str += HEX_CHARS[(b & 0xF0) >> 4];
    str += HEX_CHARS[b & 0x0F];
  }
  return str;
}

} // reactivesocket
<commit_msg>Make ResumeIdentificationToken::generateNew() be random (#231)<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include "src/Common.h"
#include <folly/io/IOBuf.h>
#include <folly/Random.h>
#include <random>
#include "src/AbstractStreamAutomaton.h"

namespace reactivesocket {

namespace {

const char* HEX_CHARS = {"0123456789abcdef"};
}

static const char* getTerminatingSignalErrorMessage(int terminatingSignal) {
  switch ((StreamCompletionSignal)terminatingSignal) {
    case StreamCompletionSignal::CONNECTION_END:
      return "connection closed";
    case StreamCompletionSignal::CONNECTION_ERROR:
      return "connection error";
    case StreamCompletionSignal::ERROR:
      return "socket error";
    case StreamCompletionSignal::SOCKET_CLOSED:
      return "reactive socket closed";
    case StreamCompletionSignal::GRACEFUL:
      DCHECK(false) << "throwing exception for GRACEFUL termination?";
      return "graceful termination";
    default:
      return "stream interrupted";
  }
}

std::ostream& operator<<(std::ostream& os, StreamCompletionSignal signal) {
  switch (signal) {
    case StreamCompletionSignal::GRACEFUL:
      return os << "GRACEFUL";
    case StreamCompletionSignal::ERROR:
      return os << "ERROR";
    case StreamCompletionSignal::INVALID_SETUP:
      return os << "INVALID_SETUP";
    case StreamCompletionSignal::UNSUPPORTED_SETUP:
      return os << "UNSUPPORTED_SETUP";
    case StreamCompletionSignal::REJECTED_SETUP:
      return os << "REJECTED_SETUP";
    case StreamCompletionSignal::CONNECTION_ERROR:
      return os << "CONNECTION_ERROR";
    case StreamCompletionSignal::CONNECTION_END:
      return os << "CONNECTION_END";
    case StreamCompletionSignal::SOCKET_CLOSED:
      return os << "SOCKET_CLOSED";
  }
  // this should be never hit because the switch is over all cases
  LOG(FATAL) << "unknown StreamCompletionSignal=" << (int)signal;
}

StreamInterruptedException::StreamInterruptedException(int _terminatingSignal)
    : std::runtime_error(getTerminatingSignalErrorMessage(_terminatingSignal)),
      terminatingSignal(_terminatingSignal) {}

ResumeIdentificationToken::ResumeIdentificationToken()
    : ResumeIdentificationToken(
          Data() = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}) {}

ResumeIdentificationToken ResumeIdentificationToken::generateNew() {
  // TODO: this will be replaced with a variable length bit array and the value
  // will be generated outside of reactivesocket
  // for now we will use temporary number generator
  folly::ThreadLocalPRNG rng;

  Data data;
  for (size_t i = 0; i < data.size(); i++) {
    data[i] = folly::Random::rand32(rng);
  }
  return ResumeIdentificationToken(std::move(data));
}

ResumeIdentificationToken ResumeIdentificationToken::fromString(
    const std::string& /*str*/) {
  CHECK(false) << "not implemented";
  return ResumeIdentificationToken();
}

std::string ResumeIdentificationToken::toString() const {
  std::string str;
  for (auto b : bits_) {
    str += HEX_CHARS[(b & 0xF0) >> 4];
    str += HEX_CHARS[b & 0x0F];
  }
  return str;
}

} // reactivesocket
<|endoftext|>


<commit_before>/*

Copyright (c) 2012, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/file.hpp"
#include "test.hpp"
#include <vector>
#include <set>

using namespace libtorrent;

int touch_file(std::string const& filename, int size)
{
	using namespace libtorrent;

	std::vector<char> v;
	v.resize(size);
	for (int i = 0; i < size; ++i)
		v[i] = i & 255;

	file f;
	error_code ec;
	if (!f.open(filename, file::write_only, ec)) return -1;
	if (ec) return -1;
	file::iovec_t b = {&v[0], v.size()};
	size_type written = f.writev(0, &b, 1, ec);
	if (written != int(v.size())) return -3;
	if (ec) return -3;
	return 0;
}

int test_main()
{
	error_code ec;

	create_directory("file_test_dir", ec);
	if (ec) fprintf(stderr, "create_directory: %s\n", ec.message().c_str());
	TEST_CHECK(!ec);

	std::string cwd = current_working_directory();

	touch_file(combine_path("file_test_dir", "abc"), 10);
	touch_file(combine_path("file_test_dir", "def"), 100);
	touch_file(combine_path("file_test_dir", "ghi"), 1000);

	std::set<std::string> files;
	for (directory i("file_test_dir", ec); !i.done(); i.next(ec))
	{
		std::string f = i.file();
		TEST_CHECK(files.count(f) == 0);
		files.insert(f);
		fprintf(stderr, " %s\n", f.c_str());
	}

	TEST_CHECK(files.count("abc") == 1);
	TEST_CHECK(files.count("def") == 1);
	TEST_CHECK(files.count("ghi") == 1);
	TEST_CHECK(files.count("..") == 1);
	TEST_CHECK(files.count(".") == 1);

	remove_all("file_test_dir", ec);
	if (ec) fprintf(stderr, "create_directory: %s\n", ec.message().c_str());

	return 0;
}

<commit_msg>expand file test<commit_after>/*

Copyright (c) 2012, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/file.hpp"
#include "test.hpp"
#include <vector>
#include <set>

using namespace libtorrent;

int touch_file(std::string const& filename, int size)
{
	using namespace libtorrent;

	std::vector<char> v;
	v.resize(size);
	for (int i = 0; i < size; ++i)
		v[i] = i & 255;

	file f;
	error_code ec;
	if (!f.open(filename, file::write_only, ec)) return -1;
	if (ec) return -1;
	file::iovec_t b = {&v[0], v.size()};
	size_type written = f.writev(0, &b, 1, ec);
	if (written != int(v.size())) return -3;
	if (ec) return -3;
	return 0;
}

int test_main()
{
	error_code ec;

	create_directory("file_test_dir", ec);
	if (ec) fprintf(stderr, "create_directory: %s\n", ec.message().c_str());
	TEST_CHECK(!ec);

	std::string cwd = current_working_directory();

	touch_file(combine_path("file_test_dir", "abc"), 10);
	touch_file(combine_path("file_test_dir", "def"), 100);
	touch_file(combine_path("file_test_dir", "ghi"), 1000);

	std::set<std::string> files;
	for (directory i("file_test_dir", ec); !i.done(); i.next(ec))
	{
		std::string f = i.file();
		TEST_CHECK(files.count(f) == 0);
		files.insert(f);
		fprintf(stderr, " %s\n", f.c_str());
	}

	TEST_CHECK(files.count("abc") == 1);
	TEST_CHECK(files.count("def") == 1);
	TEST_CHECK(files.count("ghi") == 1);
	TEST_CHECK(files.count("..") == 1);
	TEST_CHECK(files.count(".") == 1);
	files.clear();

	recursive_copy("file_test_dir", "file_test_dir2", ec);

	for (directory i("file_test_dir2", ec); !i.done(); i.next(ec))
	{
		std::string f = i.file();
		TEST_CHECK(files.count(f) == 0);
		files.insert(f);
		fprintf(stderr, " %s\n", f.c_str());
	}

	remove_all("file_test_dir", ec);
	if (ec) fprintf(stderr, "remove_all: %s\n", ec.message().c_str());
	remove_all("file_test_dir2", ec);
	if (ec) fprintf(stderr, "remove_all: %s\n", ec.message().c_str());

	return 0;
}

<|endoftext|>


<commit_before>#include "base/buffer.h"

#include <stdarg.h>
#include <stdlib.h>
#include <algorithm>

#ifdef _WIN32
#include <winsock2.h>
#undef min
#undef max
#else
#include <sys/socket.h>
#endif

#include "base/logging.h"
#include "file/fd_util.h"

Buffer::Buffer() { }
Buffer::~Buffer() { }

char *Buffer::Append(ssize_t length) {
  size_t old_size = data_.size();
  data_.resize(old_size + length);
  return &data_[0] + old_size;
}

void Buffer::Append(const std::string &str) {
  char *ptr = Append(str.size());
  memcpy(ptr, str.data(), str.size());
}

void Buffer::Append(const char *str) {
  size_t len = strlen(str);
  char *dest = Append(len);
  memcpy(dest, str, len);
}

void Buffer::AppendValue(int value) {
  char buf[16];
  // This is slow.
  sprintf(buf, "%i", value);
  Append(buf);
}

void Buffer::Take(size_t length, std::string *dest) {
  CHECK_LE(length, data_.size());
  dest->resize(length);
  memcpy(&(*dest)[0], &data_[0], length);
  data_.erase(data_.begin(), data_.begin() + length);
}

int Buffer::TakeLineCRLF(std::string *dest) {
  int after_next_line = OffsetToAfterNextCRLF();
  if (after_next_line < 0)
    return after_next_line;
  else {
    Take(after_next_line - 2, dest);
    Skip(2);  // Skip the CRLF
    return after_next_line - 2;
  }
}

void Buffer::Skip(size_t length) {
  data_.erase(data_.begin(), data_.begin() + length);
}

int Buffer::SkipLineCRLF() {
  int after_next_line = OffsetToAfterNextCRLF();
  if (after_next_line < 0)
    return after_next_line;
  else {
    Skip(after_next_line);
    return after_next_line - 2;
  }
}

int Buffer::OffsetToAfterNextCRLF() {
  for (size_t i = 0; i < data_.size() - 1; i++) {
    if (data_[i] == '\r' && data_[i + 1] == '\n') {
      return i + 2;
    }
  }
  return -1;
}

void Buffer::Printf(const char *fmt, ...) {
  char buffer[512];
  va_list vl;
  va_start(vl, fmt);
  ssize_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl);
  if (retval >= (ssize_t)sizeof(buffer)) {
    // Output was truncated. TODO: Do something.
    FLOG("Buffer::Printf truncated output");
  }
  CHECK_GE(retval, 0);
  va_end(vl);
  char *ptr = Append(retval);
  CHECK(ptr);
  memcpy(ptr, buffer, retval);
}

bool Buffer::Flush(int fd) {
  // Look into using send() directly.
  bool success = (ssize_t)data_.size() == fd_util::WriteLine(fd, &data_[0], data_.size());
  if (success) {
    data_.resize(0);
  }
  return success;
}

bool Buffer::FlushSocket(uintptr_t sock) {
  // TODO: send may need retries!
  size_t sent = send(sock, &data_[0], data_.size(), 0);
  // bool success = fd_util::WriteLine(fd, data_.data(), data_.size());
  if (sent == data_.size()) {
    data_.resize(0);
    return true;
  } else {
    ELOG("FlushSocket failed");
    return false;
  }
}

void Buffer::ReadAll(int fd) {
  char buf[1024];
  int retval;
  while ((retval = recv(fd, buf, sizeof(buf), 0)) > 0) {
    char *p = Append((size_t)retval);
    memcpy(p, buf, retval);
  }
}

void Buffer::Read(int fd, size_t sz) {
  char buf[1024];
  int retval;
  while ((retval = recv(fd, buf, std::min(sz, sizeof(buf)), 0)) > 0) {
    char *p = Append((size_t)retval);
    memcpy(p, buf, retval);
    sz -= retval;
    if (sz == 0)
      break;
  }
}

void Buffer::PeekAll(std::string *dest) {
  dest->resize(data_.size());
  memcpy(&(*dest)[0], &data_[0], data_.size());
}<commit_msg>If needed, call send() multiple times in HTTP.<commit_after>#include "base/buffer.h"

#include <stdarg.h>
#include <stdlib.h>
#include <algorithm>

#ifdef _WIN32
#include <winsock2.h>
#undef min
#undef max
#else
#include <sys/socket.h>
#endif

#include "base/logging.h"
#include "file/fd_util.h"

Buffer::Buffer() { }
Buffer::~Buffer() { }

char *Buffer::Append(ssize_t length) {
  size_t old_size = data_.size();
  data_.resize(old_size + length);
  return &data_[0] + old_size;
}

void Buffer::Append(const std::string &str) {
  char *ptr = Append(str.size());
  memcpy(ptr, str.data(), str.size());
}

void Buffer::Append(const char *str) {
  size_t len = strlen(str);
  char *dest = Append(len);
  memcpy(dest, str, len);
}

void Buffer::AppendValue(int value) {
  char buf[16];
  // This is slow.
  sprintf(buf, "%i", value);
  Append(buf);
}

void Buffer::Take(size_t length, std::string *dest) {
  CHECK_LE(length, data_.size());
  dest->resize(length);
  memcpy(&(*dest)[0], &data_[0], length);
  data_.erase(data_.begin(), data_.begin() + length);
}

int Buffer::TakeLineCRLF(std::string *dest) {
  int after_next_line = OffsetToAfterNextCRLF();
  if (after_next_line < 0)
    return after_next_line;
  else {
    Take(after_next_line - 2, dest);
    Skip(2);  // Skip the CRLF
    return after_next_line - 2;
  }
}

void Buffer::Skip(size_t length) {
  data_.erase(data_.begin(), data_.begin() + length);
}

int Buffer::SkipLineCRLF() {
  int after_next_line = OffsetToAfterNextCRLF();
  if (after_next_line < 0)
    return after_next_line;
  else {
    Skip(after_next_line);
    return after_next_line - 2;
  }
}

int Buffer::OffsetToAfterNextCRLF() {
  for (size_t i = 0; i < data_.size() - 1; i++) {
    if (data_[i] == '\r' && data_[i + 1] == '\n') {
      return i + 2;
    }
  }
  return -1;
}

void Buffer::Printf(const char *fmt, ...) {
  char buffer[512];
  va_list vl;
  va_start(vl, fmt);
  ssize_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl);
  if (retval >= (ssize_t)sizeof(buffer)) {
    // Output was truncated. TODO: Do something.
    FLOG("Buffer::Printf truncated output");
  }
  CHECK_GE(retval, 0);
  va_end(vl);
  char *ptr = Append(retval);
  CHECK(ptr);
  memcpy(ptr, buffer, retval);
}

bool Buffer::Flush(int fd) {
  // Look into using send() directly.
  bool success = (ssize_t)data_.size() == fd_util::WriteLine(fd, &data_[0], data_.size());
  if (success) {
    data_.resize(0);
  }
  return success;
}

bool Buffer::FlushSocket(uintptr_t sock) {
  for (size_t pos = 0, end = data_.size(); pos < end; ) {
    size_t sent = send(sock, &data_[pos], end - pos, 0);
    if (sent < 0) {
      ELOG("FlushSocket failed");
      return false;
    }
    pos += sent;

    // Buffer full, don't spin.
    if (sent == 0) {
#ifdef _WIN32
      Sleep(1);
#else
      sleep(1);
#endif
    }
  }

  data_.resize(0);
  return true;
}

void Buffer::ReadAll(int fd) {
  char buf[1024];
  int retval;
  while ((retval = recv(fd, buf, sizeof(buf), 0)) > 0) {
    char *p = Append((size_t)retval);
    memcpy(p, buf, retval);
  }
}

void Buffer::Read(int fd, size_t sz) {
  char buf[1024];
  int retval;
  while ((retval = recv(fd, buf, std::min(sz, sizeof(buf)), 0)) > 0) {
    char *p = Append((size_t)retval);
    memcpy(p, buf, retval);
    sz -= retval;
    if (sz == 0)
      break;
  }
}

void Buffer::PeekAll(std::string *dest) {
  dest->resize(data_.size());
  memcpy(&(*dest)[0], &data_[0], data_.size());
}<|endoftext|>


<commit_before><?hh //strict

namespace typesafety;

final class Context implements Writable<string>
{

    public function __construct
    (
        private Arguments $args,
        private Console $console = new Console()
    )
    {
    }

    public function getArguments() : Arguments
    {
        return $this->args;
    }

    public function write(string $text) : void
    {
        $this->console->write($text);
    }

    public function writeln(string $text) : void
    {
        $this->console->writeln($text);
    }

}
<commit_msg>add fromArray<commit_after><?hh //strict

namespace typesafety;

final class Context implements Writable<string>
{

    public function __construct
    (
        private Arguments $args,
        private Console $console = new Console()
    )
    {
    }

    public function getArguments() : Arguments
    {
        return $this->args;
    }

    public function write(string $text) : void
    {
        $this->console->write($text);
    }

    public function writeln(string $text) : void
    {
        $this->console->writeln($text);
    }

    public static function fromArray(array<string> $argv) : Context
    {
        return new Context(
            Arguments::fromArray($argv)
        );
    }

}
<|endoftext|>