<commit_before>/**************************************************************************
 * Copyright(c) 1998-2007, 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.                  *
 **************************************************************************/

#include "AliMuonAnalysisOutput.h"

// ROOT includes
#include "TAxis.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "THashList.h"
#include "TRegexp.h"
#include "TFile.h"
#include "TMath.h"

// STEER inlcudes
#include "AliLog.h"

// PWG includes
#include "AliCounterCollection.h"
#include "AliMergeableCollection.h"

/// \cond CLASSIMP
ClassImp(AliMuonAnalysisOutput) // Class implementation in ROOT context
/// \endcond

//________________________________________________________________________
AliMuonAnalysisOutput::AliMuonAnalysisOutput ( TObjArray* outputList, const char* name ) :
  TNamed(name,name),
  fCounterCollection(0x0),
  fMergeableCollection(0x0),
  fOutputList(outputList),
  fIsOwner(0)
//,
//  fOutputPrototypeList(0x0)
{
  //
  /// Constructor
  //
  Init();
}

//________________________________________________________________________
AliMuonAnalysisOutput::AliMuonAnalysisOutput ( const char *filename, const char* outputName ) :
  TNamed(filename,filename),
  fCounterCollection(0x0),
  fMergeableCollection(0x0),
  fOutputList(0x0),
  fIsOwner(kTRUE)
//,
//  fOutputPrototypeList(0x0)
{
  //
  /// Constructor
  //
  TFile* file = TFile::Open(filename);
  if ( file ) {
    fOutputList = static_cast<TObjArray*>(file->FindObjectAny(outputName));
    delete file;
  }
  else AliError(Form("Cannot open %s",filename));

  Init();
}

//________________________________________________________________________
AliMuonAnalysisOutput::~AliMuonAnalysisOutput()
{
  //
  /// Destructor
  //
  if ( fIsOwner ) delete fOutputList;
}

//________________________________________________________________________
Bool_t AliMuonAnalysisOutput::Init()
{
  //
  /// Initialize objects
  //
  if ( ! fOutputList ) {
    AliError("No output list provided or found!");
    return kTRUE;
  }
  fCounterCollection = static_cast<AliCounterCollection*>(fOutputList->At(0));
  fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->At(1));

  return kTRUE;
}

////________________________________________________________________________
//Bool_t AliMuonAnalysisOutput::AddObjectToCollection ( TObject* object )
//{
//  //
//  /// Add object to collection
//  //
//
//  if ( ! fOutputPrototypeList ) {
//    fOutputPrototypeList = new THashList();
//    fOutputPrototypeList->SetOwner();
//  }
//  if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
//    AliWarning(Form("Object with name %s already in the list", object->GetName()));
//    return kFALSE;
//  }
//  fOutputPrototypeList->Add(object);
//
//  return kTRUE;
//}

//________________________________________________________________________
TObject* AliMuonAnalysisOutput::GetMergeableObject ( TString physSel, TString trigClassName, TString centrality, TString objectName )
{
  //
  /// Get mergeable object
  /// (create collection if necessary)
  //

  if ( ! fMergeableCollection ) return 0x0;

  TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());

  return fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
//  if ( ! obj ) {
//    CreateMergeableObjects(physSel, trigClassName, centrality);
//    obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
//    AliInfo(Form("Mergeable object collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
//  }
//  return obj;
}

//________________________________________________________________________
TObject* AliMuonAnalysisOutput::GetSum ( TString physSel, TString trigClassNames, TString centrality, TString objectPattern )
{
  //
  /// Sum objects
  /// - physSel, trigClassNames must be in the form: key1,key2
  /// - centrality must be in the form minValue_maxValue
  /// - objectPattern must be in the form match1,match2
  ///   meaning that the object name must contain match1 or match2
  ///   wildcard * is allowed

  if ( ! fMergeableCollection ) return 0x0;

  TString sumCentralityString = GetCentralities(centrality);

  TObjString* objString = 0x0;

  THashList objectNameInCollection;
  objectNameInCollection.SetOwner();
  TObjArray* physSelList = physSel.Tokenize(",");
  TObjArray* trigClassList = trigClassNames.Tokenize(",");
  TObjArray* centralityList = sumCentralityString.Tokenize(",");
  for ( Int_t isel=0; isel<physSelList->GetEntriesFast(); isel++ ) {
    for ( Int_t itrig = 0; itrig<trigClassList->GetEntriesFast(); itrig++ ) {
      for ( Int_t icent=0; icent<centralityList->GetEntriesFast(); icent++ ) {
        TString currId = Form("/%s/%s/%s/", physSelList->UncheckedAt(isel)->GetName(), trigClassList->UncheckedAt(itrig)->GetName(),centralityList->UncheckedAt(icent)->GetName());
        TList* objNameList = fMergeableCollection->CreateListOfObjectNames(currId.Data());
        TIter next(objNameList);
        while ( (objString = static_cast<TObjString*>(next())) ) {
          if ( ! objectNameInCollection.FindObject(objString->GetName()) ) objectNameInCollection.Add(new TObjString(objString->GetName()));
        }
        delete objNameList;
      }
    }
  }
  delete physSelList;
  delete trigClassList;
  delete centralityList;

  TObjArray* objPatternList = objectPattern.Tokenize(",");

  TString matchingObjectNames = "";
  TIter next(&objectNameInCollection);
  while ( (objString = static_cast<TObjString*>(next())) ) {
    TString objName = objString->String();
    for ( Int_t ipat=0; ipat<objPatternList->GetEntriesFast(); ipat++ ) {
      TString currPattern = objPatternList->UncheckedAt(ipat)->GetName();
      if ( currPattern.Contains("*") ) {
        if ( ! objName.Contains(TRegexp(currPattern.Data(),kTRUE)) ) continue;
      }
      else if ( objName != currPattern ) continue;

      if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
      matchingObjectNames += objName;
    }
  }
  delete objPatternList;

  TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
  idPattern.ReplaceAll(" ","");

  AliDebug(1,Form("Sum pattern %s", idPattern.Data()));

  return fMergeableCollection->GetSum(idPattern.Data());
}

////___________________________________________________________________________
//void AliMuonAnalysisOutput::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
//{
//  //
//  /// Create mergeable objects
//  //
//  TObject* obj = 0x0;
//  TString objectName = "";
//  TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
//  for ( Int_t iobj=0; iobj<fOutputPrototypeList->GetEntries(); ++iobj ) {
//    objectName = fOutputPrototypeList->At(iobj)->GetName();
//    obj = fOutputPrototypeList->At(iobj)->Clone(objectName.Data());
//    fMergeableCollection->Adopt(identifier, obj);
//  } // loop on histos
//}

//______________________________________________
TString AliMuonAnalysisOutput::GetCentralities ( const TString centralityRange ) const
{
  /// Get list of centrality bins in mergeable collection
  /// matching the chosen centrality range
  /// Centrality range is in the form minVal1_maxVal1,minVal2_maxVal2,etc...

  if ( centralityRange.Contains(",") ) return centralityRange;

  TString matchingCentralities = "";
  if ( ! centralityRange.Contains("_") ) {
    AliError("Centrality range must be in the form: minVal_maxVal");
    return matchingCentralities;
  }

  TObjArray* centralityRangeArr = centralityRange.Tokenize("_");
  Double_t minCentr = static_cast<TObjString*>(centralityRangeArr->At(0))->GetString().Atof();
  Double_t maxCentr = static_cast<TObjString*>(centralityRangeArr->At(1))->GetString().Atof();
  delete centralityRangeArr;

  TList* centrKeyList = fMergeableCollection->CreateListOfKeys(2);
  for ( Int_t ikey=0; ikey<centrKeyList->GetEntries(); ikey++ ) {
    TString centr = centrKeyList->At(ikey)->GetName();
    TObjArray* array = centr.Tokenize("_");
    Double_t currMinCentr = static_cast<TObjString*>(array->At(0))->GetString().Atof();
    Double_t currMaxCentr = static_cast<TObjString*>(array->At(1))->GetString().Atof();
    delete array;
    if ( currMinCentr >= minCentr && currMaxCentr <= maxCentr ) {
      if ( ! matchingCentralities.IsNull() ) matchingCentralities.Append(",");
      matchingCentralities += centr;
    }
  }

  AliDebug(2,Form("Centralities in %s: %s",centralityRange.Data(),matchingCentralities.Data()));

  return matchingCentralities;
}

//______________________________________________
Bool_t AliMuonAnalysisOutput::RemoveFromList ( TObject* obj )
{
  /// Remove object from the list (to save memory)
  if ( ! fIsOwner ) {
    AliError("Operation not permitted: you're not the onwer of the list");
    return kFALSE;
  }

  TObject* removedObj = fOutputList->Remove(obj);
  if ( ! removedObj ) {
    AliWarning(Form("Cannot find object. Nothing done"));
    return kFALSE;
  }
  AliDebug(1,Form("Removing %s (%s) from output list",removedObj->GetName(),removedObj->ClassName()));

  if ( fCounterCollection == removedObj ) fCounterCollection = 0x0;
  else if ( fMergeableCollection == removedObj ) fMergeableCollection = 0x0;
  fOutputList->Compress();
  delete removedObj;

  return kTRUE;
}
<commit_msg>Return kFALSE in case of problems<commit_after>/**************************************************************************
 * Copyright(c) 1998-2007, 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.                  *
 **************************************************************************/

#include "AliMuonAnalysisOutput.h"

// ROOT includes
#include "TAxis.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "THashList.h"
#include "TRegexp.h"
#include "TFile.h"
#include "TMath.h"

// STEER inlcudes
#include "AliLog.h"

// PWG includes
#include "AliCounterCollection.h"
#include "AliMergeableCollection.h"

/// \cond CLASSIMP
ClassImp(AliMuonAnalysisOutput) // Class implementation in ROOT context
/// \endcond

//________________________________________________________________________
AliMuonAnalysisOutput::AliMuonAnalysisOutput ( TObjArray* outputList, const char* name ) :
  TNamed(name,name),
  fCounterCollection(0x0),
  fMergeableCollection(0x0),
  fOutputList(outputList),
  fIsOwner(0)
//,
//  fOutputPrototypeList(0x0)
{
  //
  /// Constructor
  //
  Init();
}

//________________________________________________________________________
AliMuonAnalysisOutput::AliMuonAnalysisOutput ( const char *filename, const char* outputName ) :
  TNamed(filename,filename),
  fCounterCollection(0x0),
  fMergeableCollection(0x0),
  fOutputList(0x0),
  fIsOwner(kTRUE)
//,
//  fOutputPrototypeList(0x0)
{
  //
  /// Constructor
  //
  TFile* file = TFile::Open(filename);
  if ( file ) {
    fOutputList = static_cast<TObjArray*>(file->FindObjectAny(outputName));
    delete file;
  }
  else AliError(Form("Cannot open %s",filename));

  Init();
}

//________________________________________________________________________
AliMuonAnalysisOutput::~AliMuonAnalysisOutput()
{
  //
  /// Destructor
  //
  if ( fIsOwner ) delete fOutputList;
}

//________________________________________________________________________
Bool_t AliMuonAnalysisOutput::Init()
{
  //
  /// Initialize objects
  //
  if ( ! fOutputList ) {
    AliError("No output list provided or found!");
    return kFALSE;
  }
  fCounterCollection = static_cast<AliCounterCollection*>(fOutputList->At(0));
  fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->At(1));

  return kTRUE;
}

