<commit_before>#include "bulkDataDistributerCb.h"

BulkDataDistributerCb::BulkDataDistributerCb()
{
    ACS_TRACE("BulkDataCallback::BulkDataCallback");

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    dim_m = 0;
    count_m = 0;

    //loop_m = 5;
    loop_m = 1000;
    //waitPeriod_m.set(0L, 400000L);
    waitPeriod_m.set(0L, 10L); // set to 0.01 ms to improve Distributor performance

    frameCount_m = 0;

    timeout_m = false;

    working_m = false;
}

BulkDataDistributerCb::BulkDataDistributerCb(TAO_StreamCtrl * stream_p)
{
    ACS_TRACE("BulkDataDistributerCb::BulkDataDistributerCb");
}

BulkDataDistributerCb::~BulkDataDistributerCb()
{
    ACS_TRACE("BulkDataCallback::~BulkDataCallback");
}

int BulkDataDistributerCb::handle_start(void)
{
    //ACS_TRACE("BulkDataDistributerCb::handle_start");

    //cout << "BulkDataDistributerCb::handle_start - state_m: " << state_m << endl;

    timeout_m = false;

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    frameCount_m = 1; // we need to wait for one frame before doing anything else

    return 0;
}

int BulkDataDistributerCb::handle_stop (void)
{
    //ACS_TRACE("BulkDataDistributerCb::handle_stop");

    int locLoop;

    locLoop = loop_m;
    while ( (frameCount_m != 0) && locLoop > 0)
	{
	ACE_OS::sleep(waitPeriod_m);
	locLoop--;
	} // we didn't receive the first frame yet
    if ( locLoop == 0 ) // TBD error handling has to be done
	{
	ACS_SHORT_LOG((LM_WARNING,"BulkDataDistributerCb::handle_stop timeout expired"));
	}

    //cout << "CCCCCCCCCCCCCCCCC enter stop state " << state_m << " " << substate_m << endl;

    if(state_m == CB_UNS)
	{
	cbFwdUserStop();
	return 0;
	}

    if((state_m == CB_SEND_PARAM) || (state_m == CB_SEND_DATA))
	{
	if  (substate_m == CB_SUB_INIT)
	    {
	    substate_m = CB_SUB_UNS;
	    return 0;
	    }

	//TO BE REMOVED (?)
	locLoop = loop_m;
	while((count_m != dim_m) && locLoop > 0)
	    {
	    ACE_OS::sleep(waitPeriod_m);
	    locLoop--;
	    }

	if ( locLoop == 0 )
	    {
	    ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::handle_stop timeout expired, not all data received"));

	    timeout_m = true;

	    //return -1;
	    }

	int res = cbFwdStop();

	state_m = CB_UNS;
	substate_m = CB_SUB_UNS;

	return res;
	}

    return 0;
}

int BulkDataDistributerCb::handle_destroy (void)
{
    //ACS_TRACE("BulkDataDistributerCb::handle_destroy");

    //cout << "BulkDataDistributerCb::handle_destroy" << endl;

    delete this;

    return 0;
}

int BulkDataDistributerCb::receive_frame (ACE_Message_Block *frame, TAO_AV_frame_info *frame_info, const ACE_Addr &)
{
    //ACS_TRACE("BulkDataDistributerCb::receive_frame");

    working_m = true;

    //ACS_SHORT_LOG((LM_INFO,"BulkDataDistributerCb::receive_frame for flow %s", flowname_m.c_str()));

    //cout << "BulkDataDistributerCb::receive_frame - state_m: " << state_m << endl;

    CORBA::ULong val1, val2;
    int res = 0;

    if(state_m == CB_UNS)
	{
	char tmp[255];
	ACE_OS::strcpy(tmp, frame->rd_ptr());

	string strDataInfo(tmp);

	istringstream iss(strDataInfo);

	iss >> val1 >> val2;

	//cout << "CCCCCCCCCCCCCCC " << val1 << " " << val2 << endl;

	if(val1 == 1)
	    {
	    state_m = CB_SEND_PARAM;
	    substate_m = CB_SUB_INIT;
	    }
	else if(val1 == 2)
	    {
	    state_m = CB_SEND_DATA;
	    substate_m = CB_SUB_INIT;
	    }
	else
	    {
	    state_m = CB_UNS;
	    substate_m = CB_SUB_UNS;
	    }

	dim_m = val2;
	count_m = 0;

// we received the first frame and we pass it to the receiver
// the variable frameCount_m is equal 1 and this help us
// to distinguish between first frame and the data

	res = cbHandshake(frame);

	frameCount_m = 0;

	working_m = true;

	return res;
	}

    if(state_m == CB_SEND_PARAM)
	{

	if ( dim_m == 0 )
	    {
	    res = cbFwdStart();
	    working_m = false;
	    return res;
	    }

	res = cbFwdStart(frame);
	count_m += frame->length();
	working_m = false;
	return res;
	}

    if (state_m == CB_SEND_DATA)
	{
	res = cbFwdReceive(frame);
	count_m += frame->length();
	working_m = false;
	return res;
	}

    working_m = false;

    return 0;
}

void BulkDataDistributerCb::setFlowname (const char * flowname_p)
{
    ACS_TRACE("BulkDataDistributerCb::setFlowname");

    flowname_m = flowname_p;

    string flwName(flowname_p);
    string flwNumber(flwName, 4, 1);

    flowNumber_m = atol(flwNumber.c_str());
}

void BulkDataDistributerCb::setSleepTime(ACE_Time_Value locWaitPeriod)
{
    ACS_TRACE("BulkDataDistributerCb::setSleepTime");

    waitPeriod_m = locWaitPeriod;
}

void BulkDataDistributerCb::setSafeTimeout(CORBA::ULong locLoop)
{
    ACS_TRACE("BulkDataDistributerCb::setSafeTimeout");

    loop_m = locLoop;
}

int
BulkDataDistributerCb::cbHandshake(ACE_Message_Block * info_p)
{
    //ACS_TRACE("BulkDataDistributerCb::cbHandshake");

    if(distr_m == 0)
	{
	ACS_SHORT_LOG((LM_INFO, "BulkDataDistributerCb::cbHandshake - distr_m == 0"));
	return -1;
	}

    try
	{
	distr_m->getDistributer()->distSendStart(flowname_m, flowNumber_m);

	distr_m->getDistributer()->distSendDataHsk(flowname_m, info_p, flowNumber_m);

	distr_m->getDistributer()->distSendStop(flowname_m, flowNumber_m);
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbHandshake exception"));
	}

// we replicate the mechanism of the sender
/*
	TAO_AV_Protocol_Object *dp_p = 0;
	ACE_CString flwn = "Flow1";
	distr_m->distributer.getFlowProtocol(flwn, dp_p);

	AVStreams::flowSpec locSpec(1);
	locSpec.length(1);
	locSpec[0] = distr_m->distributer.flowSpec_m[0];

// we replicate the mechanism of the sender for the start

	distr_m->distributer.streamctrl_p->start(locSpec);

	int res = dp_p->send_frame(info_p);
	if(res < 0) { return -1; }

	distr_m->distributer.streamctrl_p->stop(locSpec);

*/

	return 0;

}

int
BulkDataDistributerCb::cbFwdStart(ACE_Message_Block * userParam_p)
{
    //ACS_TRACE("BulkDataDistributerCb::cbFwdStart");

/*
    TAO_AV_Protocol_Object *dp_p = 0;
    ACE_CString flwn = "Flow1";
    distr_m->distributer.getFlowProtocol(flwn, dp_p);

    int res = dp_p->send_frame(userParam_p);
    if(res < 0) { return -1; }
*/

    try
	{
	distr_m->getDistributer()->distSendData(flowname_m,userParam_p, flowNumber_m);
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStart exception"));
	}
    return 0;

}

int
BulkDataDistributerCb::cbFwdReceive(ACE_Message_Block * frame_p)
{
    //ACS_TRACE("BulkDataDistributerCb::cbReceive");

/*
    TAO_AV_Protocol_Object *dp_p = 0;
    ACE_CString flwn = "Flow1";
    distr_m->distributer.getFlowProtocol(flwn, dp_p);

    int res = dp_p->send_frame(frame_p);
    if(res < 0) { return -1; }
*/

    try
	{
	distr_m->getDistributer()->distSendData(flowname_m, frame_p, flowNumber_m);
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdReceive exception"));
	}

    return 0;
}

int
BulkDataDistributerCb::cbFwdStop()
{
    //ACS_TRACE("BulkDataDistributerCb::cbFwdStop");

/*
    TAO_AV_Protocol_Object *dp_p = 0;
    ACE_CString flwn = "Flow1";
    distr_m->distributer.getFlowProtocol(flwn, dp_p);

    AVStreams::flowSpec locSpec(1);
    locSpec.length(1);
    locSpec[0] = distr_m->distributer.flowSpec_m[0];

    distr_m->distributer.streamctrl_p->stop(locSpec);
*/

    try
	{
	timeout_m = distr_m->getDistributer()->distSendStopTimeout(flowname_m, flowNumber_m);
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStop exception"));
	}

    return 0;
}

int
BulkDataDistributerCb::cbFwdUserStop()
{
    //ACS_TRACE("BulkDataDistributerCb::cbFwdUserStop");

    try
	{
	distr_m->getDistributer()->distSendStop(flowname_m, flowNumber_m);
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStop exception"));
	}

    return 0;
}

void BulkDataDistributerCb::setDistributerImpl(BulkDataDistributerImpl<BulkDataDistributerCb> *distr_p)
{
    ACS_TRACE("BulkDataDistributerCb::setDistributerImpl");

    distr_m = distr_p;
}

CORBA::Boolean BulkDataDistributerCb::isTimeout()
{
    ACS_TRACE("BulkDataDistributerCb::isTimeout");

    return timeout_m;
}

CORBA::Boolean BulkDataDistributerCb::isWorking()
{
    ACS_TRACE("BulkDataDistributerCb::isWorking");

    return working_m;
}

/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(BulkDataDistributerImpl<BulkDataDistributerCb>)
/* ----------------------------------------------------------------*/

<commit_msg>Added check distr_m!=NULL<commit_after>#include "bulkDataDistributerCb.h"

BulkDataDistributerCb::BulkDataDistributerCb()
{
    ACS_TRACE("BulkDataCallback::BulkDataCallback");

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    dim_m = 0;
    count_m = 0;

    //loop_m = 5;
    loop_m = 1000;
    //waitPeriod_m.set(0L, 400000L);
    waitPeriod_m.set(0L, 10L); // set to 0.01 ms to improve Distributor performance

    frameCount_m = 0;

    timeout_m = false;

    working_m = false;
}

