-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExcelUtilsX.h
More file actions
122 lines (89 loc) · 3.02 KB
/
ExcelUtilsX.h
File metadata and controls
122 lines (89 loc) · 3.02 KB
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
#ifndef _ExcelUtilsX_
#define _ExcelUtilsX_
#include "ExcelUtils.h"
#include "xVect.h"
namespace ExcelUtils {
BSTR CharPtrToBSTR(const char * charPtr);
BSTR WcharPtrToBSTR(const wchar_t * charPtr);
#pragma pack(push, 4)
template <class T>
struct SAFEARRAY {
USHORT cDims;
USHORT fFeatures;
ULONG cbElements;
ULONG cLocks;
T * pvData;
SAFEARRAYBOUND rgsabound[1];
T * GetEl(ptrdiff_t i, bool errorIfOutOfRange = true) {
if (!this) return nullptr;
if (this->cDims != 1) {
RECOVERABLE_ERROR("array dimension is not 1", -1);
return nullptr;
}
if (this->cbElements != sizeof(T)) {
RECOVERABLE_ERROR("Wrong element size", -1);
return nullptr;
}
i -= this->rgsabound[0].lLbound;
if ((size_t)i >= this->rgsabound[0].cElements) {
if (errorIfOutOfRange) RECOVERABLE_ERROR("Index out of range", -1);
return nullptr;
}
return &((T*)this->pvData)[i];
}
};
#pragma pack(pop)
template <class T>
void aVectToSafeArray(::SAFEARRAY *& sa, const aVect<T> & t) {
if (SafeArrayDestroy(sa) != S_OK) MY_ERROR("SafeArrayDestroy failed");
SAFEARRAYBOUND bounds;
#ifdef _WIN64
if (t.Count() >= UINT_MAX) MY_ERROR("vector too large for SAFEARRAY");
#endif
bounds.cElements = (ULONG)t.Count();
bounds.lLbound = 1;
VARENUM varType;
if (std::is_same<T, double>::value) {
varType = VT_R8;
} else {
MY_ERROR("TODO");
}
sa = SafeArrayCreate(varType, 1, &bounds);
auto ptr = GetEl((ExcelUtils::SAFEARRAY<double>*)sa, 1);
memcpy(ptr, t, t.Count() * sizeof(T));
}
inline void MySysFreeString(BSTR & str) {
SysFreeString(str);
str = NULL;
}
template <class T>
T * GetEl(SAFEARRAY<T> * ptr, ptrdiff_t i, bool errorIfOutOfRange = true) {
if (!ptr) return nullptr;
return ptr->GetEl(i, errorIfOutOfRange);
}
template<bool insertLineFeed>
void AppendWcharToBSTR(BSTR & str1, const wchar_t * str2) {
size_t oldLen = str1 ? wcslen(str1) : 0;
size_t addLen = str2 ? wcslen(str2) : 0;
size_t newLen = oldLen + addLen + insertLineFeed;// + 1 for the line feed
if (oldLen > 0) {
//static aVect<char> buf;
aVect<char> buf;
buf.Redim(2 * (newLen + 1)); // + 1 for the null terminator
memcpy(buf, str1, 2 * oldLen); //copy old string
if (insertLineFeed) buf[2 * oldLen] = 10; buf[2 * oldLen + 1] = 0; //line feed
memcpy((char*)buf + 2 * (oldLen + insertLineFeed), str2, 2 * addLen); //append additional string
buf[2 * newLen] = buf[2 * newLen + 1] = 0; //null terminator
//logFile.Printf("AppendWcharToBSTR: MySysFreeString(0x%p)\n", str1);
MySysFreeString(str1);
str1 = SysAllocStringByteLen(buf, (UINT)buf.Count() - 2); //SysAllocStringByteLen appends a 1-byte null terminator
}
else {
MySysFreeString(str1);
if (str2) str1 = SysAllocStringByteLen((char*)str2, (UINT)(2 * (addLen)));//SysAllocStringByteLen appends 1-byte a null terminator
}
}
void SEH_Translate(unsigned int u, PEXCEPTION_POINTERS pExp);
VARIANT ExceptionHandler(std::exception_ptr eptr);
}
#endif