| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 | //---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include <Configuration.h>#include <CoreMain.h>#include <Common.h>#include <Usage.h>#include <FileInfo.h>//---------------------------------------------------------------------------#pragma package(smart_init)//---------------------------------------------------------------------------const UnicodeString LastInternalExceptionCounter(L"LastInternalException2");const UnicodeString LastUpdateExceptionCounter(L"LastUpdateException");//---------------------------------------------------------------------------__fastcall TUsage::TUsage(TConfiguration * Configuration){  FCriticalSection = new TCriticalSection();  FConfiguration = Configuration;  FValues = new TStringList();  FValues->Delimiter = L'&';  FValues->StrictDelimiter = true;  FCollect = true;  Default();}//---------------------------------------------------------------------------__fastcall TUsage::~TUsage(){  delete FValues;  delete FCriticalSection;}//---------------------------------------------------------------------------void __fastcall TUsage::Default(){  TGuard Guard(FCriticalSection);  FPeriodCounters.clear();  FLifetimeCounters.clear();  FValues->Clear();  if (Collect) // optimization  {    Set(L"FirstUse", StandardTimestamp());    Set(L"FirstVersion", IntToStr(FConfiguration->CompoundVersion));    UpdateLastReport();  }}//---------------------------------------------------------------------------void __fastcall TUsage::Load(THierarchicalStorage * Storage){  TGuard Guard(FCriticalSection);  Default();  if (Storage->OpenSubKey(L"Values", false))  {    TStrings * Names = new TStringList();    try    {      Storage->GetValueNames(Names);      for (int Index = 0; Index < Names->Count; Index++)      {        UnicodeString Name = Names->Strings[Index];        Set(Name, Storage->ReadString(Name, L""));      }      Storage->CloseSubKey();    }    __finally    {      delete Names;    }  }  Load(Storage, L"PeriodCounters", FPeriodCounters);  Load(Storage, L"LifetimeCounters", FLifetimeCounters);}//---------------------------------------------------------------------------void __fastcall TUsage::Load(THierarchicalStorage * Storage,  const UnicodeString& Name, TCounters & Counters){  if (Storage->OpenSubKey(Name, false))  {    TStrings * Names = new TStringList();    try    {      Storage->GetValueNames(Names);      for (int Index = 0; Index < Names->Count; Index++)      {        UnicodeString Name = Names->Strings[Index];        Counters.insert(          std::make_pair(Name, Storage->ReadInteger(Name, 0)));      }      Storage->CloseSubKey();    }    __finally    {      delete Names;    }  }}//---------------------------------------------------------------------------void __fastcall TUsage::Save(THierarchicalStorage * Storage) const{  TGuard Guard(FCriticalSection);  if (Storage->OpenSubKey(L"Values", true))  {    Storage->ClearValues();    Storage->WriteValues(FValues, true);    Storage->CloseSubKey();  }  Save(Storage, L"PeriodCounters", FPeriodCounters);  Save(Storage, L"LifetimeCounters", FLifetimeCounters);}//---------------------------------------------------------------------------void __fastcall TUsage::Save(THierarchicalStorage * Storage,  const UnicodeString & Name, const TCounters & Counters) const{  if (Storage->OpenSubKey(Name, true))  {    Storage->ClearValues();    TCounters::const_iterator i = Counters.begin();    while (i != Counters.end())    {      Storage->WriteInteger(i->first, i->second);      i++;    }    Storage->CloseSubKey();  }}//---------------------------------------------------------------------------void __fastcall TUsage::Set(const UnicodeString & Key, const UnicodeString & Value){  if (Collect)  {    TGuard Guard(FCriticalSection);    FValues->Values[Key] = Value;  }}//---------------------------------------------------------------------------void __fastcall TUsage::Set(const UnicodeString & Key, int Value){  Set(Key, IntToStr(Value));}//---------------------------------------------------------------------------void __fastcall TUsage::Set(const UnicodeString & Key, bool Value){  Set(Key, Value ? 1 : 0);}//---------------------------------------------------------------------------UnicodeString __fastcall TUsage::Get(const UnicodeString & Key){  TGuard Guard(FCriticalSection);  UnicodeString Result = FValues->Values[Key];  Result.Unique();  return Result;}//---------------------------------------------------------------------------void __fastcall TUsage::UpdateLastReport(){  Set(L"LastReport", StandardTimestamp());}//---------------------------------------------------------------------------void __fastcall TUsage::Reset(){  TGuard Guard(FCriticalSection);  UpdateLastReport();  FPeriodCounters.clear();  ResetLastExceptions();}//---------------------------------------------------------------------------void __fastcall TUsage::UpdateCurrentVersion(){  TGuard Guard(FCriticalSection);  int CompoundVersion = FConfiguration->CompoundVersion;  DebugAssert(ZeroBuildNumber(CompoundVersion) == CompoundVersion);  // ZeroBuildNumber for compatibility with versions that stored build number into the compound version  int PrevVersion = ZeroBuildNumber(StrToIntDef(Get(L"CurrentVersion"), 0));  if (PrevVersion != CompoundVersion)  {    Set(L"Installed", StandardTimestamp());  }  if (PrevVersion != 0)  {    if (PrevVersion < CompoundVersion)    {      Inc(L"Upgrades");    }    else if (PrevVersion > CompoundVersion)    {      Inc(L"Downgrades");    }    if (PrevVersion != CompoundVersion)    {      ResetLastExceptions();    }  }  Set(L"CurrentVersion", CompoundVersion);}//---------------------------------------------------------------------------void __fastcall TUsage::ResetValue(const UnicodeString & Key){  int Index = FValues->IndexOfName(Key);  if (Index >= 0)  {    FValues->Delete(Index);  }}//---------------------------------------------------------------------------void __fastcall TUsage::ResetLastExceptions(){  TGuard Guard(FCriticalSection);  ResetValue(LastInternalExceptionCounter);  ResetValue(LastUpdateExceptionCounter);}//---------------------------------------------------------------------------int __fastcall TUsage::Inc(const UnicodeString & Key, int Increment){  int Result;  if (Collect)  {    TGuard Guard(FCriticalSection);    Inc(Key, FPeriodCounters, Increment);    Result = Inc(Key, FLifetimeCounters, Increment);  }  else  {    Result = -1;  }  return Result;}//---------------------------------------------------------------------------int __fastcall TUsage::Inc(const UnicodeString & Key, TCounters & Counters, int Increment){  int Result;  TCounters::iterator i = Counters.find(Key);  if (i != Counters.end())  {    i->second += Increment;    Result = i->second;  }  else  {    Counters.insert(std::make_pair(Key, Increment));    Result = Increment;  }  return Result;}//---------------------------------------------------------------------------void __fastcall TUsage::SetMax(const UnicodeString & Key, int Value){  if (Collect)  {    TGuard Guard(FCriticalSection);    SetMax(Key, Value, FPeriodCounters);    SetMax(Key, Value, FLifetimeCounters);  }}//---------------------------------------------------------------------------void __fastcall TUsage::IncAndSetMax(const UnicodeString & IncKey, const UnicodeString & MaxKey, int Value){  Inc(IncKey, Value);  SetMax(MaxKey, Value);}//---------------------------------------------------------------------------void __fastcall TUsage::SetMax(const UnicodeString & Key, int Value,  TCounters & Counters){  TCounters::iterator i = Counters.find(Key);  if (i != Counters.end())  {    if (Value > i->second)    {      i->second = Value;    }  }  else  {    Counters.insert(std::make_pair(Key, Value));  }}//---------------------------------------------------------------------------void __fastcall TUsage::SetCollect(bool value){  TGuard Guard(FCriticalSection);  if (Collect != value)  {    FCollect = value;    if (!FCollect)    {      FPeriodCounters.clear();      FLifetimeCounters.clear();      FValues->Clear();    }    else    {      Default();    }  }}//---------------------------------------------------------------------------UnicodeString __fastcall TUsage::Serialize(const UnicodeString & Delimiter, const UnicodeString & Filter) const{  TGuard Guard(FCriticalSection);  UnicodeString Result;  UnicodeString FilterUpper = Filter.UpperCase();  for (int Index = 0; Index < FValues->Count; Index++)  {    Serialize(Result, FValues->Names[Index], FValues->ValueFromIndex[Index], Delimiter, FilterUpper);  }  Serialize(Result, L"Period", FPeriodCounters, Delimiter, FilterUpper);  Serialize(Result, L"Lifetime", FLifetimeCounters, Delimiter, FilterUpper);  return Result;}//---------------------------------------------------------------------------void __fastcall TUsage::Serialize(  UnicodeString & List, const UnicodeString & Name, const TCounters & Counters,  const UnicodeString & Delimiter, const UnicodeString & FilterUpper) const{  TCounters::const_iterator i = Counters.begin();  while (i != Counters.end())  {    Serialize(List, Name + i->first, IntToStr(i->second), Delimiter, FilterUpper);    i++;  }}//---------------------------------------------------------------------------void __fastcall TUsage::Serialize(  UnicodeString & List, const UnicodeString & Name, const UnicodeString & Value,  const UnicodeString & Delimiter, const UnicodeString & FilterUpper) const{  if (FilterUpper.IsEmpty() ||      (Name.UpperCase().Pos(FilterUpper) > 0) ||      (Value.UpperCase().Pos(FilterUpper) > 0))  {    AddToList(List, FORMAT(L"%s=%s", (Name, Value)), Delimiter);  }}//---------------------------------------------------------------------------int __fastcall TUsage::CalculateCounterSize(__int64 Size){  const int SizeCounterFactor = 10240;  return (Size <= 0) ? 0 : (Size < SizeCounterFactor ? 1 : static_cast<int>(Size / SizeCounterFactor));}
 |