BulkDataDistributerCb::BulkDataDistributerCb(TAO_StreamCtrl * stream_p)
{
    ACS_TRACE("BulkDataDistributerCb::BulkDataDistributerCb");
}

BulkDataDistributerCb::~BulkDataDistributerCb()
{
    ACS_TRACE("BulkDataCallback::~BulkDataCallback");
}

int BulkDataDistributerCb::handle_start(void)
{
    //ACS_TRACE("BulkDataDistributerCb::handle_start");

    //cout << "BulkDataDistributerCb::handle_start - state_m: " << state_m << endl;

    timeout_m = false;

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    frameCount_m = 1; // we need to wait for one frame before doing anything else

    return 0;
}

int BulkDataDistributerCb::handle_stop (void)
{
    //ACS_TRACE("BulkDataDistributerCb::handle_stop");

    int locLoop;

    locLoop = loop_m;
    while ( (frameCount_m != 0) && locLoop > 0)
	{
	ACE_OS::sleep(waitPeriod_m);
	locLoop--;
	} // we didn't receive the first frame yet
    if ( locLoop == 0 ) // TBD error handling has to be done
	{
	ACS_SHORT_LOG((LM_WARNING,"BulkDataDistributerCb::handle_stop timeout expired"));
	}

    //cout << "CCCCCCCCCCCCCCCCC enter stop state " << state_m << " " << substate_m << endl;

    if(state_m == CB_UNS)
	{
	cbFwdUserStop();
	return 0;
	}

    if((state_m == CB_SEND_PARAM) || (state_m == CB_SEND_DATA))
	{
	if  (substate_m == CB_SUB_INIT)
	    {
	    substate_m = CB_SUB_UNS;
	    return 0;
	    }

	//TO BE REMOVED (?)
	locLoop = loop_m;
	while((count_m != dim_m) && locLoop > 0)
	    {
	    ACE_OS::sleep(waitPeriod_m);
	    locLoop--;
	    }

	if ( locLoop == 0 )
	    {
	    ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::handle_stop timeout expired, not all data received"));

	    timeout_m = true;

	    //return -1;
	    }

	int res = cbFwdStop();

	state_m = CB_UNS;
	substate_m = CB_SUB_UNS;

	return res;
	}

    return 0;
}

int BulkDataDistributerCb::handle_destroy (void)
{
    //ACS_TRACE("BulkDataDistributerCb::handle_destroy");

    //cout << "BulkDataDistributerCb::handle_destroy" << endl;

    delete this;

    return 0;
}

int BulkDataDistributerCb::receive_frame (ACE_Message_Block *frame, TAO_AV_frame_info *frame_info, const ACE_Addr &)
{
    //ACS_TRACE("BulkDataDistributerCb::receive_frame");

    working_m = true;

    //ACS_SHORT_LOG((LM_INFO,"BulkDataDistributerCb::receive_frame for flow %s", flowname_m.c_str()));

    //cout << "BulkDataDistributerCb::receive_frame - state_m: " << state_m << endl;

    CORBA::ULong val1, val2;
    int res = 0;

    if(state_m == CB_UNS)
	{
	char tmp[255];
	ACE_OS::strcpy(tmp, frame->rd_ptr());

	string strDataInfo(tmp);

	istringstream iss(strDataInfo);

	iss >> val1 >> val2;

	//cout << "CCCCCCCCCCCCCCC " << val1 << " " << val2 << endl;

	if(val1 == 1)
	    {
	    state_m = CB_SEND_PARAM;
	    substate_m = CB_SUB_INIT;
	    }
	else if(val1 == 2)
	    {
	    state_m = CB_SEND_DATA;
	    substate_m = CB_SUB_INIT;
	    }
	else
	    {
	    state_m = CB_UNS;
	    substate_m = CB_SUB_UNS;
	    }

	dim_m = val2;
	count_m = 0;

// we received the first frame and we pass it to the receiver
// the variable frameCount_m is equal 1 and this help us
// to distinguish between first frame and the data

	res = cbHandshake(frame);

	frameCount_m = 0;

	working_m = true;

	return res;
	}

    if(state_m == CB_SEND_PARAM)
	{

	if ( dim_m == 0 )
	    {
	    res = cbFwdStart();
	    working_m = false;
	    return res;
	    }

	res = cbFwdStart(frame);
	count_m += frame->length();
	working_m = false;
	return res;
	}

    if (state_m == CB_SEND_DATA)
	{
	res = cbFwdReceive(frame);
	count_m += frame->length();
	working_m = false;
	return res;
	}

    working_m = false;

    return 0;
}

void BulkDataDistributerCb::setFlowname (const char * flowname_p)
{
    ACS_TRACE("BulkDataDistributerCb::setFlowname");

    flowname_m = flowname_p;

    string flwName(flowname_p);
    string flwNumber(flwName, 4, 1);

    flowNumber_m = atol(flwNumber.c_str());
}

void BulkDataDistributerCb::setSleepTime(ACE_Time_Value locWaitPeriod)
{
    ACS_TRACE("BulkDataDistributerCb::setSleepTime");

    waitPeriod_m = locWaitPeriod;
}

void BulkDataDistributerCb::setSafeTimeout(CORBA::ULong locLoop)
{
    ACS_TRACE("BulkDataDistributerCb::setSafeTimeout");

    loop_m = locLoop;
}

int
BulkDataDistributerCb::cbHandshake(ACE_Message_Block * info_p)
{
    //ACS_TRACE("BulkDataDistributerCb::cbHandshake");

    if(distr_m == 0)
	{
	ACS_SHORT_LOG((LM_INFO, "BulkDataDistributerCb::cbHandshake - distr_m == 0"));
	return -1;
	}

    try
	{
	distr_m->getDistributer()->distSendStart(flowname_m, flowNumber_m);

	distr_m->getDistributer()->distSendDataHsk(flowname_m, info_p, flowNumber_m);

	distr_m->getDistributer()->distSendStop(flowname_m, flowNumber_m);
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbHandshake exception"));
	}

// we replicate the mechanism of the sender
/*
	TAO_AV_Protocol_Object *dp_p = 0;
	ACE_CString flwn = "Flow1";
	distr_m->distributer.getFlowProtocol(flwn, dp_p);

	AVStreams::flowSpec locSpec(1);
	locSpec.length(1);
	locSpec[0] = distr_m->distributer.flowSpec_m[0];

// we replicate the mechanism of the sender for the start

	distr_m->distributer.streamctrl_p->start(locSpec);

	int res = dp_p->send_frame(info_p);
	if(res < 0) { return -1; }

	distr_m->distributer.streamctrl_p->stop(locSpec);

*/

	return 0;

}

int
BulkDataDistributerCb::cbFwdStart(ACE_Message_Block * userParam_p)
{
    //ACS_TRACE("BulkDataDistributerCb::cbFwdStart");

/*
    TAO_AV_Protocol_Object *dp_p = 0;
    ACE_CString flwn = "Flow1";
    distr_m->distributer.getFlowProtocol(flwn, dp_p);

    int res = dp_p->send_frame(userParam_p);
    if(res < 0) { return -1; }
*/

    try
	{
    	if (distr_m!=NULL)
    	{
    		distr_m->getDistributer()->distSendData(flowname_m,userParam_p, flowNumber_m);
    	}
    	else
    	{
    		ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStart distr_m==NULL !!!"));
    	}
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStart exception"));
	}
    return 0;

}

int
BulkDataDistributerCb::cbFwdReceive(ACE_Message_Block * frame_p)
{
    //ACS_TRACE("BulkDataDistributerCb::cbReceive");

/*
    TAO_AV_Protocol_Object *dp_p = 0;
    ACE_CString flwn = "Flow1";
    distr_m->distributer.getFlowProtocol(flwn, dp_p);

    int res = dp_p->send_frame(frame_p);
    if(res < 0) { return -1; }
*/

    try
	{
    	if (distr_m!=NULL)
    		distr_m->getDistributer()->distSendData(flowname_m, frame_p, flowNumber_m);
    	else
    		ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdReceive distr_m==NULL !!!"));
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdReceive exception"));
	}

    return 0;
}

int
BulkDataDistributerCb::cbFwdStop()
{
    //ACS_TRACE("BulkDataDistributerCb::cbFwdStop");

/*
    TAO_AV_Protocol_Object *dp_p = 0;
    ACE_CString flwn = "Flow1";
    distr_m->distributer.getFlowProtocol(flwn, dp_p);

    AVStreams::flowSpec locSpec(1);
    locSpec.length(1);
    locSpec[0] = distr_m->distributer.flowSpec_m[0];

    distr_m->distributer.streamctrl_p->stop(locSpec);
*/

    try
	{
    	if (distr_m!=NULL)
    		timeout_m = distr_m->getDistributer()->distSendStopTimeout(flowname_m, flowNumber_m);
    	else
    		ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStop distr_m==NULL !!!"));
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdStop exception"));
	}

    return 0;
}

int
BulkDataDistributerCb::cbFwdUserStop()
{
    //ACS_TRACE("BulkDataDistributerCb::cbFwdUserStop");

    try
	{
    	if (distr_m!=NULL)
    		distr_m->getDistributer()->distSendStop(flowname_m, flowNumber_m);
    	else
    		ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdUserStop distr_m==NULL !!!"));
	}
    catch(...)
	{
	ACS_SHORT_LOG((LM_ERROR,"BulkDataDistributerCb::cbFwdUserStop exception"));
	}

    return 0;
}

void BulkDataDistributerCb::setDistributerImpl(BulkDataDistributerImpl<BulkDataDistributerCb> *distr_p)
{
    ACS_TRACE("BulkDataDistributerCb::setDistributerImpl");

    distr_m = distr_p;
}

CORBA::Boolean BulkDataDistributerCb::isTimeout()
{
    ACS_TRACE("BulkDataDistributerCb::isTimeout");

    return timeout_m;
}

CORBA::Boolean BulkDataDistributerCb::isWorking()
{
    ACS_TRACE("BulkDataDistributerCb::isWorking");

    return working_m;
}

/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(BulkDataDistributerImpl<BulkDataDistributerCb>)
/* ----------------------------------------------------------------*/

<|endoftext|>


<commit_before>/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "sk_tool_utils.h"
#include "SkRandom.h"

#if SK_SUPPORT_GPU
#include "etc1.h"

#include "GrContext.h"
#include "GrGpu.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrTextureProxy.h"
#include "effects/GrSimpleTextureEffect.h"
#include "ops/GrFillRectOp.h"

