<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id:  */

//____________________________________________________________________
//
// START - T0.
//
// This class is a singleton that handles various parameters of
// the START detectors.
// Eventually, this class will use the Conditions DB to get the
// various parameters, which code can then request from here.
//
#include "AliLog.h"
#include "AliSTARTParameters.h"
#include "AliSTARTCalibData.h"
#include "AliSTARTAlignData.h"
#include <AliCDBManager.h>
#include <AliCDBEntry.h>
#include <AliCDBStorage.h>
#include <Riostream.h>

AliSTARTAlignData* AliSTARTParameters::fgAlignData = 0;
AliSTARTCalibData* AliSTARTParameters::fgCalibData = 0;
//====================================================================
ClassImp(AliSTARTParameters)
#if 0
  ; // This is here to keep Emacs for indenting the next line
#endif

//____________________________________________________________________
AliSTARTParameters* AliSTARTParameters::fgInstance = 0;
//____________________________________________________________________
AliSTARTParameters*
AliSTARTParameters::Instance()
{
  // Get static instance
  if (!fgInstance) fgInstance = new AliSTARTParameters;
  return fgInstance;
}

//____________________________________________________________________
AliSTARTParameters::AliSTARTParameters()
  : fIsInit(kFALSE)
{
  // Default constructor
  for (Int_t ipmt=0; ipmt<24; ipmt++)
    {
      SetTimeDelayCablesCFD(ipmt);
      SetTimeDelayCablesLED(ipmt);
      SetTimeDelayElectronicCFD(ipmt);
      SetTimeDelayElectronicLED(ipmt);
      SetTimeDelayPMT(ipmt);
      SetVariableDelayLine(ipmt);
      SetSlewingLED(ipmt);
      SetPh2Mip();
      SetChannelWidth();
      SetmV2channel();
      SetGain();
      SetQTmin();
      SetQTmax();
      SetPMTeff(ipmt);
   }
  SetZposition();

}

//__________________________________________________________________
void
AliSTARTParameters::Init()
{
  // Initialize the parameters manager.  We need to get stuff from the
  // CDB here.
  //  if (fIsInit) return;

  AliCDBManager* cdb      = AliCDBManager::Instance();
  cout<<" AliSTARTParameters::Init() CDB "<<cdb<<endl;
  AliCDBStorage *stor = cdb->GetStorage("local://DBLocal");
  fCalibentry  = stor->Get("START/Calib/Gain_TimeDelay_Slewing_Walk",1);
  if (fCalibentry){
   fgCalibData  = (AliSTARTCalibData*)fCalibentry->GetObject();
   cout<<" got calibdata "<<endl;
  }
   fAlignentry     = stor-> Get("START/Align/Positions",1);
  if (fAlignentry){
   fgAlignData  = (AliSTARTAlignData*) fAlignentry->GetObject();
   cout<<" got align data "<<endl;
  }
  cout<<" in INT :: calib "<<fCalibentry<<" align "<<fAlignentry<<endl;

  fIsInit = kTRUE;
}

//__________________________________________________________________
Float_t
AliSTARTParameters::GetGain(Int_t ipmt) const
{
  // Returns the calibrated gain for each PMT
  //

  if (!fCalibentry)
    return fFixedGain;

  return fgCalibData->GetGain(ipmt);
}

//__________________________________________________________________
Float_t
AliSTARTParameters::GetTimeDelayLED(Int_t ipmt)
{
  // return time delay for LED channel
  //
  if (!fCalibentry) {
    fTimeDelayLED = fTimeDelayCablesLED[ipmt] + fTimeDelayElectronicLED[ipmt] + fTimeDelayPMT[ipmt];
    return  fTimeDelayLED;
  }
  return fgCalibData ->GetTimeDelayLED(ipmt);
}
//__________________________________________________________________
Float_t
AliSTARTParameters::GetTimeDelayCFD(Int_t ipmt)
{
  // return time delay for CFD channel
   //
  if (!fCalibentry)
    {
      fTimeDelayCFD = fTimeDelayCablesCFD[ipmt] + fTimeDelayElectronicCFD[ipmt] + fTimeDelayPMT[ipmt] + fVariableDelayLine[ipmt];
      return fTimeDelayCFD;
    }

  return fgCalibData->GetTimeDelayCFD(ipmt);
}

//__________________________________________________________________

void
AliSTARTParameters::SetSlewingLED(Int_t ipmt)
{
  //  Set Slweing Correction for LED channel

  Float_t mv[23] = {25, 30,40,60, 80,100,150,200,250,300,400,500,600,800,1000,1500, 2000, 3000, 4000, 5500, 6000, 7000,8000};
  Float_t y[23] = {5044, 4719, 3835, 3224, 2847, 2691,2327,  1937, 1781, 1560, 1456 ,1339, 1163.5, 1027, 819, 650, 520, 370.5, 234, 156, 78, 0};

  TGraph* gr = new TGraph(23,mv,y);
  fSlewingLED.AddAtAndExpand(gr,ipmt);
 }
//__________________________________________________________________
void
AliSTARTParameters::SetPMTeff(Int_t ipmt)
{
  Float_t lambda[50];
  Float_t eff[50 ] = {0,        0,       0.23619,  0.202909, 0.177913,
		    0.175667, 0.17856, 0.190769, 0.206667, 0.230286,
		    0.252276, 0.256267,0.26,     0.27125,  0.281818,
		    0.288118, 0.294057,0.296222, 0.301622, 0.290421,
		    0.276615, 0.2666,  0.248,    0.23619,  0.227814,
		    0.219818, 0.206667,0.194087, 0.184681, 0.167917,
		    0.154367, 0.1364,  0.109412, 0.0834615,0.0725283,
		    0.0642963,0.05861, 0.0465,   0.0413333,0.032069,
		    0.0252203,0.02066, 0.016262, 0.012,    0.00590476,
		    0.003875, 0.00190, 0,        0,        0          } ;
  for (Int_t i=0; i<50; i++) lambda[i]=200+10*i;

  TGraph* gr = new TGraph(50,lambda,eff);
  fPMTeff.AddAtAndExpand(gr,ipmt);
}
<commit_msg>Setting default CDB storage<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id:  */

//____________________________________________________________________
//
// START - T0.
//
// This class is a singleton that handles various parameters of
// the START detectors.
// Eventually, this class will use the Conditions DB to get the
// various parameters, which code can then request from here.
//
#include "AliLog.h"
#include "AliSTARTParameters.h"
#include "AliSTARTCalibData.h"
#include "AliSTARTAlignData.h"
#include <AliCDBManager.h>
#include <AliCDBEntry.h>
#include <AliCDBStorage.h>
#include <Riostream.h>

AliSTARTAlignData* AliSTARTParameters::fgAlignData = 0;
AliSTARTCalibData* AliSTARTParameters::fgCalibData = 0;
//====================================================================
ClassImp(AliSTARTParameters)
#if 0
  ; // This is here to keep Emacs for indenting the next line
#endif

//____________________________________________________________________
AliSTARTParameters* AliSTARTParameters::fgInstance = 0;
//____________________________________________________________________
AliSTARTParameters*
AliSTARTParameters::Instance()
{
  // Get static instance
  if (!fgInstance) fgInstance = new AliSTARTParameters;
  return fgInstance;
}

//____________________________________________________________________
AliSTARTParameters::AliSTARTParameters()
  : fIsInit(kFALSE)
{
  // Default constructor
  for (Int_t ipmt=0; ipmt<24; ipmt++)
    {
      SetTimeDelayCablesCFD(ipmt);
      SetTimeDelayCablesLED(ipmt);
      SetTimeDelayElectronicCFD(ipmt);
      SetTimeDelayElectronicLED(ipmt);
      SetTimeDelayPMT(ipmt);
      SetVariableDelayLine(ipmt);
      SetSlewingLED(ipmt);
      SetPh2Mip();
      SetChannelWidth();
      SetmV2channel();
      SetGain();
      SetQTmin();
      SetQTmax();
      SetPMTeff(ipmt);
   }
  SetZposition();

}

//__________________________________________________________________
void
AliSTARTParameters::Init()
{
  // Initialize the parameters manager.  We need to get stuff from the
  // CDB here.
  //  if (fIsInit) return;

  AliCDBManager* cdb      = AliCDBManager::Instance();
  cout<<" AliSTARTParameters::Init() CDB "<<cdb<<endl;
  AliCDBStorage *stor = cdb->GetStorage("local://$ALICE_ROOT");
  fCalibentry  = stor->Get("START/Calib/Gain_TimeDelay_Slewing_Walk",1);
  if (fCalibentry){
   fgCalibData  = (AliSTARTCalibData*)fCalibentry->GetObject();
   cout<<" got calibdata "<<endl;
  }
   fAlignentry     = stor-> Get("START/Align/Positions",1);
  if (fAlignentry){
   fgAlignData  = (AliSTARTAlignData*) fAlignentry->GetObject();
   cout<<" got align data "<<endl;
  }
  cout<<" in INT :: calib "<<fCalibentry<<" align "<<fAlignentry<<endl;

  fIsInit = kTRUE;
}

//__________________________________________________________________
Float_t
AliSTARTParameters::GetGain(Int_t ipmt) const
{
  // Returns the calibrated gain for each PMT
  //

  if (!fCalibentry)
    return fFixedGain;

  return fgCalibData->GetGain(ipmt);
}

//__________________________________________________________________
Float_t
AliSTARTParameters::GetTimeDelayLED(Int_t ipmt)
{
  // return time delay for LED channel
  //
  if (!fCalibentry) {
    fTimeDelayLED = fTimeDelayCablesLED[ipmt] + fTimeDelayElectronicLED[ipmt] + fTimeDelayPMT[ipmt];
    return  fTimeDelayLED;
  }
  return fgCalibData ->GetTimeDelayLED(ipmt);
}
//__________________________________________________________________
Float_t
AliSTARTParameters::GetTimeDelayCFD(Int_t ipmt)
{
  // return time delay for CFD channel
   //
  if (!fCalibentry)
    {
      fTimeDelayCFD = fTimeDelayCablesCFD[ipmt] + fTimeDelayElectronicCFD[ipmt] + fTimeDelayPMT[ipmt] + fVariableDelayLine[ipmt];
      return fTimeDelayCFD;
    }

  return fgCalibData->GetTimeDelayCFD(ipmt);
}

//__________________________________________________________________

void
AliSTARTParameters::SetSlewingLED(Int_t ipmt)
{
  //  Set Slweing Correction for LED channel

  Float_t mv[23] = {25, 30,40,60, 80,100,150,200,250,300,400,500,600,800,1000,1500, 2000, 3000, 4000, 5500, 6000, 7000,8000};
  Float_t y[23] = {5044, 4719, 3835, 3224, 2847, 2691,2327,  1937, 1781, 1560, 1456 ,1339, 1163.5, 1027, 819, 650, 520, 370.5, 234, 156, 78, 0};

  TGraph* gr = new TGraph(23,mv,y);
  fSlewingLED.AddAtAndExpand(gr,ipmt);
 }
