configuration include - page 2

 
Without interrupting your found path, but I would like to know, isn't it also possible to add such a configuration file using the #resource compiler directive?

Wouldn't that be like reading a file with a function, but with a different source path?


 
Dominik Christian Egert #:
Without interrupting your found path, but I would like to know, isn't it also possible to add such a configuration file using the #resource compiler directive?

Wouldn't that be like reading a file with a function, but with a different source path?


Perhaps , if it were broken down into parallel simple structures that are assembled on init . (i assume you mean the following)

#resource "data.bin" as int ExtData[]             // declare the numeric array containing data from the data.bin file
#resource "data.bin" as MqlRates ExtData[]        // declare the simple structures array containing data from the data.bin file
 
Lorentzos Roussos #: Perhaps , if it were broken down into parallel simple structures that are assembled on init . (i assume you mean the following)

Actually, Dominik Christian Egert is correct and I had forgotten that you can also import a file as a data resource instead of having to use BMP files.

I'm still of the opinion that the #include file of global variable declarations would be more efficient, but the data resource method may be more practical.

It may depend on how you are supplying this data to the normal users you have bought a valid license instead of the demo tester users, in order to make a similar process for both types of licenses.

 
Lorentzos Roussos #: Perhaps , if it were broken down into parallel simple structures that are assembled on init . (i assume you mean the following)

Also remember that you can map the simply structure array data into a more complex structure by using "union".

 

Indeed @Dominik Christian Egert 's solution is optimal because when these structures are used , they wont be altered and , the size is known . Assuming i provide a header bin which directs the loading process. (and is overridden if the user specifies a different input)

I failed spectacularly with trying to read\write to a uchar array yesterday , might have been the tanquerray.

#property strict
#define BS_CHAR   1
#define BS_SHORT  2
#define BS_INT    4
#define BS_LONG   8
#define BS_FLOAT  4
#define BS_DOUBLE 8
#include "bs.mqh";
struct bytestream{
uchar  bytes[];
int    total,step,navi;
       bytestream(void){reset(true);}
       bytestream(int _step){reset(true);set_step(_step);}
  void reset(bool remove){
       if(remove){ArrayFree(bytes);}
       total=0;step=5000;navi=0;
       finalized=false;
       }
  void set_step(int new_step){step=new_step;}
  void reset_navs(){navi=0;}
  template <typename X>
  void write_bytes(X from){
       int total_bytes=sizeof(from);
       for(int i=0;i<total_bytes;i++)
         {
         long turn=(((long)from)<<(i*8))>>((total_bytes-1)*8);
         add_byte(((uchar)turn));
         }
       }
  template <typename X>
  void read_bytes(X &result){
       int total_bytes=sizeof(result);
       long turn=0;
       for(int i=0;i<total_bytes;i++)
       {
       navi++;
       if(navi>ArraySize(bytes)){Print("Error , navigated beyond bytestream");return;}
       turn+=((bytes[navi-1])<<((total_bytes-1-i)*8));
       }
       result=(X)turn;
       }
  void load_from_array(uchar &load_from[]){
       reset(true);
       total=ArraySize(load_from);
       if(total>0){
       ArrayResize(bytes,total,0);
       ArrayCopy(bytes,load_from,0,0,total);
       finalized=true;
       }}
  void load_from_bytestream_file(string folder,string filename){
       reset(true);
       string location=folder+"\\"+filename;
       if(FileIsExist(location)){
       int f=FileOpen(location,FILE_READ|FILE_BIN);
       if(f!=INVALID_HANDLE){
       total=(int)FileReadInteger(f,INT_VALUE);
       if(total>0){
       ArrayResize(bytes,total,0);
       for(int i=0;i<ArraySize(bytes);i++){bytes[i]=(uchar)FileReadInteger(f,CHAR_VALUE);}
       }
       FileClose(f);
       finalized=true;
       }}}
  void save_as_bytestream(string folder,string filename){
       if(!finalized){finalize();}
       string location=folder+"\\"+filename;
       if(FileIsExist(location)){FileDelete(location);}
       int f=FileOpen(location,FILE_WRITE|FILE_BIN);
       if(f!=INVALID_HANDLE){
       //#
       FileWriteInteger(f,ArraySize(bytes),INT_VALUE);
       for(int i=0;i<ArraySize(bytes);i++){FileWriteInteger(f,bytes[i],CHAR_VALUE);}
       FileClose(f);
       }}
  void save_as_code(string folder,string filename,string data_name){
       if(!finalized){finalize();}
       string location=folder+"\\"+filename;
       if(FileIsExist(location)){FileDelete(location);}
       int f=FileOpen(location,FILE_WRITE|FILE_TXT|FILE_UNICODE);
       if(f!=INVALID_HANDLE){
       FileWriteString(f,"#property strict\n");
       FileWriteString(f,"uchar "+data_name+"[]={");
       for(int i=0;i<ArraySize(bytes);i++){
       FileWriteString(f,IntegerToString(bytes[i]));
       if(i<(ArraySize(bytes)-1)){FileWriteString(f,",");}
       }
       FileWriteString(f,"};\n");
       FileClose(f);
       }}
       private:
  bool finalized;
   int add_byte(uchar byte){
       total++;
       if(total>ArraySize(bytes)){ArrayResize(bytes,total+step,0);}
       bytes[total-1]=byte;
       finalized=false;
       return(total-1);
       }
  void finalize(){
       if(total==0){ArrayFree(bytes);}else{
       ArrayResize(bytes,total,0);}
       finalized=true;
       }  
};
/*
template <typename X>
void BytestreamWrite(X what,


void
*/  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
  double a=1.3153252;
     int b=1356425;
    char c=101;
     int d=486356;
  double e=346.432542;
  bytestream  bs(2000);
  bs.write_bytes(a);
  bs.write_bytes(b);
  bs.write_bytes(c);
  bs.write_bytes(d);
  bs.write_bytes(e);
  bs.save_as_code("bytestream","bs.mqh","test_data");
  //read test
  bs.reset(true);
  bs.load_from_array(test_data);
  bs.reset_navs();
  bs.read_bytes(a);
  Print("a="+a);
  bs.read_bytes(b);
  Print("b="+b);
  bs.read_bytes(c);
  Print("c="+c);
  bs.read_bytes(d);
  Print("d="+d);
  bs.read_bytes(e);
  Print("e="+e);