// Basic test of Ganesh's ETC1 support
class ETC1GM : public skiagm::GM {
public:
    ETC1GM() {
        this->setBGColor(0xFFCCCCCC);
    }

protected:
    SkString onShortName() override {
        return SkString("etc1");
    }

    SkISize onISize() override {
        return SkISize::Make(kTexWidth + 2*kPad, kTexHeight + 2*kPad);
    }

    void onOnceBeforeDraw() override {
        SkBitmap bm;
        SkImageInfo ii = SkImageInfo::Make(kTexWidth, kTexHeight, kRGB_565_SkColorType,
                                           kOpaque_SkAlphaType);
        bm.allocPixels(ii);

        bm.erase(SK_ColorBLUE, SkIRect::MakeWH(kTexWidth, kTexHeight));

        for (int y = 0; y < kTexHeight; y += 4) {
            for (int x = 0; x < kTexWidth; x += 4) {
                bm.erase((x+y) % 8 ? SK_ColorRED : SK_ColorGREEN, SkIRect::MakeXYWH(x, y, 4, 4));
            }
        }

        int size = etc1_get_encoded_data_size(bm.width(), bm.height());
        fETC1Data.reset(size);

        unsigned char* pixels = (unsigned char*) fETC1Data.get();

        if (etc1_encode_image((unsigned char*) bm.getAddr16(0, 0),
                              bm.width(), bm.height(), 2, bm.rowBytes(), pixels)) {
            fETC1Data.reset();
        }
    }

    void onDraw(SkCanvas* canvas) override {
        GrRenderTargetContext* renderTargetContext =
            canvas->internal_private_accessTopLayerRenderTargetContext();
        if (!renderTargetContext) {
            skiagm::GM::DrawGpuOnlyMessage(canvas);
            return;
        }

        GrContext* context = canvas->getGrContext();
        if (!context || context->abandoned()) {
            return;
        }

        GrBackendTexture tex = context->contextPriv().getGpu()->createTestingOnlyBackendTexture(
            fETC1Data.get(),
            kTexWidth,
            kTexHeight,
            GrColorType::kRGB_ETC1,
            false,
            GrMipMapped::kNo,
            kTexWidth/2); // rowbytes are meaningless for compressed textures, but this is
                          // basically right

        if (!tex.isValid()) {
            return;
        }

        auto proxy = context->contextPriv().proxyProvider()->wrapBackendTexture(
                                                                 tex, kTopLeft_GrSurfaceOrigin,
                                                                 kAdopt_GrWrapOwnership,
                                                                 kRead_GrIOType);
        if (!proxy) {
            return;
        }

        const SkMatrix trans = SkMatrix::MakeTrans(-kPad, -kPad);

        auto fp = GrSimpleTextureEffect::Make(proxy, trans);

        GrPaint grPaint;
        grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
        grPaint.addColorFragmentProcessor(std::move(fp));

        SkRect rect = SkRect::MakeXYWH(kPad, kPad, kTexWidth, kTexHeight);

        renderTargetContext->priv().testingOnly_addDrawOp(
            GrFillRectOp::Make(context, std::move(grPaint), GrAAType::kNone, SkMatrix::I(), rect));
    }

private:
    static const int kPad = 8;
    static const int kTexWidth = 16;
    static const int kTexHeight = 20;

    SkAutoTMalloc<char> fETC1Data;

    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new ETC1GM;)

#endif
<commit_msg>Temporarily disable etc1 GM on Google3<commit_after>/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "sk_tool_utils.h"
#include "SkRandom.h"

#if SK_SUPPORT_GPU && !defined(SK_BUILD_FOR_GOOGLE3)
#include "etc1.h"

#include "GrContext.h"
#include "GrGpu.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrTextureProxy.h"
#include "effects/GrSimpleTextureEffect.h"
#include "ops/GrFillRectOp.h"

// Basic test of Ganesh's ETC1 support
class ETC1GM : public skiagm::GM {
public:
    ETC1GM() {
        this->setBGColor(0xFFCCCCCC);
    }

protected:
    SkString onShortName() override {
        return SkString("etc1");
    }

    SkISize onISize() override {
        return SkISize::Make(kTexWidth + 2*kPad, kTexHeight + 2*kPad);
    }

    void onOnceBeforeDraw() override {
        SkBitmap bm;
        SkImageInfo ii = SkImageInfo::Make(kTexWidth, kTexHeight, kRGB_565_SkColorType,
                                           kOpaque_SkAlphaType);
        bm.allocPixels(ii);

        bm.erase(SK_ColorBLUE, SkIRect::MakeWH(kTexWidth, kTexHeight));

        for (int y = 0; y < kTexHeight; y += 4) {
            for (int x = 0; x < kTexWidth; x += 4) {
                bm.erase((x+y) % 8 ? SK_ColorRED : SK_ColorGREEN, SkIRect::MakeXYWH(x, y, 4, 4));
            }
        }

        int size = etc1_get_encoded_data_size(bm.width(), bm.height());
        fETC1Data.reset(size);

        unsigned char* pixels = (unsigned char*) fETC1Data.get();

        if (etc1_encode_image((unsigned char*) bm.getAddr16(0, 0),
                              bm.width(), bm.height(), 2, bm.rowBytes(), pixels)) {
            fETC1Data.reset();
        }
    }

    void onDraw(SkCanvas* canvas) override {
        GrRenderTargetContext* renderTargetContext =
            canvas->internal_private_accessTopLayerRenderTargetContext();
        if (!renderTargetContext) {
            skiagm::GM::DrawGpuOnlyMessage(canvas);
            return;
        }

        GrContext* context = canvas->getGrContext();
        if (!context || context->abandoned()) {
            return;
        }

        GrBackendTexture tex = context->contextPriv().getGpu()->createTestingOnlyBackendTexture(
            fETC1Data.get(),
            kTexWidth,
            kTexHeight,
            GrColorType::kRGB_ETC1,
            false,
            GrMipMapped::kNo,
            kTexWidth/2); // rowbytes are meaningless for compressed textures, but this is
                          // basically right

        if (!tex.isValid()) {
            return;
        }

        auto proxy = context->contextPriv().proxyProvider()->wrapBackendTexture(
                                                                 tex, kTopLeft_GrSurfaceOrigin,
                                                                 kAdopt_GrWrapOwnership,
                                                                 kRead_GrIOType);
        if (!proxy) {
            return;
        }

        const SkMatrix trans = SkMatrix::MakeTrans(-kPad, -kPad);

        auto fp = GrSimpleTextureEffect::Make(proxy, trans);

        GrPaint grPaint;
        grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
        grPaint.addColorFragmentProcessor(std::move(fp));

        SkRect rect = SkRect::MakeXYWH(kPad, kPad, kTexWidth, kTexHeight);

        renderTargetContext->priv().testingOnly_addDrawOp(
            GrFillRectOp::Make(context, std::move(grPaint), GrAAType::kNone, SkMatrix::I(), rect));
    }

private:
    static const int kPad = 8;
    static const int kTexWidth = 16;
    static const int kTexHeight = 20;

    SkAutoTMalloc<char> fETC1Data;

    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new ETC1GM;)

#endif
<|endoftext|>


