| 1 |
//============================================================================ |
//============================================================================ |
| 2 |
// $Id: PamOffLineSW_Main.cpp,v 1.52 2008-09-12 14:03:55 messineo Exp $ |
// $Id: PamOffLineSW_Main.cpp,v 1.8 2009/12/24 10:31:13 mocchiut Exp $ |
| 3 |
// Description : Pamela Off-Line Software |
// Description : Pamela Off-Line Software |
| 4 |
//============================================================================ |
//============================================================================ |
| 5 |
|
|
| 8 |
#include "StateManager.h" |
#include "StateManager.h" |
| 9 |
|
|
| 10 |
#include "PacketUser.h" |
#include "PacketUser.h" |
| 11 |
|
#include <TArrayL64.h> |
| 12 |
|
|
| 13 |
extern "C" { |
extern "C" { |
| 14 |
#include <dirent.h> |
#include <dirent.h> |
| 43 |
|
|
| 44 |
//global variables |
//global variables |
| 45 |
bool simulated_data = false; |
bool simulated_data = false; |
| 46 |
bool do_vrl_check = false; |
//bool do_vrl_check = false; //EMI |
| 47 |
|
bool do_vrl_check = true; //EMI |
| 48 |
|
|
| 49 |
char* db_host = ""; |
|
| 50 |
|
const char* db_host = ""; |
| 51 |
int db_port = 0; |
int db_port = 0; |
| 52 |
char* db_name = ""; |
const char* db_name = ""; |
| 53 |
char conn[100]=""; |
char conn[100]=""; |
| 54 |
|
|
| 55 |
LogUtil::logLevel loglevel=LogUtil::LOGERROR; |
LogUtil::logLevel loglevel=LogUtil::LOGERROR; |
| 56 |
char* logfilename = "chewbacca.log"; |
const char* logfilename = "chewbacca.log"; |
| 57 |
//current route |
//current route |
| 58 |
int route = 999; |
int route = 999; |
| 59 |
//previous route |
//previous route |
| 60 |
int old_route = 999; |
int old_route = 999; |
| 61 |
|
|
| 62 |
|
Long64_t filelength = 0LL; |
| 63 |
|
Long64_t streamposi = 0LL; |
| 64 |
|
Long64_t downcount = 1LL; |
| 65 |
|
TArrayL64 *dwin=new TArrayL64(12); |
| 66 |
|
Long64_t cadcount = 0LL; |
| 67 |
|
|
| 68 |
bool skip_cadre = false; |
bool skip_cadre = false; |
| 69 |
long int iNumGoodCadres=0; //total number of good cadres |
long int iNumGoodCadres=0; //total number of good cadres |
| 70 |
|
|
| 71 |
// global variables used in all the project |
// global variables used in all the project |
| 72 |
namespace PamOffLineSW |
namespace PamOffLineSW |
| 73 |
{ |
{ |
| 74 |
char* db_user = ""; |
const char* db_user = ""; |
| 75 |
char* db_pwd = ""; |
const char* db_pwd = ""; |
| 76 |
char* connection = NULL; |
char* pelosconnection = NULL; |
| 77 |
//marco_new_01 |
//marco_new_01 |
| 78 |
bool single_connection=false; |
bool single_connection=false; |
| 79 |
long int iNumCadres=0; //cadre's number |
long int iNumCadres=0; //cadre's number |
| 83 |
char* fni; //path completo |
char* fni; //path completo |
| 84 |
short compression = 3; |
short compression = 3; |
| 85 |
// char *outDir = "."; |
// char *outDir = "."; |
| 86 |
char *outDir = ""; |
const char *outDir = ""; |
| 87 |
|
|
| 88 |
char * nome_output="chewbacca"; |
// char * nome_output="chewbacca"; //EMI |
| 89 |
bool multiFile = 0; |
const char * nome_output="L0PAM";//EMI |
| 90 |
unsigned long int step_pkt_number=0; |
bool multiFile = 0; |
| 91 |
unsigned long int step_pkt_obt=0; |
// unsigned long int step_pkt_number=0; // EMI |
| 92 |
|
unsigned long int step_pkt_number=3000; |
| 93 |
|
// unsigned long int step_pkt_obt=0; // EMI |
| 94 |
|
unsigned long int step_pkt_obt=7200000; // EMI |
| 95 |
LogUtil* mainLogUtil = NULL; |
LogUtil* mainLogUtil = NULL; |
| 96 |
TSQLServer* sqlServer = NULL; |
TSQLServer* sqlServer = NULL; |
| 97 |
unsigned long int max_pkt_number = 16777215;//biggest value before reset |
unsigned long int max_pkt_number = 16777215;//biggest value before reset |
| 98 |
unsigned long int max_pkt_obt = 4294967295u;//biggest value before reset |
unsigned long int max_pkt_obt = 4294967295u;//biggest value before reset |
| 99 |
|
|
| 100 |
bool is_new_route = false; |
// bool is_new_route = false; // EMI |
| 101 |
|
bool is_new_route = true; // EMI ??????????? VA BENE? SECONDO ME SI` |
| 102 |
unsigned int download = 0; |
unsigned int download = 0; |
| 103 |
unsigned int orbit_number=0; |
unsigned int orbit_number=0; |
| 104 |
unsigned int mmm_number = 0;//session_number |
unsigned int mmm_number = 0;//session_number |
| 105 |
unsigned long int time_Offset=0; |
unsigned long int time_Offset=0; |
| 106 |
bool tryMerge = false; |
// bool tryMerge = false; |
| 107 |
|
bool tryMerge = true; |
| 108 |
|
bool candelete = true; //EM |
| 109 |
|
|
| 110 |
bool do_cont_check=true;//if do_cont_check is false do not use a DB ... |
bool do_cont_check=true;//if do_cont_check is false do not use a DB ... |
| 111 |
|
|
| 112 |
//TODO: now it is unused |
//TODO: now it is unused |
| 113 |
unsigned long int delta_Time=0;//in seconds |
unsigned long int delta_Time=0;//in seconds |
| 114 |
|
#define TAGVALUELEN 4 |
| 115 |
|
char tag_value[TAGVALUELEN]; |
| 116 |
} |
} |
| 117 |
|
|
| 118 |
// main: |
// main: |
| 175 |
cout << "\t (-help | --help | -h) print this help and exit \n"; |
cout << "\t (-help | --help | -h) print this help and exit \n"; |
| 176 |
cout << "\t -simu if the input file contains simulated data instead of real data\n"; |
cout << "\t -simu if the input file contains simulated data instead of real data\n"; |
| 177 |
cout << "\t -vrl if you want to perform the vrl check\n"; |
cout << "\t -vrl if you want to perform the vrl check\n"; |
| 178 |
|
cout << "\t -no-vrl if you DO NOT want to perform the vrl check\n"; |
| 179 |
|
cout << "\t -gpamela gpamela data as input\n"; |
| 180 |
cout << "\t -filelog set the log filename. [default: chewbacca.log]\n"; |
cout << "\t -filelog set the log filename. [default: chewbacca.log]\n"; |
| 181 |
cout << "\t -loglevel set the log level. Values: [0,3] (error,warning,info,all) [default:0]\n"; |
cout << "\t -loglevel set the log level. Values: [0,3] (error,warning,info,all) [default:0]\n"; |
| 182 |
cout << "\t -c set the compression level for the generated ROOT file(s). Values: [0,9] [default = 3]\n"; |
cout << "\t -c set the compression level for the generated ROOT file(s). Values: [0,9] [default = 3]\n"; |
| 195 |
cout << "\t -session_number Value of the session number. If 0 this is retrieved from the input file name. [default = 0]\n"; |
cout << "\t -session_number Value of the session number. If 0 this is retrieved from the input file name. [default = 0]\n"; |
| 196 |
cout << "\t -time_Offset Value of the timeOffset. If 0 this is retrieved using the orbital number. [default = 0]\n"; |
cout << "\t -time_Offset Value of the timeOffset. If 0 this is retrieved using the orbital number. [default = 0]\n"; |
| 197 |
cout << "\t -tryMerge if you want to try to Merge ROOT files\n"; |
cout << "\t -tryMerge if you want to try to Merge ROOT files\n"; |
| 198 |
//marco_new_01 |
cout << "\t -dontMerge if you do not want to try to Merge ROOT files\n"; |
| 199 |
|
cout << "\t -dontDelete if you do not want to delete bad ROOT files from disks\n"; |
| 200 |
|
//marco_new_01 |
| 201 |
cout << "\t -single_connection if you want to open only one connection to DB.\n"; |
cout << "\t -single_connection if you want to open only one connection to DB.\n"; |
| 202 |
// cout << "\t -delta_Time set the allowed difference (seconds) in the Real Time between two root file. [default = 0]\n"; |
cout << "\t -tag if you want add the 'The owner of the file' - the tag lenght is 4 char\n"; |
| 203 |
|
// cout << "\t -delta_Time set the allowed difference (seconds) in the Real Time between two root file. [default = 0]\n"; |
| 204 |
//cout << "\t -multi generate multiple root files \n"; |
//cout << "\t -multi generate multiple root files \n"; |
| 205 |
exit(1); |
exit(1); |
| 206 |
} |
} |
| 219 |
exit(1); |
exit(1); |
| 220 |
} |
} |
| 221 |
|
|
| 222 |
|
//input file |
| 223 |
|
fni= argv[1]; |
| 224 |
|
|
| 225 |
for (int i = 2; i < argc; i++) |
for (int i = 2; i < argc; i++) |
| 226 |
{ |
{ |
| 227 |
//marco_new_01 |
//marco_new_01 |
| 237 |
tryMerge = true; |
tryMerge = true; |
| 238 |
continue; |
continue; |
| 239 |
} |
} |
| 240 |
|
|
| 241 |
|
if (!strcmp(argv[i], "-dontMerge")) // EMI |
| 242 |
|
{ |
| 243 |
|
tryMerge = false; |
| 244 |
|
continue; |
| 245 |
|
} |
| 246 |
|
|
| 247 |
|
if (!strcmp(argv[i], "-dontDelete")) // EMI |
| 248 |
|
{ |
| 249 |
|
candelete = false; |
| 250 |
|
continue; |
| 251 |
|
} |
| 252 |
|
|
| 253 |
if (!strcmp(argv[i], "-time_Offset")){ |
if (!strcmp(argv[i], "-time_Offset")){ |
| 254 |
if (++i >= argc){ |
if (++i >= argc){ |
| 336 |
simulated_data = true; |
simulated_data = true; |
| 337 |
continue; |
continue; |
| 338 |
} |
} |
| 339 |
|
|
| 340 |
|
if (!strcmp(argv[i], "-gpamela")) |
| 341 |
|
{ |
| 342 |
|
simulated_data = true; |
| 343 |
|
do_vrl_check = false; |
| 344 |
|
nome_output = (char *)gSystem->BaseName(fni); |
| 345 |
|
tryMerge = false; |
| 346 |
|
candelete = false; |
| 347 |
|
continue; |
| 348 |
|
} |
| 349 |
|
|
| 350 |
|
if (!strcmp(argv[i], "-no-vrl")) //EMI |
| 351 |
|
{ |
| 352 |
|
do_vrl_check = false; |
| 353 |
|
} |
| 354 |
if (!strcmp(argv[i], "-vrl")) |
if (!strcmp(argv[i], "-vrl")) |
| 355 |
{ |
{ |
| 356 |
do_vrl_check = true; |
do_vrl_check = true; |
| 414 |
exit(1); |
exit(1); |
| 415 |
} |
} |
| 416 |
DIR* tempdir; |
DIR* tempdir; |
| 417 |
if ((tempdir = opendir(argv[i])) != 0) { |
if ((tempdir = opendir(gSystem->ExpandPathName(argv[i]))) != 0) { // EMI |
| 418 |
outDir = argv[i]; |
outDir = argv[i]; |
| 419 |
closedir(tempdir); |
closedir(tempdir); |
| 420 |
} else { |
} else { |
| 538 |
db_pwd = argv[i]; |
db_pwd = argv[i]; |
| 539 |
continue; |
continue; |
| 540 |
} |
} |
| 541 |
|
if (!strcmp(argv[i], "-tag")){ |
| 542 |
|
if (++i >= argc){ |
| 543 |
|
cerr << "-tag needs arguments. \n"; |
| 544 |
|
cout << "Try '-help' for more information. \n"; |
| 545 |
|
exit(1); |
| 546 |
|
} |
| 547 |
|
int len=strlen(argv[i])>TAGVALUELEN?TAGVALUELEN:strlen(argv[i]); |
| 548 |
|
strncpy(tag_value,argv[i],len); |
| 549 |
|
tag_value[len]=0; |
| 550 |
|
continue; |
| 551 |
|
} |
| 552 |
|
|
| 553 |
//TODO: check that multiFile is always 0 |
//TODO: check that multiFile is always 0 |
| 554 |
// if (!strcmp(argv[i], "-multi")){multiFile = 1; cout<<"debug: multi= "<<multiFile<<endl;} |
// if (!strcmp(argv[i], "-multi")){multiFile = 1; cout<<"debug: multi= "<<multiFile<<endl;} |
| 555 |
} |
} |
| 556 |
|
|
|
//input file |
|
|
fni= argv[1]; |
|
|
|
|
| 557 |
//TODO: maybe if simulated data I don't need nothig so I can skip the following lines |
//TODO: maybe if simulated data I don't need nothig so I can skip the following lines |
| 558 |
// and use instead something similar to: |
// and use instead something similar to: |
| 559 |
//if(simulated data){orbit_number=99999; mmm_number=999; download=999; } |
if (simulated_data) {orbit_number=99999; mmm_number=999; download=999; } |
| 560 |
|
|
| 561 |
//I need the following lines only to retrieve orbit_number and mmm_number (session_number)from the filename |
//I need the following lines only to retrieve orbit_number and mmm_number (session_number)from the filename |
| 562 |
if((!orbit_number)||(!mmm_number)) |
if((!orbit_number)||(!mmm_number)) |
| 629 |
char *pamdbhost = getenv("PAM_DBHOST"); |
char *pamdbhost = getenv("PAM_DBHOST"); |
| 630 |
if (pamdbhost) |
if (pamdbhost) |
| 631 |
{ |
{ |
| 632 |
connection = pamdbhost; |
pelosconnection = pamdbhost; |
| 633 |
} |
} |
| 634 |
else |
else |
| 635 |
{ |
{ |
| 648 |
db_name="chewbacca_db"; |
db_name="chewbacca_db"; |
| 649 |
} |
} |
| 650 |
sprintf(conn,"mysql://%s:%d/%s",db_host,db_port,db_name); |
sprintf(conn,"mysql://%s:%d/%s",db_host,db_port,db_name); |
| 651 |
connection=conn; |
pelosconnection=conn; |
| 652 |
} |
} |
| 653 |
} |
} |
| 654 |
else{ |
else{ |
| 655 |
sprintf(conn,"mysql://%s:%d/%s",db_host,db_port,db_name); |
sprintf(conn,"mysql://%s:%d/%s",db_host,db_port,db_name); |
| 656 |
connection=conn; |
pelosconnection=conn; |
| 657 |
} |
} |
| 658 |
|
|
| 659 |
if (!strcmp(db_user,"")) |
if (!strcmp(db_user,"")) |
| 683 |
} |
} |
| 684 |
} |
} |
| 685 |
|
|
| 686 |
string msg = "Using DB: " + string(connection);// +" "+ string(db_user) +" "+ string(db_pwd); |
string msg = "Using DB: " + string(pelosconnection);// +" "+ string(db_user) +" "+ string(db_pwd); |
| 687 |
mainLogUtil->logAlways(msg); |
mainLogUtil->logAlways(msg); |
| 688 |
} |
} |
| 689 |
|
|
| 692 |
string msg = "Input file: " + (string)fni; |
string msg = "Input file: " + (string)fni; |
| 693 |
mainLogUtil->logAlways(msg); |
mainLogUtil->logAlways(msg); |
| 694 |
|
|
| 695 |
msg = "Output directory for the generated root file(s): " + (string)outDir; |
msg = "Output directory for the generated root file(s): " + (string)outDir; |
| 696 |
mainLogUtil->logAlways(msg); |
mainLogUtil->logAlways(msg); |
| 697 |
|
msg = "Output directory for the generated root file(s) expanded: " + (string)gSystem->ExpandPathName(outDir); // EMI |
| 698 |
|
mainLogUtil->logAlways(msg); //EMI |
| 699 |
|
|
| 700 |
msg = "Output root name for the generated root file(s): " + (string)nome_output; |
msg = "Output root name for the generated root file(s): " + (string)nome_output; |
| 701 |
mainLogUtil->logAlways(msg); |
mainLogUtil->logAlways(msg); |
| 851 |
ifstream fin; |
ifstream fin; |
| 852 |
fin.open(fni, ifstream::binary); |
fin.open(fni, ifstream::binary); |
| 853 |
if (!fin) {cout<<"Can not open input file "<<fni<<endl; exit(1);} |
if (!fin) {cout<<"Can not open input file "<<fni<<endl; exit(1);} |
| 854 |
|
|
| 855 |
|
|
| 856 |
|
// |
| 857 |
|
// EM determine file length, number of downloads (a part small fractions of download due to VRL memory) and interval window for allowed change in download number |
| 858 |
|
// |
| 859 |
|
fin.seekg(0,std::ios::end); |
| 860 |
|
filelength = (Long64_t)fin.tellg(); |
| 861 |
|
// |
| 862 |
|
// filelength = 3840214016LL; |
| 863 |
|
// filelength = 5763760128LL; |
| 864 |
|
// filelength = 15370027008LL; |
| 865 |
|
// |
| 866 |
|
downcount = (Long64_t)round((Double_t)filelength/2000000000.); |
| 867 |
|
if ( downcount < 1LL ) downcount = 1LL; |
| 868 |
|
Long64_t downsize = (Long64_t)round((Double_t)filelength/(Double_t)downcount); |
| 869 |
|
Long64_t hwint = Long64_t((Double_t)downsize/25.); |
| 870 |
|
// |
| 871 |
|
if ( downcount > 5LL ) dwin->Set(2LL+2LL*downcount); |
| 872 |
|
dwin->Reset(); |
| 873 |
|
dwin->AddAt(0LL,0); |
| 874 |
|
// |
| 875 |
|
Int_t dco = 1; |
| 876 |
|
// |
| 877 |
|
for (Int_t ee=1; ee<(-1+2+2*downcount); ee+=2){ |
| 878 |
|
dwin->AddAt(((downsize*(dco-1))+hwint),ee); |
| 879 |
|
dwin->AddAt(((downsize*dco)-hwint),ee+1); |
| 880 |
|
dco++; |
| 881 |
|
}; |
| 882 |
|
// |
| 883 |
|
fin.seekg(0,std::ios::beg); |
| 884 |
|
// |
| 885 |
|
dwin->AddAt(filelength,(-1LL+2LL+2LL*downcount)); |
| 886 |
|
// |
| 887 |
|
// printf(" file lenght is %L downcount is %L downsize is %L hwint is %L \n",filelength,downcount,downsize,hwint); |
| 888 |
|
stringstream ess; |
| 889 |
|
ess.str() = ""; |
| 890 |
|
ess << " (EM) " << " file lenght is "<< filelength<< " downcount is "<< downcount <<" downsize is "<< downsize <<" hwint is " << hwint; |
| 891 |
|
string emsg = ess.str(); |
| 892 |
|
mainLogUtil->logInfo(emsg); |
| 893 |
|
// |
| 894 |
|
// cout << " file lenght is "<< filelength<< " downcount is "<< downcount <<" downsize is "<< downsize <<" hwint is " << hwint << endl; |
| 895 |
|
// for (Int_t ee=0; ee<TMath::Max((2+2*downcount),12LL); ee++){ |
| 896 |
|
// cout << " " << ee << " ==> "<< dwin->At(ee) << endl; |
| 897 |
|
// //a printf(" %i ==> %L \n",ee,dwin->At(ee)); |
| 898 |
|
// }; |
| 899 |
|
|
| 900 |
//main read loop |
//main read loop |
| 901 |
while(fin.eof()==0) |
while(fin.eof()==0) |
| 902 |
{ |
{ |
| 903 |
isCadreGood = true; |
isCadreGood = true; |
| 904 |
//start reading the file |
//start reading the file |
| 905 |
fin.read(ccHeader_VRL, LENGTH_HEADER_VRL); |
fin.read(ccHeader_VRL, LENGTH_HEADER_VRL); |
| 906 |
|
streamposi = (Long64_t)fin.tellg(); // stream position in the file |
| 907 |
|
// printf(" position in file is %i \n",streamposi); |
| 908 |
|
|
| 909 |
if (!fin.good()) |
if (!fin.good()) |
| 910 |
{ |
{ |
| 911 |
//TODO: check here |
//TODO: check here |
| 923 |
if(do_vrl_check){isCadreGood=false;} |
if(do_vrl_check){isCadreGood=false;} |
| 924 |
break; |
break; |
| 925 |
} |
} |
| 926 |
|
skip_cadre = false; |
| 927 |
//check of the VRL header e setta route number |
//check of the VRL header e setta route number |
| 928 |
if(!VRL_Header_Check(ccHeader_VRL,LENGTH_HEADER_VRL)) |
if(!VRL_Header_Check(ccHeader_VRL,LENGTH_HEADER_VRL)) |
| 929 |
{ |
{ |
| 1018 |
if(route!=old_route) |
if(route!=old_route) |
| 1019 |
{ |
{ |
| 1020 |
is_new_route=true; |
is_new_route=true; |
| 1021 |
|
cadcount = 1LL; |
| 1022 |
download++; |
download++; |
| 1023 |
stringstream oss; |
stringstream oss; |
| 1024 |
oss<<"Found a new download n: "<<download<<". Header VRL ends at byte: "<<iByte_tot; |
oss<<"Found a new download n: "<<download<<". Header VRL ends at byte: "<<iByte_tot; |
| 1026 |
mainLogUtil->logAll(msg); |
mainLogUtil->logAll(msg); |
| 1027 |
} |
} |
| 1028 |
// is_new_route will be reset to false in PacketUser after the packet is used and stored |
// is_new_route will be reset to false in PacketUser after the packet is used and stored |
| 1029 |
|
|
| 1030 |
|
|
| 1031 |
//main processing of the data, searching for Pamela Packets |
//main processing of the data, searching for Pamela Packets |
| 1032 |
for(int i=0; i<LENGTH_DATA_CADRE; i++) |
for(int i=0; i<LENGTH_DATA_CADRE; i++) |
| 1033 |
{ |
{ |
| 1034 |
StateManager::getInstance().getCurrentState()->readInput(ccData[i]); |
StateManager::getInstance().getCurrentState()->readInput(ccData[i]); |
| 1035 |
iByte_tot++; |
iByte_tot++; |
| 1036 |
if(exitdbg==true){cout<<"**** DBG EXIT FOR****"<<endl; break;} |
if(exitdbg==true){cout<<"**** DBG EXIT FOR****"<<endl; break;} |
| 1037 |
} |
} |
| 1038 |
} |
} |
| 1039 |
else{ |
else{ |
| 1040 |
iByte_tot+=LENGTH_DATA_CADRE; |
iByte_tot+=LENGTH_DATA_CADRE; |
| 1108 |
mainLogUtil->logAll(msg); |
mainLogUtil->logAll(msg); |
| 1109 |
return false; |
return false; |
| 1110 |
} |
} |
| 1111 |
|
// EM qui condizione su posizione file |
| 1112 |
route = (int)headVRL[3]; |
Bool_t downchangeallowed = false; |
| 1113 |
|
for (Int_t ee=0; ee<(-1+2+2*downcount); ee+=2){ |
| 1114 |
if(route!=old_route) |
if ( streamposi >= dwin->At(ee) && streamposi < dwin->At(ee+1) ) downchangeallowed = true; |
| 1115 |
{ |
// printf(" %i ==> %i \n",ee,dwin->At(ee)); |
| 1116 |
stringstream oss; |
}; |
| 1117 |
oss<<"Changing ROUTE at byte: "<<iByte_tot<<" route = "<<route<<" old value = "<<old_route<<" (download="<<download<<")"; |
if ( cadcount < 10000LL && cadcount > 0LL) downchangeallowed = false; |
| 1118 |
string msg = oss.str(); |
cadcount++; |
| 1119 |
mainLogUtil->logAll(msg); |
// cout << " cadcount " << cadcount << endl; |
| 1120 |
} |
// printf("cadcount %L \n",cadcount); |
| 1121 |
|
if ( downchangeallowed ){ |
| 1122 |
|
// printf(" change allowed! \n"); |
| 1123 |
|
|
| 1124 |
|
route = (int)headVRL[3]; |
| 1125 |
|
|
| 1126 |
|
if(route!=old_route) |
| 1127 |
|
{ |
| 1128 |
|
stringstream oss; |
| 1129 |
|
oss<<"Changing ROUTE at byte: "<<iByte_tot<<" route = "<<route<<" old value = "<<old_route<<" (download="<<download<<")"; |
| 1130 |
|
string msg = oss.str(); |
| 1131 |
|
mainLogUtil->logAll(msg); |
| 1132 |
|
} |
| 1133 |
|
|
| 1134 |
|
}; |
| 1135 |
|
|
| 1136 |
//TODO: check the cadre number and save this info? |
//TODO: check the cadre number and save this info? |
| 1137 |
//TODO check that the lenght is 8 |
//TODO check that the lenght is 8 |