<commit_before>// $Id$
// Category: interfaces
//
// Author: D. Adamova
//
//========================================================
//
//------------TG4ListTreeFrame.cxx--------------------------------//
//--------- Frame for the ListTree container---//
//
//=========================================================

#include "TG4ListTreeFrame.h"
#include "TG4GuiVolume.h"
#include "TG4Globals.h"

#include <TGListTree.h>
#include <TGCanvas.h>
#include <TGTab.h>

#include <G4LogicalVolume.hh>
#include <G4UImanager.hh>

ClassImp(TG4ListTreeFrame)

TG4ListTreeFrame::TG4ListTreeFrame( TGTab* Tab, TGMainFrame* ActionFrame)
{
//------>canvas for the ListTree
   TGCompositeFrame* parent= Tab->AddTab("Volumes");
   fCanvasWindow = new TGCanvas( parent, 400, 240);
   ULong_t back= TGFrame::GetWhitePixel();
   fCanvasWindow->ChangeBackground(back);

//----->ListTree for the logical volumes
   fVolumesListTree= new TGListTree(fCanvasWindow->GetViewPort(), 10, 10, kHorizontalFrame);
   fVolumesListTree->Associate(ActionFrame);
//------->container for the ListTree
   fCanvasWindow->SetContainer(fVolumesListTree);

   TGLayoutHints *lCanvasLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
   parent->AddFrame(fCanvasWindow, lCanvasLayout);

}

TG4ListTreeFrame::TG4ListTreeFrame(const TG4ListTreeFrame& ltf)
{
// Dummy copy constructor
  TG4Globals::Exception(
    "Attempt to use TG4ListTreeFrame copy constructor.");
}

TG4ListTreeFrame& TG4ListTreeFrame::operator=(const TG4ListTreeFrame& ltf)
{
  // check assignement to self
  if (this == &ltf) return *this;

  TG4Globals::Exception(
    "Attempt to assign  singleton.");

  return *this;
}

TG4ListTreeFrame::~TG4ListTreeFrame()
{
//---> liquidator

   G4cout << "\n Now in  TG4ListTreeFrame destructor \n" << G4endl;
   delete fCanvasWindow;
   delete fVolumesListTree;

}

TGListTreeItem*  TG4ListTreeFrame::
AddItem(TObject* obj, TGListTreeItem* parent, const char* name,
                       const TGPicture* open, const TGPicture* closed)
{
//----->Add item to the list tree
    return fVolumesListTree->AddItem(parent, name, obj, open, closed);
}

Bool_t TG4ListTreeFrame::ProcessSubMessage(Long_t msg, Long_t parm1)
{
//---> Processes events generated by the ListTree widget

	switch (GET_SUBMSG(msg)) {

//----->Cases to Handle mouse click
   //-->case 1
	case kCT_ITEMCLICK:
    //---> Button 1: Select volume
            if (parm1 == kButton1){
	    TGListTreeItem* item = fVolumesListTree->GetSelected();
             if (item) {

	     TG4GuiVolume* volume=((TG4GuiVolume*) item->GetUserData());
	     G4LogicalVolume* lvolume = volume->GetLogicalVolume();

	      if  ( lvolume ) {
	       G4cout << "The selected logical volume name is   "
	            << lvolume->GetName() << G4endl;
		  };
	      };
	    };

    //---> Button 3: Draw Volume
            if (parm1 == kButton3){
             TGListTreeItem* item = fVolumesListTree->GetSelected();
	     if (item){
                DrawSelectedVolume(item);};
	    };

	    break;

   //-->case 2
	case kCT_ITEMDBLCLICK:
	    if (parm1 == kButton1) {
		if (fVolumesListTree->GetSelected() != 0) {
		    gClient->NeedRedraw(fVolumesListTree);
		};
	    };
	    break;
   //-->default for GET_SUBMSG
	default:
	    break;
	}

    return kTRUE;
}

void  TG4ListTreeFrame::DrawSelectedVolume(TGListTreeItem* item)
{
//---> draw the volume belonging to the item

  TG4GuiVolume* volume=((TG4GuiVolume*) item->GetUserData());
  G4LogicalVolume* lvolume = volume->GetLogicalVolume();
//-------->>>>>>inserted part for getting parent and number of daughters
  TGListTreeItem* iParent = item -> GetParent();
  G4int noDght, ii;
  G4int icopy = 0;
  G4String parentName, lName;

  if (iParent) {

      TG4GuiVolume* vParent   = ((TG4GuiVolume*) iParent->GetUserData());
      G4LogicalVolume* lvParent = vParent->GetLogicalVolume();
      parentName = lvParent->GetName();
      noDght = lvParent->GetNoDaughters();
//------>>>> end of getting parent and number of daughters

   //------->>>>inserted for getting no on copies
      ii = 0;
      while ( ii < noDght){
         if ( lvParent->GetDaughter(ii)->GetLogicalVolume() ==  lvolume )
              icopy++;

             ii++;
          };
   //------>>>> end of getting no of copies

      lName = lvolume->GetName();
  }
//------->>>>> case of iParent = 0
  else {
      lName = "ALIC";
      icopy = 1;
  };

  G4cout << "For logical volume   " << lName << "   "
         << "the number of copies is :!   "  << icopy << endl;
//------> looping over number of copies
   ii=0;
   while ( ii < icopy) {
      G4String lCommand = "/vis/scene/add/volume  " ;
      lCommand += lName;
      lCommand += "  ";
      TG4Globals::AppendNumberToString( lCommand, ii);
      lCommand += "  -1";
      G4cout << "!!!!ADD VOLUME COMMAND IS!!!!   " << lCommand << G4endl;
      G4UImanager::GetUIpointer()->ApplyCommand( lCommand );
      G4UImanager::GetUIpointer()->ApplyCommand(
	          "/control/execute vis_cont.mac");
      ii++;
      };

}

<commit_msg>update to geant4 4.0 (not yet released) - removal of old vis~ commands<commit_after>// $Id$
// Category: interfaces
//
// Author: D. Adamova
//
//========================================================
//
//------------TG4ListTreeFrame.cxx--------------------------------//
//--------- Frame for the ListTree container---//
//
//=========================================================

#include "TG4ListTreeFrame.h"
#include "TG4GuiVolume.h"
#include "TG4Globals.h"

#include <TGListTree.h>
#include <TGCanvas.h>
#include <TGTab.h>

#include <G4LogicalVolume.hh>
#include <G4UImanager.hh>

ClassImp(TG4ListTreeFrame)

TG4ListTreeFrame::TG4ListTreeFrame( TGTab* Tab, TGMainFrame* ActionFrame)
{
//------>canvas for the ListTree
   TGCompositeFrame* parent= Tab->AddTab("Volumes");
   fCanvasWindow = new TGCanvas( parent, 400, 240);
   ULong_t back= TGFrame::GetWhitePixel();
   fCanvasWindow->ChangeBackground(back);

//----->ListTree for the logical volumes
   fVolumesListTree= new TGListTree(fCanvasWindow->GetViewPort(), 10, 10, kHorizontalFrame);
   fVolumesListTree->Associate(ActionFrame);
//------->container for the ListTree
   fCanvasWindow->SetContainer(fVolumesListTree);

   TGLayoutHints *lCanvasLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
   parent->AddFrame(fCanvasWindow, lCanvasLayout);

}

TG4ListTreeFrame::TG4ListTreeFrame(const TG4ListTreeFrame& ltf)
{
// Dummy copy constructor
  TG4Globals::Exception(
    "Attempt to use TG4ListTreeFrame copy constructor.");
}

TG4ListTreeFrame& TG4ListTreeFrame::operator=(const TG4ListTreeFrame& ltf)
{
  // check assignement to self
  if (this == &ltf) return *this;

  TG4Globals::Exception(
    "Attempt to assign  singleton.");

  return *this;
}

TG4ListTreeFrame::~TG4ListTreeFrame()
{
//---> liquidator

   G4cout << "\n Now in  TG4ListTreeFrame destructor \n" << G4endl;
   delete fCanvasWindow;
   delete fVolumesListTree;

}

TGListTreeItem*  TG4ListTreeFrame::
AddItem(TObject* obj, TGListTreeItem* parent, const char* name,
                       const TGPicture* open, const TGPicture* closed)
{
//----->Add item to the list tree
    return fVolumesListTree->AddItem(parent, name, obj, open, closed);
}

Bool_t TG4ListTreeFrame::ProcessSubMessage(Long_t msg, Long_t parm1)
{
//---> Processes events generated by the ListTree widget

	switch (GET_SUBMSG(msg)) {

//----->Cases to Handle mouse click
   //-->case 1
	case kCT_ITEMCLICK:
    //---> Button 1: Select volume
            if (parm1 == kButton1){
	    TGListTreeItem* item = fVolumesListTree->GetSelected();
             if (item) {

	     TG4GuiVolume* volume=((TG4GuiVolume*) item->GetUserData());
	     G4LogicalVolume* lvolume = volume->GetLogicalVolume();

	      if  ( lvolume ) {
	       G4cout << "The selected logical volume name is   "
	            << lvolume->GetName() << G4endl;
		  };
	      };
	    };

    //---> Button 3: Draw Volume
            if (parm1 == kButton3){
             TGListTreeItem* item = fVolumesListTree->GetSelected();
	     if (item){
                DrawSelectedVolume(item);};
	    };

	    break;

   //-->case 2
	case kCT_ITEMDBLCLICK:
	    if (parm1 == kButton1) {
		if (fVolumesListTree->GetSelected() != 0) {
		    gClient->NeedRedraw(fVolumesListTree);
		};
	    };
	    break;
   //-->default for GET_SUBMSG
	default:
	    break;
	}

    return kTRUE;
}