<commit_before>/*
 * StepCompleter.hpp
 *
 *  Created on: Mar 7, 2015
 *      Author: Péter Fankhauser
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#include "free_gait_core/step/StepCompleter.hpp"
#include "free_gait_core/leg_motion/leg_motion.hpp"

namespace free_gait {

StepCompleter::StepCompleter(std::shared_ptr<StepParameters> parameters, std::shared_ptr<AdapterBase> adapter)
    : parameters_(parameters),
      adapter_(adapter_)
{
}

StepCompleter::~StepCompleter()
{
}

bool StepCompleter::complete(const State& state, const StepQueue& queue, Step& step) const
{
  for (auto& legMotion : step.legMotions_) {
    switch ((legMotion.second)->getType()) {
      case LegMotionBase::Type::Footstep:
        setParameters(dynamic_cast<Footstep&>(*legMotion.second));
        break;
      case LegMotionBase::Type::LegMode:
        setParameters(dynamic_cast<LegMode&>(*legMotion.second));
        break;
      default:
        break;
    }
    switch (legMotion.second->getTrajectoryType()) {
      case LegMotionBase::TrajectoryType::EndEffector:
        if (!complete(state, step, dynamic_cast<EndEffectorMotionBase&>(*legMotion.second))) return false;
        break;
      case LegMotionBase::TrajectoryType::Joints:
        if (!complete(state, step, dynamic_cast<JointMotionBase&>(*legMotion.second))) return false;
        break;
      default:
        throw std::runtime_error("StepCompleter::complete() could not complete leg motion of this type.");
        break;
    }
  }

  if (step.baseMotion_) {
    switch (step.baseMotion_->getType()) {
      case BaseMotionBase::Type::Auto:
        setParameters(dynamic_cast<BaseAuto&>(*step.baseMotion_));
        break;
      case BaseMotionBase::Type::Trajectory:
        setParameters(dynamic_cast<BaseTrajectory&>(*step.baseMotion_));
        break;
      default:
        break;
    }
    if (!complete(state, step, queue, *(step.baseMotion_))) return false;
  }

  return true;
}

bool StepCompleter::complete(const State& state, const Step& step, EndEffectorMotionBase& endEffectorMotion) const
{
  // Input.
//  ControlSetup controlSetupIn = state.getControlSetup(endEffectorMotion.getLimb());
//  bool positionIn = controlSetupIn.at(ControlLevel::Position);
//  bool velocityIn = controlSetupIn.at(ControlLevel::Velocity);
//  bool accelerationIn = controlSetupIn.at(ControlLevel::Acceleration);
//  bool effortIn = controlSetupIn.at(ControlLevel::Effort);

  // Output.
  ControlSetup controlSetupOut = endEffectorMotion.getControlSetup();
  bool positionOut = controlSetupOut.at(ControlLevel::Position);
  bool velocityOut = controlSetupOut.at(ControlLevel::Velocity);
  bool accelerationOut = controlSetupOut.at(ControlLevel::Acceleration);
  bool effortOut = controlSetupOut.at(ControlLevel::Effort);

  if (positionOut) {
    // TODO Check frame.
    Position startPositionInBaseFrame = adapter_->getPositionBaseToFootInBaseFrame(endEffectorMotion.getLimb(), state.getJointPositions(endEffectorMotion.getLimb()));
    Position startPositionInWorldFrame = adapter_->getPositionWorldToBaseInWorldFrame() + adapter_->getOrientationWorldToBase().inverseRotate(startPositionInBaseFrame);
    Position startPositionInDesiredFrame = startPositionInWorldFrame; // TODO
    endEffectorMotion.updateStartPosition(startPositionInDesiredFrame);
  }
  return endEffectorMotion.compute(state, step, *adapter_);
}

bool StepCompleter::complete(const State& state, const Step& step, JointMotionBase& jointMotion) const
{
  // Input.
  ControlSetup controlSetupIn = state.getControlSetup(jointMotion.getLimb());
  bool positionIn = controlSetupIn.at(ControlLevel::Position);
  bool velocityIn = controlSetupIn.at(ControlLevel::Velocity);
  bool accelerationIn = controlSetupIn.at(ControlLevel::Acceleration);
  bool effortIn = controlSetupIn.at(ControlLevel::Effort);

  // Output.
  ControlSetup controlSetupOut = jointMotion.getControlSetup();
  bool positionOut = controlSetupOut.at(ControlLevel::Position);
  bool velocityOut = controlSetupOut.at(ControlLevel::Velocity);
  bool accelerationOut = controlSetupOut.at(ControlLevel::Acceleration);
  bool effortOut = controlSetupOut.at(ControlLevel::Effort);

  // Check for special mode transitions.
  if (positionIn && !effortIn && positionOut && effortOut) {
    JointPositions startPosition = state.getJointPositions(jointMotion.getLimb());
    jointMotion.updateStartPosition(startPosition);
    JointEfforts startEffort = state.getJointEfforts(jointMotion.getLimb());
    startEffort.setZero();
    jointMotion.updateStartEfforts(startEffort);
  } else if (positionIn && effortIn && !positionOut && effortOut) {
    JointEfforts startEffort = adapter_->getJointEfforts(jointMotion.getLimb());
    jointMotion.updateStartEfforts(startEffort);
  } //else if (positionIn && effortIn && positionOut && !effortOut) {
    // TODO: Decrease torque to zero in special step.
  //} else if (!positionIn && effortIn && positionOut && !effortOut) {
    // TODO: Decrease compression on leg in special step.
  // }
  else {

    // Standard transitions.
    if (positionOut) {
      JointPositions startPosition = state.getJointPositions(jointMotion.getLimb());
      jointMotion.updateStartPosition(startPosition);
    }
    if (velocityOut) {
      JointVelocities startVelocity = state.getJointVelocities(jointMotion.getLimb());
      jointMotion.updateStartVelocity(startVelocity);
    }
    if (accelerationOut) {
      JointAccelerations startAcceleration = state.getJointAccelerations(jointMotion.getLimb());
      jointMotion.updateStartAcceleration(startAcceleration);
    }
    if (effortOut) {
      JointEfforts startEffort = state.getJointEfforts(jointMotion.getLimb());
      jointMotion.updateStartEfforts(startEffort);
    }

  }
  return jointMotion.compute(state, step, *adapter_);
}

bool StepCompleter::complete(const State& state, const Step& step, const StepQueue& queue, BaseMotionBase& baseMotion) const
{
  if (baseMotion.getControlSetup().at(ControlLevel::Position)) {
    // TODO Check frame.
    Pose pose(state.getPositionWorldToBaseInWorldFrame(), state.getOrientationWorldToBase());
    baseMotion.updateStartPose(pose);
  }
  if (baseMotion.getControlSetup().at(ControlLevel::Velocity)) {
    // TODO
  }
  return baseMotion.compute(state, step, queue, *adapter_);
}

void StepCompleter::setParameters(Footstep& footstep) const
{
  const auto& parameters = parameters_->footTargetParameters_;

  if (footstep.surfaceNormal_) {
    if (*(footstep.surfaceNormal_) == Vector::Zero())
      footstep.surfaceNormal_.reset(nullptr);
  }
  if (footstep.profileHeight_ == 0.0)
    footstep.profileHeight_ = parameters.profileHeight;
  if (footstep.profileType_.empty())
    footstep.profileType_ = parameters.profileType;
  if (footstep.averageVelocity_ == 0.0)
    footstep.averageVelocity_ = parameters.averageVelocity;

  footstep.liftOffVelocity_ = parameters.liftOffVelocity;
  footstep.touchdownVelocity_ = parameters.touchdownVelocity;
}

void StepCompleter::setParameters(LegMode& legMode) const
{
  const auto& parameters = parameters_->legModeParameters_;

  if (legMode.surfaceNormal_) {
    if (*(legMode.surfaceNormal_) == Vector::Zero())
      legMode.surfaceNormal_.reset(nullptr);
  }
  if (legMode.duration_ == 0.0)
    legMode.duration_ = parameters.duration;
  if (legMode.frameId_.empty())
    legMode.frameId_ = parameters.frameId;
}

void StepCompleter::setParameters(BaseAuto& baseAuto) const
{
  const auto& parameters = parameters_->baseAutoParameters_;

  if (baseAuto.height_) {
    if (*(baseAuto.height_) == 0.0)
      baseAuto.height_.reset(nullptr);
  }
  if (baseAuto.averageLinearVelocity_ == 0.0)
    baseAuto.averageLinearVelocity_ = parameters.averageLinearVelocity;
  if (baseAuto.averageAngularVelocity_ == 0.0)
    baseAuto.averageAngularVelocity_ = parameters.averageAngularVelocity;
  if (baseAuto.supportMargin_ == 0.0)
    baseAuto.supportMargin_ = parameters.supportMargin;
  baseAuto.minimumDuration_ = parameters.minimumDuration_;

  baseAuto.nominalPlanarStanceInBaseFrame_.clear();
  baseAuto.nominalPlanarStanceInBaseFrame_ = parameters.nominalPlanarStanceInBaseFrame;
}

void StepCompleter::setParameters(BaseTrajectory& baseTrajectory) const
{
//  const auto& parameters = parameters_->baseAutoParameters_;
//
//  if (baseAuto.controllerType_.empty())
//    baseAuto.controllerType_ = parameters.controllerType;
}

} /* namespace */

<commit_msg>Startup fix.<commit_after>/*
 * StepCompleter.hpp
 *
 *  Created on: Mar 7, 2015
 *      Author: Péter Fankhauser
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#include "free_gait_core/step/StepCompleter.hpp"
#include "free_gait_core/leg_motion/leg_motion.hpp"

namespace free_gait {

StepCompleter::StepCompleter(std::shared_ptr<StepParameters> parameters, std::shared_ptr<AdapterBase> adapter)
    : parameters_(parameters),
      adapter_(adapter)
{
}

StepCompleter::~StepCompleter()
{
}

bool StepCompleter::complete(const State& state, const StepQueue& queue, Step& step) const
{
  for (auto& legMotion : step.legMotions_) {
    switch ((legMotion.second)->getType()) {
      case LegMotionBase::Type::Footstep:
        setParameters(dynamic_cast<Footstep&>(*legMotion.second));
        break;
      case LegMotionBase::Type::LegMode:
        setParameters(dynamic_cast<LegMode&>(*legMotion.second));
        break;
      default:
        break;
    }
    switch (legMotion.second->getTrajectoryType()) {
      case LegMotionBase::TrajectoryType::EndEffector:
        if (!complete(state, step, dynamic_cast<EndEffectorMotionBase&>(*legMotion.second))) return false;
        break;
      case LegMotionBase::TrajectoryType::Joints:
        if (!complete(state, step, dynamic_cast<JointMotionBase&>(*legMotion.second))) return false;
        break;
      default:
        throw std::runtime_error("StepCompleter::complete() could not complete leg motion of this type.");
        break;
    }
  }

  if (step.baseMotion_) {
    switch (step.baseMotion_->getType()) {
      case BaseMotionBase::Type::Auto:
        setParameters(dynamic_cast<BaseAuto&>(*step.baseMotion_));
        break;
      case BaseMotionBase::Type::Trajectory:
        setParameters(dynamic_cast<BaseTrajectory&>(*step.baseMotion_));
        break;
      default:
        break;
    }
    if (!complete(state, step, queue, *(step.baseMotion_))) return false;
  }

  return true;
}

bool StepCompleter::complete(const State& state, const Step& step, EndEffectorMotionBase& endEffectorMotion) const
{
  // Input.
//  ControlSetup controlSetupIn = state.getControlSetup(endEffectorMotion.getLimb());
//  bool positionIn = controlSetupIn.at(ControlLevel::Position);
//  bool velocityIn = controlSetupIn.at(ControlLevel::Velocity);
//  bool accelerationIn = controlSetupIn.at(ControlLevel::Acceleration);
//  bool effortIn = controlSetupIn.at(ControlLevel::Effort);

  // Output.
  ControlSetup controlSetupOut = endEffectorMotion.getControlSetup();
  bool positionOut = controlSetupOut.at(ControlLevel::Position);
  bool velocityOut = controlSetupOut.at(ControlLevel::Velocity);
  bool accelerationOut = controlSetupOut.at(ControlLevel::Acceleration);
  bool effortOut = controlSetupOut.at(ControlLevel::Effort);

  if (positionOut) {
    // TODO Check frame.
    Position startPositionInBaseFrame = adapter_->getPositionBaseToFootInBaseFrame(endEffectorMotion.getLimb(), state.getJointPositions(endEffectorMotion.getLimb()));
    Position startPositionInWorldFrame = adapter_->getPositionWorldToBaseInWorldFrame() + adapter_->getOrientationWorldToBase().inverseRotate(startPositionInBaseFrame);
    Position startPositionInDesiredFrame = startPositionInWorldFrame; // TODO
    endEffectorMotion.updateStartPosition(startPositionInDesiredFrame);
  }
  return endEffectorMotion.compute(state, step, *adapter_);
}

bool StepCompleter::complete(const State& state, const Step& step, JointMotionBase& jointMotion) const
{
  // Input.
  ControlSetup controlSetupIn = state.getControlSetup(jointMotion.getLimb());
  bool positionIn = controlSetupIn.at(ControlLevel::Position);
  bool velocityIn = controlSetupIn.at(ControlLevel::Velocity);
  bool accelerationIn = controlSetupIn.at(ControlLevel::Acceleration);
  bool effortIn = controlSetupIn.at(ControlLevel::Effort);

  // Output.
  ControlSetup controlSetupOut = jointMotion.getControlSetup();
  bool positionOut = controlSetupOut.at(ControlLevel::Position);
  bool velocityOut = controlSetupOut.at(ControlLevel::Velocity);
  bool accelerationOut = controlSetupOut.at(ControlLevel::Acceleration);
  bool effortOut = controlSetupOut.at(ControlLevel::Effort);

  // Check for special mode transitions.
  if (positionIn && !effortIn && positionOut && effortOut) {
    JointPositions startPosition = state.getJointPositions(jointMotion.getLimb());
    jointMotion.updateStartPosition(startPosition);
    JointEfforts startEffort = state.getJointEfforts(jointMotion.getLimb());
    startEffort.setZero();
    jointMotion.updateStartEfforts(startEffort);
  } else if (positionIn && effortIn && !positionOut && effortOut) {
    JointEfforts startEffort = adapter_->getJointEfforts(jointMotion.getLimb());
    jointMotion.updateStartEfforts(startEffort);
  } //else if (positionIn && effortIn && positionOut && !effortOut) {
    // TODO: Decrease torque to zero in special step.
  //} else if (!positionIn && effortIn && positionOut && !effortOut) {
    // TODO: Decrease compression on leg in special step.
  // }
  else {

    // Standard transitions.
    if (positionOut) {
      JointPositions startPosition = state.getJointPositions(jointMotion.getLimb());
      jointMotion.updateStartPosition(startPosition);
    }
    if (velocityOut) {
      JointVelocities startVelocity = state.getJointVelocities(jointMotion.getLimb());
      jointMotion.updateStartVelocity(startVelocity);
    }
    if (accelerationOut) {
      JointAccelerations startAcceleration = state.getJointAccelerations(jointMotion.getLimb());
      jointMotion.updateStartAcceleration(startAcceleration);
    }
    if (effortOut) {
      JointEfforts startEffort = state.getJointEfforts(jointMotion.getLimb());
      jointMotion.updateStartEfforts(startEffort);
    }

  }
  return jointMotion.compute(state, step, *adapter_);
}

bool StepCompleter::complete(const State& state, const Step& step, const StepQueue& queue, BaseMotionBase& baseMotion) const
{
  if (baseMotion.getControlSetup().at(ControlLevel::Position)) {
    // TODO Check frame.
    Pose pose(state.getPositionWorldToBaseInWorldFrame(), state.getOrientationWorldToBase());
    baseMotion.updateStartPose(pose);
  }
  if (baseMotion.getControlSetup().at(ControlLevel::Velocity)) {
    // TODO
  }
  return baseMotion.compute(state, step, queue, *adapter_);
}

void StepCompleter::setParameters(Footstep& footstep) const
{
  const auto& parameters = parameters_->footTargetParameters_;

  if (footstep.surfaceNormal_) {
    if (*(footstep.surfaceNormal_) == Vector::Zero())
      footstep.surfaceNormal_.reset(nullptr);
  }
  if (footstep.profileHeight_ == 0.0)
    footstep.profileHeight_ = parameters.profileHeight;
  if (footstep.profileType_.empty())
    footstep.profileType_ = parameters.profileType;
  if (footstep.averageVelocity_ == 0.0)
    footstep.averageVelocity_ = parameters.averageVelocity;

  footstep.liftOffVelocity_ = parameters.liftOffVelocity;
  footstep.touchdownVelocity_ = parameters.touchdownVelocity;
}

void StepCompleter::setParameters(LegMode& legMode) const
{
  const auto& parameters = parameters_->legModeParameters_;

  if (legMode.surfaceNormal_) {
    if (*(legMode.surfaceNormal_) == Vector::Zero())
      legMode.surfaceNormal_.reset(nullptr);
  }
  if (legMode.duration_ == 0.0)
    legMode.duration_ = parameters.duration;
  if (legMode.frameId_.empty())
    legMode.frameId_ = parameters.frameId;
}

void StepCompleter::setParameters(BaseAuto& baseAuto) const
{
  const auto& parameters = parameters_->baseAutoParameters_;

  if (baseAuto.height_) {
    if (*(baseAuto.height_) == 0.0)
      baseAuto.height_.reset(nullptr);
  }
  if (baseAuto.averageLinearVelocity_ == 0.0)
    baseAuto.averageLinearVelocity_ = parameters.averageLinearVelocity;
  if (baseAuto.averageAngularVelocity_ == 0.0)
    baseAuto.averageAngularVelocity_ = parameters.averageAngularVelocity;
  if (baseAuto.supportMargin_ == 0.0)
    baseAuto.supportMargin_ = parameters.supportMargin;
  baseAuto.minimumDuration_ = parameters.minimumDuration_;

  baseAuto.nominalPlanarStanceInBaseFrame_.clear();
  baseAuto.nominalPlanarStanceInBaseFrame_ = parameters.nominalPlanarStanceInBaseFrame;
}

void StepCompleter::setParameters(BaseTrajectory& baseTrajectory) const
{
//  const auto& parameters = parameters_->baseAutoParameters_;
//
//  if (baseAuto.controllerType_.empty())
//    baseAuto.controllerType_ = parameters.controllerType;
}

} /* namespace */