////________________________________________________________________________
//Bool_t AliMuonAnalysisOutput::AddObjectToCollection ( TObject* object )
//{
//  //
//  /// Add object to collection
//  //
//
//  if ( ! fOutputPrototypeList ) {
//    fOutputPrototypeList = new THashList();
//    fOutputPrototypeList->SetOwner();
//  }
//  if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
//    AliWarning(Form("Object with name %s already in the list", object->GetName()));
//    return kFALSE;
//  }
//  fOutputPrototypeList->Add(object);
//
//  return kTRUE;
//}

//________________________________________________________________________
TObject* AliMuonAnalysisOutput::GetMergeableObject ( TString physSel, TString trigClassName, TString centrality, TString objectName )
{
  //
  /// Get mergeable object
  /// (create collection if necessary)
  //

  if ( ! fMergeableCollection ) return 0x0;

  TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());

  return fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
//  if ( ! obj ) {
//    CreateMergeableObjects(physSel, trigClassName, centrality);
//    obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
//    AliInfo(Form("Mergeable object collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
//  }
//  return obj;
}

//________________________________________________________________________
TObject* AliMuonAnalysisOutput::GetSum ( TString physSel, TString trigClassNames, TString centrality, TString objectPattern )
{
  //
  /// Sum objects
  /// - physSel, trigClassNames must be in the form: key1,key2
  /// - centrality must be in the form minValue_maxValue
  /// - objectPattern must be in the form match1,match2
  ///   meaning that the object name must contain match1 or match2
  ///   wildcard * is allowed

  if ( ! fMergeableCollection ) return 0x0;

  TString sumCentralityString = GetCentralities(centrality);

  TObjString* objString = 0x0;

  THashList objectNameInCollection;
  objectNameInCollection.SetOwner();
  TObjArray* physSelList = physSel.Tokenize(",");
  TObjArray* trigClassList = trigClassNames.Tokenize(",");
  TObjArray* centralityList = sumCentralityString.Tokenize(",");
  for ( Int_t isel=0; isel<physSelList->GetEntriesFast(); isel++ ) {
    for ( Int_t itrig = 0; itrig<trigClassList->GetEntriesFast(); itrig++ ) {
      for ( Int_t icent=0; icent<centralityList->GetEntriesFast(); icent++ ) {
        TString currId = Form("/%s/%s/%s/", physSelList->UncheckedAt(isel)->GetName(), trigClassList->UncheckedAt(itrig)->GetName(),centralityList->UncheckedAt(icent)->GetName());
        TList* objNameList = fMergeableCollection->CreateListOfObjectNames(currId.Data());
        TIter next(objNameList);
        while ( (objString = static_cast<TObjString*>(next())) ) {
          if ( ! objectNameInCollection.FindObject(objString->GetName()) ) objectNameInCollection.Add(new TObjString(objString->GetName()));
        }
        delete objNameList;
      }
    }
  }
  delete physSelList;
  delete trigClassList;
  delete centralityList;

  TObjArray* objPatternList = objectPattern.Tokenize(",");

  TString matchingObjectNames = "";
  TIter next(&objectNameInCollection);
  while ( (objString = static_cast<TObjString*>(next())) ) {
    TString objName = objString->String();
    for ( Int_t ipat=0; ipat<objPatternList->GetEntriesFast(); ipat++ ) {
      TString currPattern = objPatternList->UncheckedAt(ipat)->GetName();
      if ( currPattern.Contains("*") ) {
        if ( ! objName.Contains(TRegexp(currPattern.Data(),kTRUE)) ) continue;
      }
      else if ( objName != currPattern ) continue;

      if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
      matchingObjectNames += objName;
    }
  }
  delete objPatternList;

  TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
  idPattern.ReplaceAll(" ","");

  AliDebug(1,Form("Sum pattern %s", idPattern.Data()));

  return fMergeableCollection->GetSum(idPattern.Data());
}

////___________________________________________________________________________
//void AliMuonAnalysisOutput::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
//{
//  //
//  /// Create mergeable objects
//  //
//  TObject* obj = 0x0;
//  TString objectName = "";
//  TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
//  for ( Int_t iobj=0; iobj<fOutputPrototypeList->GetEntries(); ++iobj ) {
//    objectName = fOutputPrototypeList->At(iobj)->GetName();
//    obj = fOutputPrototypeList->At(iobj)->Clone(objectName.Data());
//    fMergeableCollection->Adopt(identifier, obj);
//  } // loop on histos
//}

//______________________________________________
TString AliMuonAnalysisOutput::GetCentralities ( const TString centralityRange ) const
{
  /// Get list of centrality bins in mergeable collection
  /// matching the chosen centrality range
  /// Centrality range is in the form minVal1_maxVal1,minVal2_maxVal2,etc...

  if ( centralityRange.Contains(",") ) return centralityRange;

  TString matchingCentralities = "";
  if ( ! centralityRange.Contains("_") ) {
    AliError("Centrality range must be in the form: minVal_maxVal");
    return matchingCentralities;
  }

  TObjArray* centralityRangeArr = centralityRange.Tokenize("_");
  Double_t minCentr = static_cast<TObjString*>(centralityRangeArr->At(0))->GetString().Atof();
  Double_t maxCentr = static_cast<TObjString*>(centralityRangeArr->At(1))->GetString().Atof();
  delete centralityRangeArr;

  TList* centrKeyList = fMergeableCollection->CreateListOfKeys(2);
  for ( Int_t ikey=0; ikey<centrKeyList->GetEntries(); ikey++ ) {
    TString centr = centrKeyList->At(ikey)->GetName();
    TObjArray* array = centr.Tokenize("_");
    Double_t currMinCentr = static_cast<TObjString*>(array->At(0))->GetString().Atof();
    Double_t currMaxCentr = static_cast<TObjString*>(array->At(1))->GetString().Atof();
    delete array;
    if ( currMinCentr >= minCentr && currMaxCentr <= maxCentr ) {
      if ( ! matchingCentralities.IsNull() ) matchingCentralities.Append(",");
      matchingCentralities += centr;
    }
  }

  AliDebug(2,Form("Centralities in %s: %s",centralityRange.Data(),matchingCentralities.Data()));

  return matchingCentralities;
}

//______________________________________________
Bool_t AliMuonAnalysisOutput::RemoveFromList ( TObject* obj )
{
  /// Remove object from the list (to save memory)
  if ( ! fIsOwner ) {
    AliError("Operation not permitted: you're not the onwer of the list");
    return kFALSE;
  }

  TObject* removedObj = fOutputList->Remove(obj);
  if ( ! removedObj ) {
    AliWarning(Form("Cannot find object. Nothing done"));
    return kFALSE;
  }
  AliDebug(1,Form("Removing %s (%s) from output list",removedObj->GetName(),removedObj->ClassName()));

  if ( fCounterCollection == removedObj ) fCounterCollection = 0x0;
  else if ( fMergeableCollection == removedObj ) fMergeableCollection = 0x0;
  fOutputList->Compress();
  delete removedObj;

  return kTRUE;
}
<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "games.h"

HiLoGame gHiLo;

const float WIN_INIT=0.05;

bool HiLoGame::enter(const TBeing *ch)
{
  if(inuse){
    ch->sendTo("This table is already in use.\n\r");
    return false;
  }

  inuse = true;
  bet = 0;
  name=ch->name;

  return true;
}

bool TBeing::checkHiLo(bool inGame = false) const
{
  if (in_room == ROOM_HILO && (inGame || (gHiLo.index(this) > -1)))
    return true;
  else
    return false;
}

void HiLoGame::BetHi(TBeing *ch, const Card *new_card)
{
  sstring buf;

  if(new_card->getValAceHi() > card->getValAceHi()){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf, TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);

    if(win_perc > 10){
      ch->sendTo("You've reach the win limit.\n\r");
      stay(ch);
    }

  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::BetLo(TBeing *ch, const Card *new_card)
{
  sstring buf;

  if(new_card->getValAceHi() < card->getValAceHi()){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf, TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);

    if(win_perc > 10){
      ch->sendTo("You've reach the win limit.\n\r");
      stay(ch);
    }

  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::stay(TBeing *ch)
{
  if(win_perc==WIN_INIT){
    ch->sendTo("You just started, you can't quit now!\n\r");
    return;
  }

  ch->sendTo("You give up and cash out your winnings.\n\r");
  act("$n gives up and cashes out $s winnings.",
      TRUE, ch, 0, 0, TO_ROOM);

  const Card *next_card=deck.draw();
  vlogf(LOG_PEEL, "drew %s", next_card->getName());

  sstring buf;
  ch->sendTo(COLOR_BASIC,"The next card was the %s.\n\r",next_card->getName());

  ssprintf(buf, "The next card was the %s.", next_card->getName());
  act(buf, TRUE, ch, 0, 0, TO_ROOM);

  payout(ch, (int)((double)bet * (1.0 + win_perc)));
  bet = 0;
  card = 0;
  observerReaction(ch, GAMBLER_WON);
}

void HiLoGame::Bet(TBeing *ch, const sstring &arg)
{
  const Card *new_card;
  sstring coin_str;
  sstring log_msg;
  sstring buf;
  TObj *chip;

  if (ch->checkHiLo()) {
    if (index(ch) < 0) {
      ch->sendTo("You are not sitting at the table yet.\n\r");
      return;
    }
    if (bet > 0) {
      if(arg=="hi" || arg=="lo"){
	new_card=deck.draw();
	vlogf(LOG_PEEL, "drew %s", new_card->getName());

	ssprintf(buf, "$n bets %s.", arg.c_str());
	act(buf, TRUE, ch, 0, 0, TO_ROOM);

	ch->sendTo(COLOR_BASIC,"You are dealt:\n\r%s\n\r",new_card->getName());

	ssprintf(log_msg, "$n is dealt:\n\r%s", new_card->getName());
	act(log_msg, TRUE, ch, 0, 0, TO_ROOM);

	if(arg=="hi"){
	  BetHi(ch, new_card);
	} else if(arg=="lo"){
	  BetLo(ch, new_card);
	}
	card=new_card;
	return;
      } else {
	ch->sendTo("You can't change your bet now.\n\r");
	ch->sendTo("You must either bet 'hi' or 'lo' for the next card.\n\r");
	return;
      }
    }
    argument_parser(arg, coin_str);
    if (coin_str.empty()){
      ch->sendTo("Bet which chip?\n\r");
      return;
    }

    if(!(chip=find_chip(ch, coin_str))){
      ch->sendTo("You don't have that chip!\n\r");
      return;
    }

    bet = chip->obj_flags.cost;
    ch->doSave(SILENT_YES);

    sstring buf;
    ssprintf(buf, "$n bets %s.", chip->getName());
    act(buf, TRUE, ch, 0, 0, TO_ROOM);
    ssprintf(buf, "You bet %s.", chip->getName());
    act(buf, TRUE, ch, 0, 0, TO_CHAR);

    (*chip)--;
    delete chip;

    win_perc=WIN_INIT;
    card=NULL;

    deck.shuffle();
    act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_CHAR);
    act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_ROOM);

    card=deck.draw();
    vlogf(LOG_PEEL, "drew %s", card->getName());

    ch->sendTo(COLOR_BASIC, "You are dealt:\n\r%s\n\r", card->getName());

    ssprintf(log_msg, "$n is dealt:\n\r%s\n\r", card->getName());
    act(log_msg, TRUE, ch, 0, 0, TO_ROOM);

    observerReaction(ch, GAMBLER_HILO_BET);
  }
}

void HiLoGame::peek(const TBeing *ch)
{
  sstring log_msg;

  if (index(ch) < 0) {
    ch->sendTo("You are not sitting at the table yet.\n\r");
    return;
  }
  if (!bet) {
    ch->sendTo("You are not playing a game.\n\r");
    return;
  }
  ssprintf(log_msg, "You peek at your hand:\n\r%s\n\r", card->getName());
  ch->sendTo(COLOR_BASIC, log_msg);
}