void  TG4ListTreeFrame::DrawSelectedVolume(TGListTreeItem* item)
{
//---> draw the volume belonging to the item

  TG4GuiVolume* volume=((TG4GuiVolume*) item->GetUserData());
  G4LogicalVolume* lvolume = volume->GetLogicalVolume();
//-------->>>>>>inserted part for getting parent and number of daughters
  TGListTreeItem* iParent = item -> GetParent();
  G4int noDght, ii;
  G4int icopy = 0;
  G4String parentName, lName;

  if (iParent) {

      TG4GuiVolume* vParent   = ((TG4GuiVolume*) iParent->GetUserData());
      G4LogicalVolume* lvParent = vParent->GetLogicalVolume();
      parentName = lvParent->GetName();
      noDght = lvParent->GetNoDaughters();
//------>>>> end of getting parent and number of daughters

   //------->>>>inserted for getting no on copies
      ii = 0;
      while ( ii < noDght){
         if ( lvParent->GetDaughter(ii)->GetLogicalVolume() ==  lvolume )
              icopy++;

             ii++;
          };
   //------>>>> end of getting no of copies

      lName = lvolume->GetName();
  }
//------->>>>> case of iParent = 0
  else {
      lName = "ALIC";
      icopy = 1;
  };

  G4cout << "For logical volume   " << lName << "   "
         << "the number of copies is :!   "  << icopy << endl;
//------> looping over number of copies
   ii=0;
   while ( ii < icopy) {
      G4String lCommand = "/vis/scene/add/volume  " ;
      lCommand += lName;
      lCommand += "  ";
      TG4Globals::AppendNumberToString( lCommand, ii);
      lCommand += "  -1";
      G4cout << "!!!!ADD VOLUME COMMAND IS!!!!   " << lCommand << G4endl;
      G4UImanager::GetUIpointer()->ApplyCommand( lCommand );
      G4UImanager::GetUIpointer()->ApplyCommand("/vis/sceneHandler/attach");
      G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/refresh");
      ii++;
      };
    G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/update");
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <cstdio>
#include "allTests.h"

int halRunAllTests(void) {
  CuString *output = CuStringNew();
  CuSuite* suite = CuSuiteNew();
/*  CuSuiteAddSuite(suite, halAlignmentTestSuite());
  CuSuiteAddSuite(suite, halMetaDataTestSuite());
  CuSuiteAddSuite(suite, halGenomeTestSuite());
  CuSuiteAddSuite(suite, halTopSegmentTestSuite());
  CuSuiteAddSuite(suite, halBottomSegmentTestSuite());
  CuSuiteAddSuite(suite, halSequenceTestSuite());
  CuSuiteAddSuite(suite, halColumnIteratorTestSuite());
  CuSuiteAddSuite(suite, halGappedSegmentIteratorTestSuite());
  CuSuiteAddSuite(suite, halRearrangementTestSuite()); */
  CuSuiteAddSuite(suite, halMappedSegmentTestSuite());
//  CuSuiteAddSuite(suite, halValidateTestSuite());
  CuSuiteRun(suite);
  CuSuiteSummary(suite, output);
  CuSuiteDetails(suite, output);
  printf("%s\n", output->buffer);
  return suite->failCount > 0;
}

int main(int argc, char *argv[]) {

  return halRunAllTests();
}
<commit_msg>remove comments<commit_after>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <cstdio>
#include "allTests.h"

int halRunAllTests(void) {
  CuString *output = CuStringNew();
  CuSuite* suite = CuSuiteNew();
  CuSuiteAddSuite(suite, halAlignmentTestSuite());
  CuSuiteAddSuite(suite, halMetaDataTestSuite());
  CuSuiteAddSuite(suite, halGenomeTestSuite());
  CuSuiteAddSuite(suite, halTopSegmentTestSuite());
  CuSuiteAddSuite(suite, halBottomSegmentTestSuite());
  CuSuiteAddSuite(suite, halSequenceTestSuite());
  CuSuiteAddSuite(suite, halColumnIteratorTestSuite());
  CuSuiteAddSuite(suite, halGappedSegmentIteratorTestSuite());
  CuSuiteAddSuite(suite, halRearrangementTestSuite());
  CuSuiteAddSuite(suite, halMappedSegmentTestSuite());
  CuSuiteAddSuite(suite, halValidateTestSuite());
  CuSuiteRun(suite);
  CuSuiteSummary(suite, output);
  CuSuiteDetails(suite, output);
  printf("%s\n", output->buffer);
  return suite->failCount > 0;
}

int main(int argc, char *argv[]) {

  return halRunAllTests();
}
<|endoftext|>


<commit_before>/**-------------------------------------------------------------------------
@file	buzzer.cpp

@brief	Generic implementation of buzzer driver

@author	Hoang Nguyen Hoan
@date	May 22, 2018

@license

Copyright (c) 2018, I-SYST, all rights reserved

Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies, and none of the
names : I-SYST or its contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

For info or contributing contact : hnhoan at i-syst dot com

THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <string.h>
#include "idelay.h"
#include "miscdev/buzzer.h"

bool Buzzer::Init(Pwm *pPwm, int Chan)
{
	if (pPwm == nullptr)
	{
		return false;
	}

	vpPwm = pPwm;
	vChan = Chan;

	return true;
}

void Buzzer::Volume(int Volume)
{
	if (Volume >= 0 && Volume <= 100)
	{
		// max volume is at 50% duty cycle
		vDutyCycle = Volume >> 1;
	}
}

/**
 * @brief	Play frequency
 *
 * @param	Freq :
 * @param	msDuration	: Play duration in msec.
 *							if != 0, wait for it then stop
 *							else let pwm running and return (no stop)
 */
void Buzzer::Play(uint32_t Freq, uint32_t msDuration)
{
	vpPwm->Frequency(Freq);
	//vpPwm->DutyCycle(vChan, vDutyCycle);
	vpPwm->Start(msDuration);

	if (msDuration)
	{
		// Wait for duration completion
		usDelay(msDuration * 1000);
		//vpPwm->Stop();
	}
}

void Buzzer::Stop()
{
	vpPwm->Stop();
}

<commit_msg>Missing set duty cycle<commit_after>/**-------------------------------------------------------------------------
@file	buzzer.cpp

@brief	Generic implementation of buzzer driver

@author	Hoang Nguyen Hoan
@date	May 22, 2018

@license

Copyright (c) 2018, I-SYST, all rights reserved

Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies, and none of the
names : I-SYST or its contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

For info or contributing contact : hnhoan at i-syst dot com

THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <string.h>
#include "idelay.h"
#include "miscdev/buzzer.h"

bool Buzzer::Init(Pwm *pPwm, int Chan)
{
	if (pPwm == nullptr)
	{
		return false;
	}

	vpPwm = pPwm;
	vChan = Chan;

	return true;
}

void Buzzer::Volume(int Volume)
{
	if (Volume >= 0 && Volume <= 100)
	{
		// max volume is at 50% duty cycle
		vDutyCycle = Volume >> 1;
		vpPwm->DutyCycle(vChan, vDutyCycle);
	}
}

/**
 * @brief	Play frequency
 *
 * @param	Freq :
 * @param	msDuration	: Play duration in msec.
 *							if != 0, wait for it then stop
 *							else let pwm running and return (no stop)
 */
void Buzzer::Play(uint32_t Freq, uint32_t msDuration)
{
	vpPwm->Frequency(Freq);
	//vpPwm->DutyCycle(vChan, vDutyCycle);
	vpPwm->Start(msDuration);

	if (msDuration)
	{
		// Wait for duration completion
		usDelay(msDuration * 1000);
		//vpPwm->Stop();
	}
}

void Buzzer::Stop()
{
	vpPwm->Stop();
}

<|endoftext|>


<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2016 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Platform.                                      *
 *                                                                       *
 *   Platform is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Platform 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Platform.                                        *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#ifndef PLA_INCLUDE_H
#define PLA_INCLUDE_H

#if defined(_WIN32) || defined(_WIN64)
	#define WINDOWS
	#define _WIN32_WINNT 0x0501
	#define __MSVCRT_VERSION__ 0x0601
	#ifdef __MINGW32__
		#define MINGW
	#endif
	#define NO_IFADDRS
#endif

#ifdef __ANDROID__
	#ifndef ANDROID
		#define ANDROID
	#endif
	#define NO_IFADDRS

	#include <jni.h>
	#include <android/log.h>
#endif

#ifdef __APPLE__
#define MACOSX
#endif

#ifdef __linux__
#define LINUX
#endif

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>

#include <algorithm>
#include <limits>
#include <iostream>
#include <iterator>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <future>

#include <dirent.h>
#include <stdlib.h>

// Windows compatibility
#ifdef WINDOWS

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <iphlpapi.h>
#include <wincrypt.h>
#undef min
#undef max

typedef SOCKET socket_t;
typedef SOCKADDR sockaddr;
typedef int socklen_t;
typedef u_long ctl_t;
#define ioctl ioctlsocket
#define sockerrno WSAGetLastError()
#define SEWOULDBLOCK	WSAEWOULDBLOCK
#define SEAGAIN		WSAEWOULDBLOCK
#define SEADDRINUSE	WSAEADDRINUSE
#define IP_DONTFRAG	IP_DONTFRAGMENT
#define SOCK_TO_INT(x) 0

#define mkdirmod(d,m) mkdir(d)

#ifdef MINGW
#include <sys/stat.h>
#include <sys/time.h>
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
#endif

#else

#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sched.h>

#ifndef NO_IFADDRS
#include <ifaddrs.h>
#endif

typedef int socket_t;
typedef int ctl_t;
#define closesocket close
#define sockerrno errno
#define SEWOULDBLOCK	EWOULDBLOCK
#define SEAGAIN		EAGAIN
#define SEADDRINUSE	EADDRINUSE
#define INVALID_SOCKET -1
#define SOCK_TO_INT(x) (x)
#define mkdirmod(d,m) mkdir(d,m)

#endif

#ifndef NULL
#define NULL (void*)(0L)
#endif

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 1024
#endif

#ifndef SERVICE_NAME_MAX
#define SERVICE_NAME_MAX 32
#endif

#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
#endif

#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif

namespace pla
{

#ifdef WINDOWS
typedef signed char			int8_t;		// 8 bits
typedef signed short		int16_t;	// 16 bits
typedef signed int			int32_t;	// 32 bits
typedef signed long long	int64_t;	// 64 bits
typedef unsigned char		uint8_t;	// 8 bits
typedef unsigned short		uint16_t;	// 16 bits
typedef unsigned int		uint32_t;	// 32 bits
typedef unsigned long long	uint64_t;	// 64 bits

typedef struct __stat64 stat_t;
inline int stat(const char *path, stat_t *buf) { return ::_stat64(path,buf); }
inline int _stat(const char *path, stat_t *buf) { return pla::stat(path,buf); }

#else
typedef ::int8_t		int8_t;		// 8 bits
typedef ::int16_t		int16_t;	// 16 bits
typedef ::int32_t		int32_t;	// 32 bits
typedef ::int64_t		int64_t;	// 64 bits
typedef ::uint8_t		uint8_t;	// 8 bits
typedef ::uint16_t		uint16_t;	// 16 bits
typedef ::uint32_t		uint32_t;	// 32 bits
typedef ::uint64_t		uint64_t;	// 64 bits

#ifdef MACOSX
typedef struct stat stat_t;
inline int stat(const char *path, stat_t *buf) { return ::stat(path,buf); }
#else
typedef struct stat64 stat_t;
inline int stat(const char *path, stat_t *buf) { return ::stat64(path,buf); }
#endif

#endif

typedef unsigned char	byte;
typedef float			float32_t;	// 32 bits float
typedef double			float64_t;	// 64 bits float

#define CONST64(n) n ## ULL	// 64 bits unsigned constant

// Aliases
template<typename T> using sptr = std::shared_ptr<T>;
template<typename T> using wptr = std::weak_ptr<T>;

// Typedefs
typedef std::chrono::duration<double> duration;
typedef std::chrono::duration<double> seconds;
typedef std::chrono::duration<double, std::milli> milliseconds;
typedef std::chrono::duration<double, std::micro> microseconds;
typedef std::chrono::duration<double, std::nano>  nanoseconds;

// Utility functions
template<typename T> T bounds(T val, T val_min, T val_max)
{
	if(val_min > val_max) std::swap(val_min,val_max);
	return std::min(val_max,std::max(val_min,val));
}

template<typename T> T sqr(T x)
{
	return x*x;
}

template<typename T> unsigned int bitcount(T n)
{
	static T m1  = (~T(0)) / 3;
	static T m2  = (~T(0)) / 5;
	static T m4  = (~T(0)) / 17;
	static T h01 = (~T(0)) / 255;

	n-= (n >> 1) & m1;			// Put count of each 2 bits into those 2 bits
	n = (n & m2) + ((n >> 2) & m2);		// Put count of each 4 bits into those 4 bits
	n = (n + (n >> 4)) & m4;		// Put count of each 8 bits into those 8 bits

	return (n * h01) >> (sizeof(T)*8 - 8);  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}

inline void memxor(char *a, const char *b, size_t size)
{
	unsigned long *la = reinterpret_cast<unsigned long*>(a);
	const unsigned long *lb = reinterpret_cast<const unsigned long*>(b);
	const size_t n = size / sizeof(unsigned long);
	for(size_t i = 0; i < n; ++i)
		la[i]^= lb[i];
	for(size_t i = n*sizeof(unsigned long); i < size; ++i)
		a[i]^= b[i];
}

inline duration structToDuration(const struct timeval &tv)
{
	return seconds(double(tv.tv_sec) + double(tv.tv_usec)/1000000.);
}

inline duration structToDuration(const struct timespec &ts)
{
	return seconds(double(ts.tv_sec) + double(ts.tv_nsec)/1000000000.);
}

inline void durationToStruct(duration d, struct timeval &tv)
{
	double secs = seconds(d).count();
	double isecs = 0.;
	double fsecs = std::modf(secs, &isecs);
	tv.tv_sec = time_t(isecs);
	tv.tv_usec = long(fsecs*1000000.);
}

inline void durationToStruct(duration d, struct timespec &ts)
{
	double secs = seconds(d).count();
	double isecs = 0.;
	double fsecs = std::modf(secs, &isecs);
	ts.tv_sec = time_t(isecs);
	ts.tv_nsec = long(fsecs*100000000.);
}

#define Queue std::queue
#define Stack std::stack
#define Deque std::deque

const size_t BufferSize = 4*1024;	// 4 KiB

extern std::mutex LogMutex;
extern bool ForceLogToFile;
extern int LogLevel;
extern std::map<std::thread::id, unsigned> ThreadsMap;

std::string GetFormattedLogTime(void);

#define LEVEL_TRACE	0
#define LEVEL_DEBUG	1
#define LEVEL_INFO	2
#define LEVEL_WARN	3
#define LEVEL_ERROR	4

template<typename T> void LogImpl(const char *file, int line, int level, const char *prefix, const T &value)
{
	if(level < pla::LogLevel) return;

	std::lock_guard<std::mutex> lock(LogMutex);

	unsigned mythreadid = 0;
	auto it = ThreadsMap.find(std::this_thread::get_id());
	if(it != ThreadsMap.end()) mythreadid = it->second;
	else {
		mythreadid = unsigned(ThreadsMap.size()) + 1;
		ThreadsMap[std::this_thread::get_id()] = mythreadid;
	}

	const char *strLevel;
	switch(level)
	{
		case LEVEL_TRACE:	strLevel = "Trace:";	break;
		case LEVEL_DEBUG:	strLevel = "Debug:";	break;
		case LEVEL_INFO:	strLevel = "Info:";		break;
		case LEVEL_WARN:	strLevel = "WARNING:";	break;
		default:			strLevel = "ERROR:";	break;
	}

	std::ostringstream oss;
	oss.fill(' ');
	oss<<pla::GetFormattedLogTime()<<' ';
#ifdef DEBUG
	std::ostringstream tmp;
	tmp<<file<<':'<<std::dec<<line;
	oss<<tmp.str();
	if(tmp.str().size() < 28) oss<<std::string(28-tmp.str().size(), ' ');
	tmp.str("");
	tmp<<mythreadid<<'@'<<prefix;
	oss<<' '<<std::setw(36)<<tmp.str()<<' ';
#endif
	oss<<std::setw(8)<<strLevel<<' '<<value;

#ifdef ANDROID
	__android_log_print(ANDROID_LOG_VERBOSE, "teapotnet", "%s", oss.str().c_str());
#else
	if(!pla::ForceLogToFile) std::cout<<oss.str()<<std::endl;
	else {
		std::ofstream log("log.txt", std::ios_base::app | std::ios_base::out);
		if(log.is_open())
		{
			log<<oss.str()<<std::endl;
			log.close();
		}
	}
#endif
}

#define LogTrace(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_TRACE, prefix, value)
#define LogDebug(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_DEBUG, prefix, value)
#define LogInfo(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_INFO, prefix, value)
#define LogWarn(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_WARN, prefix, value)
#define LogError(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_ERROR, prefix, value)
#define Log(prefix, value)		LogInfo(prefix, value)
#define NOEXCEPTION(stmt)		try { stmt; } catch(const std::exception &e) { LogWarn("Exception", e.what()); } catch(...) {}

// Debug tools
#define VAR(x) 				{ std::ostringstream s; s<<""#x"="<<x; Log("VAR", s.str()); }

}

#endif
<commit_msg>Fixed define for MSG_NOSIGNAL<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2016 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Platform.                                      *
 *                                                                       *
 *   Platform is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Platform 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Platform.                                        *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#ifndef PLA_INCLUDE_H
#define PLA_INCLUDE_H

#if defined(_WIN32) || defined(_WIN64)
	#define WINDOWS
	#define _WIN32_WINNT 0x0501
	#define __MSVCRT_VERSION__ 0x0601
	#ifdef __MINGW32__
		#define MINGW
	#endif
	#define NO_IFADDRS
#endif

#ifdef __ANDROID__
	#ifndef ANDROID
		#define ANDROID
	#endif
	#define NO_IFADDRS

	#include <jni.h>
	#include <android/log.h>
#endif

#ifdef __APPLE__
#define MACOSX
#endif

#ifdef __linux__
#define LINUX
#endif

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>

#include <algorithm>
#include <limits>
#include <iostream>
#include <iterator>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <future>

#include <dirent.h>
#include <stdlib.h>

// Windows compatibility
#ifdef WINDOWS

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <iphlpapi.h>
#include <wincrypt.h>
#undef min
#undef max

typedef SOCKET socket_t;
typedef SOCKADDR sockaddr;
typedef int socklen_t;
typedef u_long ctl_t;
#define ioctl ioctlsocket
#define sockerrno WSAGetLastError()
#define SEWOULDBLOCK	WSAEWOULDBLOCK
#define SEAGAIN		WSAEWOULDBLOCK
#define SEADDRINUSE	WSAEADDRINUSE
#define IP_DONTFRAG	IP_DONTFRAGMENT
#define SOCK_TO_INT(x) 0

#define mkdirmod(d,m) mkdir(d)

#ifdef MINGW
#include <sys/stat.h>
#include <sys/time.h>
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
#endif

#else

#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sched.h>

#ifndef NO_IFADDRS
#include <ifaddrs.h>
#endif

typedef int socket_t;
typedef int ctl_t;
#define closesocket close
#define sockerrno errno
#define SEWOULDBLOCK	EWOULDBLOCK
#define SEAGAIN		EAGAIN
#define SEADDRINUSE	EADDRINUSE
#define INVALID_SOCKET -1
#define SOCK_TO_INT(x) (x)
#define mkdirmod(d,m) mkdir(d,m)

#endif

#ifndef NULL
#define NULL (void*)(0L)
#endif

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 1024
#endif

#ifndef SERVICE_NAME_MAX
#define SERVICE_NAME_MAX 32
#endif

#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
#endif

#ifndef LINUX
#define MSG_NOSIGNAL 0
#endif

namespace pla
{

#ifdef WINDOWS
typedef signed char					int8_t;		// 8 bits
typedef signed short				int16_t;	// 16 bits
typedef signed int					int32_t;	// 32 bits
typedef signed long long		int64_t;	// 64 bits
typedef unsigned char				uint8_t;	// 8 bits
typedef unsigned short			uint16_t;	// 16 bits
typedef unsigned int				uint32_t;	// 32 bits
typedef unsigned long long	uint64_t;	// 64 bits

typedef struct __stat64 stat_t;
inline int stat(const char *path, stat_t *buf) { return ::_stat64(path,buf); }
inline int _stat(const char *path, stat_t *buf) { return pla::stat(path,buf); }

#else
typedef ::int8_t		int8_t;		// 8 bits
typedef ::int16_t		int16_t;	// 16 bits
typedef ::int32_t		int32_t;	// 32 bits
typedef ::int64_t		int64_t;	// 64 bits
typedef ::uint8_t		uint8_t;	// 8 bits
typedef ::uint16_t	uint16_t;	// 16 bits
typedef ::uint32_t	uint32_t;	// 32 bits
typedef ::uint64_t	uint64_t;	// 64 bits

#ifdef MACOSX
typedef struct stat stat_t;
inline int stat(const char *path, stat_t *buf) { return ::stat(path,buf); }
#else
typedef struct stat64 stat_t;
inline int stat(const char *path, stat_t *buf) { return ::stat64(path,buf); }
#endif

#endif

typedef unsigned char	byte;
typedef float		float32_t;	// 32 bits float
typedef double	float64_t;	// 64 bits float

#define CONST64(n) n ## ULL	// 64 bits unsigned constant

// Aliases
template<typename T> using sptr = std::shared_ptr<T>;
template<typename T> using wptr = std::weak_ptr<T>;

// Typedefs
typedef std::chrono::duration<double> duration;
typedef std::chrono::duration<double> seconds;
typedef std::chrono::duration<double, std::milli> milliseconds;
typedef std::chrono::duration<double, std::micro> microseconds;
typedef std::chrono::duration<double, std::nano>  nanoseconds;

// Utility functions
template<typename T> T bounds(T val, T val_min, T val_max)
{
	if(val_min > val_max) std::swap(val_min,val_max);
	return std::min(val_max,std::max(val_min,val));
}

template<typename T> T sqr(T x)
{
	return x*x;
}

template<typename T> unsigned int bitcount(T n)
{
	static T m1  = (~T(0)) / 3;
	static T m2  = (~T(0)) / 5;
	static T m4  = (~T(0)) / 17;
	static T h01 = (~T(0)) / 255;

	n-= (n >> 1) & m1;			// Put count of each 2 bits into those 2 bits
	n = (n & m2) + ((n >> 2) & m2);		// Put count of each 4 bits into those 4 bits
	n = (n + (n >> 4)) & m4;		// Put count of each 8 bits into those 8 bits

	return (n * h01) >> (sizeof(T)*8 - 8);  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}

inline void memxor(char *a, const char *b, size_t size)
{
	unsigned long *la = reinterpret_cast<unsigned long*>(a);
	const unsigned long *lb = reinterpret_cast<const unsigned long*>(b);
	const size_t n = size / sizeof(unsigned long);
	for(size_t i = 0; i < n; ++i)
		la[i]^= lb[i];
	for(size_t i = n*sizeof(unsigned long); i < size; ++i)
		a[i]^= b[i];
}

inline duration structToDuration(const struct timeval &tv)
{
	return seconds(double(tv.tv_sec) + double(tv.tv_usec)/1000000.);
}

inline duration structToDuration(const struct timespec &ts)
{
	return seconds(double(ts.tv_sec) + double(ts.tv_nsec)/1000000000.);
}

inline void durationToStruct(duration d, struct timeval &tv)
{
	double secs = seconds(d).count();
	double isecs = 0.;
	double fsecs = std::modf(secs, &isecs);
	tv.tv_sec = time_t(isecs);
	tv.tv_usec = long(fsecs*1000000.);
}

inline void durationToStruct(duration d, struct timespec &ts)
{
	double secs = seconds(d).count();
	double isecs = 0.;
	double fsecs = std::modf(secs, &isecs);
	ts.tv_sec = time_t(isecs);
	ts.tv_nsec = long(fsecs*100000000.);
}

#define Queue std::queue
#define Stack std::stack
#define Deque std::deque

const size_t BufferSize = 4*1024;	// 4 KiB

extern std::mutex LogMutex;
extern bool ForceLogToFile;
extern int LogLevel;
extern std::map<std::thread::id, unsigned> ThreadsMap;

std::string GetFormattedLogTime(void);

#define LEVEL_TRACE	0
#define LEVEL_DEBUG	1
#define LEVEL_INFO	2
#define LEVEL_WARN	3
#define LEVEL_ERROR	4

template<typename T> void LogImpl(const char *file, int line, int level, const char *prefix, const T &value)
{
	if(level < pla::LogLevel) return;

	std::lock_guard<std::mutex> lock(LogMutex);

	unsigned mythreadid = 0;
	auto it = ThreadsMap.find(std::this_thread::get_id());
	if(it != ThreadsMap.end()) mythreadid = it->second;
	else {
		mythreadid = unsigned(ThreadsMap.size()) + 1;
		ThreadsMap[std::this_thread::get_id()] = mythreadid;
	}

	const char *strLevel;
	switch(level)
	{
		case LEVEL_TRACE:	strLevel = "Trace:";	break;
		case LEVEL_DEBUG:	strLevel = "Debug:";	break;
		case LEVEL_INFO:	strLevel = "Info:";		break;
		case LEVEL_WARN:	strLevel = "WARNING:";	break;
		default:			strLevel = "ERROR:";	break;
	}

	std::ostringstream oss;
	oss.fill(' ');
	oss<<pla::GetFormattedLogTime()<<' ';
#ifdef DEBUG
	std::ostringstream tmp;
	tmp<<file<<':'<<std::dec<<line;
	oss<<tmp.str();
	if(tmp.str().size() < 28) oss<<std::string(28-tmp.str().size(), ' ');
	tmp.str("");
	tmp<<mythreadid<<'@'<<prefix;
	oss<<' '<<std::setw(36)<<tmp.str()<<' ';
#endif
	oss<<std::setw(8)<<strLevel<<' '<<value;

#ifdef ANDROID
	__android_log_print(ANDROID_LOG_VERBOSE, "teapotnet", "%s", oss.str().c_str());
#else
	if(!pla::ForceLogToFile) std::cout<<oss.str()<<std::endl;
	else {
		std::ofstream log("log.txt", std::ios_base::app | std::ios_base::out);
		if(log.is_open())
		{
			log<<oss.str()<<std::endl;
			log.close();
		}
	}
#endif
}

#define LogTrace(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_TRACE, prefix, value)
#define LogDebug(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_DEBUG, prefix, value)
#define LogInfo(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_INFO, prefix, value)
#define LogWarn(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_WARN, prefix, value)
#define LogError(prefix, value)		LogImpl(__FILE__, __LINE__, LEVEL_ERROR, prefix, value)
#define Log(prefix, value)		LogInfo(prefix, value)
#define NOEXCEPTION(stmt)		try { stmt; } catch(const std::exception &e) { LogWarn("Exception", e.what()); } catch(...) {}

// Debug tools
#define VAR(x) 				{ std::ostringstream s; s<<""#x"="<<x; Log("VAR", s.str()); }

}

#endif
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2018 IncludeOS AS, Oslo, Norway
//
// 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.

#ifndef UTIL_ALLOC_PMR
#define UTIL_ALLOC_PMR

#if __has_include(<experimental/memory_resource>)
#include <experimental/memory_resource>
#include <experimental/vector>
namespace std {
  namespace pmr = std::experimental::pmr;
}
#else
#include <memory_resource>
#include <vector> // For pmr::vector
#endif

#include <delegate>
#include <malloc.h>

namespace os::mem::detail {
  class Pmr_pool;
  using Pool_ptr = std::shared_ptr<Pmr_pool>;
}

namespace os::mem {

  class Pmr_resource;

  class Pmr_pool {
  public:
    static constexpr size_t default_max_resources    = 0xffffff;
    static constexpr size_t resource_division_offset = 2;
    using Resource     = Pmr_resource;
    using Resource_ptr = std::unique_ptr<Pmr_resource, delegate<void(Resource*)>>;

    inline Pmr_pool(size_t capacity,
                    size_t cap_suballoc = 0,
                    size_t max_rescount = default_max_resources);
    inline Pmr_pool() = default;
    inline Resource_ptr get_resource();
    inline void return_resource(Resource* res);
    inline std::size_t resource_capacity();
    inline std::size_t resource_count();
    inline std::size_t total_capacity();
    inline void set_resource_capacity(std::size_t);
    inline void set_total_capacity(std::size_t);
    inline std::size_t allocated();
    inline std::size_t allocatable();
    inline std::size_t alloc_count();
    inline std::size_t dealloc_count();
    inline bool full();
    inline bool empty();

  private:
    detail::Pool_ptr impl;
  };

  class Pmr_resource : public std::pmr::memory_resource {
  public:
    using Pool_ptr = detail::Pool_ptr;
    using Event    = delegate<void(Pmr_resource& res)>;
    inline Pmr_resource(Pool_ptr p);
    inline Pool_ptr pool();
    inline void* do_allocate(std::size_t size, std::size_t align) override;
    inline void do_deallocate (void* ptr, size_t, size_t) override;
    inline bool do_is_equal(const std::pmr::memory_resource&) const noexcept override;
    inline std::size_t capacity();
    inline std::size_t allocatable();
    inline std::size_t allocated();
    inline std::size_t alloc_count();
    inline std::size_t dealloc_count();
    inline bool full();
    inline bool empty();

    /** Fires when the resource has been full and is not full anymore **/
    void on_non_full(Event e){ non_full = e; }

    /** Fires on transition from < N bytes to >= N bytes allocatable **/
    void on_avail(std::size_t N, Event e) { avail_thresh = N; avail = e; }

  private:
    Pool_ptr pool_;
    std::size_t used = 0;
    std::size_t allocs = 0;
    std::size_t deallocs = 0;
    std::size_t avail_thresh = 0;
    Event non_full{};
    Event avail{};
  };

  struct Default_pmr : public std::pmr::memory_resource {
    void* do_allocate(std::size_t size, std::size_t align) override {
      return memalign(align, size);
    }

    void do_deallocate (void* ptr, size_t, size_t) override {
      std::free(ptr);
    }

    bool do_is_equal (const std::pmr::memory_resource& other) const noexcept override {
      if (const auto* underlying = dynamic_cast<const Default_pmr*>(&other))
        return true;
      return false;
    }
  };

}

#include <util/detail/alloc_pmr.hpp>

#endif
<commit_msg>pmr: make default resource throw on failure<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2018 IncludeOS AS, Oslo, Norway
//
// 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.

#ifndef UTIL_ALLOC_PMR
#define UTIL_ALLOC_PMR

#if __has_include(<experimental/memory_resource>)
#include <experimental/memory_resource>
#include <experimental/vector>
namespace std {
  namespace pmr = std::experimental::pmr;
}
#else
#include <memory_resource>
#include <vector> // For pmr::vector
#endif

#include <delegate>
#include <malloc.h>

namespace os::mem::detail {
  class Pmr_pool;
  using Pool_ptr = std::shared_ptr<Pmr_pool>;
}

namespace os::mem {

  class Pmr_resource;

  class Pmr_pool {
  public:
    static constexpr size_t default_max_resources    = 0xffffff;
    static constexpr size_t resource_division_offset = 2;
    using Resource     = Pmr_resource;
    using Resource_ptr = std::unique_ptr<Pmr_resource, delegate<void(Resource*)>>;

    inline Pmr_pool(size_t capacity,
                    size_t cap_suballoc = 0,
                    size_t max_rescount = default_max_resources);
    inline Pmr_pool() = default;
    inline Resource_ptr get_resource();
    inline void return_resource(Resource* res);
    inline std::size_t resource_capacity();
    inline std::size_t resource_count();
    inline std::size_t total_capacity();
    inline void set_resource_capacity(std::size_t);
    inline void set_total_capacity(std::size_t);
    inline std::size_t allocated();
    inline std::size_t allocatable();
    inline std::size_t alloc_count();
    inline std::size_t dealloc_count();
    inline bool full();
    inline bool empty();

  private:
    detail::Pool_ptr impl;
  };

  class Pmr_resource : public std::pmr::memory_resource {
  public:
    using Pool_ptr = detail::Pool_ptr;
    using Event    = delegate<void(Pmr_resource& res)>;
    inline Pmr_resource(Pool_ptr p);
    inline Pool_ptr pool();
    inline void* do_allocate(std::size_t size, std::size_t align) override;
    inline void do_deallocate (void* ptr, size_t, size_t) override;
    inline bool do_is_equal(const std::pmr::memory_resource&) const noexcept override;
    inline std::size_t capacity();
    inline std::size_t allocatable();
    inline std::size_t allocated();
    inline std::size_t alloc_count();
    inline std::size_t dealloc_count();
    inline bool full();
    inline bool empty();

    /** Fires when the resource has been full and is not full anymore **/
    void on_non_full(Event e){ non_full = e; }

    /** Fires on transition from < N bytes to >= N bytes allocatable **/
    void on_avail(std::size_t N, Event e) { avail_thresh = N; avail = e; }

  private:
    Pool_ptr pool_;
    std::size_t used = 0;
    std::size_t allocs = 0;
    std::size_t deallocs = 0;
    std::size_t avail_thresh = 0;
    Event non_full{};
    Event avail{};
  };

  struct Default_pmr : public std::pmr::memory_resource {
    void* do_allocate(std::size_t size, std::size_t align) override {
      auto* res = memalign(align, size);
      if (res == nullptr)
        throw std::bad_alloc();
      return res;
    }

    void do_deallocate (void* ptr, size_t, size_t) override {
      std::free(ptr);
    }

    bool do_is_equal (const std::pmr::memory_resource& other) const noexcept override {
      if (const auto* underlying = dynamic_cast<const Default_pmr*>(&other))
        return true;
      return false;
    }
  };

}

#include <util/detail/alloc_pmr.hpp>

#endif
<|endoftext|>


<commit_before>class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        int i, sum;
        vector<int> results;
        map<int, int> hmap;
        for (i = 0; i < numbers.size(); i++){
            if(!hmap.count(numbers[i])){
                hmap.insert(pair<int, int>(numbers[i], i));
            }
            if (hmap.count(target - numbers[i])){
                int n = hmap[target - numbers[i]];
                if (n < i){
                    results.push_back(n + 1);
                    results.push_back(i + 1);
                    return results;
                }
            }
        }
        return results;
    }
};
<commit_msg>task 2 start<commit_after><|endoftext|>


