admin
2023-01-02 954ead41d9391bca28a3cc4f9592f73f25b3bbc8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once
 
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
#endif
#include <iostream>
#include <stdint.h>
#include <sstream>
#include <string>
#include <stdlib.h>
 
using namespace std;
#include "Include_FTAPI.h"
#include "Include_3rd_protobuf.h"
using namespace google;
using namespace Futu;
 
#pragma warning(disable:4100)
#pragma warning(disable:4189)
 
inline void ProtoBufToBodyData(const protobuf::Message& pbObj, string& strBody)
{
    protobuf::util::JsonPrintOptions ops;
    ops.add_whitespace = true;
    ops.always_print_enums_as_ints = true;
 
    protobuf::util::Status status = MessageToJsonString(pbObj, &strBody, ops);
    if (status.error_code() != protobuf::util::error::OK)
    {
        strBody.clear();
    }
}
 
#if defined(_WIN32)
inline string UTF8ToGBK(const string &strUTF8)
{
    int nLen = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
    wchar_t* wszGBK = new wchar_t[nLen + 1];
    memset(wszGBK, 0, nLen * 2 + 2);
    MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, wszGBK, nLen);
    nLen = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
    char* szGBK = new char[nLen + 1];
    memset(szGBK, 0, nLen + 1);
    WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, nLen, NULL, NULL);
    string strGBK(szGBK);
    if (wszGBK) delete[] wszGBK;
    if (szGBK) delete[] szGBK;
    return strGBK;
}
#endif
 
inline string UTF8ToLocal(const string &strUTF8)
{
#if defined(_WIN32)
    int nCodePage = GetConsoleOutputCP();
    if (nCodePage == 936)
    {
        return UTF8ToGBK(strUTF8);
    }
    else
    {
        return strUTF8;
    }
#else
    return strUTF8;
#endif
}
 
#define PrintRsp(str)    std::cout << str << endl;\
                        string strBody;\
                        ProtoBufToBodyData(stRsp, strBody);\
                        std::cout << strBody << endl;
 
#define Print(str) std::cout << str << endl;
 
 
#define PrintError(errMsg) std::cout << "ERROR: " << __FUNCTION__ << ", retMsg = " << errMsg << std::endl;
 
#define PrintUTF8(errMsg) std::cout << "ERROR: " << __FUNCTION__ << ", retMsg = " << UTF8ToLocal(errMsg) << std::endl;
 
inline void CPSleep(int32_t nSec)
{
#ifdef _WIN32
    Sleep(nSec * 1000);
#else
    struct timespec spec;
    spec.tv_sec = nSec;
    spec.tv_nsec = 0;
    nanosleep(&spec, NULL);
#endif
}
 
 
class Semaphore
{
#if defined(_WIN32)
    HANDLE m_sema;
#else
    sem_t *m_sem;
#endif
 
public:
    Semaphore(int32_t initValue)
    {
#if defined(_WIN32)
        m_sema = ::CreateSemaphoreA(NULL, initValue, 0x7fffffff, NULL);
#else
        pid_t pid = getpid();
        stringstream str;
        str << "ftapi.sample." << (long)pid;
        m_sem = ::sem_open(str.str().c_str(), O_CREAT | O_EXCL, S_IRWXU, initValue);
#endif
    }
 
    ~Semaphore()
    {
#if defined(_WIN32)
        ::CloseHandle(m_sema);
#else
        ::sem_close(m_sem);
#endif
    }
 
    void wait()
    {
#if defined(_WIN32)
        ::WaitForSingleObject(m_sema, INFINITE);
#else
        ::sem_wait(m_sem);
#endif
    }
 
    void post()
    {
#if defined(_WIN32)
        ::ReleaseSemaphore(m_sema, 1, NULL);
#else
        ::sem_post(m_sem);
#endif
    }
 
    bool trywait()
    {
#if defined(_WIN32)
        return WAIT_OBJECT_0 == ::WaitForSingleObject(m_sema, 0);
#else
        return 0 == ::sem_trywait(m_sem);
#endif
    }
};