int HiLoGame::exitGame(const TBeing *ch)
{
  int inx;

  if ((inx = index(ch)) < 0) {
    forceCrash("%s left a table he was not at!", ch->name);
    return FALSE;
  }
  inuse = FALSE;
  name="";
  bet = 0;
  card = 0;
  win_perc=0;
  setup_deck();
  ch->sendTo("You leave the hi-lo table.\n\r");
  return TRUE;
}

int HiLoGame::index(const TBeing *ch) const
{
  if(ch->name == name)
    return 0;

  return -1;
}
<commit_msg>removed debug log<commit_after>#include "stdsneezy.h"
#include "games.h"

HiLoGame gHiLo;

const float WIN_INIT=0.05;

bool HiLoGame::enter(const TBeing *ch)
{
  if(inuse){
    ch->sendTo("This table is already in use.\n\r");
    return false;
  }

  inuse = true;
  bet = 0;
  name=ch->name;

  return true;
}

bool TBeing::checkHiLo(bool inGame = false) const
{
  if (in_room == ROOM_HILO && (inGame || (gHiLo.index(this) > -1)))
    return true;
  else
    return false;
}

void HiLoGame::BetHi(TBeing *ch, const Card *new_card)
{
  sstring buf;

  if(new_card->getValAceHi() > card->getValAceHi()){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf, TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);

    if(win_perc > 10){
      ch->sendTo("You've reach the win limit.\n\r");
      stay(ch);
    }

  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::BetLo(TBeing *ch, const Card *new_card)
{
  sstring buf;

  if(new_card->getValAceHi() < card->getValAceHi()){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf, TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);

    if(win_perc > 10){
      ch->sendTo("You've reach the win limit.\n\r");
      stay(ch);
    }

  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::stay(TBeing *ch)
{
  if(win_perc==WIN_INIT){
    ch->sendTo("You just started, you can't quit now!\n\r");
    return;
  }

  ch->sendTo("You give up and cash out your winnings.\n\r");
  act("$n gives up and cashes out $s winnings.",
      TRUE, ch, 0, 0, TO_ROOM);

  const Card *next_card=deck.draw();
  //  vlogf(LOG_PEEL, "drew %s", next_card->getName());

  sstring buf;
  ch->sendTo(COLOR_BASIC,"The next card was the %s.\n\r",next_card->getName());

  ssprintf(buf, "The next card was the %s.", next_card->getName());
  act(buf, TRUE, ch, 0, 0, TO_ROOM);

  payout(ch, (int)((double)bet * (1.0 + win_perc)));
  bet = 0;
  card = 0;
  observerReaction(ch, GAMBLER_WON);
}

void HiLoGame::Bet(TBeing *ch, const sstring &arg)
{
  const Card *new_card;
  sstring coin_str;
  sstring log_msg;
  sstring buf;
  TObj *chip;

  if (ch->checkHiLo()) {
    if (index(ch) < 0) {
      ch->sendTo("You are not sitting at the table yet.\n\r");
      return;
    }
    if (bet > 0) {
      if(arg=="hi" || arg=="lo"){
	new_card=deck.draw();
	//	vlogf(LOG_PEEL, "drew %s", new_card->getName());

	ssprintf(buf, "$n bets %s.", arg.c_str());
	act(buf, TRUE, ch, 0, 0, TO_ROOM);

	ch->sendTo(COLOR_BASIC,"You are dealt:\n\r%s\n\r",new_card->getName());

	ssprintf(log_msg, "$n is dealt:\n\r%s", new_card->getName());
	act(log_msg, TRUE, ch, 0, 0, TO_ROOM);

	if(arg=="hi"){
	  BetHi(ch, new_card);
	} else if(arg=="lo"){
	  BetLo(ch, new_card);
	}
	card=new_card;
	return;
      } else {
	ch->sendTo("You can't change your bet now.\n\r");
	ch->sendTo("You must either bet 'hi' or 'lo' for the next card.\n\r");
	return;
      }
    }
    argument_parser(arg, coin_str);
    if (coin_str.empty()){
      ch->sendTo("Bet which chip?\n\r");
      return;
    }

    if(!(chip=find_chip(ch, coin_str))){
      ch->sendTo("You don't have that chip!\n\r");
      return;
    }

    bet = chip->obj_flags.cost;
    ch->doSave(SILENT_YES);

    sstring buf;
    ssprintf(buf, "$n bets %s.", chip->getName());
    act(buf, TRUE, ch, 0, 0, TO_ROOM);
    ssprintf(buf, "You bet %s.", chip->getName());
    act(buf, TRUE, ch, 0, 0, TO_CHAR);

    (*chip)--;
    delete chip;

    win_perc=WIN_INIT;
    card=NULL;

    deck.shuffle();
    act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_CHAR);
    act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_ROOM);

    card=deck.draw();
    //    vlogf(LOG_PEEL, "drew %s", card->getName());

    ch->sendTo(COLOR_BASIC, "You are dealt:\n\r%s\n\r", card->getName());

    ssprintf(log_msg, "$n is dealt:\n\r%s\n\r", card->getName());
    act(log_msg, TRUE, ch, 0, 0, TO_ROOM);

    observerReaction(ch, GAMBLER_HILO_BET);
  }
}

void HiLoGame::peek(const TBeing *ch)
{
  sstring log_msg;

  if (index(ch) < 0) {
    ch->sendTo("You are not sitting at the table yet.\n\r");
    return;
  }
  if (!bet) {
    ch->sendTo("You are not playing a game.\n\r");
    return;
  }
  ssprintf(log_msg, "You peek at your hand:\n\r%s\n\r", card->getName());
  ch->sendTo(COLOR_BASIC, log_msg);
}

int HiLoGame::exitGame(const TBeing *ch)
{
  int inx;

  if ((inx = index(ch)) < 0) {
    forceCrash("%s left a table he was not at!", ch->name);
    return FALSE;
  }
  inuse = FALSE;
  name="";
  bet = 0;
  card = 0;
  win_perc=0;
  setup_deck();
  ch->sendTo("You leave the hi-lo table.\n\r");
  return TRUE;
}

int HiLoGame::index(const TBeing *ch) const
{
  if(ch->name == name)
    return 0;

  return -1;
}
<|endoftext|>


<commit_before>#include <mapbox/geojsonvt.hpp>
#include <memory>
#include "util.hpp"

using namespace mapbox::geojsonvt;

int main() {

    unsigned iterations = 1000;

    std::string filename("data/countries.geojson");
    std::string data = loadFile(filename);
    // load once before benchmarking to warm up
    const auto features = GeoJSONVT::convertFeatures(data);
    std::unique_ptr<GeoJSONVT> vt = std::make_unique<GeoJSONVT>(features);

    Timer timer;

    for (unsigned i=0;i<iterations;++i) {
        GeoJSONVT::convertFeatures(data);
    }
    timer.report("convertFeatures");

    for (unsigned i=0;i<iterations;++i) {
        std::make_unique<GeoJSONVT>(features);
    }
    timer.report("parse");

    for (unsigned z=0;z<255;++z) {
        for (unsigned x=0;x<255;++x) {
            for (unsigned y=0;y<255;++y) {
                vt->getTile(z, x, y);
            }
        }
    }
    timer.report("getTile");
}<commit_msg>dodge lacking support for std::make_unique in older clang-3.5<commit_after>#include <mapbox/geojsonvt.hpp>
#include <memory>
#include "util.hpp"

using namespace mapbox::geojsonvt;

int main() {

    unsigned iterations = 1000;

    std::string filename("data/countries.geojson");
    std::string data = loadFile(filename);
    // load once before benchmarking to warm up
    const auto features = GeoJSONVT::convertFeatures(data);
    GeoJSONVT vt(features);

    Timer timer;

    for (unsigned i=0;i<iterations;++i) {
        GeoJSONVT::convertFeatures(data);
    }
    timer.report("convertFeatures");

    for (unsigned i=0;i<iterations;++i) {
        GeoJSONVT vt_(features);
    }
    timer.report("parse");

    for (unsigned z=0;z<255;++z) {
        for (unsigned x=0;x<255;++x) {
            for (unsigned y=0;y<255;++y) {
                vt.getTile(z, x, y);
            }
        }
    }
    timer.report("getTile");
}<|endoftext|>


<commit_before>#include "srm/count.hpp"
#include "srm/report.hpp"
#include "srm/table.hpp"

#include "testutil.hpp"

#include <sstream>
#include <sys/time.h>
#include <climits>

// Program that reads text of length n as input and repeats the following:
// Select two a substring length s in [0, n / 2] and two substrings Y and Z,
// Y <= Z with lengths s at random. Runs different range matching algorithms
// to finds suffices of text lexicographically in [Y, Z). Prints tuple
//   s <match count> <lcp of the substrings> <time to count> <time to report> <time to table>.
// The number of iterations can be limited by a command line argument.

/// Gets the current processor time in seconds. Linux specific, implement for
/// other platforms.
double getCPUTime() {
	timespec t;
	if(clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t)) {
		fail("Measuring CPU time failed.");
	}
	return (double)t.tv_sec + 1e-9 * (double)t.tv_nsec;
}

class Timer {
public:
	Timer() {
		reset();
	}

	void reset() {
		start = getCPUTime();
	}

	double getElapsedTime() {
		return getCPUTime() - start;
	}

private:
	double start;
};

/// Simple O(n log n) suffix array construction taken from:
///   http://github.com/ttalvitie/libcontest
/// Return the start indices of the suffices of string S sorted in
/// lexicographical order. Characters past the end come before other characters
/// in the order. The empty suffix is included.
vector<int> constructSuffixArray(const string& S) {
	struct Elem {
		int start;
		int parts[2];
	};

	int n = S.size();
	vector<pair<char, int> > C(n + 1);
	vector<int> tmp(n + 1);
	vector<Elem> T(n + 1);
	vector<Elem> T2(n + 1);

	for(int i = 0; i <= n; ++i) {
		C[i].first = (i == n) ? CHAR_MIN : S[i];
		C[i].second = -i;
	}
	sort(C.begin(), C.end());

	for(int i = 0; i <= n; ++i) {
		int start = -C[i].second;
		T[i].start = start;
		if(start == n) {
			T[i].parts[0] = 0;
		} else {
			T[i].parts[0] = 1;
			T[i].parts[1] = S[start];
		}
	}

	int t = 1;
	while(t <= n) {
		for(int i = 0; i <= n; ++i) {
			if(i != 0 &&
				T[i].parts[0] == T[i - 1].parts[0] &&
				T[i].parts[1] == T[i - 1].parts[1]
			) {
				tmp[T[i].start] = tmp[T[i - 1].start];
			} else {
				tmp[T[i].start] = i;
			}
		}

		for(int i = 0; i <= n; ++i) {
			T[i].start = i;
			T[i].parts[0] = (i + t > n) ? 0 : tmp[i + t];
			T[i].parts[1] = tmp[i];
		}

		for(int s = 0; s < 2; ++s) {
			fill(tmp.begin(), tmp.end(), 0);
			for(int i = 0; i <= n; ++i) {
				++tmp[T[i].parts[s]];
			}

			int x = 0;
			for(int i = 0; i <= n; ++i) {
				int y = tmp[i];
				tmp[i] = x;
				x += y;
			}

			for(int i = 0; i <= n; ++i) {
				T2[tmp[T[i].parts[s]]++] = T[i];
			}

			swap(T, T2);
		}

		t *= 2;
	}

	for(int i = 0; i <= n; ++i) {
		tmp[i] = T[i].start;
	}

	return tmp;
}

int main(int argc, char* argv[]) {
	// Read limit from command line.
	int64_t limit = -1;
	if(argc > 1) {
		stringstream ss(argv[1]);
		ss >> limit;
		if(ss.fail() || ss.bad() || !ss.eof() || argc > 2) {
			fail("Usage: ./benchmark [iteration limit].");
		}
	}

	// Read input text.
	string text;
	char buf[4096];
	while(cin.good()) {
		cin.read(buf, 4096);
		text.append(buf, cin.gcount());
	}
	if(cin.bad() || !cin.eof()) fail("Reading input failed.");

	size_t n = text.size();
	if(n < 16) fail("Too short text!");

	// Compute the suffix array. This is needed to facilitate finding suffices
	// with high lcp.
	vector<int> suffix_array = constructSuffixArray(text);

	// Filter out suffices that start after n/2 so that we can easily find
	// suffices that have at most n/2 size.
	auto new_end = remove_if(
		suffix_array.begin(), suffix_array.end(),
		[n](int x) {
			return (size_t)x > n / 2;
		}
	);
	suffix_array.erase(new_end, suffix_array.end());

	size_t log_n = 0;
	while(((size_t)1 << log_n) < n) ++log_n;

	for(int64_t i = 0; i != limit; ++i) {
		size_t s = logrand(n / 2);

		size_t a, b;
		a = rand((size_t)1, suffix_array.size() - 2);
		if(choice(true, false)) {
			// Select Z uniformly.
			b = rand((size_t)0, suffix_array.size() - 1);
		} else {
			// Prefer Y and Z that are close together in the suffix array so that we get
			// some cases with high LCP.

			if(choice(true, false)) {
				b = a - logrand(a);
			} else {
				b = a + logrand(suffix_array.size() - 1 - a);
			}
		}

		if(a > b) swap(a, b);

		auto y_begin = text.begin() + suffix_array[a];
		auto y_end = y_begin + s;
		auto z_begin = text.begin() + suffix_array[b];
		auto z_end = z_begin + s;

		// Make sure that Y <= Z.
		if(lexicographical_compare(z_begin, z_end, y_begin, y_end)) {
			fail();
			swap(a, b);
			swap(y_begin, z_begin);
			swap(y_end, z_end);
		}

		// Compute the LCP.
		size_t lcp = 0;
		while(lcp < s && *(y_begin + lcp) == *(z_begin + lcp)) ++lcp;

		Timer timer;

		// Try all the range matching algorithms, saving the results.

		// count
		timer.reset();

		size_t count_result =
			srm::makeRangeCounter(y_begin, y_end, z_begin, z_end)
				.count(text.begin(), text.end());

		double count_time = timer.getElapsedTime();

		// report
		vector<size_t> report_result;
		report_result.reserve(n);

		timer.reset();

		srm::reportRangeMatches(
			text.begin(), text.end(),
			y_begin, y_end,
			z_begin, z_end,
			[&](size_t i) { report_result.push_back(i); }
		);

		double report_time = timer.getElapsedTime();

		// table
		vector<bool> table_result(n);

		timer.reset();

		srm::computeRangeMatchTableToIterator(
			text.begin(), text.end(),
			y_begin, y_end,
			z_begin, z_end,
			table_result.begin()
		);

		double table_time = timer.getElapsedTime();

		// Cross-check results for validity, so that we get additional tests
		// and the compiler cannot realistically optimize things out.
		if(count_result != report_result.size()) {
			fail("Count and report disagree about the match count.");
		}

		for(size_t i : report_result) {
			if(table_result[i] == false) fail("Report and table disagree about a match.");
			table_result[i] = false;
		}
		for(size_t i = 0; i < n; ++i) {
			if(table_result[i] == true) fail("Report and table disagree about a match.");
		}

		cout << s << " " << count_result << " " << lcp << " " << count_time << " " << report_time << " " << table_time << "\n";
	}

	return 0;
}
<commit_msg>Added field to the benchmark output that shows the distribution used for bound string choice.<commit_after>#include "srm/count.hpp"
#include "srm/report.hpp"
#include "srm/table.hpp"

#include "testutil.hpp"

#include <sstream>
#include <sys/time.h>
#include <climits>

// Program that reads text of length n as input and repeats the following:
// Select two a substring length s in [0, n / 2] and two substrings Y and Z,
// Y <= Z with lengths s at random. Runs different range matching algorithms
// to finds suffices of text lexicographically in [Y, Z). Prints tuple
//   - Substring length s
//   - 1 if substrings were chosen with a distribution preferring string
//     lexicographically close, otherwise 0.
//   - Match count
//   - LCP of substrings
//   - Time to count
//   - Time to report
//   - Time to table
// The number of iterations can be limited by a command line argument.

/// Gets the current processor time in seconds. Linux specific, implement for
/// other platforms.
double getCPUTime() {
	timespec t;
	if(clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t)) {
		fail("Measuring CPU time failed.");
	}
	return (double)t.tv_sec + 1e-9 * (double)t.tv_nsec;
}

class Timer {
public:
	Timer() {
		reset();
	}

	void reset() {
		start = getCPUTime();
	}

	double getElapsedTime() {
		return getCPUTime() - start;
	}

private:
	double start;
};

/// Simple O(n log n) suffix array construction taken from:
///   http://github.com/ttalvitie/libcontest
/// Return the start indices of the suffices of string S sorted in
/// lexicographical order. Characters past the end come before other characters
/// in the order. The empty suffix is included.
vector<int> constructSuffixArray(const string& S) {
	struct Elem {
		int start;
		int parts[2];
	};

	int n = S.size();
	vector<pair<char, int> > C(n + 1);
	vector<int> tmp(n + 1);
	vector<Elem> T(n + 1);
	vector<Elem> T2(n + 1);

	for(int i = 0; i <= n; ++i) {
		C[i].first = (i == n) ? CHAR_MIN : S[i];
		C[i].second = -i;
	}
	sort(C.begin(), C.end());

	for(int i = 0; i <= n; ++i) {
		int start = -C[i].second;
		T[i].start = start;
		if(start == n) {
			T[i].parts[0] = 0;
		} else {
			T[i].parts[0] = 1;
			T[i].parts[1] = S[start];
		}
	}

	int t = 1;
	while(t <= n) {
		for(int i = 0; i <= n; ++i) {
			if(i != 0 &&
				T[i].parts[0] == T[i - 1].parts[0] &&
				T[i].parts[1] == T[i - 1].parts[1]
			) {
				tmp[T[i].start] = tmp[T[i - 1].start];
			} else {
				tmp[T[i].start] = i;
			}
		}

		for(int i = 0; i <= n; ++i) {
			T[i].start = i;
			T[i].parts[0] = (i + t > n) ? 0 : tmp[i + t];
			T[i].parts[1] = tmp[i];
		}

		for(int s = 0; s < 2; ++s) {
			fill(tmp.begin(), tmp.end(), 0);
			for(int i = 0; i <= n; ++i) {
				++tmp[T[i].parts[s]];
			}

			int x = 0;
			for(int i = 0; i <= n; ++i) {
				int y = tmp[i];
				tmp[i] = x;
				x += y;
			}

			for(int i = 0; i <= n; ++i) {
				T2[tmp[T[i].parts[s]]++] = T[i];
			}

			swap(T, T2);
		}

		t *= 2;
	}

	for(int i = 0; i <= n; ++i) {
		tmp[i] = T[i].start;
	}

	return tmp;
}

int main(int argc, char* argv[]) {
	// Read limit from command line.
	int64_t limit = -1;
	if(argc > 1) {
		stringstream ss(argv[1]);
		ss >> limit;
		if(ss.fail() || ss.bad() || !ss.eof() || argc > 2) {
			fail("Usage: ./benchmark [iteration limit].");
		}
	}

	// Read input text.
	string text;
	char buf[4096];
	while(cin.good()) {
		cin.read(buf, 4096);
		text.append(buf, cin.gcount());
	}
	if(cin.bad() || !cin.eof()) fail("Reading input failed.");

	size_t n = text.size();
	if(n < 16) fail("Too short text!");

	// Compute the suffix array. This is needed to facilitate finding suffices
	// with high lcp.
	vector<int> suffix_array = constructSuffixArray(text);

	// Filter out suffices that start after n/2 so that we can easily find
	// suffices that have at most n/2 size.
	auto new_end = remove_if(
		suffix_array.begin(), suffix_array.end(),
		[n](int x) {
			return (size_t)x > n / 2;
		}
	);
	suffix_array.erase(new_end, suffix_array.end());

	size_t log_n = 0;
	while(((size_t)1 << log_n) < n) ++log_n;

	for(int64_t i = 0; i != limit; ++i) {
		size_t s = logrand(n / 2);

		size_t a, b;
		a = rand((size_t)1, suffix_array.size() - 2);
		bool close = choice(true, false);
		if(close) {
			// Prefer Y and Z that are close together in the suffix array so that we get
			// some cases with high LCP.

			if(choice(true, false)) {
				b = a - logrand(a);
			} else {
				b = a + logrand(suffix_array.size() - 1 - a);
			}
		} else {
			// Select Z uniformly.
			b = rand((size_t)0, suffix_array.size() - 1);
		}

		if(a > b) swap(a, b);

		auto y_begin = text.begin() + suffix_array[a];
		auto y_end = y_begin + s;
		auto z_begin = text.begin() + suffix_array[b];
		auto z_end = z_begin + s;

		// Make sure that Y <= Z.
		if(lexicographical_compare(z_begin, z_end, y_begin, y_end)) {
			fail();
			swap(a, b);
			swap(y_begin, z_begin);
			swap(y_end, z_end);
		}

		// Compute the LCP.
		size_t lcp = 0;
		while(lcp < s && *(y_begin + lcp) == *(z_begin + lcp)) ++lcp;

		Timer timer;

		// Try all the range matching algorithms, saving the results.

		// count
		timer.reset();

		size_t count_result =
			srm::makeRangeCounter(y_begin, y_end, z_begin, z_end)
				.count(text.begin(), text.end());

		double count_time = timer.getElapsedTime();

		// report
		vector<size_t> report_result;
		report_result.reserve(n);

		timer.reset();

		srm::reportRangeMatches(
			text.begin(), text.end(),
			y_begin, y_end,
			z_begin, z_end,
			[&](size_t i) { report_result.push_back(i); }
		);

		double report_time = timer.getElapsedTime();

		// table
		vector<bool> table_result(n);

		timer.reset();

		srm::computeRangeMatchTableToIterator(
			text.begin(), text.end(),
			y_begin, y_end,
			z_begin, z_end,
			table_result.begin()
		);

		double table_time = timer.getElapsedTime();

		// Cross-check results for validity, so that we get additional tests
		// and the compiler cannot realistically optimize things out.
		if(count_result != report_result.size()) {
			fail("Count and report disagree about the match count.");
		}

		for(size_t i : report_result) {
			if(table_result[i] == false) fail("Report and table disagree about a match.");
			table_result[i] = false;
		}
		for(size_t i = 0; i < n; ++i) {
			if(table_result[i] == true) fail("Report and table disagree about a match.");
		}

		cout << s << " " << close << " " << count_result << " " << lcp << " " << count_time << " " << report_time << " " << table_time << "\n";
	}

	return 0;
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	サークル・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/glfw_app/blob/master/LICENSE
*/
//=====================================================================//
#include "common/vtx.hpp"

namespace imath {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	円クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class circle {

		vtx::ipos	center_;
		vtx::ipos	start_;
		vtx::ipos	term_;

		int32_t		x_;
		int32_t		y_;
		int32_t		p_;
		int32_t		radius_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクタ
		 */
		//-----------------------------------------------------------------//
		circle() noexcept :  center_(0), start_(0), term_(0),
			x_(0), y_(0), p_(0), radius_(0)
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief	中心を設定
			@param[in]	center	中心座標
		 */
		//-----------------------------------------------------------------//
		void set_center(const vtx::ipos& center) noexcept
		{
			center_ = center;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	開始、終点を設定（１８０度以内である事）@n
					※円にする場合「開始」と「終点」を逆にしてもう一度呼ぶ
			@param[in]	start	開始位置
			@param[in]	term	終端位置
			@return 不整合なら「false」
		 */
		//-----------------------------------------------------------------//
		bool set_start(const vtx::ipos& start, const vtx::ipos& term) noexcept
		{
			start_ = start;
			term_ = term;
			int32_t len0 = (start - center_).len();
			int32_t len1 = (term - center_).len();
			int32_t d = len0 - len1;
			if(-1 <= d && d <= 1) {
				radius_ = (len0 + len1) / 2;
				x_ = start.x;
				y_ = start.y;
//				p = (5 - radius_ * 4) / 4;
				return true;
			}
			else return false;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	ステップ
			@return 終端なら「true」
		 */
		//-----------------------------------------------------------------//
		bool step() noexcept
		{
			int32_t x = 0;
			int32_t y = radius_;
			int32_t p = (5 - radius_ * 4) / 4;
			// circlePoints(xCenter, yCenter, x, y, pix);
			while(x < y) {
				x++;
				if(p < 0) {
					p += 2 * x + 1;
				} else {
					y--;
					p += 2 * (x - y) + 1;
				}
				// circlePoints(xCenter, yCenter, x, y, pix);
			}
			return true;
		}
	};
}
<commit_msg>update: circle position output manage<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	サークル・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/glfw_app/blob/master/LICENSE
*/
//=====================================================================//
#include "common/vtx.hpp"

namespace imath {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	円クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class circle {

		vtx::ipos	start_;
		vtx::ipos	center_;
		vtx::ipos	term_;

		vtx::ipos	pos_;
		vtx::ipos	fin_;
		int32_t		rad_;
		int32_t		rad_sqr_;
		int32_t		oct_;

		bool		cw_;

		static int32_t octant_(const vtx::ipos& p) noexcept
		{
			uint32_t n = 0;
			if(std::abs(p.x) > std::abs(p.y)) n |= 0b001;
			if(p.x < 0) n |= 0b100;
			if(p.y < 0) n |= 0b010;
			static const int8_t map[8] = {
				0, 1, 3, 2, 7, 6, 4, 5
			};
			return map[n];
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクタ
		 */
		//-----------------------------------------------------------------//
		circle() noexcept :  start_(0), center_(0), term_(0),
			pos_(0), fin_(0), rad_(0), rad_sqr_(0), oct_(0), cw_(true)
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief	角度に対する座標
			@param[in]	an	角度（０～１．０）@n
							※０：３時、０．２５：６時、０．５：９時、０．７５：１２時
			@param[in]	rad	半径
		 */
		//-----------------------------------------------------------------//
		static vtx::ipos angle_to_position(float an, int32_t rad) noexcept
		{
			vtx::ipos pos;
			pos.x = cosf(an * vtx::radian_f_) * static_cast<float>(rad);
			pos.y = sinf(an * vtx::radian_f_) * static_cast<float>(rad);
			return pos;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	機能テスト用
		 */
		//-----------------------------------------------------------------//
		void test() noexcept
		{
			for(uint32_t i = 0; i < 8; ++i) {
				static const int pp[8 * 2] = {
					 50,  90,
					 90,  50,
					 90, -50,
					 50, -90,
					-50, -90,
					-90, -50,
					-90,  50,
					-50,  90
				};
				auto n = octant_(vtx::ipos(pp[i*2+0], pp[i*2+1]));
				utils::format("%d\n") % n;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	開始、終点を設定（１８０度以内である事）@n
					※円にする場合「開始」と「終点」を逆にしてもう一度呼ぶ
			@param[in]	sta	開始位置
			@param[in]	cen	中心位置
			@param[in]	fin	終端位置
			@param[in]	cw	反時計方向なら「false」
			@return 不整合なら「false」
		 */
		//-----------------------------------------------------------------//
		bool start(const vtx::ipos& sta, const vtx::ipos& cen, const vtx::ipos& fin, bool cw = true) noexcept
		{
			vtx::ipos d0 = sta - cen;
			vtx::ipos d1 = fin - cen;
			int32_t len0 = d0.len();
			int32_t len1 = d1.len();
			if(len0 != len1) {
				return false;
			}
			start_  = sta;
			center_ = cen;
			term_   = fin;
			cw_ = cw;
			oct_ = octant_(d1);

			rad_ = len0 * 2;
			rad_sqr_ = rad_ * rad_;
			pos_.x = d0.x * 2;
			pos_.y = d0.y * 2;
			fin_.x = d1.x * 2;
			fin_.y = d1.y * 2;

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	ステップ
			@return 終端なら「true」
		 */
		//-----------------------------------------------------------------//
		bool step() noexcept
		{
			bool limit = false;
			auto oct = octant_(pos_);
			switch(oct) {
			case 0:
			case 7:
				if(cw_) pos_.x += 2;
				else pos_.x -= 2;
				pos_.y = std::sqrt(rad_sqr_ - pos_.x * pos_.x);
				break;
			case 1:
			case 2:
				if(cw_) pos_.y -= 2;
				else pos_.y += 2;
				pos_.x = std::sqrt(rad_sqr_ - pos_.y * pos_.y);
				break;
			case 3:
			case 4:
				if(cw_) pos_.x -= 2;
				else pos_.x += 2;
				pos_.y = -std::sqrt(rad_sqr_ - pos_.x * pos_.x);
				break;
			case 5:
			case 6:
				if(cw_) pos_.y += 2;
				else pos_.y -= 2;
				pos_.x = -std::sqrt(rad_sqr_ - pos_.y * pos_.y);
				break;
			}
			if(oct != oct_) return false;

			switch(oct_) {
			case 0:
			case 1:
				if(cw_) {
					if(pos_.x >= fin_.x && pos_.y <= fin_.y) limit = true;
				} else {
					if(pos_.x <= fin_.x && pos_.y >= fin_.y) limit = true;
				}
				break;
			case 2:
			case 3:
				if(cw_) {
					if(pos_.x <= fin_.x && pos_.y <= fin_.y) limit = true;
				} else {
					if(pos_.x >= fin_.x && pos_.y >= fin_.y) limit = true;
				}
				break;
			case 4:
			case 5:
				if(cw_) {
					if(pos_.x <= fin_.x && pos_.y <= fin_.y) limit = true;
				} else {
					if(pos_.x >= fin_.x && pos_.y >= fin_.y) limit = true;
				}
				break;
			case 6:
			case 7:
				if(cw_) {
					if(pos_.x >= fin_.x && pos_.y >= fin_.y) limit = true;
				} else {
					if(pos_.x <= fin_.x && pos_.y <= fin_.y) limit = true;
				}
				break;
			}

			return limit;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	生成された位置を取得
			@return 生成された位置
		 */
		//-----------------------------------------------------------------//
		vtx::ipos get_position() const noexcept
		{
			vtx::ipos p;
			p.x = (pos_.x + 1) / 2 + center_.x;
			p.y = (pos_.y + 1) / 2 + center_.y;
			return p;
		}
	};
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX600 グループ・TPU I/O 制御
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/intr_utils.hpp"
#include "common/vect.h"

#include "common/format.hpp"

/// F_PCLKB は周期パラメーター計算で必要で、設定が無いとエラーにします。
#ifndef F_PCLKB
#  error "tpu_io.hpp requires F_PCLKB to be defined"
#endif

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  TPU I/O クラス
		@param[in]	TPU	チャネルクラス
		@param[in]	TASK	タイマー動作クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class TPU, class TASK = utils::null_task>
	class tpu_io {

		uint8_t		level_;

		static TASK	task_;

		static volatile uint32_t counter_;

		static INTERRUPT_FUNC void tpu_task_() {
			++counter_;
			task_();
		}

		void sleep_() const { asm("nop"); }

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		tpu_io() : level_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  動作開始
			@param[in]	freq	タイマー周波数
			@param[in]	level	割り込みレベル（０ならポーリング）
			@return レンジオーバーなら「false」を返す
		*/
		//-----------------------------------------------------------------//
		bool start(uint32_t freq, uint8_t level = 0)
		{
			if(freq == 0) return false;

			level_ = level;

			uint32_t cmt = F_PCLKB / freq;

			uint8_t cks = 0;
			while(cmt > 65536) {
				cmt >>= 1;
				++cks;
			}

			// プリスケーラーの算出 cks
			// 1: 1/2, 2: 1/4, 3: 1/8, ...
			// TPU0: 1/1(0), 1/4(2), 1/16(4), 1/64(6)
			uint8_t prs = 0;
			switch(cks) {
			case 1:
				cmt >>= 1;
			case 2:
				prs = 1;
				break;
			case 3:
				cmt >>= 1;
			case 4:
				prs = 2;
				break;
			case 5:
				cmt >>= 1;
			case 6:
				prs = 3;
				break;
			default:
				return false;
				break;
			}

			power_cfg::turn(TPU::get_peripheral());

			TPU::TCR = TPU::TCR.CCLR.b(1) | TPU::TCR.TPSC.b(prs);  // TGRA のコンペアマッチ
			if(cmt > 0) cmt--;
			TPU::TGRA = cmt;
			TPU::TCNT = 0x0000;

			if(level_ > 0) {  // 割り込み設定
				bool ena = level_ != 0 ? true : false;

				set_interrupt_task(tpu_task_, static_cast<uint32_t>(ICU::VECTOR::INTB128));
				ICU::SLIBXR128 = TPU::get_TGIA();
				ICU::IPR.INTB128 = level_;
				ICU::IER.INTB128 = ena;

				TPU::TIER.TGIEA = 1;  // TGRA interrupt
			} else {
				TPU::TIER.TGIEA = 0;
			}

			TPU::enable();

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  タイマー同期
		*/
		//-----------------------------------------------------------------//
		void sync() const
		{
			if(level_ > 0) {
				volatile uint32_t cnt = counter_;
				while(cnt == counter_) sleep_();
			} else {
				while(TPU::TSR.TGFA() == 0) sleep_();
				TPU::TSR.TGFA = 0;
				task_();
				++counter_;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  割り込みカウンターの値を取得
			@return 割り込みカウンターの値
		*/
		//-----------------------------------------------------------------//
		uint32_t get_counter() const { return counter_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  TASK クラスの参照
			@return TASK クラス
		*/
		//-----------------------------------------------------------------//
		static TASK& at_task() { return task_; }
	};

	template <class TPU, class TASK> volatile uint32_t tpu_io<TPU, TASK>::counter_ = 0;
	template <class TPU, class TASK> TASK tpu_io<TPU, TASK>::task_;

}
<commit_msg>fix TPU prs = 0<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX600 グループ・TPU I/O 制御
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/intr_utils.hpp"
#include "common/vect.h"

/// F_PCLKB は周期パラメーター計算で必要で、設定が無いとエラーにします。
#ifndef F_PCLKB
#  error "tpu_io.hpp requires F_PCLKB to be defined"
#endif

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  TPU I/O クラス
		@param[in]	TPU	チャネルクラス
		@param[in]	TASK	タイマー動作クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class TPU, class TASK = utils::null_task>
	class tpu_io {

		uint8_t		level_;

		static volatile uint32_t counter_;

		static TASK	task_;

		static INTERRUPT_FUNC void tpu_task_() {
			if(TPU::TSR.TGFA()) TPU::TSR.TGFA = 0;
			++counter_;
			task_();
		}

		void sleep_() const { asm("nop"); }

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		tpu_io() : level_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  動作開始
			@param[in]	freq	タイマー周波数
			@param[in]	level	割り込みレベル（０ならポーリング）
			@return レンジオーバーなら「false」を返す
		*/
		//-----------------------------------------------------------------//
		bool start(uint32_t freq, uint8_t level = 0)
		{
			if(freq == 0) return false;

			level_ = level;

			uint32_t cmt = F_PCLKB / freq;

			uint8_t cks = 0;
			while(cmt > 65536) {
				cmt >>= 1;
				++cks;
			}

			// プリスケーラーの算出 cks
			// 1: 1/2, 2: 1/4, 3: 1/8, ...
			// TPU0: 1/1(0), 1/4(2), 1/16(4), 1/64(6)
			uint8_t prs = 0;
			switch(cks) {
			case 0:
				break;
			case 1:
				cmt >>= 1;
			case 2:
				prs = 1;
				break;
			case 3:
				cmt >>= 1;
			case 4:
				prs = 2;
				break;
			case 5:
				cmt >>= 1;
			case 6:
				prs = 3;
				break;
			default:
				return false;
				break;
			}

			power_cfg::turn(TPU::get_peripheral());

			TPU::TCR = TPU::TCR.CCLR.b(1) | TPU::TCR.TPSC.b(prs);  // TGRA のコンペアマッチ
			if(cmt > 0) cmt--;
			TPU::TGRA = cmt;
			TPU::TCNT = 0x0000;

			if(level_ > 0) {  // 割り込み設定
#if (defined(SIG_RX64M) || defined(SIG_RX71M))
				set_interrupt_task(tpu_task_, static_cast<uint32_t>(ICU::VECTOR::INTB128));
				ICU::SLIBXR128 = TPU::get_TGIA();
				ICU::IPR.INTB128 = level_;
				ICU::IER.INTB128 = true;
#endif
				TPU::TIER.TGIEA = 1;  // TGRA interrupt
			} else {
				TPU::TIER.TGIEA = 0;
			}

			TPU::enable();

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  タイマー同期
		*/
		//-----------------------------------------------------------------//
		void sync() const
		{
			if(level_ > 0) {
				volatile uint32_t cnt = counter_;
				while(cnt == counter_) sleep_();
			} else {
				while(TPU::TSR.TGFA() == 0) sleep_();
				TPU::TSR.TGFA = 0;
				task_();
				++counter_;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  割り込みカウンターの値を取得
			@return 割り込みカウンターの値
		*/
		//-----------------------------------------------------------------//
		uint32_t get_counter() const { return counter_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  TCNT レジスターの値を取得
			@return TCNT レジスター
		*/
		//-----------------------------------------------------------------//
		uint16_t get_tcnt_count() const { return TPU::TCNT(); }

		//-----------------------------------------------------------------//
		/*!
			@brief  TASK クラスの参照
			@return TASK クラス
		*/
		//-----------------------------------------------------------------//
		static TASK& at_task() { return task_; }
	};

	template <class TPU, class TASK> volatile uint32_t tpu_io<TPU, TASK>::counter_ = 0;
	template <class TPU, class TASK> TASK tpu_io<TPU, TASK>::task_;
}
<|endoftext|>


<commit_before>#define CURL_STATICLIB
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <curl/curl.h>
#include <string.h>
/*condor_urlfetch
 *This program downloads the url specified as the first argument into the
 *file specified in the second argument, as well as stdout.
 *If the fetch fails, the file will not be overwritten, but it will still
 *be printed to stdout.
 *Errorcode Definitions: (0 successful execution)
 * 1 - usage error
 * 2 - Error writing to file
 * 3 - Error opening the prevfile to read from
 * 4 - curl_easy_perform failed
 * 5 - Error creating a temporary file
 */

using namespace std;

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
int write_prevfile(char *prev);
bool isEmpty(FILE *file);

/*********************************************************************
    main()
*********************************************************************/

int main(int argc, char *argv[])
{
    if((argc < 3) || (argc > 4))
    {
        perror("usage: condor_urlfetch  (-daemon)  http://my.site/condor_config  last_config.url");
        return 1;
    }
//Determines whether the -daemon flag is present, and set argv offets accordingly
//If the -daemon flag is there and is not master, the program will not download
//a new page.
    int lastLoc = 2;
    bool toPull = true;

    if(argv[1][0] == '-')
    {

        lastLoc++;
        if(strncmp(argv[1], "-MASTER", 10) != 0)
        {
            toPull = false;
        }
    }

    CURL *curl;
    FILE *tempFile;
    FILE *ptrFile;
    CURLcode res;
    char *url = argv[lastLoc - 1];
    char *tempName;
    tempName = tmpnam(NULL);

    tempFile = fopen(tempName, "wb");
    if(tempFile == NULL)
    {
        perror("Error creating a temporary file");
        return(5);
    }

    curl = curl_easy_init();
    if ((curl) && (toPull))
    {

        tempFile = fopen(tempName, "wb");
        if(tempFile == NULL)
        {
            perror("Error creating a temporary file");
            return(5);
        }
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, tempFile);
        res = curl_easy_perform(curl);

        if(res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
               curl_easy_strerror(res));
            return(4);
        }
        curl_easy_cleanup(curl);
        fclose(tempFile);
    }
    tempFile = fopen(tempName, "rb");
    if(tempFile == NULL)
    {
        perror("Error opening a temporary file");
        return(5);
    }

//If something has been written to tempfile, copy this to our output file.
    if(!isEmpty(tempFile))
    {

        std::ifstream  src(tempName, std::ios::binary);
        std::ofstream  dst(argv[lastLoc], std::ios::binary);

        dst << src.rdbuf();
    }
    if(write_prevfile(argv[lastLoc]) != 0)
    {
        perror("Error opening file as read only");
        exit(3);
    }
    remove(tempName);
    return 0;
}

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    size_t written = 0;
    if((size != 0) && (nmemb != 0))
    {
        written = fwrite(ptr, size, nmemb, stream);
        if(written!= nmemb)
        {
            perror("Error reading file.");
            exit(2);
        }
    }

    return written;
}

int write_prevfile(char *prev)
{
    FILE *ptrFile;

    ptrFile = fopen(prev, "r");

    if(!ptrFile)
    {
        printf("Error: Failed to open previous file for reading.\n");
        return 1;
    }

    std::ifstream  toPrint(prev, std::ios::binary);

    cout << toPrint.rdbuf();
    fclose(ptrFile);

    return 0;
}

bool isEmpty(FILE *ptrFile)
{
    long offset = ftell(ptrFile);
    fseek(ptrFile, 0, SEEK_END);

    if (ftell(ptrFile) == 0)
    {
        return true;
    }

    fseek(ptrFile, offset, SEEK_SET);
    return false;
}
<commit_msg>Ticket #4018<commit_after>#define CURL_STATICLIB
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <curl/curl.h>
#include <string.h>
/*condor_urlfetch
 *This program downloads the url specified as the first argument into the
 *file specified in the second argument, as well as stdout.
 *If the fetch fails, the file will not be overwritten, but it will still
 *be printed to stdout.
 *Errorcode Definitions: (0 successful execution)
 * 1 - usage error
 * 2 - Error writing to file
 * 3 - Error opening the prevfile to read from
 * 4 - curl_easy_perform failed
 * 5 - Error creating a temporary file
 */

using namespace std;

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
int write_prevfile(char *prev);
bool isEmpty(FILE *file);

/*********************************************************************
    main()
*********************************************************************/

int main(int argc, char *argv[])
{
    if((argc < 3) || (argc > 4))
    {
        perror("usage: condor_urlfetch  (-daemon)  http://my.site/condor_config  last_config.url");
        return 1;
    }
//Determines whether the -daemon flag is present, and set argv offets accordingly
//If the -daemon flag is there and is not master, the program will not download
//a new page.
    int lastLoc = 2;
    bool toPull = true;

    if(argv[1][0] == '-')
    {

        lastLoc++;
        if(strncmp(argv[1], "-MASTER", 10) != 0)
        {
            toPull = false;
        }
    }

    CURL *curl;
    FILE *tempFile;
    CURLcode res;
    char *url = argv[lastLoc - 1];
    char *tempName;
    tempName = tmpnam(NULL);

    tempFile = fopen(tempName, "wb");
    if(tempFile == NULL)
    {
        perror("Error creating a temporary file");
        return(5);
    }

    curl = curl_easy_init();
    if ((curl) && (toPull))
    {

        tempFile = fopen(tempName, "wb");
        if(tempFile == NULL)
        {
            perror("Error creating a temporary file");
            return(5);
        }
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, tempFile);
        res = curl_easy_perform(curl);

        if(res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
               curl_easy_strerror(res));
            return(4);
        }
        curl_easy_cleanup(curl);
        fclose(tempFile);
    }
    tempFile = fopen(tempName, "rb");
    if(tempFile == NULL)
    {
        perror("Error opening a temporary file");
        return(5);
    }

//If something has been written to tempfile, copy this to our output file.
    if(!isEmpty(tempFile))
    {

        std::ifstream  src(tempName, std::ios::binary);
        std::ofstream  dst(argv[lastLoc], std::ios::binary);

        dst << src.rdbuf();
    }
    if(write_prevfile(argv[lastLoc]) != 0)
    {
        perror("Error opening file as read only");
        exit(3);
    }
    remove(tempName);
    return 0;
}

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    size_t written = 0;
    if((size != 0) && (nmemb != 0))
    {
        written = fwrite(ptr, size, nmemb, stream);
        if(written!= nmemb)
        {
            perror("Error reading file.");
            exit(2);
        }
    }

    return written;
}

int write_prevfile(char *prev)
{
    FILE *ptrFile;

    ptrFile = fopen(prev, "r");

    if(!ptrFile)
    {
        printf("Error: Failed to open previous file for reading.\n");
        return 1;
    }

    std::ifstream  toPrint(prev, std::ios::binary);

    cout << toPrint.rdbuf();
    fclose(ptrFile);

    return 0;
}

bool isEmpty(FILE *ptrFile)
{
    long offset = ftell(ptrFile);
    fseek(ptrFile, 0, SEEK_END);

    if (ftell(ptrFile) == 0)
    {
        return true;
    }

    fseek(ptrFile, offset, SEEK_SET);
    return false;
}
<|endoftext|>


<commit_before>// KMail Account
#include <config.h>

#include "kmaccount.h"

#include "accountmanager.h"
using KMail::AccountManager;
#include "kmacctfolder.h"
#include "kmfoldermgr.h"
#include "kmfiltermgr.h"
#include "messagesender.h"
#include "kmmessage.h"
#include "broadcaststatus.h"
using KPIM::BroadcastStatus;
#include "kmfoldercachedimap.h"

#include "progressmanager.h"
using KPIM::ProgressItem;
using KPIM::ProgressManager;

using KMail::FolderJob;

#include <kapplication.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kconfig.h>

#include <qeventloop.h>

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <assert.h>

//----------------------
#include "kmaccount.moc"

//-----------------------------------------------------------------------------
KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent)
  : QObject(parent), mPrecommand(precommand)
{
  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  mPrecommandProcess.setUseShell(true);
  mPrecommandProcess << precommand;

  connect(&mPrecommandProcess, SIGNAL(processExited(KProcess *)),
          SLOT(precommandExited(KProcess *)));
}

//-----------------------------------------------------------------------------
KMPrecommand::~KMPrecommand()
{
}

//-----------------------------------------------------------------------------
bool KMPrecommand::start()
{
  bool ok = mPrecommandProcess.start( KProcess::NotifyOnExit );
  if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.")
    .arg(mPrecommand));
  return ok;
}

//-----------------------------------------------------------------------------
void KMPrecommand::precommandExited(KProcess *p)
{
  int exitCode = p->normalExit() ? p->exitStatus() : -1;
  if (exitCode)
    KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2")
      .arg(exitCode).arg(strerror(exitCode)));
  emit finished(!exitCode);
}

//-----------------------------------------------------------------------------
KMAccount::KMAccount(AccountManager* aOwner, const QString& aName, uint id)
  : KAccount( id, aName ),
    mTrash(KMKernel::self()->trashFolder()->idString()),
    mOwner(aOwner),
    mFolder(0),
    mTimer(0),
    mInterval(0),
    mExclude(false),
    mCheckingMail(false),
    mHasInbox(false),
    mMailCheckProgressItem(0),
    mPrecommandProcess(0)
{
  assert(aOwner != 0);
}

void KMAccount::init() {
  mTrash = kmkernel->trashFolder()->idString();
  mExclude = false;
  mInterval = 0;
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
KMAccount::~KMAccount()
{
  if (!kmkernel->shuttingDown() && mFolder) mFolder->removeAccount(this);
  if (mTimer) deinstallTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::setName(const QString& aName)
{
  mName = aName;
}

//-----------------------------------------------------------------------------
void KMAccount::clearPasswd()
{
}

//-----------------------------------------------------------------------------
void KMAccount::setFolder(KMFolder* aFolder, bool addAccount)
{
  if(!aFolder) {
    //kdDebug(5006) << "KMAccount::setFolder() : aFolder == 0" << endl;
    mFolder = 0;
    return;
  }
  mFolder = (KMAcctFolder*)aFolder;
  if (addAccount) mFolder->addAccount(this);
}

//-----------------------------------------------------------------------------
void KMAccount::readConfig(KConfig& config)
{
  QString folderName;
  mFolder = 0;
  folderName = config.readEntry("Folder");
  setCheckInterval(config.readNumEntry("check-interval", 0));
  setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString()));
  setCheckExclude(config.readBoolEntry("check-exclude", false));
  setPrecommand(config.readPathEntry("precommand"));

  if (!folderName.isEmpty())
  {
    setFolder(kmkernel->folderMgr()->findIdString(folderName), true);
  }

  if (mInterval == 0)
    deinstallTimer();
  else
    installTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::writeConfig(KConfig& config)
{
  // ID, Name
  KAccount::writeConfig(config);

  config.writeEntry("Type", type());
  config.writeEntry("Folder", mFolder ? mFolder->idString() : QString::null);
  config.writeEntry("check-interval", mInterval);
  config.writeEntry("check-exclude", mExclude);
  config.writePathEntry("precommand", mPrecommand);
  config.writeEntry("trash", mTrash);
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipt(KMMessage* aMsg)
{
  KConfig* cfg = KMKernel::config();
  bool sendReceipts;

  KConfigGroupSaver saver(cfg, "General");

  sendReceipts = cfg->readBoolEntry("send-receipts", false);
  if (!sendReceipts) return;

  KMMessage *newMsg = aMsg->createDeliveryReceipt();
  if (newMsg) {
    mReceipts.append(newMsg);
    QTimer::singleShot( 0, this, SLOT( sendReceipts() ) );
  }
}

//-----------------------------------------------------------------------------
bool KMAccount::processNewMsg(KMMessage* aMsg)
{
  int rc, processResult;

  assert(aMsg != 0);

  // Save this one for readding
  KMFolderCachedImap* parent = 0;
  if( type() == "cachedimap" )
    parent = static_cast<KMFolderCachedImap*>( aMsg->storage() );

  // checks whether we should send delivery receipts
  // and sends them.
  sendReceipt(aMsg);

  // Set status of new messages that are marked as old to read, otherwise
  // the user won't see which messages newly arrived.
  // This is only valid for pop accounts and produces wrong stati for imap.
  if ( type() != "cachedimap" && type() != "imap" ) {
    if ( aMsg->isOld() )
      aMsg->setStatus(KMMsgStatusUnread);  // -sanders
    //    aMsg->setStatus(KMMsgStatusRead);
    else
      aMsg->setStatus(KMMsgStatusNew);
  }
/*
QFile fileD0( "testdat_xx-kmaccount-0" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
  // 0==message moved; 1==processing ok, no move; 2==critical error, abort!

  processResult = kmkernel->filterMgr()->process(aMsg,KMFilterMgr::Inbound,true,id());
  if (processResult == 2) {
    perror("Critical error: Unable to collect mail (out of space?)");
    KMessageBox::information(0,(i18n("Critical error: "
      "Unable to collect mail: ")) + QString::fromLocal8Bit(strerror(errno)));
    return false;
  }
  else if (processResult == 1)
  {
    if( type() == "cachedimap" )
      ; // already done by caller: parent->addMsgInternal( aMsg, false );
    else {
      // TODO: Perhaps it would be best, if this if was handled by a virtual
      // method, so the if( !dimap ) above could die?
      kmkernel->filterMgr()->tempOpenFolder(mFolder);
      rc = mFolder->addMsg(aMsg);
/*
QFile fileD0( "testdat_xx-kmaccount-1" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
      if (rc) {
        perror("failed to add message");
        KMessageBox::information(0, i18n("Failed to add message:\n") +
                                 QString(strerror(rc)));
        return false;
      }
      int count = mFolder->count();
      // If count == 1, the message is immediately displayed
      if (count != 1) mFolder->unGetMsg(count - 1);
    }
  }

  // Count number of new messages for each folder
  QString folderId;
  if ( processResult == 1 ) {
    folderId = ( type() == "cachedimap" ) ? parent->folder()->idString()
                                          : mFolder->idString();
  }
  else {
    folderId = aMsg->parent()->idString();
  }
  addToNewInFolder( folderId, 1 );

  return true; //Everything's fine - message has been added by filter  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckInterval(int aInterval)
{
  if (aInterval <= 0)
    mInterval = 0;
  else
    mInterval = aInterval;
  // Don't call installTimer from here! See #117935.
}

int KMAccount::checkInterval() const
{
  if ( mInterval <= 0 )
    return mInterval;
  return QMAX( mInterval, GlobalSettings::self()->minimumCheckInterval() );
}

//----------------------------------------------------------------------------
void KMAccount::deleteFolderJobs()
{
  mJobList.setAutoDelete(true);
  mJobList.clear();
  mJobList.setAutoDelete(false);
}

//----------------------------------------------------------------------------
void KMAccount::ignoreJobsForMessage( KMMessage* msg )
{
  //FIXME: remove, make folders handle those
  for( QPtrListIterator<FolderJob> it(mJobList); it.current(); ++it ) {
    if ( it.current()->msgList().first() == msg) {
      FolderJob *job = it.current();
      mJobList.remove( job );
      delete job;
      break;
    }
  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckExclude(bool aExclude)
{
  mExclude = aExclude;
}

//-----------------------------------------------------------------------------
void KMAccount::installTimer()
{
  if (mInterval <= 0) return;
  if(!mTimer)
  {
    mTimer = new QTimer(0, "mTimer");
    connect(mTimer,SIGNAL(timeout()),SLOT(mailCheck()));
  }
  else
  {
    mTimer->stop();
  }
  mTimer->start( checkInterval() * 60000 );
}

//-----------------------------------------------------------------------------
void KMAccount::deinstallTimer()
{
  delete mTimer;
  mTimer = 0;
}

//-----------------------------------------------------------------------------
void KMAccount::startPrecommand(const QString &precommand)
{
  // Run the pre command if there is one
  if ( precommand.isEmpty() )
    emit precommandExited( true );

  KMPrecommand *mPrecommandProcess = new KMPrecommand(precommand, this);

  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  connect(mPrecommandProcess, SIGNAL(finished(bool)),
          SLOT(precommandFinished(bool)));

  kdDebug(5006) << "Running precommand " << precommand << endl;
  if (!mPrecommandProcess->start())
    emit precommandExited( false );
}
//-----------------------------------------------------------------------------
void KMAccount::precommandFinished( bool success )
{
  delete mPrecommandProcess; mPrecommandProcess = 0;

  emit precommandExited( success );
}
//-----------------------------------------------------------------------------
void KMAccount::mailCheck()
{
  if (mTimer)
    mTimer->stop();

  if ( kmkernel ) {
    AccountManager *acctmgr = kmkernel->acctMgr();
    if ( acctmgr )
      acctmgr->singleCheckMail(this, false);
  }
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipts()
{
  QValueList<KMMessage*>::Iterator it;
  for(it = mReceipts.begin(); it != mReceipts.end(); ++it)
    kmkernel->msgSender()->send(*it); //might process events
  mReceipts.clear();
}

//-----------------------------------------------------------------------------
QString KMAccount::encryptStr(const QString &aStr)
{
  QString result;
  for (uint i = 0; i < aStr.length(); i++)
    /* yes, no typo. can't encode ' ' or '!' because
       they're the unicode BOM. stupid scrambling. stupid. */
    result += (aStr[i].unicode() <= 0x21 ) ? aStr[i] :
      QChar(0x1001F - aStr[i].unicode());
  return result;
}

//-----------------------------------------------------------------------------
QString KMAccount::importPassword(const QString &aStr)
{
  unsigned int i, val;
  unsigned int len = aStr.length();
  QCString result;
  result.resize(len+1);

  for (i=0; i<len; i++)
  {
    val = aStr[i] - ' ';
    val = (255-' ') - val;
    result[i] = (char)(val + ' ');
  }
  result[i] = '\0';

  return encryptStr(result);
}

void KMAccount::invalidateIMAPFolders()
{
  // Default: Don't do anything. The IMAP account will handle it
}

void KMAccount::pseudoAssign( const KMAccount * a ) {
  if ( !a ) return;

  setName( a->name() );
  setId( a->id() );
  setCheckInterval( a->checkInterval() );
  setCheckExclude( a->checkExclude() );
  setFolder( a->folder() );
  setPrecommand( a->precommand() );
  setTrash( a->trash() );
}

//-----------------------------------------------------------------------------
void KMAccount::checkDone( bool newmail, CheckStatus status )
{
    setCheckingMail( false );
  // Reset the timeout for automatic mailchecking. The user might have
  // triggered the check manually.
  if (mTimer)
    mTimer->start( checkInterval() * 60000 );
  if ( mMailCheckProgressItem ) {
    // set mMailCheckProgressItem = 0 before calling setComplete() to prevent
    // a race condition
    ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
    mMailCheckProgressItem = 0;
    savedMailCheckProgressItem->setComplete(); // that will delete it
  }

  emit newMailsProcessed( mNewInFolder );
  emit finishedCheck( newmail, status );
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
void KMAccount::addToNewInFolder( QString folderId, int num )
{
  if ( mNewInFolder.find( folderId ) == mNewInFolder.end() )
    mNewInFolder[folderId] = num;
  else
    mNewInFolder[folderId] += num;
}
<commit_msg>Fix crash on pop fetching (r706425 in 3.5 branch).<commit_after>// KMail Account
#include <config.h>

#include "kmaccount.h"

#include "accountmanager.h"
using KMail::AccountManager;
#include "kmacctfolder.h"
#include "kmfoldermgr.h"
#include "kmfiltermgr.h"
#include "messagesender.h"
#include "kmmessage.h"
#include "broadcaststatus.h"
using KPIM::BroadcastStatus;
#include "kmfoldercachedimap.h"

#include "progressmanager.h"
using KPIM::ProgressItem;
using KPIM::ProgressManager;

using KMail::FolderJob;

#include <kapplication.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kconfig.h>

#include <qeventloop.h>

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <assert.h>

//----------------------
#include "kmaccount.moc"

//-----------------------------------------------------------------------------
KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent)
  : QObject(parent), mPrecommand(precommand)
{
  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  mPrecommandProcess.setUseShell(true);
  mPrecommandProcess << precommand;

  connect(&mPrecommandProcess, SIGNAL(processExited(KProcess *)),
          SLOT(precommandExited(KProcess *)));
}

//-----------------------------------------------------------------------------
KMPrecommand::~KMPrecommand()
{
}

//-----------------------------------------------------------------------------
bool KMPrecommand::start()
{
  bool ok = mPrecommandProcess.start( KProcess::NotifyOnExit );
  if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.")
    .arg(mPrecommand));
  return ok;
}

//-----------------------------------------------------------------------------
void KMPrecommand::precommandExited(KProcess *p)
{
  int exitCode = p->normalExit() ? p->exitStatus() : -1;
  if (exitCode)
    KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2")
      .arg(exitCode).arg(strerror(exitCode)));
  emit finished(!exitCode);
}

//-----------------------------------------------------------------------------
KMAccount::KMAccount(AccountManager* aOwner, const QString& aName, uint id)
  : KAccount( id, aName ),
    mTrash(KMKernel::self()->trashFolder()->idString()),
    mOwner(aOwner),
    mFolder(0),
    mTimer(0),
    mInterval(0),
    mExclude(false),
    mCheckingMail(false),
    mHasInbox(false),
    mMailCheckProgressItem(0),
    mPrecommandProcess(0)
{
  assert(aOwner != 0);
}

void KMAccount::init() {
  mTrash = kmkernel->trashFolder()->idString();
  mExclude = false;
  mInterval = 0;
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
KMAccount::~KMAccount()
{
  if (!kmkernel->shuttingDown() && mFolder) mFolder->removeAccount(this);
  if (mTimer) deinstallTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::setName(const QString& aName)
{
  mName = aName;
}

//-----------------------------------------------------------------------------
void KMAccount::clearPasswd()
{
}

//-----------------------------------------------------------------------------
void KMAccount::setFolder(KMFolder* aFolder, bool addAccount)
{
  if(!aFolder) {
    //kdDebug(5006) << "KMAccount::setFolder() : aFolder == 0" << endl;
    mFolder = 0;
    return;
  }
  mFolder = (KMAcctFolder*)aFolder;
  if (addAccount) mFolder->addAccount(this);
}

//-----------------------------------------------------------------------------
void KMAccount::readConfig(KConfig& config)
{
  QString folderName;
  mFolder = 0;
  folderName = config.readEntry("Folder");
  setCheckInterval(config.readNumEntry("check-interval", 0));
  setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString()));
  setCheckExclude(config.readBoolEntry("check-exclude", false));
  setPrecommand(config.readPathEntry("precommand"));

  if (!folderName.isEmpty())
  {
    setFolder(kmkernel->folderMgr()->findIdString(folderName), true);
  }

  if (mInterval == 0)
    deinstallTimer();
  else
    installTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::writeConfig(KConfig& config)
{
  // ID, Name
  KAccount::writeConfig(config);

  config.writeEntry("Type", type());
  config.writeEntry("Folder", mFolder ? mFolder->idString() : QString::null);
  config.writeEntry("check-interval", mInterval);
  config.writeEntry("check-exclude", mExclude);
  config.writePathEntry("precommand", mPrecommand);
  config.writeEntry("trash", mTrash);
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipt(KMMessage* aMsg)
{
  KConfig* cfg = KMKernel::config();
  bool sendReceipts;

  KConfigGroupSaver saver(cfg, "General");

  sendReceipts = cfg->readBoolEntry("send-receipts", false);
  if (!sendReceipts) return;

  KMMessage *newMsg = aMsg->createDeliveryReceipt();
  if (newMsg) {
    mReceipts.append(newMsg);
    QTimer::singleShot( 0, this, SLOT( sendReceipts() ) );
  }
}

//-----------------------------------------------------------------------------
bool KMAccount::processNewMsg(KMMessage* aMsg)
{
  int rc, processResult;

  assert(aMsg != 0);

  // Save this one for readding
  KMFolderCachedImap* parent = 0;
  if( type() == "cachedimap" )
    parent = static_cast<KMFolderCachedImap*>( aMsg->storage() );

  // checks whether we should send delivery receipts
  // and sends them.
  sendReceipt(aMsg);

  // Set status of new messages that are marked as old to read, otherwise
  // the user won't see which messages newly arrived.
  // This is only valid for pop accounts and produces wrong stati for imap.
  if ( type() != "cachedimap" && type() != "imap" ) {
    if ( aMsg->isOld() )
      aMsg->setStatus(KMMsgStatusUnread);  // -sanders
    //    aMsg->setStatus(KMMsgStatusRead);
    else
      aMsg->setStatus(KMMsgStatusNew);
  }
/*
QFile fileD0( "testdat_xx-kmaccount-0" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
  // 0==message moved; 1==processing ok, no move; 2==critical error, abort!

  processResult = kmkernel->filterMgr()->process(aMsg,KMFilterMgr::Inbound,true,id());
  if (processResult == 2) {
    perror("Critical error: Unable to collect mail (out of space?)");
    KMessageBox::information(0,(i18n("Critical error: "
      "Unable to collect mail: ")) + QString::fromLocal8Bit(strerror(errno)));
    return false;
  }
  else if (processResult == 1)
  {
    if( type() == "cachedimap" )
      ; // already done by caller: parent->addMsgInternal( aMsg, false );
    else {
      // TODO: Perhaps it would be best, if this if was handled by a virtual
      // method, so the if( !dimap ) above could die?
      kmkernel->filterMgr()->tempOpenFolder(mFolder);
      rc = mFolder->addMsg(aMsg);
/*
QFile fileD0( "testdat_xx-kmaccount-1" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
      if (rc) {
        perror("failed to add message");
        KMessageBox::information(0, i18n("Failed to add message:\n") +
                                 QString(strerror(rc)));
        return false;
      }
      int count = mFolder->count();
      // If count == 1, the message is immediately displayed
      if (count != 1) mFolder->unGetMsg(count - 1);
    }
  }

  // Count number of new messages for each folder
  QString folderId;
  if ( processResult == 1 ) {
    folderId = ( type() == "cachedimap" ) ? parent->folder()->idString()
                                          : mFolder->idString();
  }
  else {
    folderId = aMsg->parent()->idString();
  }
  addToNewInFolder( folderId, 1 );

  return true; //Everything's fine - message has been added by filter  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckInterval(int aInterval)
{
  if (aInterval <= 0)
    mInterval = 0;
  else
    mInterval = aInterval;
  // Don't call installTimer from here! See #117935.
}

int KMAccount::checkInterval() const
{
  if ( mInterval <= 0 )
    return mInterval;
  return QMAX( mInterval, GlobalSettings::self()->minimumCheckInterval() );
}

//----------------------------------------------------------------------------
void KMAccount::deleteFolderJobs()
{
  mJobList.setAutoDelete(true);
  mJobList.clear();
  mJobList.setAutoDelete(false);
}

//----------------------------------------------------------------------------
void KMAccount::ignoreJobsForMessage( KMMessage* msg )
{
  //FIXME: remove, make folders handle those
  for( QPtrListIterator<FolderJob> it(mJobList); it.current(); ++it ) {
    if ( it.current()->msgList().first() == msg) {
      FolderJob *job = it.current();
      mJobList.remove( job );
      delete job;
      break;
    }
  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckExclude(bool aExclude)
{
  mExclude = aExclude;
}

//-----------------------------------------------------------------------------
void KMAccount::installTimer()
{
  if (mInterval <= 0) return;
  if(!mTimer)
  {
    mTimer = new QTimer(0, "mTimer");
    connect(mTimer,SIGNAL(timeout()),SLOT(mailCheck()));
  }
  else
  {
    mTimer->stop();
  }
  mTimer->start( checkInterval() * 60000 );
}

//-----------------------------------------------------------------------------
void KMAccount::deinstallTimer()
{
  delete mTimer;
  mTimer = 0;
}

//-----------------------------------------------------------------------------
void KMAccount::startPrecommand(const QString &precommand)
{
  // Run the pre command if there is one
  if ( precommand.isEmpty() ) {
    emit precommandExited( true );
    return;
  }

  KMPrecommand *mPrecommandProcess = new KMPrecommand(precommand, this);

  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  connect(mPrecommandProcess, SIGNAL(finished(bool)),
          SLOT(precommandFinished(bool)));

  kdDebug(5006) << "Running precommand " << precommand << endl;
  if (!mPrecommandProcess->start())
    emit precommandExited( false );
}
//-----------------------------------------------------------------------------
void KMAccount::precommandFinished( bool success )
{
  delete mPrecommandProcess; mPrecommandProcess = 0;

  emit precommandExited( success );
}
//-----------------------------------------------------------------------------
void KMAccount::mailCheck()
{
  if (mTimer)
    mTimer->stop();

  if ( kmkernel ) {
    AccountManager *acctmgr = kmkernel->acctMgr();
    if ( acctmgr )
      acctmgr->singleCheckMail(this, false);
  }
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipts()
{
  QValueList<KMMessage*>::Iterator it;
  for(it = mReceipts.begin(); it != mReceipts.end(); ++it)
    kmkernel->msgSender()->send(*it); //might process events
  mReceipts.clear();
}

//-----------------------------------------------------------------------------
QString KMAccount::encryptStr(const QString &aStr)
{
  QString result;
  for (uint i = 0; i < aStr.length(); i++)
    /* yes, no typo. can't encode ' ' or '!' because
       they're the unicode BOM. stupid scrambling. stupid. */
    result += (aStr[i].unicode() <= 0x21 ) ? aStr[i] :
      QChar(0x1001F - aStr[i].unicode());
  return result;
}

//-----------------------------------------------------------------------------
QString KMAccount::importPassword(const QString &aStr)
{
  unsigned int i, val;
  unsigned int len = aStr.length();
  QCString result;
  result.resize(len+1);

  for (i=0; i<len; i++)
  {
    val = aStr[i] - ' ';
    val = (255-' ') - val;
    result[i] = (char)(val + ' ');
  }
  result[i] = '\0';

  return encryptStr(result);
}

void KMAccount::invalidateIMAPFolders()
{
  // Default: Don't do anything. The IMAP account will handle it
}

void KMAccount::pseudoAssign( const KMAccount * a ) {
  if ( !a ) return;

  setName( a->name() );
  setId( a->id() );
  setCheckInterval( a->checkInterval() );
  setCheckExclude( a->checkExclude() );
  setFolder( a->folder() );
  setPrecommand( a->precommand() );
  setTrash( a->trash() );
}

//-----------------------------------------------------------------------------
void KMAccount::checkDone( bool newmail, CheckStatus status )
{
    setCheckingMail( false );
  // Reset the timeout for automatic mailchecking. The user might have
  // triggered the check manually.
  if (mTimer)
    mTimer->start( checkInterval() * 60000 );
  if ( mMailCheckProgressItem ) {
    // set mMailCheckProgressItem = 0 before calling setComplete() to prevent
    // a race condition
    ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
    mMailCheckProgressItem = 0;
    savedMailCheckProgressItem->setComplete(); // that will delete it
  }

  emit newMailsProcessed( mNewInFolder );
  emit finishedCheck( newmail, status );
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
void KMAccount::addToNewInFolder( QString folderId, int num )
{
  if ( mNewInFolder.find( folderId ) == mNewInFolder.end() )
    mNewInFolder[folderId] = num;
  else
    mNewInFolder[folderId] += num;
}
<|endoftext|>