<|endoftext|>


<commit_before>/* Please refer to license.txt */

#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <dirent.h>
#include <boost/filesystem.hpp>

#include "file.hpp"

#include "../error/error.hpp"

#include "../string/string.hpp"

#include "../internal_header.hpp"

namespace mfile
{

FileManager::FileManager()
{
}

FileManager::~FileManager()
{
}

void FileManager::exportFile(std::string filepath, std::string output_data, bool overwrite) //Export a file.
{
	FILE *file = nullptr; //The file.

	if (overwrite) file = fopen(filepath.c_str(), "w+"); //Open the file for writing, overwriting whatever currently exists, if anything.
	else file = fopen(filepath.c_str(), "a"); //Open the file for writing. Do not overwrite, append.

	if (!file) //Error checking.
	{
		//cout << "Failed to open file: \"" << filepath << "\".\n"; //Let the user know there was an error.
		//cout << "Attempting to create folder...\n"; //Let the user know we're trying to create the directory.

		//TODO: This portiong needs to be put into a "make_directories_until()" function.

		//TODO: This needs to be adjusted to recursively make the missing folders.

		bool start_saving = false; //Start saving the characters from the string?
		std::string folderpath = ""; //The folderpath.
		std::string temp_string = ""; //Folderpath is initially read into this, backwards. Used for ordering it correctly.
		for (int i = filepath.length() - 1; i >= 0; --i) //Loop through and extract the folderpath
		{
			if (!start_saving && (filepath[i] == '\\' || filepath[i] == '/')) //If not already saving the characters...Check if it's a / or \ character.
			{
				start_saving = true; //Yay, end of filename found, now we can extract the folderpath.
			}
			if (start_saving) //Ok, it is saving the characters.
			{
				temp_string += filepath[i]; //Save the character.
			}
		}
		for (int i = temp_string.length() - 1; i >= 0; --i) //Now reverse the order of characters so that the folderpath is no longer backwards.
		{
			folderpath += temp_string[i]; //Save the character.
		}

		try
		{
			mkDir("./" + folderpath); //Create the folder. With error checking.
		}
		catch (...)
		{
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			std::string *message = new std::string;
			*message = "Failed to create directory: \"";
			*message += folderpath;
			*message += "\".";
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error;
		}

		if (overwrite) file = fopen(filepath.c_str(), "w+"); //Open the file for writing, overwriting any currently existing file.
		else file = fopen(filepath.c_str(), "a"); //Open the file for writing. Do not overwrite, append.

		if (!file) //Error checking.
		{
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			std::string *message = new std::string;
			*message = "Failed to create file.";
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error; //Failure.
		}

		//TODO: End portion that needs being put into a "make_directories_until()" function.
	}

	fprintf(file, output_data.c_str());  //Write out the string.

	fclose(file); //Close the file.
} //FileManager::exportFile()

void FileManager::mkDir(std::string path) //Create a directory at the specified location.
{
	#if OS == OS_WINDOWS //If the operating system is windows.
		if (mkdir(path.c_str()) == -1) //Create the directory.
		{
			//throw strerror(errno); //Throw an error. //TODO: Refine the error to use the error module.
			std::string *error_message = new std::string; //The error message.
			*error_message = mstring::toString(strerror(errno)); //Convert the char* that is strerror to a string.
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, error_message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error;
		}
	#else //OS is not windows.
		if (mkdir(path.c_str(), 0777) == -1)//creating a directory
		{
			//throw strerror(errno); //Throw an error. //TODO: Refine the error to use the error module.
			std::string *error_message = new std::string; //The error message.
			*error_message = mstring::toString(strerror(errno)); //Convert the char* that is strerror to a string.
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, error_message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error;
		}
	#endif
}

bool FileManager::directoryExists(std::string path) //Checks if specified directory exists.
{
	//This function could probably be done better with a call to an external library's superoptimised directory_exists() function.
	//But, until such a time that we have such a library, this will be used.

	//TODO: This portion probably can be put into an external function.

	//This portion of code determines the path to the directory the directory we're looking for is in.

	bool start_saving = false; //Start saving the characters from the string?
	std::string folderpath = ""; //The folderpath.
	std::string temp_string = ""; //Folderpath is initially read into this, backwards. Used for ordering it correctly.
	std::string directory_name_reverse = ""; //The name of the folder it's looking for. Reversed. This is used because the path is read backwards and everything after the slash is chopped off, thus determining the directory we're looking for's name.
	std::string directory_name = ""; //The name of the folder it's looking for.
	for (int i = path.length() - 1; i >= 0; --i) //Loop through and extract the folderpath. Pretty much the folder the folder is in.
	{
		if (!start_saving && (path[i] == '\\' || path[i] == '/') && i != path.length() - 1) //If not already saving the characters...Check if it's a / or \ character.
		{
			start_saving = true; //Nw we can extract the folderpath.
			directory_name_reverse += path[i];
		}
		else if (start_saving) //Ok, it is saving the characters.
		{
			temp_string += path[i]; //Save the character.
		}
		if (i == 0)
		{
			temp_string = "/."; //Fallback in case there's nothing for it to cleave off.
		}
	}
	for (int i = temp_string.length() - 1; i >= 0; --i) //Now reverse the order of characters so that the folderpath is no longer backwards.
	{
		folderpath += temp_string[i]; //Save the character.
	}
	for (int i = directory_name_reverse.length() - 1;  i >= 0; --i)
	{
		if (directory_name_reverse[i] != '\\' && directory_name_reverse[i] != '/') directory_name += directory_name_reverse[i];
	}
	//TODO: End portion that can be put in external function.

	//This portion of code looks at all the contents in the directory of the directory we're checking the existence of, and looks to see if the directory exists.
	//If it does, then return true. Else return false.

	std::vector<std::string> folders; //Stores all the folder names it finds.

	getFolders(folderpath, folders); //Grabs all the folders in the folder containing the folder which we're checking the existence of.

	if (folders.size() == 0)
	{
		return false; //If it found nothing...The directory definitely does not exist!
	}

	for (unsigned int i = 0; i < folders.size(); ++i)
	{
		if (folders[i] == directory_name) return true; //Yes, directory exists.
	}

	return false; //Default case: does not exist.
} //FileManager::directoryExists()

void FileManager::separatePathFromFilename(std::string &path_with_filename, std::string &path)
{
	//Loop from the back, find the /, chop off everything.

	std::string input(path_with_filename);
	std::string::iterator i = input.end()-1;
	bool done = false;
	while (!done)
	{
		//If it found where the filepath ends...
		if ((*i) != '/' && (*i) != '\\')
		{
			--i; //Keep going.
			input.pop_back(); //Delete the last character.
		}
		else
		{
			done = true;
		}
	}

	path = input;
}

void FileManager::getFolders(std::string path, std::vector<std::string> &folders) //Get all the folders in a directory.
{
	/*#if OS == OS_WINDOWS
		struct stat s; //Required for the Windows version of the code
	#endif

	DIR *dir ; //Open the bases folder.

	if ((dir = opendir(path.c_str())) == nullptr) //Open directory. With error checking.
	{
		std::string *filename = new std::string; //The filename.
		*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
		std::string *message = new std::string;
		*message = "Failed to open directory.";
		merror::Error *error = generateError(merror::FUNCTION_FAILURE, message, merror::SEVERITY_IGNORE, __LINE__, filename);
		throw error;
	}

	struct dirent *entry = readdir(dir); //The current directory entry

	while (entry != NULL) //Loop through all the folders (and files) in this directory.
	{
		#if OS == OS_WINDOWS

			//TODO: Test this to see if it works in Windows.

			stat(entry->d_name, &s);
			if (s.st_mode & S_IFDIR)
			{
				if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) //Make sure it's not the current directory, or the one containing this directory!
				{
					folders.push_back(entry->d_name);
				}
			}

			entry = readdir(dir); //Load in the next entry.

		#else

			if (entry->d_type == DT_DIR) //If the entry type is a folder.
			{
				if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) //Make sure it's not the current directory, or the one containing this directory!
				{
					folders.push_back(entry->d_name);
				}
			}

		#endif
	}

	closedir(dir);*/

	namespace fs = boost::filesystem;
	fs::path someDir(path);
	fs::directory_iterator end_iter;

	if ( fs::exists(someDir) && fs::is_directory(someDir))
	{
		for( fs::directory_iterator dir_iter(someDir) ; dir_iter != end_iter ; ++dir_iter)
		{
			if (fs::is_directory(dir_iter->status()) )
			{
				folders.push_back(dir_iter->path().filename().string());
			}
		}
	}
} //FileManager::getFolders()

} //namespace mfile
<commit_msg>Fixed mkdir function to use boost.<commit_after>/* Please refer to license.txt */

#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <dirent.h>
#include <boost/filesystem.hpp>

#include "file.hpp"

#include "../error/error.hpp"

#include "../string/string.hpp"

#include "../internal_header.hpp"

namespace mfile
{

FileManager::FileManager()
{
}

FileManager::~FileManager()
{
}

void FileManager::exportFile(std::string filepath, std::string output_data, bool overwrite) //Export a file.
{
	FILE *file = nullptr; //The file.

	if (overwrite) file = fopen(filepath.c_str(), "w+"); //Open the file for writing, overwriting whatever currently exists, if anything.
	else file = fopen(filepath.c_str(), "a"); //Open the file for writing. Do not overwrite, append.

	if (!file) //Error checking.
	{
		//cout << "Failed to open file: \"" << filepath << "\".\n"; //Let the user know there was an error.
		//cout << "Attempting to create folder...\n"; //Let the user know we're trying to create the directory.

		//TODO: This portiong needs to be put into a "make_directories_until()" function.

		//TODO: This needs to be adjusted to recursively make the missing folders.

		bool start_saving = false; //Start saving the characters from the string?
		std::string folderpath = ""; //The folderpath.
		std::string temp_string = ""; //Folderpath is initially read into this, backwards. Used for ordering it correctly.
		for (int i = filepath.length() - 1; i >= 0; --i) //Loop through and extract the folderpath
		{
			if (!start_saving && (filepath[i] == '\\' || filepath[i] == '/')) //If not already saving the characters...Check if it's a / or \ character.
			{
				start_saving = true; //Yay, end of filename found, now we can extract the folderpath.
			}
			if (start_saving) //Ok, it is saving the characters.
			{
				temp_string += filepath[i]; //Save the character.
			}
		}
		for (int i = temp_string.length() - 1; i >= 0; --i) //Now reverse the order of characters so that the folderpath is no longer backwards.
		{
			folderpath += temp_string[i]; //Save the character.
		}

		try
		{
			mkDir("./" + folderpath); //Create the folder. With error checking.
		}
		catch (...)
		{
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			std::string *message = new std::string;
			*message = "Failed to create directory: \"";
			*message += folderpath;
			*message += "\".";
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error;
		}

		if (overwrite) file = fopen(filepath.c_str(), "w+"); //Open the file for writing, overwriting any currently existing file.
		else file = fopen(filepath.c_str(), "a"); //Open the file for writing. Do not overwrite, append.

		if (!file) //Error checking.
		{
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			std::string *message = new std::string;
			*message = "Failed to create file.";
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error; //Failure.
		}

		//TODO: End portion that needs being put into a "make_directories_until()" function.
	}

	fprintf(file, output_data.c_str());  //Write out the string.

	fclose(file); //Close the file.
} //FileManager::exportFile()

void FileManager::mkDir(std::string path) //Create a directory at the specified location.
{
	/*#if OS == OS_WINDOWS //If the operating system is windows.
		if (mkdir(path.c_str()) == -1) //Create the directory.
		{
			//throw strerror(errno); //Throw an error. //TODO: Refine the error to use the error module.
			std::string *error_message = new std::string; //The error message.
			*error_message = mstring::toString(strerror(errno)); //Convert the char* that is strerror to a string.
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, error_message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error;
		}
	#else //OS is not windows.
		if (mkdir(path.c_str(), 0777) == -1)//creating a directory
		{
			//throw strerror(errno); //Throw an error. //TODO: Refine the error to use the error module.
			std::string *error_message = new std::string; //The error message.
			*error_message = mstring::toString(strerror(errno)); //Convert the char* that is strerror to a string.
			std::string *filename = new std::string; //The filename.
			*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
			merror::Error *error = generateError(merror::FUNCTION_FAILURE, error_message, merror::SEVERITY_IGNORE, __LINE__, filename);
			throw error;
		}
	#endif*/
	namespace fs = boost::filesystem;
	if (!fs::create_directory(path))
	{
		std::string *error_message = new std::string; //The error message.
		*error_message = "Failed to create directory \'" + path + "\'";
		std::string *filename = new std::string; //The filename.
		*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
		merror::Error *error = generateError(merror::FUNCTION_FAILURE, error_message, merror::SEVERITY_IGNORE, __LINE__, filename);
		throw error;
	}
}

bool FileManager::directoryExists(std::string path) //Checks if specified directory exists.
{
	//This function could probably be done better with a call to an external library's superoptimised directory_exists() function.
	//But, until such a time that we have such a library, this will be used.

	//TODO: This portion probably can be put into an external function.

	//This portion of code determines the path to the directory the directory we're looking for is in.

	bool start_saving = false; //Start saving the characters from the string?
	std::string folderpath = ""; //The folderpath.
	std::string temp_string = ""; //Folderpath is initially read into this, backwards. Used for ordering it correctly.
	std::string directory_name_reverse = ""; //The name of the folder it's looking for. Reversed. This is used because the path is read backwards and everything after the slash is chopped off, thus determining the directory we're looking for's name.
	std::string directory_name = ""; //The name of the folder it's looking for.
	for (int i = path.length() - 1; i >= 0; --i) //Loop through and extract the folderpath. Pretty much the folder the folder is in.
	{
		if (!start_saving && (path[i] == '\\' || path[i] == '/') && i != path.length() - 1) //If not already saving the characters...Check if it's a / or \ character.
		{
			start_saving = true; //Nw we can extract the folderpath.
			directory_name_reverse += path[i];
		}
		else if (start_saving) //Ok, it is saving the characters.
		{
			temp_string += path[i]; //Save the character.
		}
		if (i == 0)
		{
			temp_string = "/."; //Fallback in case there's nothing for it to cleave off.
		}
	}
	for (int i = temp_string.length() - 1; i >= 0; --i) //Now reverse the order of characters so that the folderpath is no longer backwards.
	{
		folderpath += temp_string[i]; //Save the character.
	}
	for (int i = directory_name_reverse.length() - 1;  i >= 0; --i)
	{
		if (directory_name_reverse[i] != '\\' && directory_name_reverse[i] != '/') directory_name += directory_name_reverse[i];
	}
	//TODO: End portion that can be put in external function.

	//This portion of code looks at all the contents in the directory of the directory we're checking the existence of, and looks to see if the directory exists.
	//If it does, then return true. Else return false.

	std::vector<std::string> folders; //Stores all the folder names it finds.

	getFolders(folderpath, folders); //Grabs all the folders in the folder containing the folder which we're checking the existence of.

	if (folders.size() == 0)
	{
		return false; //If it found nothing...The directory definitely does not exist!
	}

	for (unsigned int i = 0; i < folders.size(); ++i)
	{
		if (folders[i] == directory_name) return true; //Yes, directory exists.
	}

	return false; //Default case: does not exist.
} //FileManager::directoryExists()

void FileManager::separatePathFromFilename(std::string &path_with_filename, std::string &path)
{
	//Loop from the back, find the /, chop off everything.

	std::string input(path_with_filename);
	std::string::iterator i = input.end()-1;
	bool done = false;
	while (!done)
	{
		//If it found where the filepath ends...
		if ((*i) != '/' && (*i) != '\\')
		{
			--i; //Keep going.
			input.pop_back(); //Delete the last character.
		}
		else
		{
			done = true;
		}
	}

	path = input;
}

void FileManager::getFolders(std::string path, std::vector<std::string> &folders) //Get all the folders in a directory.
{
	/*#if OS == OS_WINDOWS
		struct stat s; //Required for the Windows version of the code
	#endif

	DIR *dir ; //Open the bases folder.

	if ((dir = opendir(path.c_str())) == nullptr) //Open directory. With error checking.
	{
		std::string *filename = new std::string; //The filename.
		*filename = mstring::toString(__FILE__); //Convert the char* that is filename to a string.
		std::string *message = new std::string;
		*message = "Failed to open directory.";
		merror::Error *error = generateError(merror::FUNCTION_FAILURE, message, merror::SEVERITY_IGNORE, __LINE__, filename);
		throw error;
	}

	struct dirent *entry = readdir(dir); //The current directory entry

	while (entry != NULL) //Loop through all the folders (and files) in this directory.
	{
		#if OS == OS_WINDOWS

			//TODO: Test this to see if it works in Windows.

			stat(entry->d_name, &s);
			if (s.st_mode & S_IFDIR)
			{
				if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) //Make sure it's not the current directory, or the one containing this directory!
				{
					folders.push_back(entry->d_name);
				}
			}

			entry = readdir(dir); //Load in the next entry.

		#else

			if (entry->d_type == DT_DIR) //If the entry type is a folder.
			{
				if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) //Make sure it's not the current directory, or the one containing this directory!
				{
					folders.push_back(entry->d_name);
				}
			}

		#endif
	}

	closedir(dir);*/

	namespace fs = boost::filesystem;
	fs::path someDir(path);
	fs::directory_iterator end_iter;

	if ( fs::exists(someDir) && fs::is_directory(someDir))
	{
		for( fs::directory_iterator dir_iter(someDir) ; dir_iter != end_iter ; ++dir_iter)
		{
			if (fs::is_directory(dir_iter->status()) )
			{
				folders.push_back(dir_iter->path().filename().string());
			}
		}
	}
} //FileManager::getFolders()

} //namespace mfile
<|endoftext|>


<commit_before>// Copyright (c) 2011 Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "fileutils.h"

#include <time.h>
#include <sys/stat.h>

#if defined WIN32 || defined _WIN32
    #include <windows.h>
    #include <sys/types.h>
    #if !defined stat
        #define stat _stat
    #endif
#else
    #include <dirent.h>
    #include <fnmatch.h>
#endif

namespace fileutils {

std::string GetBaseName(const std::string &path) {
    std::string::size_type lastSep = path.find_last_of("/\\");
    if (lastSep != std::string::npos) {
        return path.substr(lastSep + 1);
    }
    return path;
}

std::string GetExtenstion(const std::string &path) {
    std::string ext;
    std::string::size_type period = path.rfind('.');
    if (period != std::string::npos) {
        ext = path.substr(period + 1);;
    }
    return ext;
}

time_t GetMoficationTime(const std::string &path) {
    struct stat attrib;
    stat(path.c_str(), &attrib);
	return attrib.st_mtime;
}

void GetFilesInDirectory(const std::string &dir, const std::string &pattern, std::vector<std::string> &result) {
#if defined WIN32 || defined _WIN32
    WIN32_FIND_DATA findFileData;
    HANDLE hFindFile = FindFirstFile((dir + "\\" + pattern).c_str(), &findFileData);
    if (hFindFile != INVALID_HANDLE_VALUE) {
        do {
            if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                result.push_back(dir + "\\" + findFileData.cFileName);
            }
        } while (FindNextFile(hFindFile, &findFileData) != 0);
        FindClose(hFindFile);
    }
#else
    DIR *dp;
    if ((dp = opendir(dir.c_str())) != 0) {
        struct dirent *dirp;
        while ((dirp = readdir(dp)) != 0) {
            if (!fnmatch(pattern.c_str(), dirp->d_name,
                            FNM_CASEFOLD | FNM_NOESCAPE | FNM_PERIOD)) {
                result.push_back(dir + "/" + dirp->d_name);
            }
        }
        closedir(dp);
    }
#endif
}

} // namespace fileutils<commit_msg>Fix on Windows sys/types.h must go before sys/stat.h<commit_after>// Copyright (c) 2011 Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "fileutils.h"

#include <time.h>

#if defined WIN32 || defined _WIN32 || defined __WIN32__
    #include <windows.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #if !defined stat
        #define stat _stat
    #endif
#else
    #include <dirent.h>
    #include <fnmatch.h>
    #include <sys/stat.h>
#endif

namespace fileutils {

std::string GetBaseName(const std::string &path) {
    std::string::size_type lastSep = path.find_last_of("/\\");
    if (lastSep != std::string::npos) {
        return path.substr(lastSep + 1);
    }
    return path;
}

std::string GetExtenstion(const std::string &path) {
    std::string ext;
    std::string::size_type period = path.rfind('.');
    if (period != std::string::npos) {
        ext = path.substr(period + 1);;
    }
    return ext;
}

time_t GetMoficationTime(const std::string &path) {
    struct stat attrib;
    stat(path.c_str(), &attrib);
	return attrib.st_mtime;
}

void GetFilesInDirectory(const std::string &dir, const std::string &pattern, std::vector<std::string> &result) {
#if defined WIN32 || defined _WIN32 || defined __WIN32__
    WIN32_FIND_DATA findFileData;
    HANDLE hFindFile = FindFirstFile((dir + "\\" + pattern).c_str(), &findFileData);
    if (hFindFile != INVALID_HANDLE_VALUE) {
        do {
            if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                result.push_back(dir + "\\" + findFileData.cFileName);
            }
        } while (FindNextFile(hFindFile, &findFileData) != 0);
        FindClose(hFindFile);
    }
#else
    DIR *dp;
    if ((dp = opendir(dir.c_str())) != 0) {
        struct dirent *dirp;
        while ((dirp = readdir(dp)) != 0) {
            if (!fnmatch(pattern.c_str(), dirp->d_name,
                            FNM_CASEFOLD | FNM_NOESCAPE | FNM_PERIOD)) {
                result.push_back(dir + "/" + dirp->d_name);
            }
        }
        closedir(dp);
    }
#endif
}

} // namespace fileutils<|endoftext|>


<commit_before>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2011
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: bulkDataNTGenSender.cpp,v 1.11 2012/11/20 11:36:34 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* bjeram  2011-04-19  created
*/
#include "bulkDataNTSenderFlow.h"
#include <iostream>
#include <ace/Get_Opt.h>
#include <ace/Tokenizer_T.h>

using namespace AcsBulkdata;
using namespace std;

void print_usage(char *argv[]) {
	cout << "Usage: " << argv[0] << " [-s streamName] -f flow1Name[,flow2Name,flow3Name...] [-b data size in bytes] [-p parameter] [-l # of loops] [-n no wait for a key]" << endl;
	exit(1);
}

int main(int argc, char *argv[])
{
	char c;
	bool sendData=true;
	bool recreate=true;
	bool waitForKey=true;
	double send_time;
	ACE_Time_Value start_time, elapsed_time;
	char *streamName = "DefaultStream";
	std::string param="defalutParamter";
	unsigned int dataSize=65000;
	unsigned int loop=1;
	list<char *> flowNames;

	// Parse the args
    ACE_Get_Opt get_opts (argc, argv, "f:s:b:p:l:n");
    while(( c = get_opts()) != -1 ) {
    	switch(c) {
    	case 'l':
    	{
    		loop = atoi(get_opts.opt_arg());
    		break;
    	}
    	case 'p':
    	{
    		param = get_opts.opt_arg();
    		break;
    	}
    	case 's':
    	{
    		streamName = get_opts.opt_arg();
    		break;
    	}
    	case 'f':
    	{
    		ACE_Tokenizer tok(get_opts.opt_arg());
    		tok.delimiter_replace(',', 0);
    		for(char *p = tok.next(); p; p = tok.next())
    			flowNames.push_back(p);

    		break;
    	}
    	case 'b':
    	{
    		dataSize = atoi(get_opts.opt_arg());
    		break;
    	}
    	case 'n':
    	{
    		waitForKey = false;
    		break;
    	}
    	default:
    	{
    		print_usage(argv);
    		break;
    	}
    	}
    }//while

    if( flowNames.size() == 0 )
    		print_usage(argv);

	LoggingProxy m_logger(0, 0, 31, 0);
	LoggingProxy::init (&m_logger);
    ACS_CHECK_LOGGER;

    ACS_SHORT_LOG((LM_INFO, "Is new bulk data enabled (ENABLE_BULKDATA_NT) %d", isBulkDataNTEnabled()));
    while(recreate)
    {
    	unsigned int numOfCreatedFlows=0;
    	vector<BulkDataNTSenderFlow*> flows;
    	try
    	{
    		double throuhgput=0;
    		double sumThrouhgput=0;
    		vector<double> 	throughputSums;
    		// first we need a stream
    		BulkDataNTSenderStream senderStream(streamName);

    		// let's create flows
    		list<char *>::iterator it;
    		for(it = flowNames.begin(); it != flowNames.end(); it++) {
    			SenderFlowConfiguration cfg;
    			BulkDataNTSenderFlow *flow = senderStream.createFlow((*it), cfg);
    			flows.push_back(flow);
    		}

    		// print out what we have created
    		std::vector<string> tmpFlowNames = senderStream.getFlowNames();
    		std::cout << "The following " << senderStream.getFlowNumber() << " flow(s) has/have been created:[ ";
    		for(unsigned int i=0;i<tmpFlowNames.size(); i++)
    			std::cout << tmpFlowNames[i] << " ";
    		std::cout << "] on stream: " << streamName << std::endl;

    		numOfCreatedFlows = senderStream.getFlowNumber();

    		std::cout << "press ENTER to send data (start/data/stop) to connected receivers ..." << std::endl;
    		if (waitForKey) getchar();
    		sendData=true;

    		throughputSums.resize(numOfCreatedFlows);

    		while(sendData)
    		{
    			// first startSend
    			for(unsigned int i=0; i<numOfCreatedFlows; i++)
    			{
    				ACS_SHORT_LOG((LM_INFO, "Going to send paramter: '%s' to flow: '%s' to %d receiver(s)", param.c_str(), tmpFlowNames[i].c_str(), flows[i]->getNumberOfReceivers()));
    				flows[i]->startSend((const unsigned char*)param.c_str(), param.size());
    				throughputSums[i]=0.0;
    			}//for
    			sumThrouhgput=0.0;
    			// then sendData
    			unsigned char *data= new unsigned char[dataSize];
    			for (unsigned int i=0; i<dataSize; i++)	data[i]=i;

    			for(unsigned int j=1; j<=loop; j++)
    			{
    				std::cout << "Loop: " << j << " of " << loop << std::endl;
    				for(unsigned int i=0; i<numOfCreatedFlows; i++)
    				{
    					ACS_SHORT_LOG((LM_INFO, "Going to send [%d/%d]: %d Bytes of data to flow: '%s' to %d receiver(s)", j, loop, dataSize, tmpFlowNames[i].c_str(), flows[i]->getNumberOfReceivers()));
    					start_time = ACE_OS::gettimeofday();
    					flows[i]->sendData(data, dataSize);
    					elapsed_time = ACE_OS::gettimeofday() - start_time;
    					send_time = (elapsed_time.sec()+( elapsed_time.usec() / 1000000. ));
    					throuhgput = (dataSize/(1024.0*1024.0))/send_time;
    					ACS_SHORT_LOG((LM_INFO, "Transfer rate for flow '%s': %f MBytes/sec",
    							tmpFlowNames[i].c_str(), throuhgput));
    					sumThrouhgput+=throuhgput;
    					throughputSums[i]+=throuhgput;
    				}//for i
    			}//for j

    			// and stopSend
    			for(unsigned int i=0; i<numOfCreatedFlows; i++)
    			{
    				ACS_SHORT_LOG((LM_INFO, "Average transfer rate for flow '%s': %f MBytes/sec",
    										tmpFlowNames[i].c_str(), throughputSums[i]/loop));
    				ACS_SHORT_LOG((LM_INFO, "Going to send stop to flow: '%s' to %d receiver(s)",
    										tmpFlowNames[i].c_str(), flows[i]->getNumberOfReceivers()));
    				flows[i]->stopSend();
    			}//for

    			ACS_SHORT_LOG((LM_INFO, "Average transfer rate for all the flow(s): %f MBytes/sec",
    			    					sumThrouhgput/(loop*numOfCreatedFlows)));

    			if (!waitForKey) //we exit both loops
    				{
    				recreate=false;
    				break;
    				}

    			std::cout << "press 'r' for re-send data, 'c' for re-create stream+flow(s), and any other key for exit + ENTER" << std::endl;
    			int c=getchar();
    			switch(c)
    			{
    			case 'r':
    			{
    				getchar();
    				sendData=true;
    				break;
    			}
    			case 'c':
    			{
    				getchar();
    				sendData=false;
    				recreate=true;
    				break;
    			}
    			default:
    			{
    				sendData=false;
    				recreate=false;
    				break;
    			}
    			}//switch
    		}//while(sendData)

    	}catch(ACSErr::ACSbaseExImpl &ex)
    	{
    		recreate=false; //in case of an error we exit the while loop
    		for(unsigned int i=0; i<numOfCreatedFlows; i++)
    		    flows[i]->dumpStatistics();

    		ex.log();
    	}

    }//while(recreate)
    m_logger.flush();
};//main
<commit_msg>add options -t -a to pass send frame and/or ACK timeout<commit_after>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2011
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: bulkDataNTGenSender.cpp,v 1.12 2012/11/22 07:57:18 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* bjeram  2011-04-19  created
*/
#include "bulkDataNTSenderFlow.h"
#include <iostream>
#include <ace/Get_Opt.h>
#include <ace/Tokenizer_T.h>

using namespace AcsBulkdata;
using namespace std;

void print_usage(char *argv[]) {
	cout << "Usage: " << argv[0] << ":" << endl;
	cout << "\t[-s] \t streamName. Default: 'DefaultStream'" << endl;
	cout << "\t-f \t flow1Name[,flow2Name,flow3Name..." << endl;
	cout << "\t[-b] \t data size in bytes. Default: 65000" << endl;
	cout << "\t[-p] \t parameter (startSend()). Default: 'defalutParamter'" << endl;
	cout << "\t[-l] \t # of loops/iterations. Default: 1" << endl;
	cout << "\t[-n] \t no wait for a key" << endl;
	cout << "\t[-t] \t send frame timeout in sec. Default: 5.0" << endl;
	cout << "\t[-t] \t ACK timeout in sec. Default: 2.0" << endl;
	exit(1);
}

int main(int argc, char *argv[])
{
	char c;
	bool sendData=true;
	bool recreate=true;
	bool waitForKey=true;
	double send_time, sendTimeout=5.0, ACKtimeout=2.0;
	ACE_Time_Value start_time, elapsed_time;
	char *streamName = "DefaultStream";
	std::string param="defalutParamter";
	unsigned int dataSize=65000;
	unsigned int loop=1;
	list<char *> flowNames;

	// Parse the args
    ACE_Get_Opt get_opts (argc, argv, "f:s:b:p:l:t:n");
    while(( c = get_opts()) != -1 ) {
    	switch(c) {
    	case 'l':
    	{
    		loop = atoi(get_opts.opt_arg());
    		break;
    	}
    	case 't':
    	{
    		sendTimeout = atof(get_opts.opt_arg());
    		break;
    	}
    	case 'a':
    	{
    		ACKtimeout = atof(get_opts.opt_arg());
    		break;
    	}
    	case 'p':
    	{
    		param = get_opts.opt_arg();
    		break;
    	}
    	case 's':
    	{
    		streamName = get_opts.opt_arg();
    		break;
    	}
    	case 'f':
    	{
    		ACE_Tokenizer tok(get_opts.opt_arg());
    		tok.delimiter_replace(',', 0);
    		for(char *p = tok.next(); p; p = tok.next())
    			flowNames.push_back(p);

    		break;
    	}
    	case 'b':
    	{
    		dataSize = atoi(get_opts.opt_arg());
    		break;
    	}
    	case 'n':
    	{
    		waitForKey = false;
    		break;
    	}
    	default:
    	{
    		print_usage(argv);
    		break;
    	}
    	}
    }//while

    if( flowNames.size() == 0 )
    		print_usage(argv);

	LoggingProxy m_logger(0, 0, 31, 0);
	LoggingProxy::init (&m_logger);
    ACS_CHECK_LOGGER;

    ACS_SHORT_LOG((LM_INFO, "Is new bulk data enabled (ENABLE_BULKDATA_NT) %d", isBulkDataNTEnabled()));
    while(recreate)
    {
    	unsigned int numOfCreatedFlows=0;
    	vector<BulkDataNTSenderFlow*> flows;
    	try
    	{
    		double throuhgput=0;
    		double sumThrouhgput=0;
    		vector<double> 	throughputSums;
    		// first we need a stream
    		BulkDataNTSenderStream senderStream(streamName);

    		// let's create flows
    		list<char *>::iterator it;
    		for(it = flowNames.begin(); it != flowNames.end(); it++) {
    			SenderFlowConfiguration cfg;
    			cfg.setACKsTimeout(ACKtimeout);
    			cfg.setSendFrameTimeout(sendTimeout);
    			BulkDataNTSenderFlow *flow = senderStream.createFlow((*it), cfg);
    			flows.push_back(flow);
    		}

    		// print out what we have created
    		std::vector<string> tmpFlowNames = senderStream.getFlowNames();
    		std::cout << "The following " << senderStream.getFlowNumber() << " flow(s) has/have been created:[ ";
    		for(unsigned int i=0;i<tmpFlowNames.size(); i++)
    			std::cout << tmpFlowNames[i] << " ";
    		std::cout << "] on stream: " << streamName << std::endl;

    		numOfCreatedFlows = senderStream.getFlowNumber();

    		std::cout << "press ENTER to send data (start/data/stop) to connected receivers ..." << std::endl;
    		if (waitForKey) getchar();
    		sendData=true;

    		throughputSums.resize(numOfCreatedFlows);

    		while(sendData)
    		{
    			// first startSend
    			for(unsigned int i=0; i<numOfCreatedFlows; i++)
    			{
    				ACS_SHORT_LOG((LM_INFO, "Going to send paramter: '%s' to flow: '%s' to %d receiver(s)", param.c_str(), tmpFlowNames[i].c_str(), flows[i]->getNumberOfReceivers()));
    				flows[i]->startSend((const unsigned char*)param.c_str(), param.size());
    				throughputSums[i]=0.0;
    			}//for
    			sumThrouhgput=0.0;
    			// then sendData
    			unsigned char *data= new unsigned char[dataSize];
    			for (unsigned int i=0; i<dataSize; i++)	data[i]=i;

    			for(unsigned int j=1; j<=loop; j++)
    			{
    				std::cout << "Loop: " << j << " of " << loop << std::endl;
    				for(unsigned int i=0; i<numOfCreatedFlows; i++)
    				{
    					ACS_SHORT_LOG((LM_INFO, "Going to send [%d/%d]: %d Bytes of data to flow: '%s' to %d receiver(s)", j, loop, dataSize, tmpFlowNames[i].c_str(), flows[i]->getNumberOfReceivers()));
    					start_time = ACE_OS::gettimeofday();
    					flows[i]->sendData(data, dataSize);
    					elapsed_time = ACE_OS::gettimeofday() - start_time;
    					send_time = (elapsed_time.sec()+( elapsed_time.usec() / 1000000. ));
    					throuhgput = (dataSize/(1024.0*1024.0))/send_time;
    					ACS_SHORT_LOG((LM_INFO, "Transfer rate for flow '%s': %f MBytes/sec",
    							tmpFlowNames[i].c_str(), throuhgput));
    					sumThrouhgput+=throuhgput;
    					throughputSums[i]+=throuhgput;
    				}//for i
    			}//for j

    			// and stopSend
    			for(unsigned int i=0; i<numOfCreatedFlows; i++)
    			{
    				ACS_SHORT_LOG((LM_INFO, "Average transfer rate for flow '%s': %f MBytes/sec",
    										tmpFlowNames[i].c_str(), throughputSums[i]/loop));
    				ACS_SHORT_LOG((LM_INFO, "Going to send stop to flow: '%s' to %d receiver(s)",
    										tmpFlowNames[i].c_str(), flows[i]->getNumberOfReceivers()));
    				flows[i]->stopSend();
    			}//for

    			ACS_SHORT_LOG((LM_INFO, "Average transfer rate for all the flow(s): %f MBytes/sec",
    			    					sumThrouhgput/(loop*numOfCreatedFlows)));

    			if (!waitForKey) //we exit both loops
    				{
    				recreate=false;
    				break;
    				}

    			std::cout << "press 'r' for re-send data, 'c' for re-create stream+flow(s), and any other key for exit + ENTER" << std::endl;
    			int c=getchar();
    			switch(c)
    			{
    			case 'r':
    			{
    				getchar();
    				sendData=true;
    				break;
    			}
    			case 'c':
    			{
    				getchar();
    				sendData=false;
    				recreate=true;
    				break;
    			}
    			default:
    			{
    				sendData=false;
    				recreate=false;
    				break;
    			}
    			}//switch
    		}//while(sendData)

    	}catch(ACSErr::ACSbaseExImpl &ex)
    	{
    		recreate=false; //in case of an error we exit the while loop
    		for(unsigned int i=0; i<numOfCreatedFlows; i++)
    		    flows[i]->dumpStatistics();

    		ex.log();
    	}

    }//while(recreate)
    m_logger.flush();
};//main
<|endoftext|>