//---
   return(INIT_SUCCEEDED);
  }


 (the include bs.mqh was a previous output with save as code)

the result was : 


 
However the data comes from the #resource, as string or uchar[]

I would use CharToStruct for conversion.


And alternatively, depending on the source



 
Dominik Christian Egert #:
However the data comes from the #resource, as string or uchar[]

I would use CharToStruct for conversion.


And alternatively, depending on the source



That solution fits . Thank you @Dominik Christian Egert

Thank you too Fernando (your name is not taggable) 

This is the simplest modification for the previous code , although , i will seek to find what i missed with float and double types

struct simple_bytestream{
uchar  bytes[];
int    total,step,navi;
       simple_bytestream(void){reset(true);}
       simple_bytestream(int _step){reset(true);set_step(_step);}
  void reset(bool remove){
       if(remove){ArrayFree(bytes);ArrayFree(copy8);ArrayResize(copy8,8,0);}
       total=0;step=5000;navi=0;
       finalized=false;
       }
  void set_step(int new_step){step=new_step;}
  void reset_navs(){navi=0;}
  template <typename X>
  void write_bytes(X from){
       int total_bytes=sizeof(from);
       bool turn=StructToCharArray(from,copy8,0);
       if(turn){
       for(int i=0;i<total_bytes;i++){add_byte(copy8[i]);}
       }}
  template <typename X>
  void read_bytes(X &result){
       int total_bytes=sizeof(result);
       ArrayCopy(copy8,bytes,0,navi,total_bytes);
       bool turn=CharArrayToStruct(result,copy8,0);
       navi+=total_bytes;
       }
  void load_from_array(uchar &load_from[]){
       reset(true);
       total=ArraySize(load_from);
       if(total>0){
       ArrayResize(bytes,total,0);
       ArrayCopy(bytes,load_from,0,0,total);
       finalized=true;
       }}
  void load_from_bytestream_file(string folder,string filename){
       reset(true);
       string location=folder+"\\"+filename;
       if(FileIsExist(location)){
       int f=FileOpen(location,FILE_READ|FILE_BIN);
       if(f!=INVALID_HANDLE){
       total=(int)FileReadInteger(f,INT_VALUE);
       if(total>0){
       ArrayResize(bytes,total,0);
       for(int i=0;i<ArraySize(bytes);i++){bytes[i]=(uchar)FileReadInteger(f,CHAR_VALUE);}
       }
       FileClose(f);
       finalized=true;
       }}}
  void save_as_bytestream(string folder,string filename){
       if(!finalized){finalize();}
       string location=folder+"\\"+filename;
       if(FileIsExist(location)){FileDelete(location);}
       int f=FileOpen(location,FILE_WRITE|FILE_BIN);
       if(f!=INVALID_HANDLE){
       //#
       FileWriteInteger(f,ArraySize(bytes),INT_VALUE);
       for(int i=0;i<ArraySize(bytes);i++){FileWriteInteger(f,bytes[i],CHAR_VALUE);}
       FileClose(f);
       }}
  void save_as_code(string folder,string filename,string data_name){
       if(!finalized){finalize();}
       string location=folder+"\\"+filename;
       if(FileIsExist(location)){FileDelete(location);}
       int f=FileOpen(location,FILE_WRITE|FILE_TXT|FILE_UNICODE);
       if(f!=INVALID_HANDLE){
       FileWriteString(f,"#property strict\n");
       FileWriteString(f,"uchar "+data_name+"[]={");
       for(int i=0;i<ArraySize(bytes);i++){
       FileWriteString(f,IntegerToString(bytes[i]));
       if(i<(ArraySize(bytes)-1)){FileWriteString(f,",");}
       }
       FileWriteString(f,"};\n");
       FileClose(f);
       }}
       private:
  bool finalized;
 uchar copy8[];
   int add_byte(uchar byte){
       total++;
       if(total>ArraySize(bytes)){ArrayResize(bytes,total+step,0);}
       bytes[total-1]=byte;
       finalized=false;
       return(total-1);
       }
  void finalize(){
       if(total==0){ArrayFree(bytes);}else{
       ArrayResize(bytes,total,0);}
       finalized=true;
       }  
};
 