//__________________________________________________________________
void
AliSTARTParameters::SetPMTeff(Int_t ipmt)
{
  Float_t lambda[50];
  Float_t eff[50 ] = {0,        0,       0.23619,  0.202909, 0.177913,
		    0.175667, 0.17856, 0.190769, 0.206667, 0.230286,
		    0.252276, 0.256267,0.26,     0.27125,  0.281818,
		    0.288118, 0.294057,0.296222, 0.301622, 0.290421,
		    0.276615, 0.2666,  0.248,    0.23619,  0.227814,
		    0.219818, 0.206667,0.194087, 0.184681, 0.167917,
		    0.154367, 0.1364,  0.109412, 0.0834615,0.0725283,
		    0.0642963,0.05861, 0.0465,   0.0413333,0.032069,
		    0.0252203,0.02066, 0.016262, 0.012,    0.00590476,
		    0.003875, 0.00190, 0,        0,        0          } ;
  for (Int_t i=0; i<50; i++) lambda[i]=200+10*i;

  TGraph* gr = new TGraph(50,lambda,eff);
  fPMTeff.AddAtAndExpand(gr,ipmt);
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <msctf.h>

#include "hooks.h"
#include "msctfhooks.h"

void MSCTFHooks_PostInsertTextAtSelection(ITfInsertAtSelection *This, TfEditCookie ec, DWORD dwFlags, const WCHAR *pchText, LONG cchText, ITfRange **ppRange)
{
	ThreadIn ti;
	if (!HooksActive())
		return;
	LastErrorSave les;
	HookSuspension hs;
	HWND hwndMaster = FindWindowEx(HWND_MESSAGE, nullptr, TEXT("DictationBridgeMaster"), nullptr);
	if (hwndMaster == nullptr)
	{
		return;
	}
	ITfRange* range = nullptr;
	if (ppRange != nullptr)
	{
		range = *ppRange;
	}
	if (range != nullptr)
	{
		MSCTFHooks_HookRange(range);
		ITfContext* ctx = nullptr;
		range->GetContext(&ctx);
		if (ctx != nullptr)
		{
			ITfContextView* view = nullptr;
			ctx->GetActiveView(&view);
			if (view != nullptr)
			{
				HWND hwnd = nullptr;
				view->GetWnd(&hwnd);
				ITfRangeACP* rangeACP = nullptr;
				range->QueryInterface(IID_ITfRangeACP, (void**) &rangeACP);
				if (rangeACP != nullptr)
				{
					LONG acpAnchor = -1, cchRange = -1;
					if (rangeACP->GetExtent(&acpAnchor, &cchRange) == S_OK)
					{
						DWORD cbData = (sizeof(DWORD) * 3) + (cchText * sizeof(WCHAR));
						BYTE* data = new BYTE[cbData];
						DWORD tmp = (DWORD)((__int64)hwnd & 0xffffffff);
						memcpy(data, &tmp, sizeof(tmp));
						tmp = (DWORD)acpAnchor;
						memcpy(data + sizeof(DWORD), &tmp, sizeof(tmp));
						tmp = (DWORD)cchRange;
						memcpy(data + sizeof(DWORD) * 2, &tmp, sizeof(tmp));
						memcpy(data + sizeof(DWORD) * 3, pchText, cchText * sizeof(WCHAR));
						COPYDATASTRUCT cds;
						cds.dwData = 0;
						cds.lpData = (PVOID) data;
						cds.cbData = cbData;
						DWORD_PTR result;
						SendMessageTimeout(hwndMaster, WM_COPYDATA, 0, (LPARAM) &cds, SMTO_BLOCK, 1000, &result);
						delete[] data;
					}
					rangeACP->Release();
				}
				view->Release();
			}
			ctx->Release();
		}
	}
}

void MSCTFHooks_PreSetText(ITfRange *This, TfEditCookie ec, DWORD dwFlags, const WCHAR *pchText, LONG cch)
{
	ThreadIn ti;
	if (!HooksActive())
		return;
	LastErrorSave les;
	HookSuspension hs;
	HWND hwndMaster = FindWindowEx(HWND_MESSAGE, nullptr, TEXT("DictationBridgeMaster"), nullptr);
	if (hwndMaster == nullptr)
	{
		return;
	}
	if (cch == 0)
	{
		WCHAR pchOrigText[512];
		ULONG cchOrigText;
		HRESULT hr = This->GetText(ec, 0, pchOrigText, ARRAYSIZE(pchOrigText), &cchOrigText);
		if (hr == S_OK && cchOrigText > 0)
		{
			HWND hwnd = nullptr;
			ITfContext* ctx = nullptr;
			This->GetContext(&ctx);
			if (ctx != nullptr)
			{
				ITfContextView* view = nullptr;
				ctx->GetActiveView(&view);
				if (view != nullptr)
				{
					view->GetWnd(&hwnd);
				}
			}
			DWORD selStart = -1;
			DWORD cbData = (sizeof(DWORD) * 3) + (cchOrigText * sizeof(WCHAR));
			BYTE* data = new BYTE[cbData];
			DWORD tmp = (DWORD)((__int64)hwnd & 0xffffffff);
			memcpy(data, &tmp, sizeof(tmp));
			tmp = (DWORD)selStart;
			memcpy(data + sizeof(DWORD), &tmp, sizeof(tmp));
			tmp = (DWORD)cchOrigText;
			memcpy(data + sizeof(DWORD) * 2, &tmp, sizeof(tmp));
			memcpy(data + sizeof(DWORD) * 3, pchOrigText, cchOrigText * sizeof(WCHAR));
			COPYDATASTRUCT cds;
			cds.dwData = 2;
			cds.lpData = (PVOID) data;
			cds.cbData = cbData;
			DWORD_PTR result;
			SendMessageTimeout(hwndMaster, WM_COPYDATA, 0, (LPARAM) &cds, SMTO_BLOCK, 1000, &result);
			delete[] data;
		}
	}
}
<commit_msg>Eliminate extraneous 'new paragraph' messages<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <msctf.h>

#include "hooks.h"
#include "msctfhooks.h"

void MSCTFHooks_PostInsertTextAtSelection(ITfInsertAtSelection *This, TfEditCookie ec, DWORD dwFlags, const WCHAR *pchText, LONG cchText, ITfRange **ppRange)
{
	ThreadIn ti;
	if (cchText <= 0)
		return;
	if (!HooksActive())
		return;
	LastErrorSave les;
	HookSuspension hs;
	HWND hwndMaster = FindWindowEx(HWND_MESSAGE, nullptr, TEXT("DictationBridgeMaster"), nullptr);
	if (hwndMaster == nullptr)
	{
		return;
	}
	ITfRange* range = nullptr;
	if (ppRange != nullptr)
	{
		range = *ppRange;
	}
	if (range != nullptr)
	{
		MSCTFHooks_HookRange(range);
		ITfContext* ctx = nullptr;
		range->GetContext(&ctx);
		if (ctx != nullptr)
		{
			ITfContextView* view = nullptr;
			ctx->GetActiveView(&view);
			if (view != nullptr)
			{
				HWND hwnd = nullptr;
				view->GetWnd(&hwnd);
				ITfRangeACP* rangeACP = nullptr;
				range->QueryInterface(IID_ITfRangeACP, (void**) &rangeACP);
				if (rangeACP != nullptr)
				{
					LONG acpAnchor = -1, cchRange = -1;
					if (rangeACP->GetExtent(&acpAnchor, &cchRange) == S_OK)
					{
						DWORD cbData = (sizeof(DWORD) * 3) + (cchText * sizeof(WCHAR));
						BYTE* data = new BYTE[cbData];
						DWORD tmp = (DWORD)((__int64)hwnd & 0xffffffff);
						memcpy(data, &tmp, sizeof(tmp));
						tmp = (DWORD)acpAnchor;
						memcpy(data + sizeof(DWORD), &tmp, sizeof(tmp));
						tmp = (DWORD)cchRange;
						memcpy(data + sizeof(DWORD) * 2, &tmp, sizeof(tmp));
						memcpy(data + sizeof(DWORD) * 3, pchText, cchText * sizeof(WCHAR));
						COPYDATASTRUCT cds;
						cds.dwData = 0;
						cds.lpData = (PVOID) data;
						cds.cbData = cbData;
						DWORD_PTR result;
						SendMessageTimeout(hwndMaster, WM_COPYDATA, 0, (LPARAM) &cds, SMTO_BLOCK, 1000, &result);
						delete[] data;
					}
					rangeACP->Release();
				}
				view->Release();
			}
			ctx->Release();
		}
	}
}

void MSCTFHooks_PreSetText(ITfRange *This, TfEditCookie ec, DWORD dwFlags, const WCHAR *pchText, LONG cch)
{
	ThreadIn ti;
	if (!HooksActive())
		return;
	LastErrorSave les;
	HookSuspension hs;
	HWND hwndMaster = FindWindowEx(HWND_MESSAGE, nullptr, TEXT("DictationBridgeMaster"), nullptr);
	if (hwndMaster == nullptr)
	{
		return;
	}
	if (cch == 0)
	{
		WCHAR pchOrigText[512];
		ULONG cchOrigText;
		HRESULT hr = This->GetText(ec, 0, pchOrigText, ARRAYSIZE(pchOrigText), &cchOrigText);
		if (hr == S_OK && cchOrigText > 0)
		{
			HWND hwnd = nullptr;
			ITfContext* ctx = nullptr;
			This->GetContext(&ctx);
			if (ctx != nullptr)
			{
				ITfContextView* view = nullptr;
				ctx->GetActiveView(&view);
				if (view != nullptr)
				{
					view->GetWnd(&hwnd);
				}
			}
			DWORD selStart = -1;
			DWORD cbData = (sizeof(DWORD) * 3) + (cchOrigText * sizeof(WCHAR));
			BYTE* data = new BYTE[cbData];
			DWORD tmp = (DWORD)((__int64)hwnd & 0xffffffff);
			memcpy(data, &tmp, sizeof(tmp));
			tmp = (DWORD)selStart;
			memcpy(data + sizeof(DWORD), &tmp, sizeof(tmp));
			tmp = (DWORD)cchOrigText;
			memcpy(data + sizeof(DWORD) * 2, &tmp, sizeof(tmp));
			memcpy(data + sizeof(DWORD) * 3, pchOrigText, cchOrigText * sizeof(WCHAR));
			COPYDATASTRUCT cds;
			cds.dwData = 2;
			cds.lpData = (PVOID) data;
			cds.cbData = cbData;
			DWORD_PTR result;
			SendMessageTimeout(hwndMaster, WM_COPYDATA, 0, (LPARAM) &cds, SMTO_BLOCK, 1000, &result);
			delete[] data;
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Matthew Malensek.
// Distributed under the BSD 2-Clause License (see LICENSE.txt for details)

#include "Updater.h"

#pragma comment(lib, "Urlmon.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "wininet.lib")

#include <Windows.h>
#include <WinInet.h>
#include <sstream>

#include "../../3RVX/Settings.h"
#include "../../3RVX/StringUtils.h"
#include "../../3RVX/Logger.h"
#include "../Controls/StatusCallback.h"
#include "Version.h"

const std::wstring Updater::DOWNLOAD_URL
    = L"https://3rvx.com/releases/";

/* Since this const depends on DOWNLOAD_URL, it needs to be defined after it. */
const std::wstring Updater::LATEST_URL
    = Updater::DOWNLOAD_URL + L"latest_version";

bool Updater::NewerVersionAvailable() {
    Version remote = RemoteVersion();
    Version local = MainAppVersion();
    CLOG(L"Remote version: %s\n Local version: %s",
        remote.ToString().c_str(),
        local.ToString().c_str());

    if (remote.ToInt() == 0 || local.ToInt() == 0) {
        /* One of the version checks failed, so say that there is no new
         * version. No need to bother the user with (hopefully) temporary
         * errors. */
        return false;
    }

    if (remote.ToInt() > local.ToInt()) {
        return true;
    } else {
        return false;
    }
}

Version Updater::MainAppVersion() {
    std::wstring mainExe = Settings::Instance()->MainApp();
    BOOL result;

    DWORD size = GetFileVersionInfoSize(mainExe.c_str(), NULL);
    if (size == 0) {
        CLOG(L"Could not determine version info size");
        return { 0, 0, 0 };
    }

    unsigned char *block = new unsigned char[size];
    result = GetFileVersionInfo(mainExe.c_str(), NULL, size, block);
    if (result == 0) {
        CLOG(L"Failed to retrieve file version info");
        delete[] block;
        return { 0, 0, 0 };
    }

    unsigned int dataSz;
    VS_FIXEDFILEINFO *vers;
    result = VerQueryValue(block, L"\\", (void **) &vers, &dataSz);
    if (result == 0) {
        CLOG(L"Could not query root block for version info");
        delete[] block;
        return { 0, 0, 0 };
    }

    if (vers->dwSignature != 0xFEEF04BD) {
        CLOG(L"Invalid version signature");
        delete[] block;
        return { 0, 0, 0 };
    }

    unsigned long verms = vers->dwProductVersionMS;
    int hi = (verms >> 16) & 0xFF;
    int lo = verms & 0xFF;

    unsigned long verls = vers->dwProductVersionLS;
    int rev = (verls >> 16) & 0xFF;

    delete[] block;
    return Version(hi, lo, rev);
}

std::wstring Updater::DownloadVersion(Version version, DownloadStatus *ds) {
    wchar_t path[MAX_PATH];
    DWORD result = GetTempPath(MAX_PATH, path);
    if (result == 0) {
        CLOG(L"Could not get temp download path");
        return L"";
    }

    std::wstring tempDir(path);
    std::wstring fname = DownloadFileName(version);
    std::wstring url = DOWNLOAD_URL + fname;
    std::wstring localFile = tempDir + L"\\" + fname;

    CLOG(L"Downloading %s to %s...", url.c_str(), localFile.c_str());
    DeleteUrlCacheEntry(url.c_str());
    HRESULT hr = URLDownloadToFile(
        NULL,
        url.c_str(),
        localFile.c_str(),
        0,
        ds);

    if (hr == S_OK) {
        return localFile;
    } else {
        return L"";
    }
}

std::wstring Updater::DownloadFileName(Version version) {
    std::wstring ext;
    if (Settings::Portable()) {
        ext = L".zip";
    } else {
        ext = L".msi";
    }
    return std::wstring(L"3RVX-" + version.ToString() + ext);
}

Version Updater::RemoteVersion() {
    HINTERNET internet = InternetOpen(
        L"3RVX Updater",
        INTERNET_OPEN_TYPE_PRECONFIG,
        NULL,
        NULL,
        NULL);

    CLOG(L"Opening URL: %s", LATEST_URL.c_str());
    HINTERNET connection = InternetOpenUrl(
        internet,
        LATEST_URL.c_str(),
        NULL,
        0,
        INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE,
        0);

    if (connection == NULL) {
        CLOG(L"Could not connect to URL!");
        return { 0, 0, 0 };
    }

    std::string str("");
    char buf[32];
    DWORD read;
    while (InternetReadFile(connection, buf, 16, &read) == TRUE && read != 0) {
        str.append(buf);
    }

    /* Only consider the first line */
    str.erase(str.find('\n'), str.size() - 1);

    size_t dot = str.find('.');
    size_t dot2 = str.find('.', dot + 1);
    std::string major = str.substr(0, dot);
    std::string minor = str.substr(dot + 1, dot2);
    std::string rev = str.substr(dot2 + 1, str.size());
    return Version(std::stoi(major), std::stoi(minor), std::stoi(rev));
}<commit_msg>More updates for StatusCallback rename<commit_after>// Copyright (c) 2015, Matthew Malensek.
// Distributed under the BSD 2-Clause License (see LICENSE.txt for details)

#include "Updater.h"

#pragma comment(lib, "Urlmon.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "wininet.lib")

#include <Windows.h>
#include <WinInet.h>
#include <sstream>

#include "../../3RVX/Settings.h"
#include "../../3RVX/StringUtils.h"
#include "../../3RVX/Logger.h"
#include "../Controls/StatusCallback.h"
#include "Version.h"

const std::wstring Updater::DOWNLOAD_URL
    = L"https://3rvx.com/releases/";

/* Since this const depends on DOWNLOAD_URL, it needs to be defined after it. */
const std::wstring Updater::LATEST_URL
    = Updater::DOWNLOAD_URL + L"latest_version";

bool Updater::NewerVersionAvailable() {
    Version remote = RemoteVersion();
    Version local = MainAppVersion();
    CLOG(L"Remote version: %s\n Local version: %s",
        remote.ToString().c_str(),
        local.ToString().c_str());

    if (remote.ToInt() == 0 || local.ToInt() == 0) {
        /* One of the version checks failed, so say that there is no new
         * version. No need to bother the user with (hopefully) temporary
         * errors. */
        return false;
    }

    if (remote.ToInt() > local.ToInt()) {
        return true;
    } else {
        return false;
    }
}

Version Updater::MainAppVersion() {
    std::wstring mainExe = Settings::Instance()->MainApp();
    BOOL result;

    DWORD size = GetFileVersionInfoSize(mainExe.c_str(), NULL);
    if (size == 0) {
        CLOG(L"Could not determine version info size");
        return { 0, 0, 0 };
    }

    unsigned char *block = new unsigned char[size];
    result = GetFileVersionInfo(mainExe.c_str(), NULL, size, block);
    if (result == 0) {
        CLOG(L"Failed to retrieve file version info");
        delete[] block;
        return { 0, 0, 0 };
    }

    unsigned int dataSz;
    VS_FIXEDFILEINFO *vers;
    result = VerQueryValue(block, L"\\", (void **) &vers, &dataSz);
    if (result == 0) {
        CLOG(L"Could not query root block for version info");
        delete[] block;
        return { 0, 0, 0 };
    }

    if (vers->dwSignature != 0xFEEF04BD) {
        CLOG(L"Invalid version signature");
        delete[] block;
        return { 0, 0, 0 };
    }

    unsigned long verms = vers->dwProductVersionMS;
    int hi = (verms >> 16) & 0xFF;
    int lo = verms & 0xFF;

    unsigned long verls = vers->dwProductVersionLS;
    int rev = (verls >> 16) & 0xFF;

    delete[] block;
    return Version(hi, lo, rev);
}

std::wstring Updater::DownloadVersion(Version version, StatusCallback *cb) {
    wchar_t path[MAX_PATH];
    DWORD result = GetTempPath(MAX_PATH, path);
    if (result == 0) {
        CLOG(L"Could not get temp download path");
        return L"";
    }

    std::wstring tempDir(path);
    std::wstring fname = DownloadFileName(version);
    std::wstring url = DOWNLOAD_URL + fname;
    std::wstring localFile = tempDir + L"\\" + fname;

    CLOG(L"Downloading %s to %s...", url.c_str(), localFile.c_str());
    DeleteUrlCacheEntry(url.c_str());
    HRESULT hr = URLDownloadToFile(
        NULL,
        url.c_str(),
        localFile.c_str(),
        0,
        cb);

    if (hr == S_OK) {
        return localFile;
    } else {
        return L"";
    }
}

std::wstring Updater::DownloadFileName(Version version) {
    std::wstring ext;
    if (Settings::Portable()) {
        ext = L".zip";
    } else {
        ext = L".msi";
    }
    return std::wstring(L"3RVX-" + version.ToString() + ext);
}

Version Updater::RemoteVersion() {
    HINTERNET internet = InternetOpen(
        L"3RVX Updater",
        INTERNET_OPEN_TYPE_PRECONFIG,
        NULL,
        NULL,
        NULL);

    CLOG(L"Opening URL: %s", LATEST_URL.c_str());
    HINTERNET connection = InternetOpenUrl(
        internet,
        LATEST_URL.c_str(),
        NULL,
        0,
        INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE,
        0);

    if (connection == NULL) {
        CLOG(L"Could not connect to URL!");
        return { 0, 0, 0 };
    }

    std::string str("");
    char buf[32];
    DWORD read;
    while (InternetReadFile(connection, buf, 16, &read) == TRUE && read != 0) {
        str.append(buf);
    }

    /* Only consider the first line */
    str.erase(str.find('\n'), str.size() - 1);

    size_t dot = str.find('.');
    size_t dot2 = str.find('.', dot + 1);
    std::string major = str.substr(0, dot);
    std::string minor = str.substr(dot + 1, dot2);
    std::string rev = str.substr(dot2 + 1, str.size());
    return Version(std::stoi(major), std::stoi(minor), std::stoi(rev));
}<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS ooo19126 (1.3.452); FILE MERGED 2005/09/05 15:00:31 rt 1.3.452.1: #i54170# Change license header: remove SISSL<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/runtime/browser/xwalk_browser_main_parts.h"

#include <string>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
#include "xwalk/application/browser/application_process_manager.h"
#include "xwalk/application/browser/application_system.h"
#include "xwalk/application/common/application.h"
#include "xwalk/application/common/application_file_util.h"
#include "xwalk/application/common/application_manifest_constants.h"
#include "xwalk/experimental/dialog/dialog_extension.h"
#include "xwalk/extensions/browser/xwalk_extension_service.h"
#include "xwalk/runtime/browser/devtools/remote_debugging_server.h"
#include "xwalk/runtime/browser/runtime.h"
#include "xwalk/runtime/browser/runtime_context.h"
#include "xwalk/runtime/browser/runtime_registry.h"
#include "xwalk/runtime/common/xwalk_switches.h"
#include "xwalk/runtime/extension/runtime_extension.h"
#include "cc/base/switches.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/result_codes.h"
#include "grit/net_resources.h"
#include "net/base/net_util.h"
#include "net/base/net_module.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"

#if defined(OS_ANDROID)
#include "content/public/browser/android/compositor.h"
#include "net/android/network_change_notifier_factory_android.h"
#include "net/base/network_change_notifier.h"
#include "ui/base/l10n/l10n_util_android.h"
#endif  // defined(OS_ANDROID)

namespace {

base::StringPiece PlatformResourceProvider(int key) {
  if (key == IDR_DIR_HEADER_HTML) {
    base::StringPiece html_data =
        ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
            IDR_DIR_HEADER_HTML);
    return html_data;
  }
  return base::StringPiece();
}

}  // namespace

namespace xwalk {

XWalkBrowserMainParts::XWalkBrowserMainParts(
    const content::MainFunctionParams& parameters)
    : BrowserMainParts(),
      startup_url_(content::kAboutBlankURL),
      parameters_(parameters),
      run_default_message_loop_(true) {
}

XWalkBrowserMainParts::~XWalkBrowserMainParts() {
}

#if defined(OS_ANDROID)
void XWalkBrowserMainParts::SetRuntimeContext(RuntimeContext* context) {
  runtime_context_ = context;
}
#endif

void XWalkBrowserMainParts::PreMainMessageLoopStart() {
#if defined(OS_ANDROID)
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableWebRTC);
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kAllowFileAccessFromFiles);
  // WebGL is disabled by default on Android, explicitly enable it in switches.
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalWebGL);
#endif

#if !defined(OS_ANDROID)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  const CommandLine::StringVector& args = command_line->GetArgs();

  if (args.empty())
    return;

  GURL url(args[0]);
  if (url.is_valid() && url.has_scheme()) {
    startup_url_ = url;
  } else {
    base::FilePath path(args[0]);
    if (!path.IsAbsolute())
      path = MakeAbsoluteFilePath(path);
    startup_url_ = net::FilePathToFileURL(path);
  }
#endif

#if defined(OS_MACOSX)
    PreMainMessageLoopStartMac();
#endif
}

void XWalkBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_ANDROID)
  MessageLoopForUI::current()->Start();
#endif
}

void XWalkBrowserMainParts::PreEarlyInitialization() {
#if defined(OS_ANDROID)
  net::NetworkChangeNotifier::SetFactory(
      new net::NetworkChangeNotifierFactoryAndroid());

  CommandLine::ForCurrentProcess()->AppendSwitch(
      cc::switches::kCompositeToMailbox);

  // Initialize the Compositor.
  content::Compositor::Initialize();
#endif

#if defined(OS_LINUX)
  // FIXME: Issue 496. We need to explicitly disable sandboxing on Linux while
  // we do not support it (ie. ship the appropriate binary), otherwise we will
  // crash on startup.
  CommandLine::ForCurrentProcess()->AppendSwitch(switches::kNoSandbox);
#endif
}

int XWalkBrowserMainParts::PreCreateThreads() {
#if defined(OS_ANDROID)
  DCHECK(runtime_context_);
  runtime_context_->InitializeBeforeThreadCreation();
#endif
  return content::RESULT_CODE_NORMAL_EXIT;
}

void XWalkBrowserMainParts::RegisterExternalExtensions() {
  CommandLine* cmd_line = CommandLine::ForCurrentProcess();
  if (!cmd_line->HasSwitch(switches::kXWalkExternalExtensionsPath))
    return;

  if (!cmd_line->HasSwitch(
          switches::kXWalkAllowExternalExtensionsForRemoteSources) &&
      !startup_url_.SchemeIsFile()) {
    VLOG(0) << "Unsupported scheme for external extensions: " <<
          startup_url_.scheme();
    return;
  }

  base::FilePath extensions_dir =
      cmd_line->GetSwitchValuePath(switches::kXWalkExternalExtensionsPath);
  if (!file_util::DirectoryExists(extensions_dir)) {
    LOG(WARNING) << "Ignoring non-existent extension directory: "
                 << extensions_dir.AsUTF8Unsafe();
    return;
  }

  extension_service_->RegisterExternalExtensionsForPath(extensions_dir);
}

void XWalkBrowserMainParts::PreMainMessageLoopRun() {
#if defined(OS_ANDROID)
  net::NetModule::SetResourceProvider(PlatformResourceProvider);
  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_default_message_loop_ = false;
  }

  DCHECK(runtime_context_);
  runtime_context_->PreMainMessageLoopRun();
#else
  runtime_context_.reset(new RuntimeContext);
  runtime_registry_.reset(new RuntimeRegistry);
  extension_service_.reset(
      new extensions::XWalkExtensionService(runtime_registry_.get()));

  RegisterInternalExtensions();
  RegisterExternalExtensions();

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
    std::string port_str =
        command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    int port;
    const char* loopback_ip = "127.0.0.1";
    if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) {
      remote_debugging_server_.reset(
          new RemoteDebuggingServer(runtime_context_.get(),
              loopback_ip, port, std::string()));
    }
  }

  NativeAppWindow::Initialize();

  if (startup_url_.SchemeIsFile()) {
    base::FilePath path;
    if (!net::FileURLToFilePath(startup_url_, &path))
      return;
    if (file_util::DirectoryExists(path)) {
      std::string error;
      scoped_refptr<xwalk::application::Application> application =
          xwalk::application::LoadApplication(
              path,
              xwalk::application::Manifest::COMMAND_LINE,
              &error);
      if (!error.empty())
        LOG(ERROR) << "Failed to load application: " << error;
      if (application != NULL) {
        xwalk::application::ApplicationSystem* system =
            runtime_context_->GetApplicationSystem();
        xwalk::application::ApplicationProcessManager* manager =
            system->process_manager();
        manager->LaunchApplication(runtime_context_.get(), application);
        return;
      }
    }
  }

  // The new created Runtime instance will be managed by RuntimeRegistry.
  Runtime::Create(runtime_context_.get(), startup_url_);

  // If the |ui_task| is specified in main function parameter, it indicates
  // that we will run this UI task instead of running the the default main
  // message loop. See |content::BrowserTestBase::SetUp| for |ui_task| usage
  // case.
  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_default_message_loop_ = false;
  }
#endif
}

bool XWalkBrowserMainParts::MainMessageLoopRun(int* result_code) {
  return !run_default_message_loop_;
}

void XWalkBrowserMainParts::PostMainMessageLoopRun() {
#if defined(OS_ANDROID)
  MessageLoopForUI::current()->Start();
#else
  runtime_context_.reset();
#endif
}

void XWalkBrowserMainParts::RegisterInternalExtensions() {
  extension_service_->RegisterExtension(scoped_ptr<XWalkExtension>(
      new RuntimeExtension()));
  extension_service_->RegisterExtension(scoped_ptr<XWalkExtension>(
      new experimental::DialogExtension(runtime_registry_.get())));
}

}  // namespace xwalk
<commit_msg>[Android] WebRTC is now enabled by default on android.<commit_after>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/runtime/browser/xwalk_browser_main_parts.h"

#include <string>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
#include "xwalk/application/browser/application_process_manager.h"
#include "xwalk/application/browser/application_system.h"
#include "xwalk/application/common/application.h"
#include "xwalk/application/common/application_file_util.h"
#include "xwalk/application/common/application_manifest_constants.h"
#include "xwalk/experimental/dialog/dialog_extension.h"
#include "xwalk/extensions/browser/xwalk_extension_service.h"
#include "xwalk/runtime/browser/devtools/remote_debugging_server.h"
#include "xwalk/runtime/browser/runtime.h"
#include "xwalk/runtime/browser/runtime_context.h"
#include "xwalk/runtime/browser/runtime_registry.h"
#include "xwalk/runtime/common/xwalk_switches.h"
#include "xwalk/runtime/extension/runtime_extension.h"
#include "cc/base/switches.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/result_codes.h"
#include "grit/net_resources.h"
#include "net/base/net_util.h"
#include "net/base/net_module.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"

#if defined(OS_ANDROID)
#include "content/public/browser/android/compositor.h"
#include "net/android/network_change_notifier_factory_android.h"
#include "net/base/network_change_notifier.h"
#include "ui/base/l10n/l10n_util_android.h"
#endif  // defined(OS_ANDROID)

namespace {

base::StringPiece PlatformResourceProvider(int key) {
  if (key == IDR_DIR_HEADER_HTML) {
    base::StringPiece html_data =
        ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
            IDR_DIR_HEADER_HTML);
    return html_data;
  }
  return base::StringPiece();
}

}  // namespace

namespace xwalk {

XWalkBrowserMainParts::XWalkBrowserMainParts(
    const content::MainFunctionParams& parameters)
    : BrowserMainParts(),
      startup_url_(content::kAboutBlankURL),
      parameters_(parameters),
      run_default_message_loop_(true) {
}

XWalkBrowserMainParts::~XWalkBrowserMainParts() {
}

#if defined(OS_ANDROID)
void XWalkBrowserMainParts::SetRuntimeContext(RuntimeContext* context) {
  runtime_context_ = context;
}
#endif

void XWalkBrowserMainParts::PreMainMessageLoopStart() {
#if defined(OS_ANDROID)
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kAllowFileAccessFromFiles);
  // WebGL is disabled by default on Android, explicitly enable it in switches.
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalWebGL);
#endif

#if !defined(OS_ANDROID)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  const CommandLine::StringVector& args = command_line->GetArgs();

  if (args.empty())
    return;

  GURL url(args[0]);
  if (url.is_valid() && url.has_scheme()) {
    startup_url_ = url;
  } else {
    base::FilePath path(args[0]);
    if (!path.IsAbsolute())
      path = MakeAbsoluteFilePath(path);
    startup_url_ = net::FilePathToFileURL(path);
  }
#endif

#if defined(OS_MACOSX)
    PreMainMessageLoopStartMac();
#endif
}

void XWalkBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_ANDROID)
  MessageLoopForUI::current()->Start();
#endif
}

void XWalkBrowserMainParts::PreEarlyInitialization() {
#if defined(OS_ANDROID)
  net::NetworkChangeNotifier::SetFactory(
      new net::NetworkChangeNotifierFactoryAndroid());

  CommandLine::ForCurrentProcess()->AppendSwitch(
      cc::switches::kCompositeToMailbox);

  // Initialize the Compositor.
  content::Compositor::Initialize();
#endif

#if defined(OS_LINUX)
  // FIXME: Issue 496. We need to explicitly disable sandboxing on Linux while
  // we do not support it (ie. ship the appropriate binary), otherwise we will
  // crash on startup.
  CommandLine::ForCurrentProcess()->AppendSwitch(switches::kNoSandbox);
#endif
}

int XWalkBrowserMainParts::PreCreateThreads() {
#if defined(OS_ANDROID)
  DCHECK(runtime_context_);
  runtime_context_->InitializeBeforeThreadCreation();
#endif
  return content::RESULT_CODE_NORMAL_EXIT;
}

void XWalkBrowserMainParts::RegisterExternalExtensions() {
  CommandLine* cmd_line = CommandLine::ForCurrentProcess();
  if (!cmd_line->HasSwitch(switches::kXWalkExternalExtensionsPath))
    return;

  if (!cmd_line->HasSwitch(
          switches::kXWalkAllowExternalExtensionsForRemoteSources) &&
      !startup_url_.SchemeIsFile()) {
    VLOG(0) << "Unsupported scheme for external extensions: " <<
          startup_url_.scheme();
    return;
  }

  base::FilePath extensions_dir =
      cmd_line->GetSwitchValuePath(switches::kXWalkExternalExtensionsPath);
  if (!file_util::DirectoryExists(extensions_dir)) {
    LOG(WARNING) << "Ignoring non-existent extension directory: "
                 << extensions_dir.AsUTF8Unsafe();
    return;
  }

  extension_service_->RegisterExternalExtensionsForPath(extensions_dir);
}

void XWalkBrowserMainParts::PreMainMessageLoopRun() {
#if defined(OS_ANDROID)
  net::NetModule::SetResourceProvider(PlatformResourceProvider);
  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_default_message_loop_ = false;
  }

  DCHECK(runtime_context_);
  runtime_context_->PreMainMessageLoopRun();
#else
  runtime_context_.reset(new RuntimeContext);
  runtime_registry_.reset(new RuntimeRegistry);
  extension_service_.reset(
      new extensions::XWalkExtensionService(runtime_registry_.get()));

  RegisterInternalExtensions();
  RegisterExternalExtensions();

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
    std::string port_str =
        command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    int port;
    const char* loopback_ip = "127.0.0.1";
    if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) {
      remote_debugging_server_.reset(
          new RemoteDebuggingServer(runtime_context_.get(),
              loopback_ip, port, std::string()));
    }
  }

  NativeAppWindow::Initialize();

  if (startup_url_.SchemeIsFile()) {
    base::FilePath path;
    if (!net::FileURLToFilePath(startup_url_, &path))
      return;
    if (file_util::DirectoryExists(path)) {
      std::string error;
      scoped_refptr<xwalk::application::Application> application =
          xwalk::application::LoadApplication(
              path,
              xwalk::application::Manifest::COMMAND_LINE,
              &error);
      if (!error.empty())
        LOG(ERROR) << "Failed to load application: " << error;
      if (application != NULL) {
        xwalk::application::ApplicationSystem* system =
            runtime_context_->GetApplicationSystem();
        xwalk::application::ApplicationProcessManager* manager =
            system->process_manager();
        manager->LaunchApplication(runtime_context_.get(), application);
        return;
      }
    }
  }

  // The new created Runtime instance will be managed by RuntimeRegistry.
  Runtime::Create(runtime_context_.get(), startup_url_);

  // If the |ui_task| is specified in main function parameter, it indicates
  // that we will run this UI task instead of running the the default main
  // message loop. See |content::BrowserTestBase::SetUp| for |ui_task| usage
  // case.
  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_default_message_loop_ = false;
  }
#endif
}

bool XWalkBrowserMainParts::MainMessageLoopRun(int* result_code) {
  return !run_default_message_loop_;
}

void XWalkBrowserMainParts::PostMainMessageLoopRun() {
#if defined(OS_ANDROID)
  MessageLoopForUI::current()->Start();
#else
  runtime_context_.reset();
#endif
}

void XWalkBrowserMainParts::RegisterInternalExtensions() {
  extension_service_->RegisterExtension(scoped_ptr<XWalkExtension>(
      new RuntimeExtension()));
  extension_service_->RegisterExtension(scoped_ptr<XWalkExtension>(
      new experimental::DialogExtension(runtime_registry_.get())));
}

}  // namespace xwalk
<|endoftext|>


<commit_before>#pragma once

#include <vpp/core/vector.hh>
#include <vpp/draw/square.hh>
#include <vpp/draw/symbols.hh>
#include <list>

namespace vpp
{
using namespace vpp;
using namespace draw;
template <typename V, typename U>
void line2d_hough(vint2 a, vint2 b, V paint, U paint_border,image2d<unsigned char> grad , int line_width = 5)
{
    int x0 = a[1]; int y0 = a[0];
    int x1 = b[1]; int y1 = b[0];

    int steep = ::abs(y1 - y0) > ::abs(x1 - x0);

    if (steep)
    {
        std::swap(x0, y0);
        std::swap(x1, y1);
    }

    if (x0 > x1)
    {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }

    int deltax = x1 - x0;
    int deltay = ::abs(y1 - y0);
    float error = 0.f;
    float deltaerr = deltay / float(deltax);
    int ystep;
    int y = y0;
    if (y0 < y1) ystep = 1; else ystep = -1;

    for (int x = x0 + 1; x <= x1; x++)
    {
        vint2 to_plot;
        vint2 d1,d2; // line border.
        if (steep)
        {
            to_plot = vint2{x, y};
            d1 = vint2{0, -1};
            d2 = vint2{0, +1};
        }
        else
        {
            to_plot = vint2{y, x};
            d1 = vint2{-1, 0};
            d2 = vint2{+1, 0};
        }

        if(grad(to_plot) < 10)
            continue;

        float interp = float(x - x0) / (x1 - x0);
        paint(to_plot, interp);
        for (int bi = 1; bi < line_width / 2; bi++)
        {
            paint_border(to_plot + bi * d1, interp, bi);
            paint_border(to_plot + bi * d2, interp, bi);
        }

        error = error + deltaerr;
        if (error >= 0.5)
        {
            y = y + ystep;
            error = error - 1.0;
        }
    }
}

template <typename V, typename U>
void line2d_hough_particles(std::list<vint2> list_points,vint2 a, vint2 b, V paint, U paint_border, int line_width = 5)
{
    int x0 = a[1]; int y0 = a[0];
    int x1 = b[1]; int y1 = b[0];

    int steep = ::abs(y1 - y0) > ::abs(x1 - x0);

    if (steep)
    {
        std::swap(x0, y0);
        std::swap(x1, y1);
    }

    if (x0 > x1)
    {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }

    for (auto &list_point : list_points)
    {
        vint2 to_plot;
        vint2 d1,d2; // point.
        if (steep)
        {
            to_plot = list_point;
            d1 = vint2{0, -1};
            d2 = vint2{0, +1};
        }
        else
        {
            to_plot = list_point;
            d1 = vint2{-1, 0};
            d2 = vint2{+1, 0};
        }

        float interp = float((list_point)[0] - x0) / (x1 - x0);
        paint(to_plot, interp);
        for (int bi = 1; bi < line_width / 2; bi++)
        {
            paint_border(to_plot + bi * d1, interp, bi);
            paint_border(to_plot + bi * d2, interp, bi);
        }

    }
}

}
<commit_msg>delete option to draw lines<commit_after>#pragma once

#include <vpp/core/vector.hh>
#include <vpp/draw/square.hh>
#include <vpp/draw/symbols.hh>
#include <list>

namespace vpp
{
using namespace vpp;
using namespace draw;
template <typename V, typename U>
void line2d_hough(vint2 a, vint2 b, V paint, U paint_border,image2d<unsigned char> grad , int line_width = 5)
{
    int x0 = a[1]; int y0 = a[0];
    int x1 = b[1]; int y1 = b[0];

    int steep = ::abs(y1 - y0) > ::abs(x1 - x0);

    if (steep)
    {
        std::swap(x0, y0);
        std::swap(x1, y1);
    }

    if (x0 > x1)
    {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }

    int deltax = x1 - x0;
    int deltay = ::abs(y1 - y0);
    float error = 0.f;
    float deltaerr = deltay / float(deltax);
    int ystep;
    int y = y0;
    if (y0 < y1) ystep = 1; else ystep = -1;

    for (int x = x0 + 1; x <= x1; x++)
    {
        vint2 to_plot;
        vint2 d1,d2; // line border.
        if (steep)
        {
            to_plot = vint2{x, y};
            d1 = vint2{0, -1};
            d2 = vint2{0, +1};
        }
        else
        {
            to_plot = vint2{y, x};
            d1 = vint2{-1, 0};
            d2 = vint2{+1, 0};
        }

        if(grad(to_plot) < 10)
            continue;

        float interp = float(x - x0) / (x1 - x0);
        paint(to_plot, interp);
        for (int bi = 1; bi < line_width / 2; bi++)
        {
            paint_border(to_plot + bi * d1, interp, bi);
            paint_border(to_plot + bi * d2, interp, bi);
        }

        error = error + deltaerr;
        if (error >= 0.5)
        {
            y = y + ystep;
            error = error - 1.0;
        }
    }
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
 * Copyright (C) 2009 Google Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h"
#include "core/workers/Worker.h"

#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/events/MessageEvent.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/UseCounter.h"
#include "core/workers/WorkerGlobalScopeProxy.h"
#include "core/workers/WorkerGlobalScopeProxyProvider.h"
#include "core/workers/WorkerScriptLoader.h"
#include "core/workers/WorkerThread.h"
#include "wtf/MainThread.h"

namespace WebCore {

inline Worker::Worker(ExecutionContext* context)
    : AbstractWorker(context)
    , m_contextProxy(0)
{
    ScriptWrappable::init(this);
}

PassRefPtrWillBeRawPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
{
    ASSERT(isMainThread());
    Document* document = toDocument(context);
    UseCounter::count(context, UseCounter::WorkerStart);
    if (!document->page()) {
        exceptionState.throwDOMException(InvalidAccessError, "The context provided is invalid.");
        return nullptr;
    }
    WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(*document->page());
    ASSERT(proxyProvider);

    RefPtrWillBeRawPtr<Worker> worker = adoptRefWillBeRefCountedGarbageCollected(new Worker(context));

    worker->suspendIfNeeded();

    KURL scriptURL = worker->resolveURL(url, exceptionState);
    if (scriptURL.isEmpty())
        return nullptr;

    // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
    worker->setPendingActivity(worker.get());

    worker->m_scriptLoader = WorkerScriptLoader::create();
    worker->m_scriptLoader->loadAsynchronously(*context, scriptURL, DenyCrossOriginRequests, worker.get());
    worker->m_contextProxy = proxyProvider->createWorkerGlobalScopeProxy(worker.get());
    return worker.release();
}

Worker::~Worker()
{
    ASSERT(isMainThread());
    ASSERT(executionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
    if (m_contextProxy)
        m_contextProxy->workerObjectDestroyed();
}

const AtomicString& Worker::interfaceName() const
{
    return EventTargetNames::Worker;
}

void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionState& exceptionState)
{
    // Disentangle the port in preparation for sending it to the remote context.
    OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, exceptionState);
    if (exceptionState.hadException())
        return;
    m_contextProxy->postMessageToWorkerGlobalScope(message, channels.release());
}

void Worker::terminate()
{
    if (m_contextProxy)
        m_contextProxy->terminateWorkerGlobalScope();
}

void Worker::stop()
{
    terminate();
}

bool Worker::hasPendingActivity() const
{
    return m_contextProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
}

void Worker::didReceiveResponse(unsigned long identifier, const ResourceResponse&)
{
    InspectorInstrumentation::didReceiveScriptResponse(executionContext(), identifier);
}

void Worker::notifyFinished()
{
    if (m_scriptLoader->failed()) {
        dispatchEvent(Event::createCancelable(EventTypeNames::error));
    } else {
        WorkerThreadStartMode startMode = DontPauseWorkerGlobalScopeOnStart;
        if (InspectorInstrumentation::shouldPauseDedicatedWorkerOnStart(executionContext()))
            startMode = PauseWorkerGlobalScopeOnStart;
        m_contextProxy->startWorkerGlobalScope(m_scriptLoader->url(), executionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), startMode);
        InspectorInstrumentation::scriptImported(executionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
    }
    m_scriptLoader = nullptr;

    unsetPendingActivity(this);
}

void Worker::trace(Visitor* visitor)
{
    AbstractWorker::trace(visitor);
}

} // namespace WebCore
<commit_msg>Have the Worker destructor handle non-started Workers better.<commit_after>/*
 * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
 * Copyright (C) 2009 Google Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h"
#include "core/workers/Worker.h"

#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/events/MessageEvent.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/UseCounter.h"
#include "core/workers/WorkerGlobalScopeProxy.h"
#include "core/workers/WorkerGlobalScopeProxyProvider.h"
#include "core/workers/WorkerScriptLoader.h"
#include "core/workers/WorkerThread.h"
#include "wtf/MainThread.h"

namespace WebCore {

inline Worker::Worker(ExecutionContext* context)
    : AbstractWorker(context)
    , m_contextProxy(0)
{
    ScriptWrappable::init(this);
}

PassRefPtrWillBeRawPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
{
    ASSERT(isMainThread());
    Document* document = toDocument(context);
    UseCounter::count(context, UseCounter::WorkerStart);
    if (!document->page()) {
        exceptionState.throwDOMException(InvalidAccessError, "The context provided is invalid.");
        return nullptr;
    }
    WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(*document->page());
    ASSERT(proxyProvider);

    RefPtrWillBeRawPtr<Worker> worker = adoptRefWillBeRefCountedGarbageCollected(new Worker(context));

    worker->suspendIfNeeded();

    KURL scriptURL = worker->resolveURL(url, exceptionState);
    if (scriptURL.isEmpty())
        return nullptr;

    // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
    worker->setPendingActivity(worker.get());

    worker->m_scriptLoader = WorkerScriptLoader::create();
    worker->m_scriptLoader->loadAsynchronously(*context, scriptURL, DenyCrossOriginRequests, worker.get());
    worker->m_contextProxy = proxyProvider->createWorkerGlobalScopeProxy(worker.get());
    return worker.release();
}

Worker::~Worker()
{
    ASSERT(isMainThread());
    if (!m_contextProxy)
        return;
    ASSERT(executionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
    m_contextProxy->workerObjectDestroyed();
}

const AtomicString& Worker::interfaceName() const
{
    return EventTargetNames::Worker;
}

void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionState& exceptionState)
{
    ASSERT(m_contextProxy);
    // Disentangle the port in preparation for sending it to the remote context.
    OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, exceptionState);
    if (exceptionState.hadException())
        return;
    m_contextProxy->postMessageToWorkerGlobalScope(message, channels.release());
}

void Worker::terminate()
{
    if (m_contextProxy)
        m_contextProxy->terminateWorkerGlobalScope();
}

void Worker::stop()
{
    terminate();
}

bool Worker::hasPendingActivity() const
{
    return (m_contextProxy && m_contextProxy->hasPendingActivity()) || ActiveDOMObject::hasPendingActivity();
}

void Worker::didReceiveResponse(unsigned long identifier, const ResourceResponse&)
{
    InspectorInstrumentation::didReceiveScriptResponse(executionContext(), identifier);
}

void Worker::notifyFinished()
{
    if (m_scriptLoader->failed()) {
        dispatchEvent(Event::createCancelable(EventTypeNames::error));
    } else {
        ASSERT(m_contextProxy);
        WorkerThreadStartMode startMode = DontPauseWorkerGlobalScopeOnStart;
        if (InspectorInstrumentation::shouldPauseDedicatedWorkerOnStart(executionContext()))
            startMode = PauseWorkerGlobalScopeOnStart;
        m_contextProxy->startWorkerGlobalScope(m_scriptLoader->url(), executionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), startMode);
        InspectorInstrumentation::scriptImported(executionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
    }
    m_scriptLoader = nullptr;

    unsetPendingActivity(this);
}

void Worker::trace(Visitor* visitor)
{
    AbstractWorker::trace(visitor);
}

} // namespace WebCore
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Real Logic Ltd.
 *
 * 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 "ClientConductor.h"

using namespace aeron;

template <typename A>
inline static std::size_t findInVector(std::vector<A>& container, std::function<int(A)> compare)
{
    std::size_t result = SIZE_MAX;

    for (std::size_t i = 0; i < container.size(); i++)
    {
        if (compare(container[i]) == 0)
        {
            result = i;
            break;
        }
    }

    return result;
}

Publication* ClientConductor::addPublication(const std::string& channel, std::int32_t streamId, std::int32_t sessionId)
{
    std::lock_guard<std::mutex> lock(m_publicationsLock);

    std::size_t element = findInVector<Publication*>(m_publications, [&](Publication* pub)
    {
        return (streamId == pub->streamId() && sessionId == pub->sessionId() && channel == pub->channel());
    });

    Publication* publication = nullptr;

    if (SIZE_MAX == element)
    {
        std::int64_t correlationId = 0;

        publication = new Publication(*this, channel, streamId, sessionId, correlationId);

        m_publications.push_back(publication);
    }
    else
    {
        publication = m_publications[element];
    }

    return publication;
}

void ClientConductor::releasePublication(Publication* publication)
{
    std::lock_guard<std::mutex> lock(m_publicationsLock);

    // TODO: send command to driver?

    std::size_t element = findInVector<Publication*>(m_publications, [&](Publication* pub)
    {
        return pub == publication;
    });

    if (SIZE_MAX != element)
    {
        m_publications.erase(m_publications.begin() + element);
    }
}

Subscription* ClientConductor::addSubscription(const std::string& channel, std::int32_t streamId, logbuffer::handler_t& handler)
{
    std::lock_guard<std::mutex> lock(m_subscriptionsLock);

    std::size_t element = findInVector<Subscription*>(m_subscriptions, [&](Subscription* sub)
    {
        return (streamId == sub->streamId() && channel == sub->channel());
    });

    Subscription* subscription = nullptr;

    if (SIZE_MAX == element)
    {
        subscription = new Subscription(*this, channel, streamId);

        m_subscriptions.push_back(subscription);
        // TODO: send command to driver
    }
    else
    {
        subscription = m_subscriptions[element];
    }

    return subscription;
}

void ClientConductor::releaseSubscription(Subscription* subscription)
{
    std::lock_guard<std::mutex> lock(m_subscriptionsLock);

    // TODO: send command to driver?

    std::size_t element = findInVector<Subscription*>(m_subscriptions, [&](Subscription* sub)
    {
        return sub == subscription;
    });

    if (SIZE_MAX != element)
    {
        m_subscriptions.erase(m_subscriptions.begin() + element);
    }
}

void ClientConductor::onNewPublication(
    std::int64_t correlationId,
    const std::string& channel,
    std::int32_t streamId,
    std::int32_t sessionId,
    std::int32_t termId,
    std::int32_t positionCounterId,
    std::int32_t mtuLengt,
    const PublicationReadyFlyweight& publicationReady)
{

}
<commit_msg>[C++]: remove stray include.<commit_after>/*
 * Copyright 2014 Real Logic Ltd.
 *
 * 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 "ClientConductor.h"

using namespace aeron;

template <typename A>
inline static std::size_t findInVector(std::vector<A>& container, std::function<int(A)> compare)
{
    std::size_t result = SIZE_MAX;

    for (std::size_t i = 0; i < container.size(); i++)
    {
        if (compare(container[i]) == 0)
        {
            result = i;
            break;
        }
    }

    return result;
}

Publication* ClientConductor::addPublication(const std::string& channel, std::int32_t streamId, std::int32_t sessionId)
{
    std::lock_guard<std::mutex> lock(m_publicationsLock);

    std::size_t element = findInVector<Publication*>(m_publications, [&](Publication* pub)
    {
        return (streamId == pub->streamId() && sessionId == pub->sessionId() && channel == pub->channel());
    });

    Publication* publication = nullptr;

    if (SIZE_MAX == element)
    {
        std::int64_t correlationId = m_driverProxy.addPublication(channel, streamId, sessionId);

        publication = new Publication(*this, channel, streamId, sessionId, correlationId);

        m_publications.push_back(publication);
    }
    else
    {
        publication = m_publications[element];
    }

    return publication;
}

void ClientConductor::releasePublication(Publication* publication)
{
    std::lock_guard<std::mutex> lock(m_publicationsLock);

    // TODO: send command to driver?

    std::size_t element = findInVector<Publication*>(m_publications, [&](Publication* pub)
    {
        return pub == publication;
    });

    if (SIZE_MAX != element)
    {
        m_publications.erase(m_publications.begin() + element);
    }
}

Subscription* ClientConductor::addSubscription(const std::string& channel, std::int32_t streamId, logbuffer::handler_t& handler)
{
    std::lock_guard<std::mutex> lock(m_subscriptionsLock);

    std::size_t element = findInVector<Subscription*>(m_subscriptions, [&](Subscription* sub)
    {
        return (streamId == sub->streamId() && channel == sub->channel());
    });

    Subscription* subscription = nullptr;

    if (SIZE_MAX == element)
    {
        subscription = new Subscription(*this, channel, streamId);

        m_subscriptions.push_back(subscription);
        // TODO: send command to driver
    }
    else
    {
        subscription = m_subscriptions[element];
    }

    return subscription;
}

void ClientConductor::releaseSubscription(Subscription* subscription)
{
    std::lock_guard<std::mutex> lock(m_subscriptionsLock);

    // TODO: send command to driver?

    std::size_t element = findInVector<Subscription*>(m_subscriptions, [&](Subscription* sub)
    {
        return sub == subscription;
    });

    if (SIZE_MAX != element)
    {
        m_subscriptions.erase(m_subscriptions.begin() + element);
    }
}

void ClientConductor::onNewPublication(
    std::int64_t correlationId,
    const std::string& channel,
    std::int32_t streamId,
    std::int32_t sessionId,
    std::int32_t termId,
    std::int32_t positionCounterId,
    std::int32_t mtuLengt,
    const PublicationReadyFlyweight& publicationReady)
{

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 "rtos/ThisThread.h"
#include "mbed_error.h"
#include "platform/mbed_atomic.h"
#include "events/EventQueue.h"
#include "events/mbed_shared_queues.h"

#include "QUECTEL_BC95_CellularStack.h"
#include "CellularUtil.h"
#include "CellularLog.h"

#define PACKET_SIZE_MAX 1358
#define TXFULL_EVENT_TIMEOUT 1s

#define AT_UPLINK_BUSY          159
#define AT_UART_BUFFER_ERROR    536
#define AT_BACK_OFF_TIMER       537

using namespace std::chrono;
using namespace mbed;
using namespace mbed_cellular_util;

QUECTEL_BC95_CellularStack::QUECTEL_BC95_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
    AT_CellularStack(atHandler, cid, stack_type, device), _event_queue(mbed_event_queue()), _txfull_event_id(0)
{
    _at.set_urc_handler("+NSONMI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsonmi));
    _at.set_urc_handler("+NSOCLI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsocli));
}

QUECTEL_BC95_CellularStack::~QUECTEL_BC95_CellularStack()
{
    if (_txfull_event_id) {
        _event_queue->cancel(_txfull_event_id);
    }

    _at.set_urc_handler("+NSONMI:", nullptr);
    _at.set_urc_handler("+NSOCLI:", nullptr);
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
{
    CellularSocket *socket = (CellularSocket *)handle;

    _at.lock();
    if (socket->id == -1) {
        const nsapi_error_t error_create = create_socket_impl(socket);
        if (error_create != NSAPI_ERROR_OK) {
            return error_create;
        }
    }

    _at.cmd_start("AT+NSOCO=");
    _at.write_int(socket->id);
    _at.write_string(address.get_ip_address(), false);
    _at.write_int(address.get_port());
    _at.cmd_stop_read_resp();

    _at.unlock();

    if (_at.get_last_error() == NSAPI_ERROR_OK) {
        socket->remoteAddress = address;
        socket->connected = true;
        return NSAPI_ERROR_OK;
    }

    return NSAPI_ERROR_NO_CONNECTION;
}

void QUECTEL_BC95_CellularStack::urc_nsonmi()
{
    int sock_id = _at.read_int();

    for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
        CellularSocket *sock = _socket[i];
        if (sock && sock->id == sock_id) {
            if (sock->_cb) {
                sock->_cb(sock->_data);
            }
            break;
        }
    }
}

void QUECTEL_BC95_CellularStack::urc_nsocli()
{
    int sock_id = _at.read_int();

    const nsapi_error_t err = _at.get_last_error();

    if (err != NSAPI_ERROR_OK) {
        return;
    }

    CellularSocket *sock = find_socket(sock_id);

    if (sock) {
        sock->closed = true;
        if (sock->_cb) {
            sock->_cb(sock->_data);
        }
        tr_info("Socket closed %d", sock_id);
    }
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_close_impl(int sock_id)
{
    CellularSocket *sock = find_socket(sock_id);

    if (sock && sock->closed) {
        return NSAPI_ERROR_OK;
    }

    sock->txfull_event = false;

    nsapi_error_t err = _at.at_cmd_discard("+NSOCL", "=", "%d", sock_id);

    tr_info("Close socket: %d error: %d", sock_id, err);

    return err;
}

nsapi_error_t QUECTEL_BC95_CellularStack::create_socket_impl(CellularSocket *socket)
{
    int sock_id = -1;
    bool socketOpenWorking = false;

    if (socket->proto == NSAPI_UDP) {
        _at.cmd_start_stop("+NSOCR", "=DGRAM,", "%d%d%d%s", 17, socket->localAddress.get_port(), 1, ((_ip_ver_sendto == NSAPI_IPv4) ? "AF_INET" : "AF_INET6"));
    } else if (socket->proto == NSAPI_TCP) {
        _at.cmd_start_stop("+NSOCR", "=STREAM,", "%d%d%d%s", 6, socket->localAddress.get_port(), 1, ((_ip_ver_sendto == NSAPI_IPv4) ? "AF_INET" : "AF_INET6"));
    } else {
        return NSAPI_ERROR_PARAMETER;
    }
    _at.resp_start();
    sock_id = _at.read_int();
    _at.resp_stop();

    socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK);

    if (!socketOpenWorking || (sock_id == -1)) {
        tr_error("Socket create failed!");
        return NSAPI_ERROR_NO_SOCKET;
    }

    tr_info("Socket create id: %d", sock_id);

    socket->id = sock_id;

    return NSAPI_ERROR_OK;
}

nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
                                                                     const void *data, nsapi_size_t size)
{
    //AT_CellularStack::socket_sendto(...) will create a socket on modem if it wasn't
    // open already.
    MBED_ASSERT(socket->id != -1);

    if (_ip_ver_sendto != address.get_ip_version()) {
        _ip_ver_sendto =  address.get_ip_version();
        socket_close_impl(socket->id);
        create_socket_impl(socket);
    }

    int sent_len = 0;

    if (size > PACKET_SIZE_MAX) {
        return NSAPI_ERROR_PARAMETER;
    }

    int retry = 0;
retry_send:
    if (socket->proto == NSAPI_UDP) {
        _at.cmd_start("AT+NSOST=");
        _at.write_int(socket->id);
        _at.write_string(address.get_ip_address(), false);
        _at.write_int(address.get_port());
        _at.write_int(size);
    } else if (socket->proto == NSAPI_TCP) {
        _at.cmd_start("AT+NSOSD=");
        _at.write_int(socket->id);
        _at.write_int(size);
    } else {
        return NSAPI_ERROR_PARAMETER;
    }

    _at.write_hex_string((char *)data, size);
    _at.cmd_stop();
    _at.resp_start();
    // skip socket id
    _at.skip_param();
    sent_len = _at.read_int();
    _at.resp_stop();

    if (_at.get_last_error() == NSAPI_ERROR_OK) {
        return sent_len;
    }

    // check for network congestion
    device_err_t err = _at.get_last_device_error();
    if (err.errType == DeviceErrorTypeErrorCME &&
            (err.errCode == AT_UART_BUFFER_ERROR || err.errCode == AT_BACK_OFF_TIMER) || err.errCode == AT_UPLINK_BUSY) {
        if (socket->proto == NSAPI_UDP) {
            if (retry < 3) {
                retry++;
                tr_warn("Socket %d sendto EAGAIN", socket->id);
                rtos::ThisThread::sleep_for(30ms);
                _at.clear_error();
                goto retry_send;
            }
            return NSAPI_ERROR_NO_MEMORY;
        }
        _socket_mutex.lock();
        if (!socket->txfull_event && !_txfull_event_id) {
            tr_warn("socket %d tx full", socket->id);
            socket->txfull_event = true;
            _txfull_event_id = _event_queue->call_in(TXFULL_EVENT_TIMEOUT, callback(this, &QUECTEL_BC95_CellularStack::txfull_event_timeout));
            if (!_txfull_event_id) {
                MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
                           "QUECTEL_BC95_CellularStack::socket_sendto_impl(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");
                _socket_mutex.unlock();
                return NSAPI_ERROR_NO_MEMORY;
            }
        }
        _socket_mutex.unlock();
        return NSAPI_ERROR_WOULD_BLOCK;
    }

    return _at.get_last_error();
}

nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
                                                                       void *buffer, nsapi_size_t size)
{
    //AT_CellularStack::socket_recvfrom(...) will create a socket on modem if it wasn't
    // open already.
    MBED_ASSERT(socket->id != -1);

    nsapi_size_or_error_t recv_len = 0;
    int port;
    char ip_address[NSAPI_IP_SIZE];

    _at.cmd_start_stop("+NSORF", "=", "%d%d", socket->id, size < PACKET_SIZE_MAX ? size : PACKET_SIZE_MAX);

    _at.resp_start();
    // receiving socket id
    _at.skip_param();
    _at.read_string(ip_address, sizeof(ip_address));
    port = _at.read_int();
    recv_len = _at.read_int();
    int hexlen = _at.read_hex_string((char *)buffer, recv_len);
    // remaining length
    _at.skip_param();
    _at.resp_stop();

    if (!recv_len || (recv_len == -1) || (_at.get_last_error() != NSAPI_ERROR_OK)) {
        return NSAPI_ERROR_WOULD_BLOCK;
    }

    if (address) {
        address->set_ip_address(ip_address);
        address->set_port(port);
    }

    if (recv_len != hexlen) {
        tr_error("Not received as much data as expected. Should receive: %d bytes, received: %d bytes", recv_len, hexlen);
    }
    return recv_len;
}

void QUECTEL_BC95_CellularStack::txfull_event_timeout()
{
    _socket_mutex.lock();
    _txfull_event_id = 0;
    for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
        CellularSocket *sock = _socket[i];
        if (sock && sock->_cb && sock->txfull_event) {
            sock->txfull_event = false;
            sock->_cb(sock->_data);
        }
    }
    _socket_mutex.unlock();
}
<commit_msg>fixed warnings: suggest parentheses around '&&' within '||'<commit_after>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 "rtos/ThisThread.h"
#include "mbed_error.h"
#include "platform/mbed_atomic.h"
#include "events/EventQueue.h"
#include "events/mbed_shared_queues.h"

#include "QUECTEL_BC95_CellularStack.h"
#include "CellularUtil.h"
#include "CellularLog.h"

#define PACKET_SIZE_MAX 1358
#define TXFULL_EVENT_TIMEOUT 1s

#define AT_UPLINK_BUSY          159
#define AT_UART_BUFFER_ERROR    536
#define AT_BACK_OFF_TIMER       537

using namespace std::chrono;
using namespace mbed;
using namespace mbed_cellular_util;

QUECTEL_BC95_CellularStack::QUECTEL_BC95_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
    AT_CellularStack(atHandler, cid, stack_type, device), _event_queue(mbed_event_queue()), _txfull_event_id(0)
{
    _at.set_urc_handler("+NSONMI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsonmi));
    _at.set_urc_handler("+NSOCLI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsocli));
}

QUECTEL_BC95_CellularStack::~QUECTEL_BC95_CellularStack()
{
    if (_txfull_event_id) {
        _event_queue->cancel(_txfull_event_id);
    }

    _at.set_urc_handler("+NSONMI:", nullptr);
    _at.set_urc_handler("+NSOCLI:", nullptr);
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
{
    CellularSocket *socket = (CellularSocket *)handle;

    _at.lock();
    if (socket->id == -1) {
        const nsapi_error_t error_create = create_socket_impl(socket);
        if (error_create != NSAPI_ERROR_OK) {
            return error_create;
        }
    }

    _at.cmd_start("AT+NSOCO=");
    _at.write_int(socket->id);
    _at.write_string(address.get_ip_address(), false);
    _at.write_int(address.get_port());
    _at.cmd_stop_read_resp();

    _at.unlock();

    if (_at.get_last_error() == NSAPI_ERROR_OK) {
        socket->remoteAddress = address;
        socket->connected = true;
        return NSAPI_ERROR_OK;
    }

    return NSAPI_ERROR_NO_CONNECTION;
}

void QUECTEL_BC95_CellularStack::urc_nsonmi()
{
    int sock_id = _at.read_int();

    for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
        CellularSocket *sock = _socket[i];
        if (sock && sock->id == sock_id) {
            if (sock->_cb) {
                sock->_cb(sock->_data);
            }
            break;
        }
    }
}

void QUECTEL_BC95_CellularStack::urc_nsocli()
{
    int sock_id = _at.read_int();

    const nsapi_error_t err = _at.get_last_error();

    if (err != NSAPI_ERROR_OK) {
        return;
    }

    CellularSocket *sock = find_socket(sock_id);

    if (sock) {
        sock->closed = true;
        if (sock->_cb) {
            sock->_cb(sock->_data);
        }
        tr_info("Socket closed %d", sock_id);
    }
}

nsapi_error_t QUECTEL_BC95_CellularStack::socket_close_impl(int sock_id)
{
    CellularSocket *sock = find_socket(sock_id);

    if (sock && sock->closed) {
        return NSAPI_ERROR_OK;
    }

    sock->txfull_event = false;

    nsapi_error_t err = _at.at_cmd_discard("+NSOCL", "=", "%d", sock_id);

    tr_info("Close socket: %d error: %d", sock_id, err);

    return err;
}

nsapi_error_t QUECTEL_BC95_CellularStack::create_socket_impl(CellularSocket *socket)
{
    int sock_id = -1;
    bool socketOpenWorking = false;

    if (socket->proto == NSAPI_UDP) {
        _at.cmd_start_stop("+NSOCR", "=DGRAM,", "%d%d%d%s", 17, socket->localAddress.get_port(), 1, ((_ip_ver_sendto == NSAPI_IPv4) ? "AF_INET" : "AF_INET6"));
    } else if (socket->proto == NSAPI_TCP) {
        _at.cmd_start_stop("+NSOCR", "=STREAM,", "%d%d%d%s", 6, socket->localAddress.get_port(), 1, ((_ip_ver_sendto == NSAPI_IPv4) ? "AF_INET" : "AF_INET6"));
    } else {
        return NSAPI_ERROR_PARAMETER;
    }
    _at.resp_start();
    sock_id = _at.read_int();
    _at.resp_stop();

    socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK);

    if (!socketOpenWorking || (sock_id == -1)) {
        tr_error("Socket create failed!");
        return NSAPI_ERROR_NO_SOCKET;
    }

    tr_info("Socket create id: %d", sock_id);

    socket->id = sock_id;

    return NSAPI_ERROR_OK;
}

nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
                                                                     const void *data, nsapi_size_t size)
{
    //AT_CellularStack::socket_sendto(...) will create a socket on modem if it wasn't
    // open already.
    MBED_ASSERT(socket->id != -1);

    if (_ip_ver_sendto != address.get_ip_version()) {
        _ip_ver_sendto =  address.get_ip_version();
        socket_close_impl(socket->id);
        create_socket_impl(socket);
    }

    int sent_len = 0;

    if (size > PACKET_SIZE_MAX) {
        return NSAPI_ERROR_PARAMETER;
    }

    int retry = 0;
retry_send:
    if (socket->proto == NSAPI_UDP) {
        _at.cmd_start("AT+NSOST=");
        _at.write_int(socket->id);
        _at.write_string(address.get_ip_address(), false);
        _at.write_int(address.get_port());
        _at.write_int(size);
    } else if (socket->proto == NSAPI_TCP) {
        _at.cmd_start("AT+NSOSD=");
        _at.write_int(socket->id);
        _at.write_int(size);
    } else {
        return NSAPI_ERROR_PARAMETER;
    }

    _at.write_hex_string((char *)data, size);
    _at.cmd_stop();
    _at.resp_start();
    // skip socket id
    _at.skip_param();
    sent_len = _at.read_int();
    _at.resp_stop();

    if (_at.get_last_error() == NSAPI_ERROR_OK) {
        return sent_len;
    }

    // check for network congestion
    device_err_t err = _at.get_last_device_error();
    if ((err.errType == DeviceErrorTypeErrorCME &&
            (err.errCode == AT_UART_BUFFER_ERROR || err.errCode == AT_BACK_OFF_TIMER)) || err.errCode == AT_UPLINK_BUSY) {
        if (socket->proto == NSAPI_UDP) {
            if (retry < 3) {
                retry++;
                tr_warn("Socket %d sendto EAGAIN", socket->id);
                rtos::ThisThread::sleep_for(30ms);
                _at.clear_error();
                goto retry_send;
            }
            return NSAPI_ERROR_NO_MEMORY;
        }
        _socket_mutex.lock();
        if (!socket->txfull_event && !_txfull_event_id) {
            tr_warn("socket %d tx full", socket->id);
            socket->txfull_event = true;
            _txfull_event_id = _event_queue->call_in(TXFULL_EVENT_TIMEOUT, callback(this, &QUECTEL_BC95_CellularStack::txfull_event_timeout));
            if (!_txfull_event_id) {
                MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
                           "QUECTEL_BC95_CellularStack::socket_sendto_impl(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");
                _socket_mutex.unlock();
                return NSAPI_ERROR_NO_MEMORY;
            }
        }
        _socket_mutex.unlock();
        return NSAPI_ERROR_WOULD_BLOCK;
    }

    return _at.get_last_error();
}

nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
                                                                       void *buffer, nsapi_size_t size)
{
    //AT_CellularStack::socket_recvfrom(...) will create a socket on modem if it wasn't
    // open already.
    MBED_ASSERT(socket->id != -1);

    nsapi_size_or_error_t recv_len = 0;
    int port;
    char ip_address[NSAPI_IP_SIZE];

    _at.cmd_start_stop("+NSORF", "=", "%d%d", socket->id, size < PACKET_SIZE_MAX ? size : PACKET_SIZE_MAX);

    _at.resp_start();
    // receiving socket id
    _at.skip_param();
    _at.read_string(ip_address, sizeof(ip_address));
    port = _at.read_int();
    recv_len = _at.read_int();
    int hexlen = _at.read_hex_string((char *)buffer, recv_len);
    // remaining length
    _at.skip_param();
    _at.resp_stop();

    if (!recv_len || (recv_len == -1) || (_at.get_last_error() != NSAPI_ERROR_OK)) {
        return NSAPI_ERROR_WOULD_BLOCK;
    }

    if (address) {
        address->set_ip_address(ip_address);
        address->set_port(port);
    }

    if (recv_len != hexlen) {
        tr_error("Not received as much data as expected. Should receive: %d bytes, received: %d bytes", recv_len, hexlen);
    }
    return recv_len;
}

void QUECTEL_BC95_CellularStack::txfull_event_timeout()
{
    _socket_mutex.lock();
    _txfull_event_id = 0;
    for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
        CellularSocket *sock = _socket[i];
        if (sock && sock->_cb && sock->txfull_event) {
            sock->txfull_event = false;
            sock->_cb(sock->_data);
        }
    }
    _socket_mutex.unlock();
}
<|endoftext|>


<commit_before>#include <bts/db/object_database.hpp>
#include <bts/db/undo_database.hpp>
#include <fc/reflect/variant.hpp>

namespace bts { namespace db {

void undo_database::enable()  { _disabled = false; }
void undo_database::disable() { _disabled = true; }

undo_database::session undo_database::start_undo_session()
{
   if( _disabled ) return session(*this);

   if( size() == max_size() )
      _stack.pop_front();

   _stack.emplace_back();
   ++_active_sessions;
   return session(*this);
}
void undo_database::on_create( const object& obj )
{
   if( _disabled ) return;

   if( _stack.empty() )
      _stack.emplace_back();
   auto& state = _stack.back();
   auto index_id = object_id_type( obj.id.space(), obj.id.type(), 0 );
   auto itr = state.old_index_next_ids.find( index_id );
   if( itr == state.old_index_next_ids.end() )
      state.old_index_next_ids[index_id] = obj.id;
   state.new_ids.insert(obj.id);
}
void undo_database::on_modify( const object& obj )
{
   if( _disabled ) return;

   if( _stack.empty() )
      _stack.emplace_back();
   auto& state = _stack.back();
   if( state.new_ids.find(obj.id) != state.new_ids.end() )
      return;
   auto itr =  state.old_values.find(obj.id);
   if( itr != state.old_values.end() ) return;
   state.old_values[obj.id] = obj.clone();
}
void undo_database::on_remove( const object& obj )
{
   if( _disabled ) return;

   if( _stack.empty() )
      _stack.emplace_back();
   auto& state = _stack.back();
   if( state.new_ids.find(obj.id) != state.new_ids.end() )
   {
      state.new_ids.erase(obj.id);
      return;
   }
   auto itr =  state.removed.find(obj.id);
   if( itr != state.removed.end() ) return;
   state.removed[obj.id] = obj.clone();
}

void undo_database::undo()
{ try {
   FC_ASSERT( !_disabled );
   FC_ASSERT( _active_sessions > 0 );
   disable();

   auto& state = _stack.back();
   for( auto& item : state.old_values )
   {
      _db.modify( _db.get_object( item.second->id ), [&]( object& obj ){ obj.move_from( *item.second ); } );
   }

   for( auto ritr = state.new_ids.rbegin(); ritr != state.new_ids.rend(); ++ritr  )
   {
      _db.remove( _db.get_object(*ritr) );
   }

   for( auto& item : state.old_index_next_ids )
   {
      _db.get_mutable_index( item.first.space(), item.first.type() ).set_next_id( item.second );
   }

   for( auto& item : state.removed )
      _db.insert( std::move(*item.second) );

   _stack.pop_back();
   if( _stack.empty() )
      _stack.emplace_back();
   enable();
   --_active_sessions;
} FC_CAPTURE_AND_RETHROW() }

void undo_database::merge()
{
   FC_ASSERT( _active_sessions > 0 );
   FC_ASSERT( _stack.size() >=2 );
   auto& state = _stack.back();
   auto& prev_state = _stack[_stack.size()-2];
   for( auto& obj : state.old_values )
   {
      if( prev_state.new_ids.find(obj.second->id) != prev_state.new_ids.end() )
         continue;
      if( prev_state.old_values.find(obj.second->id) == prev_state.old_values.end() )
         prev_state.old_values[obj.second->id] = std::move(obj.second);
   }
   for( auto id : state.new_ids )
      prev_state.new_ids.insert(id);
   for( auto& item : state.old_index_next_ids )
   {
      if( prev_state.old_index_next_ids.find( item.first ) == prev_state.old_index_next_ids.end() )
         prev_state.old_index_next_ids[item.first] = item.second;
   }
   for( auto& obj : state.removed )
      if( prev_state.new_ids.find(obj.second->id) == prev_state.new_ids.end() )
         prev_state.removed[obj.second->id] = std::move(obj.second);
      else
         prev_state.new_ids.erase(obj.second->id);
   _stack.pop_back();
   --_active_sessions;
}
void undo_database::commit()
{
   --_active_sessions;
}

void undo_database::pop_commit()
{
   FC_ASSERT( _active_sessions == 0 );
   FC_ASSERT( !_stack.empty() );

   disable();
   try {
      auto& state = _stack.back();

      for( auto& item : state.old_values )
      {
         _db.modify( _db.get_object( item.second->id ), [&]( object& obj ){ obj.move_from( *item.second ); } );
      }

      for( auto ritr = state.new_ids.rbegin(); ritr != state.new_ids.rend(); ++ritr  )
      {
         _db.remove( _db.get_object(*ritr) );
      }

      for( auto& item : state.old_index_next_ids )
      {
         _db.get_mutable_index( item.first.space(), item.first.type() ).set_next_id( item.second );
      }

      for( auto& item : state.removed )
         _db.insert( std::move(*item.second) );

      _stack.pop_back();
   }
   catch ( const fc::exception& e )
   {
      elog( "error popping commit ${e}", ("e", e.to_detail_string() )  );
      enable();
      throw;
   }
   enable();
}

} } // bts::db
<commit_msg>undo_database:  Assert when commit() has no matching start_undo_session()<commit_after>#include <bts/db/object_database.hpp>
#include <bts/db/undo_database.hpp>
#include <fc/reflect/variant.hpp>

namespace bts { namespace db {

void undo_database::enable()  { _disabled = false; }
void undo_database::disable() { _disabled = true; }

undo_database::session undo_database::start_undo_session()
{
   if( _disabled ) return session(*this);

   if( size() == max_size() )
      _stack.pop_front();

   _stack.emplace_back();
   ++_active_sessions;
   return session(*this);
}
void undo_database::on_create( const object& obj )
{
   if( _disabled ) return;

   if( _stack.empty() )
      _stack.emplace_back();
   auto& state = _stack.back();
   auto index_id = object_id_type( obj.id.space(), obj.id.type(), 0 );
   auto itr = state.old_index_next_ids.find( index_id );
   if( itr == state.old_index_next_ids.end() )
      state.old_index_next_ids[index_id] = obj.id;
   state.new_ids.insert(obj.id);
}
void undo_database::on_modify( const object& obj )
{
   if( _disabled ) return;

   if( _stack.empty() )
      _stack.emplace_back();
   auto& state = _stack.back();
   if( state.new_ids.find(obj.id) != state.new_ids.end() )
      return;
   auto itr =  state.old_values.find(obj.id);
   if( itr != state.old_values.end() ) return;
   state.old_values[obj.id] = obj.clone();
}
void undo_database::on_remove( const object& obj )
{
   if( _disabled ) return;

   if( _stack.empty() )
      _stack.emplace_back();
   auto& state = _stack.back();
   if( state.new_ids.find(obj.id) != state.new_ids.end() )
   {
      state.new_ids.erase(obj.id);
      return;
   }
   auto itr =  state.removed.find(obj.id);
   if( itr != state.removed.end() ) return;
   state.removed[obj.id] = obj.clone();
}

void undo_database::undo()
{ try {
   FC_ASSERT( !_disabled );
   FC_ASSERT( _active_sessions > 0 );
   disable();

   auto& state = _stack.back();
   for( auto& item : state.old_values )
   {
      _db.modify( _db.get_object( item.second->id ), [&]( object& obj ){ obj.move_from( *item.second ); } );
   }

   for( auto ritr = state.new_ids.rbegin(); ritr != state.new_ids.rend(); ++ritr  )
   {
      _db.remove( _db.get_object(*ritr) );
   }

   for( auto& item : state.old_index_next_ids )
   {
      _db.get_mutable_index( item.first.space(), item.first.type() ).set_next_id( item.second );
   }

   for( auto& item : state.removed )
      _db.insert( std::move(*item.second) );

   _stack.pop_back();
   if( _stack.empty() )
      _stack.emplace_back();
   enable();
   --_active_sessions;
} FC_CAPTURE_AND_RETHROW() }

void undo_database::merge()
{
   FC_ASSERT( _active_sessions > 0 );
   FC_ASSERT( _stack.size() >=2 );
   auto& state = _stack.back();
   auto& prev_state = _stack[_stack.size()-2];
   for( auto& obj : state.old_values )
   {
      if( prev_state.new_ids.find(obj.second->id) != prev_state.new_ids.end() )
         continue;
      if( prev_state.old_values.find(obj.second->id) == prev_state.old_values.end() )
         prev_state.old_values[obj.second->id] = std::move(obj.second);
   }
   for( auto id : state.new_ids )
      prev_state.new_ids.insert(id);
   for( auto& item : state.old_index_next_ids )
   {
      if( prev_state.old_index_next_ids.find( item.first ) == prev_state.old_index_next_ids.end() )
         prev_state.old_index_next_ids[item.first] = item.second;
   }
   for( auto& obj : state.removed )
      if( prev_state.new_ids.find(obj.second->id) == prev_state.new_ids.end() )
         prev_state.removed[obj.second->id] = std::move(obj.second);
      else
         prev_state.new_ids.erase(obj.second->id);
   _stack.pop_back();
   --_active_sessions;
}
void undo_database::commit()
{
   FC_ASSERT( _active_sessions > 0 );
   --_active_sessions;
}

void undo_database::pop_commit()
{
   FC_ASSERT( _active_sessions == 0 );
   FC_ASSERT( !_stack.empty() );

   disable();
   try {
      auto& state = _stack.back();

      for( auto& item : state.old_values )
      {
         _db.modify( _db.get_object( item.second->id ), [&]( object& obj ){ obj.move_from( *item.second ); } );
      }

      for( auto ritr = state.new_ids.rbegin(); ritr != state.new_ids.rend(); ++ritr  )
      {
         _db.remove( _db.get_object(*ritr) );
      }

      for( auto& item : state.old_index_next_ids )
      {
         _db.get_mutable_index( item.first.space(), item.first.type() ).set_next_id( item.second );
      }

      for( auto& item : state.removed )
         _db.insert( std::move(*item.second) );

      _stack.pop_back();
   }
   catch ( const fc::exception& e )
   {
      elog( "error popping commit ${e}", ("e", e.to_detail_string() )  );
      enable();
      throw;
   }
   enable();
}

} } // bts::db
<|endoftext|>