<commit_before>#include <UnitTest/stdafx.h>
#include <UnitTest/UnitTest.h>
#include <core/smartview/block/block.h>
#include <core/smartview/block/blockBytes.h>
#include <core/smartview/block/blockStringA.h>
#include <core/smartview/block/blockStringW.h>
#include <core/smartview/block/blockT.h>

namespace blocktest
{
	TEST_CLASS(blocktest)
	{
	public:
		// Without this, clang gets weird
		static const bool dummy_var = true;

		TEST_CLASS_INITIALIZE(initialize) { unittest::init(); }
		TEST_METHOD(Test_block)
		{
			auto block1 = smartview::block::create(L"test");
			auto block2 = smartview::block::create(L"block2");
			auto block3 = smartview::block::create(L"");
			Assert::AreEqual(block1->isHeader(), true);
			block1->setSize(5);
			Assert::AreEqual(block1->isHeader(), false);
			block1->setOffset(6);
			Assert::AreEqual(block1->isHeader(), false);
			block1->setSource(7);

			Assert::AreEqual(block1->getText(), std::wstring(L"test"));
			Assert::AreEqual(block1->getChildren().empty(), true);
			Assert::AreEqual(block1->toString(), std::wstring(L"test"));
			Assert::AreEqual(block1->getSize(), size_t(5));
			Assert::AreEqual(block1->getOffset(), size_t(6));
			Assert::AreEqual(block1->getSource(), ULONG(7));

			block1->setText(L"the %1!ws!", L"other");
			Assert::AreEqual(block1->getText(), std::wstring(L"the other"));
			block1->addHeader(L" this %1!ws!", L"that");
			Assert::AreEqual(block1->toString(), std::wstring(L"the other this that"));

			block1->setText(L"hello");
			Assert::AreEqual(block1->getText(), std::wstring(L"hello"));

			block1->setText(L"hello %1!ws!", L"world");
			Assert::AreEqual(block1->getText(), std::wstring(L"hello world"));

			block1->terminateBlock();
			block1->terminateBlock();
			block1->addChild(block2);
			Assert::AreEqual(block1->toString(), std::wstring(L"hello world this that\r\nblock2"));

			block1->addBlankLine();
			block1->addLabeledChild(L"Label: ", block2);
			Assert::AreEqual(block1->toString(), std::wstring(L"hello world this that\r\nblock2\r\n\r\nLabel: block2"));

			Assert::AreEqual(block3->hasData(), false);
			block3->addChild(block1);
			Assert::AreEqual(block3->hasData(), true);
			block3->setSource(42);
			Assert::AreEqual(block3->getSource(), ULONG(42));
			Assert::AreEqual(block1->getSource(), ULONG(42));
		}

		TEST_METHOD(Test_blockStringA)
		{
			auto block1 = std::make_shared<smartview::blockStringA>();
			Assert::AreEqual(block1->isSet(), false);
		}

		TEST_METHOD(Test_blockStringW)
		{
			auto block1 = std::make_shared<smartview::blockStringW>();
			Assert::AreEqual(block1->isSet(), false);
			auto block2 = smartview::blockStringW::parse(std::wstring(L"test"), 4, 5);
			Assert::AreEqual(block2->length(), size_t(4));
		}
	};
} // namespace blocktest<commit_msg>Add missing test case<commit_after>#include <UnitTest/stdafx.h>
#include <UnitTest/UnitTest.h>
#include <core/smartview/block/block.h>
#include <core/smartview/block/blockBytes.h>
#include <core/smartview/block/blockStringA.h>
#include <core/smartview/block/blockStringW.h>
#include <core/smartview/block/blockT.h>

namespace blocktest
{
	TEST_CLASS(blocktest)
	{
	public:
		// Without this, clang gets weird
		static const bool dummy_var = true;

		TEST_CLASS_INITIALIZE(initialize) { unittest::init(); }
		TEST_METHOD(Test_block)
		{
			auto block1 = smartview::block::create(L"test");
			auto block2 = smartview::block::create(L"block2");
			auto block3 = smartview::block::create(L"");
			Assert::AreEqual(block1->isHeader(), true);
			block1->setSize(5);
			Assert::AreEqual(block1->isHeader(), false);
			block1->setOffset(6);
			Assert::AreEqual(block1->isHeader(), false);
			block1->setSource(7);

			Assert::AreEqual(block1->getText(), std::wstring(L"test"));
			Assert::AreEqual(block1->getChildren().empty(), true);
			Assert::AreEqual(block1->toString(), std::wstring(L"test"));
			Assert::AreEqual(block1->getSize(), size_t{5});
			Assert::AreEqual(block1->getOffset(), size_t{6});
			Assert::AreEqual(block1->getSource(), ULONG{7});

			block1->setText(L"the %1!ws!", L"other");
			Assert::AreEqual(block1->getText(), std::wstring(L"the other"));
			block1->addHeader(L" this %1!ws!", L"that");
			Assert::AreEqual(block1->toString(), std::wstring(L"the other this that"));

			block1->setText(L"hello");
			Assert::AreEqual(block1->getText(), std::wstring(L"hello"));

			// Text with % and no arguments should go straight in
			block1->setText(L"%d %ws %");
			Assert::AreEqual(block1->getText(), std::wstring(L"%d %ws %"));

			block1->setText(L"hello %1!ws!", L"world");
			Assert::AreEqual(block1->getText(), std::wstring(L"hello world"));

			block1->terminateBlock();
			block1->terminateBlock();
			block1->addChild(block2);
			Assert::AreEqual(block1->toString(), std::wstring(L"hello world this that\r\nblock2"));

			block1->addBlankLine();
			block1->addLabeledChild(L"Label: ", block2);
			Assert::AreEqual(block1->toString(), std::wstring(L"hello world this that\r\nblock2\r\n\r\nLabel: block2"));

			Assert::AreEqual(block3->hasData(), false);
			block3->addChild(block1);
			Assert::AreEqual(block3->hasData(), true);
			block3->setSource(42);
			Assert::AreEqual(block3->getSource(), ULONG{42});
			Assert::AreEqual(block1->getSource(), ULONG{42});
		}

		TEST_METHOD(Test_blockStringA)
		{
			auto block1 = std::make_shared<smartview::blockStringA>();
			Assert::AreEqual(block1->isSet(), false);
		}

		TEST_METHOD(Test_blockStringW)
		{
			auto block1 = std::make_shared<smartview::blockStringW>();
			Assert::AreEqual(block1->isSet(), false);
			auto block2 = smartview::blockStringW::parse(std::wstring(L"test"), 4, 5);
			Assert::AreEqual(block2->length(), size_t(4));
		}
	};
} // namespace blocktest<|endoftext|>


<commit_before>#include "AntGoalTestApp.hpp"
#include "../sim/worldobject/AntHome.hpp"
#include "../sim/nav/Node.hpp"
#include "../sim/agent/testagent/AntGoalTester.hpp"
#include "../sim/agent/testagent/AntEatAntTest.hpp"
#include "../sim/agent/testagent/AntExploreAntTest.hpp"
#include "../sim/agent/testagent/AntFindFoodAntTest.hpp"
#include "../sim/agent/testagent/AntForageAntTest.hpp"
#include "../sim/agent/testagent/AntGoHomeAntTest.hpp"
#include "../sim/agent/testagent/AntMoveToLocationAntTest.hpp"
#include "../util/make_unique.hpp"
#include "../sim/knowledge/GenericPercept.hpp"

#include <iostream>
#include <vector>

// Christopher D. Canfield
// November 2013
// AntGoalTestApp.cpp

using namespace std;
using namespace cdc;

void createNavGraph1(vector<Node>& graph);
unique_ptr<AntGoalTester> getTestAnt(GuiEventManager& manager, AntHome& home, NavGraphHelper& navGraphHelper, Node& node);

AntGoalTestApp::AntGoalTestApp() :
	viewManager(eventManager, 1000, 1000, 800, 800, 200, 800),
	ticks(0)
{
}

AntGoalTestApp::~AntGoalTestApp()
{
}

void AntGoalTestApp::setup()
{
	createNavGraph1(navGraph);
	navGraphHelper = NavGraphHelper(navGraph);

	ant = getTestAnt(eventManager, *antHome, navGraphHelper, navGraph[6]);

	window = std::unique_ptr<sf::RenderWindow>(new sf::RenderWindow(sf::VideoMode(800, 800), "GUI Tests"));
	window->setFramerateLimit(60);

	viewManager.setWindow(window.get());
	viewManager.getSimView().setViewport(sf::FloatRect(0.f, 0.f, 1.f, 1.f));
}

bool AntGoalTestApp::run()
{
	GenericPercept percept;
	ant->update(ticks, percept);
	++ticks;

	window->clear(sf::Color::Green);
	window->draw(*ant);
	window->display();

	return !ant->isGoalFinished();
}

void AntGoalTestApp::teardown()
{

}

unique_ptr<AntGoalTester> getTestAnt(GuiEventManager& manager, AntHome& home, NavGraphHelper& navGraphHelper, Node& target)
{
	cout << "Ant goal tester type: " << endl;
	cout << "  1: AntEat" << endl;
	cout << "  2: AntExplore" << endl;
	cout << "  3: AntFindFood" << endl;
	cout << "  4: AntForage" << endl;
	cout << "  5: AntGoHome" << endl;
	cout << "  6: AntMoveToLocation" << endl;

	int goalType;
	cin >> goalType;

	switch (goalType)
	{
	case 1:
		return make_unique<AntEatAntTest>(manager, home, navGraphHelper);
		break;
	case 2:
		return make_unique<AntExploreAntTest>(manager, home, navGraphHelper);
		break;
	case 3:
		return make_unique<AntFindFoodAntTest>(manager, home, navGraphHelper);
		break;
	case 4:
		return make_unique<AntForageAntTest>(manager, home, navGraphHelper);
		break;
	case 5:
		return make_unique<AntGoHomeAntTest>(manager, home, navGraphHelper);
		break;
	case 6:
		return make_unique<AntMoveToLocationAntTest>(manager, home, navGraphHelper, target);
		break;
	default:
		throw runtime_error("Invalid goal selection");
	}
}

void createNavGraph1(vector<Node>& navGraph)
{
	navGraph.reserve(11);
	navGraph.push_back(Node(GridLocation(0, 0), 10, 20));	// 0
	navGraph.push_back(Node(GridLocation(0, 1), 10, 20));	// 1
	navGraph.push_back(Node(GridLocation(0, 2), 10, 20));	// 2
	navGraph.push_back(Node(GridLocation(0, 3), 10, 20));	// 3
	navGraph.push_back(Node(GridLocation(1, 0), 10, 20));	// 4
	navGraph.push_back(Node(GridLocation(1, 1), 10, 20));	// 5
	navGraph.push_back(Node(GridLocation(1, 2), 10, 20));	// 6
	navGraph.push_back(Node(GridLocation(1, 3), 10, 20));	// 7
	navGraph.push_back(Node(GridLocation(2, 0), 10, 20));	// 8
	navGraph.push_back(Node(GridLocation(2, 1), 10, 20));	// 9
	navGraph.push_back(Node(GridLocation(2, 2), 10, 20));	// 10
	navGraph.push_back(Node(GridLocation(2, 3), 10, 20));	// 11

	auto edge_00_01 = make_shared<Edge>(navGraph[0], navGraph[1], 1);
	auto edge_00_10 = make_shared<Edge>(navGraph[0], navGraph[4], 1);
	navGraph[0].addEdge(edge_00_01).addEdge(edge_00_10);

	auto edge_01_02 = make_shared<Edge>(navGraph[1], navGraph[2], 1);
	auto edge_01_11 = make_shared<Edge>(navGraph[1], navGraph[5], 1);
	navGraph[1].addEdge(edge_01_02).addEdge(edge_01_11);

	auto edge_02_03 = make_shared<Edge>(navGraph[2], navGraph[3], 1);
	auto edge_02_12 = make_shared<Edge>(navGraph[2], navGraph[6], 1);
	navGraph[2].addEdge(edge_02_03).addEdge(edge_02_12);

	auto edge_03_13 = make_shared<Edge>(navGraph[3], navGraph[7], 1);
	navGraph[3].addEdge(edge_03_13);

	auto edge_10_11 = make_shared<Edge>(navGraph[4], navGraph[5], 1);
	auto edge_10_20 = make_shared<Edge>(navGraph[4], navGraph[8], 1);
	navGraph[4].addEdge(edge_10_11).addEdge(edge_10_20);

	auto edge_11_12 = make_shared<Edge>(navGraph[5], navGraph[6], 1);
	auto edge_11_21 = make_shared<Edge>(navGraph[5], navGraph[9], 1);
	navGraph[5].addEdge(edge_11_12).addEdge(edge_11_21);

	auto edge_12_13 = make_shared<Edge>(navGraph[6], navGraph[7], 1);
	auto edge_12_22 = make_shared<Edge>(navGraph[6], navGraph[10], 1);
	navGraph[6].addEdge(edge_12_13).addEdge(edge_12_22);

	auto edge_13_23 = make_shared<Edge>(navGraph[7], navGraph[11], 1);
	navGraph[7].addEdge(edge_13_23);

	auto edge_20_21 = make_shared<Edge>(navGraph[8], navGraph[9], 1);
	navGraph[8].addEdge(edge_20_21);

	auto edge_21_22 = make_shared<Edge>(navGraph[9], navGraph[10], 1);
	navGraph[9].addEdge(edge_21_22);

	auto edge_22_23 = make_shared<Edge>(navGraph[10], navGraph[11], 1);
	navGraph[10].addEdge(edge_22_23);
}<commit_msg>Updated nav graph in AntGoalTestApp<commit_after>#include "AntGoalTestApp.hpp"
#include "../sim/worldobject/AntHome.hpp"
#include "../sim/nav/Node.hpp"
#include "../sim/agent/testagent/AntGoalTester.hpp"
#include "../sim/agent/testagent/AntEatAntTest.hpp"
#include "../sim/agent/testagent/AntExploreAntTest.hpp"
#include "../sim/agent/testagent/AntFindFoodAntTest.hpp"
#include "../sim/agent/testagent/AntForageAntTest.hpp"
#include "../sim/agent/testagent/AntGoHomeAntTest.hpp"
#include "../sim/agent/testagent/AntMoveToLocationAntTest.hpp"
#include "../util/make_unique.hpp"
#include "../sim/knowledge/GenericPercept.hpp"

#include <iostream>
#include <vector>

// Christopher D. Canfield
// November 2013
// AntGoalTestApp.cpp

using namespace std;
using namespace cdc;

void createNavGraph1(vector<Node>& graph);
unique_ptr<AntGoalTester> getTestAnt(GuiEventManager& manager, AntHome& home, NavGraphHelper& navGraphHelper, Node& node);

AntGoalTestApp::AntGoalTestApp() :
	viewManager(eventManager, 1000, 1000, 800, 800, 200, 800),
	ticks(0)
{
}

AntGoalTestApp::~AntGoalTestApp()
{
}

void AntGoalTestApp::setup()
{
	createNavGraph1(navGraph);
	navGraphHelper = NavGraphHelper(navGraph);

	ant = getTestAnt(eventManager, *antHome, navGraphHelper, navGraph[6]);

	window = std::unique_ptr<sf::RenderWindow>(new sf::RenderWindow(sf::VideoMode(800, 800), "GUI Tests"));
	window->setFramerateLimit(60);

	viewManager.setWindow(window.get());
	viewManager.getSimView().setViewport(sf::FloatRect(0.f, 0.f, 1.f, 1.f));
}

bool AntGoalTestApp::run()
{
	GenericPercept percept;
	ant->update(ticks, percept);
	++ticks;

	window->clear(sf::Color::Green);
	window->draw(*ant);
	window->display();

	return !ant->isGoalFinished();
}

void AntGoalTestApp::teardown()
{

}

unique_ptr<AntGoalTester> getTestAnt(GuiEventManager& manager, AntHome& home, NavGraphHelper& navGraphHelper, Node& target)
{
	cout << "Ant goal tester type: " << endl;
	cout << "  1: AntEat" << endl;
	cout << "  2: AntExplore" << endl;
	cout << "  3: AntFindFood" << endl;
	cout << "  4: AntForage" << endl;
	cout << "  5: AntGoHome" << endl;
	cout << "  6: AntMoveToLocation" << endl;

	int goalType;
	cin >> goalType;

	switch (goalType)
	{
	case 1:
		return make_unique<AntEatAntTest>(manager, home, navGraphHelper);
		break;
	case 2:
		return make_unique<AntExploreAntTest>(manager, home, navGraphHelper);
		break;
	case 3:
		return make_unique<AntFindFoodAntTest>(manager, home, navGraphHelper);
		break;
	case 4:
		return make_unique<AntForageAntTest>(manager, home, navGraphHelper);
		break;
	case 5:
		return make_unique<AntGoHomeAntTest>(manager, home, navGraphHelper);
		break;
	case 6:
		return make_unique<AntMoveToLocationAntTest>(manager, home, navGraphHelper, target);
		break;
	default:
		throw runtime_error("Invalid goal selection");
	}
}

void createNavGraph1(vector<Node>& navGraph)
{
	navGraph.reserve(11);
	navGraph.push_back(Node(GridLocation(0, 0), 10, 10));	// 0
	navGraph.push_back(Node(GridLocation(0, 1), 10, 20));	// 1
	navGraph.push_back(Node(GridLocation(0, 2), 10, 30));	// 2
	navGraph.push_back(Node(GridLocation(0, 3), 10, 40));	// 3
	navGraph.push_back(Node(GridLocation(1, 0), 20, 10));	// 4
	navGraph.push_back(Node(GridLocation(1, 1), 20, 20));	// 5
	navGraph.push_back(Node(GridLocation(1, 2), 20, 30));	// 6
	navGraph.push_back(Node(GridLocation(1, 3), 20, 40));	// 7
	navGraph.push_back(Node(GridLocation(2, 0), 30, 10));	// 8
	navGraph.push_back(Node(GridLocation(2, 1), 30, 20));	// 9
	navGraph.push_back(Node(GridLocation(2, 2), 30, 30));	// 10
	navGraph.push_back(Node(GridLocation(2, 3), 30, 40));	// 11

	auto edge_00_01 = make_shared<Edge>(navGraph[0], navGraph[1], 1);
	auto edge_00_10 = make_shared<Edge>(navGraph[0], navGraph[4], 1);
	navGraph[0].addEdge(edge_00_01).addEdge(edge_00_10);

	auto edge_01_02 = make_shared<Edge>(navGraph[1], navGraph[2], 1);
	auto edge_01_11 = make_shared<Edge>(navGraph[1], navGraph[5], 1);
	navGraph[1].addEdge(edge_01_02).addEdge(edge_01_11);

	auto edge_02_03 = make_shared<Edge>(navGraph[2], navGraph[3], 1);
	auto edge_02_12 = make_shared<Edge>(navGraph[2], navGraph[6], 1);
	navGraph[2].addEdge(edge_02_03).addEdge(edge_02_12);

	auto edge_03_13 = make_shared<Edge>(navGraph[3], navGraph[7], 1);
	navGraph[3].addEdge(edge_03_13);

	auto edge_10_11 = make_shared<Edge>(navGraph[4], navGraph[5], 1);
	auto edge_10_20 = make_shared<Edge>(navGraph[4], navGraph[8], 1);
	navGraph[4].addEdge(edge_10_11).addEdge(edge_10_20);

	auto edge_11_12 = make_shared<Edge>(navGraph[5], navGraph[6], 1);
	auto edge_11_21 = make_shared<Edge>(navGraph[5], navGraph[9], 1);
	navGraph[5].addEdge(edge_11_12).addEdge(edge_11_21);

	auto edge_12_13 = make_shared<Edge>(navGraph[6], navGraph[7], 1);
	auto edge_12_22 = make_shared<Edge>(navGraph[6], navGraph[10], 1);
	navGraph[6].addEdge(edge_12_13).addEdge(edge_12_22);

	auto edge_13_23 = make_shared<Edge>(navGraph[7], navGraph[11], 1);
	navGraph[7].addEdge(edge_13_23);

	auto edge_20_21 = make_shared<Edge>(navGraph[8], navGraph[9], 1);
	navGraph[8].addEdge(edge_20_21);

	auto edge_21_22 = make_shared<Edge>(navGraph[9], navGraph[10], 1);
	navGraph[9].addEdge(edge_21_22);

	auto edge_22_23 = make_shared<Edge>(navGraph[10], navGraph[11], 1);
	navGraph[10].addEdge(edge_22_23);
}<|endoftext|>


<commit_before>#include "BindServiceStub.h"

#include <grpc_cb_core/common/completion_queue_for_next_sptr.h>  // for CompletionQueueForNextSptr
#include <grpc_cb_core/client/service_stub.h>  // for ServiceStub
#include <grpc_cb_core/common/status.h>  // for Status

#include <LuaIntf/LuaIntf.h>
#include <string>

using namespace grpc_cb_core;
using namespace LuaIntf;
using string = std::string;

namespace {

void SetErrorCb(ServiceStub* pServiceStub, const LuaRef& luaErrorCb)
{
    assert(pServiceStub);
    if (!luaErrorCb)
    {
        pServiceStub->SetErrorCb(ErrorCb());  // clear error callback
        return;
    }
    // XXX
}

// Sync request.
// Return (response_string, nil, nil) or
//   (nil, error_string, grpc_status_code).
// XXX change to return (string|nil, string, code)
std::tuple<LuaRef, LuaRef, LuaRef>
SyncRequest(lua_State* L, ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest)
{
    assert(L);
    assert(pServiceStub);
    string sResponse;
    Status status = pServiceStub->SyncRequest(
        sMethod, sRequest, sResponse);
    const LuaRef NIL(L, nullptr);
    if (status.ok())
        return std::make_tuple(LuaRef::fromValue(L, sResponse), NIL, NIL);
    return std::make_tuple(NIL,
        LuaRef::fromValue(L, status.GetDetails()),
        LuaRef::fromValue(L, status.GetCode()));
}  // SyncRequest()

void AsyncRequest(ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest,
    const LuaRef& luaResponseCb, const LuaRef& luaErrorCb)
{
    assert(pServiceStub);
    ResponseCb cbResponse;  // function<void (const string&)>
    if (luaResponseCb)
    {
        luaResponseCb.checkFunction();  // void (string)
        cbResponse = [luaResponseCb](const string& sResponse) {
            luaResponseCb.call(sResponse);
        };
    }
    ErrorCb cbError;  // function<void (const Status& status)>
    if (luaErrorCb)
    {
        luaErrorCb.checkFunction();  // void (string, int)
        cbError = [luaErrorCb](const Status& status) {
            // XXX if (status.ok()) call(nil, 0)
            luaErrorCb.call(status.GetDetails(), status.GetCode());
        };
    }
    pServiceStub->AsyncRequest(sMethod, sRequest, cbResponse, cbError);
}  // AsyncRequest()

}  // namespace

namespace bind {

void BindServiceStub(const LuaRef& mod)
{
    lua_State* L = mod.state();
    LuaBinding(mod).beginClass<ServiceStub>("ServiceStub")
        .addConstructor(LUA_ARGS(const ChannelSptr&,
            _opt<CompletionQueueForNextSptr>))
        .addFunction("set_error_cb", &SetErrorCb)
        .addFunction("sync_request",
            [L](ServiceStub* pServiceStub, const string& sMethod,
                    const string& sRequest) {
                return SyncRequest(L, pServiceStub, sMethod, sRequest);
            })
        .addFunction("async_request", &AsyncRequest)
        .addFunction("run", &ServiceStub::Run)
        .addFunction("shutdown", &ServiceStub::Shutdown)
    .endClass();  // ServiceStub
}  // BindServiceStub()

}  // namespace bind
<commit_msg>Add FromLuaErrorCb().<commit_after>#include "BindServiceStub.h"

#include <grpc_cb_core/common/completion_queue_for_next_sptr.h>  // for CompletionQueueForNextSptr
#include <grpc_cb_core/client/service_stub.h>  // for ServiceStub
#include <grpc_cb_core/common/status.h>  // for Status

#include <LuaIntf/LuaIntf.h>
#include <string>

using namespace grpc_cb_core;
using namespace LuaIntf;
using string = std::string;

namespace {

// Convert lua error callback into ErrorCb.
// function(error_str, status_code) -> void (const Status&)
ErrorCb FromLuaErrorCb(const LuaRef& luaErrorCb)
{
    if (!luaErrorCb) return ErrorCb();
    luaErrorCb.checkFunction();  // function(string, int)
    return [luaErrorCb](const Status& status) {
        if (!status.ok())
        {
            luaErrorCb(status.GetDetails(), status.GetCode());
            return;
        }

        // Need to nil error_str if no error.
        lua_State* L = luaErrorCb.state();
        const LuaRef NIL(L, nullptr);
        luaErrorCb(NIL, status.GetCode());
    };
}

void SetErrorCb(ServiceStub* pServiceStub, const LuaRef& luaErrorCb)
{
    assert(pServiceStub);
    pServiceStub->SetErrorCb(FromLuaErrorCb(luaErrorCb));
}

// Sync request.
// Return (response_string, nil, nil) or
//   (nil, error_string, grpc_status_code).
// XXX change to return (string|nil, string, code)
std::tuple<LuaRef, LuaRef, LuaRef>
SyncRequest(lua_State* L, ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest)
{
    assert(L);
    assert(pServiceStub);
    string sResponse;
    Status status = pServiceStub->SyncRequest(
        sMethod, sRequest, sResponse);
    const LuaRef NIL(L, nullptr);
    if (status.ok())
        return std::make_tuple(LuaRef::fromValue(L, sResponse), NIL, NIL);
    return std::make_tuple(NIL,
        LuaRef::fromValue(L, status.GetDetails()),
        LuaRef::fromValue(L, status.GetCode()));
}  // SyncRequest()

void AsyncRequest(ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest,
    const LuaRef& luaResponseCb, const LuaRef& luaErrorCb)
{
    assert(pServiceStub);
    ResponseCb cbResponse;  // function<void (const string&)>
    if (luaResponseCb)
    {
        luaResponseCb.checkFunction();  // void (string)
        cbResponse = [luaResponseCb](const string& sResponse) {
            luaResponseCb(sResponse);
        };
    }
    ErrorCb cbError = FromLuaErrorCb(luaErrorCb);
    pServiceStub->AsyncRequest(sMethod, sRequest, cbResponse, cbError);
}  // AsyncRequest()

}  // namespace

namespace bind {

void BindServiceStub(const LuaRef& mod)
{
    lua_State* L = mod.state();
    LuaBinding(mod).beginClass<ServiceStub>("ServiceStub")
        .addConstructor(LUA_ARGS(const ChannelSptr&,
            _opt<CompletionQueueForNextSptr>))
        .addFunction("set_error_cb", &SetErrorCb)
        .addFunction("sync_request",
            [L](ServiceStub* pServiceStub, const string& sMethod,
                    const string& sRequest) {
                return SyncRequest(L, pServiceStub, sMethod, sRequest);
            })
        .addFunction("async_request", &AsyncRequest)
        .addFunction("run", &ServiceStub::Run)
        .addFunction("shutdown", &ServiceStub::Shutdown)
    .endClass();  // ServiceStub
}  // BindServiceStub()

}  // namespace bind
<|endoftext|>


<commit_before>/*
 * RSessionContext.cpp
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/r_util/RSessionContext.hpp>

#include <iostream>

#include <boost/format.hpp>

#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/algorithm/string/predicate.hpp>

#include <core/FilePath.hpp>
#include <core/Settings.hpp>
#include <core/FileSerializer.hpp>

#include <core/http/Util.hpp>
#include <core/http/URL.hpp>

#include <core/system/System.hpp>
#include <core/system/Environment.hpp>

#include <core/r_util/RActiveSessions.hpp>
#include <core/r_util/RProjectFile.hpp>

#ifndef _WIN32
#include <sys/stat.h>
#endif

#define kSessionSuffix "-d"
#define kProjectNone   "none"

namespace rstudio {
namespace core {
namespace r_util {

SessionScope SessionScope::fromProject(
                               const std::string& project,
                               const std::string& id,
                               const FilePathToProjectId& filePathToProjectId)
{
   if (project != kProjectNone)
   {
      ProjectId projectId = filePathToProjectId(project);
      return SessionScope(projectId, id);
   }
   else
   {
      return projectNone(id);
   }
}

std::string SessionScope::projectPathForScope(
                               const SessionScope& scope,
                               const ProjectIdToFilePath& projectIdToFilePath)
{
   return projectIdToFilePath(scope.projectId());
}

SessionScope SessionScope::fromProjectId(const ProjectId& project,
                                         const std::string& id)
{
   return SessionScope(project, id);
}

SessionScope SessionScope::projectNone(const std::string& id)
{
   return SessionScope(ProjectId(kProjectNoneId), id);
}

bool SessionScope::isProjectNone() const
{
   return project_.id() == kProjectNoneId;
}

bool SessionScope::isWorkspaces() const
{
   return project_.id() == kWorkspacesId;
}

bool isSharedPath(const std::string& projectPath,
                  const core::FilePath& userHomePath)
{
#ifndef _WIN32
   // ensure this is a real path
   FilePath projectDir = FilePath::resolveAliasedPath(projectPath,
                                                      userHomePath);
   if (!projectDir.exists())
      return false;

   struct stat st;
   if (::stat(projectDir.absolutePath().c_str(), &st) == 0)
   {
      // consider this project to be shared if we aren't the owner
      if (st.st_uid != ::geteuid())
      {
         return true;
      }
   }
   else
   {
      Error error = systemError(errno, ERROR_LOCATION);
      error.addProperty("path", projectDir.absolutePath());
      LOG_ERROR(error);
   }

#endif
   return false;
}

SessionScopeState validateSessionScope(const SessionScope& scope,
                          const core::FilePath& userHomePath,
                          const core::FilePath& userScratchPath,
                          core::r_util::ProjectIdToFilePath projectIdToFilePath,
                          bool projectSharingEnabled,
                          std::string* pProjectFilePath)
{
   // does this session exist?
   r_util::ActiveSessions activeSessions(userScratchPath);
   boost::shared_ptr<r_util::ActiveSession> pSession
                                          = activeSessions.get(scope.id());
   if (pSession->empty() || !pSession->validate(userHomePath,
                                                projectSharingEnabled))
      return ScopeInvalidSession;

   // if this isn't project none then check if the project exists
   if (!scope.isProjectNone())
   {
      // lookup the project path by id
      std::string project = r_util::SessionScope::projectPathForScope(
               scope,
               projectIdToFilePath);
      if (project.empty())
         return ScopeMissingProject;

      // if session points to another project then the scope is invalid
      if (project != pSession->project())
         return ScopeInvalidProject;

      // get the path to the project directory
      FilePath projectDir = FilePath::resolveAliasedPath(project, userHomePath);
      if (!projectDir.exists())
         return ScopeMissingProject;

      // get the path to the project file
      FilePath projectPath = r_util::projectFromDirectory(projectDir);
      if (!projectPath.exists())
         return ScopeMissingProject;

      // record path to project file
      *pProjectFilePath = projectPath.absolutePath();
   }
   else
   {
      // if the session project isn't project none then it's invalid
      if (pSession->project() != kProjectNone)
         return ScopeInvalidProject;
   }

   // if we got this far the scope is valid, do one final check for
   // trying to open a shared project if sharing is disabled
   if (!projectSharingEnabled &&
       r_util::isSharedPath(*pProjectFilePath, userHomePath))
   {
      return r_util::ScopeMissingProject;
   }
   else
   {
      return ScopeValid;
   }
}

std::string urlPathForSessionScope(const SessionScope& scope)
{
   // get a URL compatible project path
   std::string project = http::util::urlEncode(scope.projectId().asString());
   boost::algorithm::replace_all(project, "%2F", "/");

   // create url
   boost::format fmt("/s/%1%%2%/");
   return boost::str(fmt % project % scope.id());
}

void parseSessionUrl(const std::string& url,
                     SessionScope* pScope,
                     std::string* pUrlPrefix,
                     std::string* pUrlWithoutPrefix)
{
   static boost::regex re("/s/([A-Fa-f0-9]{5})([A-Fa-f0-9]{8})([A-Fa-f0-9]{8})/");

   boost::smatch match;
   if (boost::regex_search(url, match, re))
   {
      if (pScope)
      {
         std::string user = http::util::urlDecode(match[1]);
         std::string project = http::util::urlDecode(match[2]);
         std::string id = match[3];
         *pScope = r_util::SessionScope::fromProjectId(
                  ProjectId(project, user), id);
      }
      if (pUrlPrefix)
      {
         *pUrlPrefix = match[0];
      }
      if (pUrlWithoutPrefix)
      {
         *pUrlWithoutPrefix = boost::algorithm::replace_first_copy(
                                   url, std::string(match[0]), "/");
      }
   }
   else
   {
      if (pScope)
         *pScope = SessionScope();
      if (pUrlPrefix)
         *pUrlPrefix = std::string();
      if (pUrlWithoutPrefix)
         *pUrlWithoutPrefix = url;
   }
}

std::string createSessionUrl(const std::string& hostPageUrl,
                             const SessionScope& scope)
{
   // get url without prefix
   std::string url;
   parseSessionUrl(hostPageUrl, NULL, NULL, &url);

   // build path for project
   std::string path = urlPathForSessionScope(scope);

   // complete the url and return it
   return http::URL::complete(url, path);
}

std::ostream& operator<< (std::ostream& os, const SessionContext& context)
{
   os << context.username;
   if (!context.scope.project().empty())
      os << " -- " << context.scope.project();
   if (!context.scope.id().empty())
      os << " [" << context.scope.id() << "]";
   return os;
}

std::string sessionScopeFile(std::string prefix,
                             const SessionScope& scope)
{
   // resolve project path
   ProjectId projectId = scope.projectId();
   std::string project = scope.isProjectNone() || scope.isWorkspaces() ?
            projectId.id() : projectId.asString();

   if (!project.empty())
   {
      // pluralize in the presence of project context so there
      // is no conflict when switching between single and multi-session
      if (!scope.project().empty())
         prefix += "s";

      if (!boost::algorithm::starts_with(project, "/"))
         project = "/" + project;

      if (!scope.id().empty())
      {
         if (!boost::algorithm::ends_with(project, "/"))
            project = project + "/";
      }
   }

   // return file path
   return prefix + project + scope.id();
}

std::string sessionScopePrefix(const std::string& username)
{
   return username + kSessionSuffix;
}

std::string sessionScopesPrefix(const std::string& username)
{
   // pluralize the prefix so there is no conflict when switching
   // between the single file and directory based schemas
   return username + kSessionSuffix "s";
}

std::string sessionContextFile(const SessionContext& context)
{
   return sessionScopeFile(sessionScopePrefix(context.username), context.scope);
}

std::string generateScopeId()
{
   std::vector<std::string> reserved;

   // reserved ids we are using now
   reserved.push_back(kProjectNoneId);
   reserved.push_back(kWorkspacesId);

   // a few more for future expansion
   reserved.push_back("21f2ed72");
   reserved.push_back("2cb256d2");
   reserved.push_back("3c9ab5a7");
   reserved.push_back("f468a750");
   reserved.push_back("6ae9dc1b");
   reserved.push_back("1d717df9");
   reserved.push_back("6d3c4c0e");
   reserved.push_back("a142989c");
   reserved.push_back("c2612a98");
   reserved.push_back("2b84c99a");

   return generateScopeId(reserved);
}

std::string generateScopeId(const std::vector<std::string>& reserved)
{
   // generate id
   std::string id = core::string_utils::toLower(
                                 core::system::generateShortenedUuid());

   // ensure 8 chracters
   if (id.length() != kProjectIdLen)
   {
      if (id.length() > kProjectIdLen)
      {
         id = id.substr(0, kProjectIdLen);
      }
      else
      {
         size_t diff = kProjectIdLen - id.length();
         std::string pad(diff, 'f');
         id += pad;
      }
   }

   // try again if this id is reserved
   if (std::find(reserved.begin(), reserved.end(), id) != reserved.end())
      return generateScopeId(reserved);
   else
      return id;
}

} // namespace r_util
} // namespace core
} // namespace rstudio

<commit_msg>fix issue in createSessionUrl that was preventing us from picking up proxied url prefixes<commit_after>/*
 * RSessionContext.cpp
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/r_util/RSessionContext.hpp>

#include <iostream>

#include <boost/format.hpp>

#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/algorithm/string/predicate.hpp>

#include <core/FilePath.hpp>
#include <core/Settings.hpp>
#include <core/FileSerializer.hpp>

#include <core/http/Util.hpp>
#include <core/http/URL.hpp>

#include <core/system/System.hpp>
#include <core/system/Environment.hpp>

#include <core/r_util/RActiveSessions.hpp>
#include <core/r_util/RProjectFile.hpp>

#ifndef _WIN32
#include <sys/stat.h>
#endif

#define kSessionSuffix "-d"
#define kProjectNone   "none"

namespace rstudio {
namespace core {
namespace r_util {

SessionScope SessionScope::fromProject(
                               const std::string& project,
                               const std::string& id,
                               const FilePathToProjectId& filePathToProjectId)
{
   if (project != kProjectNone)
   {
      ProjectId projectId = filePathToProjectId(project);
      return SessionScope(projectId, id);
   }
   else
   {
      return projectNone(id);
   }
}

std::string SessionScope::projectPathForScope(
                               const SessionScope& scope,
                               const ProjectIdToFilePath& projectIdToFilePath)
{
   return projectIdToFilePath(scope.projectId());
}

SessionScope SessionScope::fromProjectId(const ProjectId& project,
                                         const std::string& id)
{
   return SessionScope(project, id);
}

SessionScope SessionScope::projectNone(const std::string& id)
{
   return SessionScope(ProjectId(kProjectNoneId), id);
}

bool SessionScope::isProjectNone() const
{
   return project_.id() == kProjectNoneId;
}

bool SessionScope::isWorkspaces() const
{
   return project_.id() == kWorkspacesId;
}

bool isSharedPath(const std::string& projectPath,
                  const core::FilePath& userHomePath)
{
#ifndef _WIN32
   // ensure this is a real path
   FilePath projectDir = FilePath::resolveAliasedPath(projectPath,
                                                      userHomePath);
   if (!projectDir.exists())
      return false;

   struct stat st;
   if (::stat(projectDir.absolutePath().c_str(), &st) == 0)
   {
      // consider this project to be shared if we aren't the owner
      if (st.st_uid != ::geteuid())
      {
         return true;
      }
   }
   else
   {
      Error error = systemError(errno, ERROR_LOCATION);
      error.addProperty("path", projectDir.absolutePath());
      LOG_ERROR(error);
   }

#endif
   return false;
}

SessionScopeState validateSessionScope(const SessionScope& scope,
                          const core::FilePath& userHomePath,
                          const core::FilePath& userScratchPath,
                          core::r_util::ProjectIdToFilePath projectIdToFilePath,
                          bool projectSharingEnabled,
                          std::string* pProjectFilePath)
{
   // does this session exist?
   r_util::ActiveSessions activeSessions(userScratchPath);
   boost::shared_ptr<r_util::ActiveSession> pSession
                                          = activeSessions.get(scope.id());
   if (pSession->empty() || !pSession->validate(userHomePath,
                                                projectSharingEnabled))
      return ScopeInvalidSession;

   // if this isn't project none then check if the project exists
   if (!scope.isProjectNone())
   {
      // lookup the project path by id
      std::string project = r_util::SessionScope::projectPathForScope(
               scope,
               projectIdToFilePath);
      if (project.empty())
         return ScopeMissingProject;

      // if session points to another project then the scope is invalid
      if (project != pSession->project())
         return ScopeInvalidProject;

      // get the path to the project directory
      FilePath projectDir = FilePath::resolveAliasedPath(project, userHomePath);
      if (!projectDir.exists())
         return ScopeMissingProject;

      // get the path to the project file
      FilePath projectPath = r_util::projectFromDirectory(projectDir);
      if (!projectPath.exists())
         return ScopeMissingProject;

      // record path to project file
      *pProjectFilePath = projectPath.absolutePath();
   }
   else
   {
      // if the session project isn't project none then it's invalid
      if (pSession->project() != kProjectNone)
         return ScopeInvalidProject;
   }

   // if we got this far the scope is valid, do one final check for
   // trying to open a shared project if sharing is disabled
   if (!projectSharingEnabled &&
       r_util::isSharedPath(*pProjectFilePath, userHomePath))
   {
      return r_util::ScopeMissingProject;
   }
   else
   {
      return ScopeValid;
   }
}

std::string urlPathForSessionScope(const SessionScope& scope)
{
   // get a URL compatible project path
   std::string project = http::util::urlEncode(scope.projectId().asString());
   boost::algorithm::replace_all(project, "%2F", "/");

   // create url
   boost::format fmt("/s/%1%%2%/");
   return boost::str(fmt % project % scope.id());
}

void parseSessionUrl(const std::string& url,
                     SessionScope* pScope,
                     std::string* pUrlPrefix,
                     std::string* pUrlWithoutPrefix)
{
   static boost::regex re("/s/([A-Fa-f0-9]{5})([A-Fa-f0-9]{8})([A-Fa-f0-9]{8})/");

   boost::smatch match;
   if (boost::regex_search(url, match, re))
   {
      if (pScope)
      {
         std::string user = http::util::urlDecode(match[1]);
         std::string project = http::util::urlDecode(match[2]);
         std::string id = match[3];
         *pScope = r_util::SessionScope::fromProjectId(
                  ProjectId(project, user), id);
      }
      if (pUrlPrefix)
      {
         *pUrlPrefix = match[0];
      }
      if (pUrlWithoutPrefix)
      {
         *pUrlWithoutPrefix = boost::algorithm::replace_first_copy(
                                   url, std::string(match[0]), "/");
      }
   }
   else
   {
      if (pScope)
         *pScope = SessionScope();
      if (pUrlPrefix)
         *pUrlPrefix = std::string();
      if (pUrlWithoutPrefix)
         *pUrlWithoutPrefix = url;
   }
}

std::string createSessionUrl(const std::string& hostPageUrl,
                             const SessionScope& scope)
{
   // build scope path for project (e.g. /s/BAF43..../).
   std::string scopePath = urlPathForSessionScope(scope);

   // determine the host scope path
   std::string hostScopePath;
   parseSessionUrl(hostPageUrl, NULL, &hostScopePath, NULL);

   // if we got a scope path then take everything before
   // it and append our target scope path
   if (!hostScopePath.empty())
   {
      // extract the base url
      size_t pos = hostPageUrl.find(hostScopePath);
      std::string baseUrl = hostPageUrl.substr(0, pos);

      // complete the url and return it
      return baseUrl + scopePath;
   }
   else
   {
      // completely unexpected that we'd pass a host page url
      // with no scope path!  log a warning and just complete
      // against the root of the host page url

      LOG_WARNING_MESSAGE("Attempted to create session url from "
                          "non prefixed host page " + hostPageUrl);

      return http::URL::complete(hostPageUrl, scopePath);
   }
}

std::ostream& operator<< (std::ostream& os, const SessionContext& context)
{
   os << context.username;
   if (!context.scope.project().empty())
      os << " -- " << context.scope.project();
   if (!context.scope.id().empty())
      os << " [" << context.scope.id() << "]";
   return os;
}

std::string sessionScopeFile(std::string prefix,
                             const SessionScope& scope)
{
   // resolve project path
   ProjectId projectId = scope.projectId();
   std::string project = scope.isProjectNone() || scope.isWorkspaces() ?
            projectId.id() : projectId.asString();

   if (!project.empty())
   {
      // pluralize in the presence of project context so there
      // is no conflict when switching between single and multi-session
      if (!scope.project().empty())
         prefix += "s";

      if (!boost::algorithm::starts_with(project, "/"))
         project = "/" + project;

      if (!scope.id().empty())
      {
         if (!boost::algorithm::ends_with(project, "/"))
            project = project + "/";
      }
   }

   // return file path
   return prefix + project + scope.id();
}

std::string sessionScopePrefix(const std::string& username)
{
   return username + kSessionSuffix;
}

std::string sessionScopesPrefix(const std::string& username)
{
   // pluralize the prefix so there is no conflict when switching
   // between the single file and directory based schemas
   return username + kSessionSuffix "s";
}

std::string sessionContextFile(const SessionContext& context)
{
   return sessionScopeFile(sessionScopePrefix(context.username), context.scope);
}

std::string generateScopeId()
{
   std::vector<std::string> reserved;

   // reserved ids we are using now
   reserved.push_back(kProjectNoneId);
   reserved.push_back(kWorkspacesId);

   // a few more for future expansion
   reserved.push_back("21f2ed72");
   reserved.push_back("2cb256d2");
   reserved.push_back("3c9ab5a7");
   reserved.push_back("f468a750");
   reserved.push_back("6ae9dc1b");
   reserved.push_back("1d717df9");
   reserved.push_back("6d3c4c0e");
   reserved.push_back("a142989c");
   reserved.push_back("c2612a98");
   reserved.push_back("2b84c99a");

   return generateScopeId(reserved);
}

std::string generateScopeId(const std::vector<std::string>& reserved)
{
   // generate id
   std::string id = core::string_utils::toLower(
                                 core::system::generateShortenedUuid());

   // ensure 8 chracters
   if (id.length() != kProjectIdLen)
   {
      if (id.length() > kProjectIdLen)
      {
         id = id.substr(0, kProjectIdLen);
      }
      else
      {
         size_t diff = kProjectIdLen - id.length();
         std::string pad(diff, 'f');
         id += pad;
      }
   }

   // try again if this id is reserved
   if (std::find(reserved.begin(), reserved.end(), id) != reserved.end())
      return generateScopeId(reserved);
   else
      return id;
}

} // namespace r_util
} // namespace core
} // namespace rstudio

<|endoftext|>