The best solution is the include for MT4 and the resource bin for MT5

The bitmap does not work for MT4 , even in ARGB_RAW (verbatum "the terminal does not mess with the color components") it is messing with the color components.

That or there is an error on my part . Noticed every 4th byte is correct the rest seem to have been Anti-Aliased by the terminal.

(so the non bmp parts are usable) 

Cheers

(its one copy and paste to be applicable on MT5 too , for moderators)

 
Lorentzos Roussos #: The best solution is the include for MT4 and the resource bin for MT5. The bitmap does not work for MT4 , even in ARGB_RAW (verbatum "the terminal does not mess with the color components") it is messing with the color components. That or there is an error on my part . Noticed every 4th byte is correct the rest seem to have been Anti-Aliased by the terminal. (so the non bmp parts are usable) 

Cheers. (its one copy and paste to be applicable on MT5 too , for moderators)

Unfortunately I have little experience with using BMP resources, so I can't help here.

Which ever solution you decide on, it may be best to use the same one for both MQL4 and MQL5 (assuming you are using a single source file for both), so that you have less code differences to maintain and worry about.

 
Fernando Carreiro #:

Unfortunately I have little experience with using BMP resources, so I can't help here.

Which ever solution you decide on, it may be best to use the same one for both MQL4 and MQL5 (assuming you are using a single source file for both), so that you have less code differences to maintain and worry about.

Yes , although its fun utilizing the full extent of MT5's capabilities . 

Anyway , i was wrong , if you set the alpha channel at 0 and utilize 3 bytes per pixel for data there is no AA and that method just has a 25% increase in size vs the 7 times increase of the include.

Thank you Fernando , i will upload the solution cleaned up later or tommorrow .

Cheers 

Files:
bytestream.mqh  17 kb
Reason: