Add mql4-lib dependencies directly; change header comments on license; fix ZmqMsg setData method bug

This commit is contained in:
Ding Li
2017-08-18 10:13:15 +08:00
parent e51eceb263
commit acd272031a
13 changed files with 686 additions and 273 deletions
+242
View File
@@ -0,0 +1,242 @@
//+------------------------------------------------------------------+
//| Module: Lang/GlobalVariable.mqh |
//| This file is part of the mql4-lib project: |
//| https://github.com/dingmaotu/mql4-lib |
//| |
//| Copyright 2017 Li Ding <dingmaotu@126.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property strict
//+------------------------------------------------------------------+
//| Encapsulates global variable functions |
//+------------------------------------------------------------------+
class GlobalVariable
{
public:
static int total() {return GlobalVariablesTotal();}
static string name(int index) {return GlobalVariableName(index);}
static void flush() {GlobalVariablesFlush();}
static bool exists(string name) {return GlobalVariableCheck(name);}
static datetime lastAccess(string name) {return GlobalVariableTime(name);}
static bool makeTemp(string name) {return GlobalVariableTemp(name);}
static double get(string name) {return GlobalVariableGet(name);}
static bool get(string name,double &value) {return GlobalVariableGet(name,value);}
static datetime set(string name,double value) {return GlobalVariableSet(name,value);}
static bool setOn(string name,double value,double check) {return GlobalVariableSetOnCondition(name,value,check);}
static bool remove(string name) {return GlobalVariableDel(name);}
static bool removeAll(string prefix=NULL,datetime before=0) {return GlobalVariablesDeleteAll(prefix,before);}
};
//+------------------------------------------------------------------+
//| TempVar is a variable whose life time is the same as the program |
//+------------------------------------------------------------------+
class TempVar
{
private:
string m_name;
bool m_owned;
public:
TempVar(string name,bool create=false):m_name(name),m_owned(create)
{
if(create)
{
GlobalVariable::makeTemp(name);
}
}
~TempVar() {if(m_owned && isValid()) {GlobalVariable::remove(m_name);}}
bool isValid() const {return GlobalVariable::exists(m_name);}
string getName() const {return m_name;}
bool set(double value) {return GlobalVariable::set(m_name,value);}
double get() const {return GlobalVariable::get(m_name);}
bool setOn(double value,double check) {return GlobalVariable::setOn(m_name,value,check);}
datetime lastAccess() const {return GlobalVariable::lastAccess(m_name);}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class AtomicVar: public TempVar
{
public:
AtomicVar(string name,long initial,bool create=false):TempVar(name,create)
{
set(initial);
}
long increment(long by=1);
long decrement(long by=1) {return increment(-by);}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
long AtomicVar::increment(long by)
{
bool success=false;
long value;
do
{
value=(long)get();
success=setOn(value+by,value);
}
while(!success);
return (value+by);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class Semaphore
{
private:
TempVar m_var;
public:
Semaphore(string name,long initial=0);
bool isValid() const {return m_var.isValid();}
bool acquire();
void release();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Semaphore::Semaphore(string name,long initial)
:m_var(name,initial!=0)
{
if(initial!=0)
{
m_var.set(initial);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool Semaphore::acquire(void)
{
bool success=false;
do
{
long value=(long)m_var.get();
if(value == 0) return false;
success=m_var.setOn(value-1,value);
}
while(!success && !IsStopped());
return success;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Semaphore::release(void)
{
bool success=false;
do
{
long value=(long)m_var.get();
success=m_var.setOn(value+1,value);
}
while(!success && !IsStopped());
}
//+------------------------------------------------------------------+
//| CriticalSection object for making atomic operations |
//| |
//| An exmaple of creating a global context (the creation and destroy|
//| are both enclosed between the SAME critical section): |
//| |
//| enter() |
//| if(refcount==0) create context |
//| else refcontext |
//| increase refcount |
//| leave() |
//| |
//| enter() |
//| decrease refcount |
//| if(refcount==0) context destroy |
//| leave() |
//+------------------------------------------------------------------+
class CriticalSection
{
private:
const string m_name;
public:
CriticalSection(string name):m_name(name){}
bool isValid() const {return m_name!=NULL;}
string getName() const {return m_name;}
void enter() { while(!GlobalVariable::makeTemp(m_name) && !IsStopped())Sleep(100); }
bool tryEnter() { return GlobalVariable::makeTemp(m_name); }
void leave() { GlobalVariable::remove(m_name);}
};
//+------------------------------------------------------------------+
//| A reference counted global pointer (or handle) |
//| Generic type parameter T can be long or int depending the handle |
//| length (64bit or 32bit) |
//| HandleManager should implement 2 static methods: create & destroy|
//+------------------------------------------------------------------+
template<typename T,typename HandleManager>
class GlobalHandle
{
private:
CriticalSection m_cs;
string m_refName;
string m_counterName;
protected:
T m_ref;
public:
GlobalHandle(string sharedKey=NULL):m_cs(sharedKey)
{
m_refName=m_cs.getName()+"_Ref";
m_counterName=m_cs.getName()+"_Count";
if(!m_cs.isValid()) m_ref=HandleManager::create();
else
{
m_cs.enter();
if(!GlobalVariable::exists(m_counterName))
{
GlobalVariable::makeTemp(m_counterName);
GlobalVariable::set(m_counterName,0);
}
if(long(GlobalVariable::get(m_counterName))==0)
{
m_ref=HandleManager::create();
if(!GlobalVariable::exists(m_refName))
{
GlobalVariable::makeTemp(m_refName);
GlobalVariable::set(m_refName,m_ref);
}
}
else
{
m_ref=(T)(GlobalVariable::get(m_refName));
}
GlobalVariable::set(m_counterName,GlobalVariable::get(m_counterName)+1);
m_cs.leave();
}
}
~GlobalHandle()
{
if(!m_cs.isValid()) {HandleManager::destroy(m_ref); return;}
m_cs.enter();
GlobalVariable::set(m_counterName,GlobalVariable::get(m_counterName)-1);
if(long(GlobalVariable::get(m_counterName))==0)
{
HandleManager::destroy(m_ref);
GlobalVariable::remove(m_refName);
GlobalVariable::remove(m_counterName);
}
m_cs.leave();
}
T ref() const {return m_ref;}
};
//+------------------------------------------------------------------+
+105
View File
@@ -0,0 +1,105 @@
//+------------------------------------------------------------------+
//| Module: Lang/Mql.mqh |
//| This file is part of the mql4-lib project: |
//| https://github.com/dingmaotu/mql4-lib |
//| |
//| Copyright 2017 Li Ding <dingmaotu@126.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property strict
#import "stdlib.ex4"
string ErrorDescription(int error_code);
int RGB(int red_value,int green_value,int blue_value);
bool CompareDoubles(double number1,double number2);
string DoubleToStrMorePrecision(double number,int precision);
string IntegerToHexString(int integer_number);
#import
//+------------------------------------------------------------------+
//| Mql language specific methods |
//+------------------------------------------------------------------+
class Mql
{
public:
static int getLastError() {return GetLastError();}
static string getErrorMessage(int errorCode) {return ErrorDescription(errorCode);}
static string doubleToString(double value,int precision) {return DoubleToStrMorePrecision(value,precision);}
static string integerToHexString(int value) {return IntegerToHexString(value);}
static int rgb(int red,int green,int blue) {return RGB(red,green,blue);}
static bool isEqual(double a,double b) {return CompareDoubles(a,b);}
static bool isStopped() {return IsStopped();}
static int getCodePage() {return MQLInfoInteger(MQL_CODEPAGE);}
static ENUM_PROGRAM_TYPE getProgramType() {return(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE);}
static bool isScript() {return Mql::getProgramType()==PROGRAM_SCRIPT;}
static bool isExpert() {return Mql::getProgramType()==PROGRAM_EXPERT;}
static bool isIndicator() {return Mql::getProgramType()==PROGRAM_INDICATOR;}
static bool isDllAllowed() {return MQLInfoInteger(MQL_DLLS_ALLOWED)!=0;}
static bool isTradeAllowed() {return MQLInfoInteger(MQL_TRADE_ALLOWED)!=0;}
static bool isSignalsAllowed() {return MQLInfoInteger(MQL_SIGNALS_ALLOWED)!=0;}
static bool isDebug() {return MQLInfoInteger(MQL_DEBUG)!=0;}
static bool isProfiling() {return MQLInfoInteger(MQL_PROFILER)!=0;}
static bool isTesting() {return MQLInfoInteger(MQL_TESTER)!=0;}
static bool isOptimizing() {return MQLInfoInteger(MQL_OPTIMIZATION)!=0;}
static bool isVisual() {return MQLInfoInteger(MQL_VISUAL_MODE)!=0;}
static bool isFrameMode() {return MQLInfoInteger(MQL_FRAME_MODE)!=0;}
static ENUM_LICENSE_TYPE getLicenseType() {return(ENUM_LICENSE_TYPE)MQLInfoInteger(MQL_LICENSE_TYPE);}
static bool isFreeLicense() {return Mql::getLicenseType()==LICENSE_FREE;}
static bool isDemoLicense() {return Mql::getLicenseType()==LICENSE_DEMO;}
static bool isFullLicense() {return Mql::getLicenseType()==LICENSE_FULL;}
static bool isTimeLicense() {return Mql::getLicenseType()==LICENSE_TIME;}
static string getProgramName() {return MQLInfoString(MQL_PROGRAM_NAME);}
static string getProgramPath() {return MQLInfoString(MQL_PROGRAM_PATH);}
};
#define ObjectAttr(Type, Private, Public) \
public:\
Type get##Public() const {return m_##Private;}\
void set##Public(Type value) {m_##Private=value;}\
private:\
Type m_##Private\
#define ObjectAttrRead(Type, Private, Public) \
public:\
Type get##Public() const {return m_##Private;}\
private:\
Type m_##Private\
#define ObjectAttrWrite(Type, Private, Public) \
public:\
void set##Public(Type value) {m_##Private=value;}\
private:\
Type m_##Private\
#ifdef _DEBUG
#define Debug(msg) Print(">>> DEBUG: In ",__FUNCTION__,"(",__FILE__,":",__LINE__,") [", msg, "]")
#else
#define Debug(msg)
#endif
//--- Execute some code in the global scope
#define BEGIN_EXECUTE(Name) class __Execute##Name\
{\
public:__Execute##Name()\
{
#define END_EXECUTE(Name) \
}\
}\
__execute##Name;
//+------------------------------------------------------------------+
+200
View File
@@ -0,0 +1,200 @@
//+------------------------------------------------------------------+
//| Module: Lang/Native.mqh |
//| This file is part of the mql4-lib project: |
//| https://github.com/dingmaotu/mql4-lib |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@126.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property strict
// Assume MT5 is 64bit, which is the default.
// Even though MT5 can be 32bit, there is no way to detect this
// by using preprocessor macros. Instead, MetaQuotes provides a
// function called IsX64 to detect this dynamically
// This is just absurd. Why do you want to know the bitness of
// the runtime? To define pointer related entities at compile time!
// All integer types in MQL is uniform on both 32bit or 64bit
// architectures, so it is almost useless to have a runtime function IsX64.
// Why not a __X64__?
#ifdef __MQL5__
#define __X64__
#endif
#ifdef __X64__
#define intptr_t long
#define uintptr_t ulong
#define size_t long
#else
#define intptr_t int
#define uintptr_t uint
#define size_t int
#endif
//--- _WIN32_WINNT version constants
#define _WIN32_WINNT_NT4 0x0400 // Windows NT 4.0
#define _WIN32_WINNT_WIN2K 0x0500 // Windows 2000
#define _WIN32_WINNT_WINXP 0x0501 // Windows XP
#define _WIN32_WINNT_WS03 0x0502 // Windows Server 2003
#define _WIN32_WINNT_WIN6 0x0600 // Windows Vista
#define _WIN32_WINNT_VISTA 0x0600 // Windows Vista
#define _WIN32_WINNT_WS08 0x0600 // Windows Server 2008
#define _WIN32_WINNT_LONGHORN 0x0600 // Windows Vista
#define _WIN32_WINNT_WIN7 0x0601 // Windows 7
#define _WIN32_WINNT_WIN8 0x0602 // Windows 8
#define _WIN32_WINNT_WINBLUE 0x0603 // Windows 8.1
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
//--- define you own for your target platform
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00
#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
#import "kernel32.dll"
void RtlMoveMemory(intptr_t dest,const uchar &array[],size_t length);
void RtlMoveMemory(uchar &array[],intptr_t src,size_t length);
void RtlMoveMemory(intptr_t &dest,intptr_t src,size_t length);
int lstrlen(intptr_t psz);
int lstrlenW(intptr_t psz);
uintptr_t lstrcpynW(string &s1,uintptr_t s2,int length);
uintptr_t lstrcpynW(uintptr_t s1,string &s2,int length);
int MultiByteToWideChar(uint codePage,
uint flags,
const intptr_t multiByteString,
int lengthMultiByte,
string &str,
int length
);
uint FormatMessageW(uint dwFlags,
intptr_t lpSource,
uint dwMessageId,
uint dwLanguageId,
ushort &buffer[],
uint nSize,
intptr_t Arguments
);
#import
//--- This is a standard header of the official MetaTrader distribution
#include <WinUser32.mqh>
//+------------------------------------------------------------------+
//| Copy the memory contents pointed by src to array |
//| array parameter should be initialized to the desired size |
//+------------------------------------------------------------------+
void ArrayFromPointer(uchar &array[],intptr_t src,int count=WHOLE_ARRAY)
{
int size=(count==WHOLE_ARRAY)?ArraySize(array):count;
RtlMoveMemory(array,src,(size_t)size);
}
//+------------------------------------------------------------------+
//| Copy array to the memory pointed by dest |
//+------------------------------------------------------------------+
void ArrayToPointer(const uchar &array[],intptr_t dest,int count=WHOLE_ARRAY)
{
int size=(count==WHOLE_ARRAY)?ArraySize(array):count;
RtlMoveMemory(dest,array,(size_t)size);
}
//+------------------------------------------------------------------+
//| For void** type, dereference a level to void* |
//+------------------------------------------------------------------+
intptr_t DereferencePointer(intptr_t pointer)
{
intptr_t res=0;
RtlMoveMemory(res,pointer,sizeof(intptr_t));
return res;
}
//+------------------------------------------------------------------+
//| Read a valid wide character string to the MQL environment |
//+------------------------------------------------------------------+
string StringFromPointer(intptr_t psz,int len=0)
{
if(len < 0) return NULL;
if(len==0) {len=lstrlenW(psz);}
string res;
StringInit(res,len+1);
lstrcpynW(res,psz,len+1);
return res;
}
//+------------------------------------------------------------------+
//| Get the pointer address of a string |
//+------------------------------------------------------------------+
uintptr_t StringToPointer(string &s)
{
return lstrcpynW(s,0,0);
}
//+------------------------------------------------------------------+
//| Read a valid utf-8 string to the MQL environment |
//| With this function, there is no need to copy the string to char |
//| array, and convert with CharArrayToString |
//+------------------------------------------------------------------+
string StringFromUtf8Pointer(intptr_t psz,int len)
{
if(len < 0) return NULL;
string res;
int required=MultiByteToWideChar(CP_UTF8,0,psz,len,res,0);
StringInit(res,required);
int resLength = MultiByteToWideChar(CP_UTF8,0,psz,len,res,required);
if(resLength != required)
{
return NULL;
}
else
{
return res;
}
}
//+------------------------------------------------------------------+
//| for null-terminated string |
//+------------------------------------------------------------------+
string StringFromUtf8Pointer(intptr_t psz)
{
if(psz==0) return NULL;
int len=lstrlen(psz);
if(len==0) return NULL;
return StringFromUtf8Pointer(psz, len);
}
//+------------------------------------------------------------------+
//| Convert a utf-8 byte array to a string |
//+------------------------------------------------------------------+
string StringFromUtf8(const uchar &utf8[])
{
return CharArrayToString(utf8, 0, -1, CP_UTF8);
}
//+------------------------------------------------------------------+
//| Convert a string to a utf-8 byte array |
//+------------------------------------------------------------------+
void StringToUtf8(const string str,uchar &utf8[],bool ending=true)
{
if(!ending && str=="") return;
int count=ending ? -1 : StringLen(str);
StringToCharArray(str,utf8,0,count,CP_UTF8);
}
//+------------------------------------------------------------------+
//| Get system defined error code message |
//+------------------------------------------------------------------+
string GetErrorMessage(int errorCode)
{
static ushort buffer[64*1024];
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
0,errorCode,0,buffer,ArraySize(buffer),0);
return ShortArrayToString(buffer);
}
//+------------------------------------------------------------------+
+19 -4
View File
@@ -1,11 +1,26 @@
//+------------------------------------------------------------------+
//| AtomicCounter.mqh |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//| Module: AtomicCounter.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property strict
#include "Common.mqh"
#include <Mql/Lang/Native.mqh>
#import "libzmq.dll"
intptr_t zmq_atomic_counter_new(void);
-117
View File
@@ -1,117 +0,0 @@
//+------------------------------------------------------------------+
//| Common.mqh |
//| This file is part of mql4-lib project (Lang/Native.mqh): |
//| (github.com/dingmaotu/mql4-lib) |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//+------------------------------------------------------------------+
#property strict
#include "Errno.mqh"
// Assume MT5 is 64bit, which is the default.
// Even though MT5 can be 32bit, there is no way to detect this
// by using preprocessor macros. Instead, MetaQuotes provides a
// function called IsX64 to detect this dynamically
// This is just absurd. Why do you want to know the bitness of
// the runtime? To define pointer related entities at compile time!
// All integer types in MQL is uniform on both 32bit or 64bit
// architectures, so it is almost useless to have a runtime function IsX64.
// Why not a __X64__?
#ifdef __MQL5__
#define __X64__
#endif
#ifdef __X64__
#define intptr_t long
#define uintptr_t ulong
#define size_t long
#else
#define intptr_t int
#define uintptr_t uint
#define size_t int
#endif
#import "kernel32.dll"
void RtlMoveMemory(intptr_t dest,const uchar &array[],size_t length);
void RtlMoveMemory(uchar &array[],intptr_t src,size_t length);
int lstrlen(intptr_t psz);
int MultiByteToWideChar(uint codePage,
uint flags,
const intptr_t multiByteString,
int lengthMultiByte,
string &str,
int length
);
#import
//+------------------------------------------------------------------+
//| Copy the memory contents pointed by src to array |
//| array parameter should be initialized to the desired size |
//+------------------------------------------------------------------+
void ArrayFromPointer(uchar &array[],intptr_t src,int count=WHOLE_ARRAY)
{
int size=(count==WHOLE_ARRAY)?ArraySize(array):count;
RtlMoveMemory(array,src,(size_t)size);
}
//+------------------------------------------------------------------+
//| Copy array to the memory pointed by dest |
//+------------------------------------------------------------------+
void ArrayToPointer(const uchar &array[],intptr_t dest,int count=WHOLE_ARRAY)
{
int size=(count==WHOLE_ARRAY)?ArraySize(array):count;
RtlMoveMemory(dest,array,(size_t)size);
}
//+------------------------------------------------------------------+
//| Read a valid utf-8 string to the MQL environment |
//| With this function, there is no need to copy the string to char |
//| array, and convert with CharArrayToString |
//+------------------------------------------------------------------+
string StringFromUtf8Pointer(intptr_t psz,int len)
{
if(len < 0) return NULL;
string res;
int required=MultiByteToWideChar(CP_UTF8,0,psz,len,res,0);
StringInit(res,required);
int resLength = MultiByteToWideChar(CP_UTF8,0,psz,len,res,required);
if(resLength != required)
{
return NULL;
}
else
{
return res;
}
}
//+------------------------------------------------------------------+
//| for null-terminated string |
//+------------------------------------------------------------------+
string StringFromUtf8Pointer(intptr_t psz)
{
int len=lstrlen(psz);
return StringFromUtf8Pointer(psz, len);
}
//+------------------------------------------------------------------+
//| Convert a utf-8 byte array to a string |
//+------------------------------------------------------------------+
string StringFromUtf8(const uchar &utf8[])
{
return CharArrayToString(utf8, 0, -1, CP_UTF8);
}
//+------------------------------------------------------------------+
//| Convert a string to a utf-8 byte array |
//+------------------------------------------------------------------+
void StringToUtf8(const string str,uchar &utf8[],bool ending=true)
{
if(!ending && str=="") return;
int count=ending ? -1 : StringLen(str);
StringToCharArray(str,utf8,0,count,CP_UTF8);
}
#ifdef _DEBUG
#define Debug(msg) Print(">>> DEBUG: In ",__FUNCTION__,"(",__FILE__,":",__LINE__,") [", msg, "]")
#else
#define Debug(msg)
#endif
//+------------------------------------------------------------------+
+22 -6
View File
@@ -1,12 +1,28 @@
//+------------------------------------------------------------------+
//| Context.mqh |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//| Module: Context.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#include "Common.mqh"
#property strict
#include <Mql/Lang/Mql.mqh>
#include <Mql/Lang/Native.mqh>
#include <Mql/Lang/GlobalVariable.mqh>
#include "SocketOptions.mqh"
#include "GlobalHandle.mqh"
//--- Context options
#define ZMQ_IO_THREADS 1
+18 -1
View File
@@ -1,5 +1,22 @@
//+------------------------------------------------------------------+
//| Errno.mqh |
//| Module: Errno.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
// Following error codes come from Microsoft CRT header errno.h
-122
View File
@@ -1,122 +0,0 @@
//+------------------------------------------------------------------+
//| GlobalHandle.mqh |
//| This file is part of mql4-lib project (Lang/GlobalVariable.mqh): |
//| (github.com/dingmaotu/mql4-lib) |
//| Copyright 2017, Li Ding |
//| dingmaotu@hotmail.com |
//+------------------------------------------------------------------+
#property strict
//+------------------------------------------------------------------+
//| Wraps global variable functions |
//+------------------------------------------------------------------+
class GlobalVariable
{
public:
static int total() {return GlobalVariablesTotal();}
static string name(int index) {return GlobalVariableName(index);}
static void flush() {GlobalVariablesFlush();}
static bool exists(string name) {return GlobalVariableCheck(name);}
static datetime lastAccess(string name) {return GlobalVariableTime(name);}
static bool makeTemp(string name) {return GlobalVariableTemp(name);}
static double get(string name) {return GlobalVariableGet(name);}
static bool get(string name,double &value) {return GlobalVariableGet(name,value);}
static datetime set(string name,double value) {return GlobalVariableSet(name,value);}
static bool setOn(string name,double value,double check) {return GlobalVariableSetOnCondition(name,value,check);}
static bool remove(string name) {return GlobalVariableDel(name);}
static bool removeAll(string prefix=NULL,datetime before=0) {return GlobalVariablesDeleteAll(prefix,before);}
};
//+------------------------------------------------------------------+
//| CriticalSection object for making atomic operations |
//| |
//| An exmaple of creating a global context (the creation and destroy|
//| are both enclosed between the SAME critical section): |
//| |
//| enter() |
//| if(refcount==0) create context |
//| else refcontext |
//| increase refcount |
//| leave() |
//| |
//| enter() |
//| decrease refcount |
//| if(refcount==0) context destroy |
//| leave() |
//+------------------------------------------------------------------+
class CriticalSection
{
private:
const string m_name;
public:
CriticalSection(string name):m_name(name){}
bool isValid() const {return m_name!=NULL;}
string getName() const {return m_name;}
void enter() { while(!GlobalVariable::makeTemp(m_name) && !IsStopped())Sleep(100); }
bool tryEnter() { return GlobalVariable::makeTemp(m_name); }
void leave() { GlobalVariable::remove(m_name);}
};
//+------------------------------------------------------------------+
//| A reference counted global pointer (or handle) |
//| HandleManager should implement 2 static methods: create & destroy|
//+------------------------------------------------------------------+
template<typename T,typename HandleManager>
class GlobalHandle
{
private:
CriticalSection m_cs;
string m_refName;
string m_counterName;
protected:
T m_ref;
public:
GlobalHandle(string sharedKey=NULL):m_cs(sharedKey)
{
m_refName=m_cs.getName()+"_Ref";
m_counterName=m_cs.getName()+"_Count";
if(!m_cs.isValid()) m_ref=HandleManager::create();
else
{
m_cs.enter();
if(!GlobalVariable::exists(m_counterName))
{
GlobalVariable::makeTemp(m_counterName);
GlobalVariable::set(m_counterName,0);
}
if(long(GlobalVariable::get(m_counterName))==0)
{
m_ref=HandleManager::create();
if(!GlobalVariable::exists(m_refName))
{
GlobalVariable::makeTemp(m_refName);
GlobalVariable::set(m_refName,m_ref);
}
}
else
{
m_ref=(T)(GlobalVariable::get(m_refName));
}
GlobalVariable::set(m_counterName,GlobalVariable::get(m_counterName)+1);
m_cs.leave();
}
}
~GlobalHandle()
{
if(!m_cs.isValid()) {HandleManager::destroy(m_ref); return;}
m_cs.enter();
GlobalVariable::set(m_counterName,GlobalVariable::get(m_counterName)-1);
if(long(GlobalVariable::get(m_counterName))==0)
{
HandleManager::destroy(m_ref);
GlobalVariable::remove(m_refName);
GlobalVariable::remove(m_counterName);
}
m_cs.leave();
}
T ref() const {return m_ref;}
};
//+------------------------------------------------------------------+
+20 -4
View File
@@ -1,11 +1,27 @@
//+------------------------------------------------------------------+
//| Socket.mqh |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//| Module: Socket.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property strict
#include "Common.mqh"
#include <Mql/Lang/Mql.mqh>
#include <Mql/Lang/Native.mqh>
#include "Context.mqh"
#include "SocketOptions.mqh"
#include "ZmqMsg.mqh"
+19 -6
View File
@@ -1,13 +1,26 @@
//+------------------------------------------------------------------+
//| Socket.mqh |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//| Module: SocketOptions.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Li Ding"
#property link "dingmaotu@hotmail.com"
#property strict
#include "Common.mqh"
#include <Mql/Lang/Native.mqh>
#import "libzmq.dll"
// We can overload the same function for different data types
+19 -6
View File
@@ -1,13 +1,26 @@
//+------------------------------------------------------------------+
//| Z85.mqh |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//| Module: Z85.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Li Ding"
#property link "dingmaotu@hotmail.com"
#property strict
#include "Common.mqh"
#include <Mql/Lang/Native.mqh>
#import "libzmq.dll"
// Encode data with Z85 encoding. Returns 0(NULL) if failed
Binary file not shown.
+22 -7
View File
@@ -1,12 +1,26 @@
//+------------------------------------------------------------------+
//| ZmqMsg.mqh |
//| Copyright 2016, Li Ding |
//| dingmaotu@hotmail.com |
//| Module: ZmqMsg.mqh |
//| This file is part of the mql-zmq project: |
//| https://github.com/dingmaotu/mql-zmq |
//| |
//| Copyright 2016-2017 Li Ding <dingmaotu@hotmail.com> |
//| |
//| Licensed under the Apache License, Version 2.0 (the "License"); |
//| you may not use this file except in compliance with the License. |
//| You may obtain a copy of the License at |
//| |
//| http://www.apache.org/licenses/LICENSE-2.0 |
//| |
//| Unless required by applicable law or agreed to in writing, |
//| software distributed under the License is distributed on an |
//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
//| either express or implied. |
//| See the License for the specific language governing permissions |
//| and limitations under the License. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Li Ding"
#property link "dingmaotu@hotmail.com"
#property strict
#include "Common.mqh"
#include <Mql/Lang/Mql.mqh>
#include <Mql/Lang/Native.mqh>
//+------------------------------------------------------------------+
//| 0MQ Message struct |
//+------------------------------------------------------------------+
@@ -121,7 +135,8 @@ string ZmqMsg::getData()
void ZmqMsg::setData(const uchar &data[])
{
intptr_t dest=data();
ArrayToPointer(data,dest);
size_t size=size();
ArrayToPointer(data,dest,size);
}
//+------------------------------------------------------------------+
//| Wraps zmq_msg_gets: get metadata associated with the msg |