forked from smarttechnologies/peparser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
widestring.h
129 lines (102 loc) · 3.46 KB
/
widestring.h
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
// Copyright (c) 2016 SMART Technologies. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#pragma once
#include <string>
namespace peparser
{
// ====================================================================================
// string conversion
inline std::string WideStringToMultiByte(const std::wstring& in)
{
size_t size = 0;
wcstombs_s(&size, NULL, 0, in.data(), in.size());
if (size == 0) return std::string();
std::string result(size, 0);
if (0 != wcstombs_s(NULL, &result[0], result.size(), in.data(), in.size()))
return std::string();
if (*result.rbegin() == '\0')
result.erase(result.end() - 1);
return result;
}
inline std::wstring MultiByteToWideString(const std::string& in)
{
size_t size = 0;
mbstowcs_s(&size, NULL, 0, in.data(), in.size());
if (size == 0) return std::wstring();
std::wstring result(size, 0);
if (0 != mbstowcs_s(NULL, &result[0], result.size(), in.data(), in.size()))
return std::wstring();
if (*result.rbegin() == L'\0')
result.erase(result.end() - 1);
return result;
}
// ====================================================================================
// searching for strings in PE files
// string literals used by compiler when generating __FILE__, __DATE__ and __TIME__ macros
template<class CharT>
struct Literals
{
static const CharT* month[];
static const CharT colon;
static const CharT null;
static const CharT slash;
static const CharT backslash;
};
enum CharConversionType
{
None = 0
, Path = 1 // will normalize path separators and lowercase
, NoCase = 2 // will lowercase
};
template<class CharT, CharConversionType X> struct CharConversion { static CharT Convert(CharT c); };
template<class CharT> struct CharConversion<CharT, None> { static CharT Convert(CharT c) { return c; } };
template<class CharT> struct CharConversion<CharT, NoCase> { static CharT Convert(CharT c) { return tolower(c); } };
template<class CharT> struct CharConversion<CharT, Path>
{
static CharT Convert(CharT c)
{
if (c == Literals<CharT>::slash)
return Literals<CharT>::backslash;
return tolower(c);
}
};
template<class CharT, CharConversionType X> const CharT* FindChar(const CharT* str, CharT c, size_t size)
{
if (size <= 0)
return nullptr;
c = CharConversion<CharT, X>::Convert(c);
for (size_t i = 0; i < size; ++i)
if (CharConversion<CharT, X>::Convert(*(str + i)) == c)
return str + i;
return nullptr;
}
template<class CharT, CharConversionType X> const CharT* FindStringEntry(const CharT* entry, const std::basic_string<CharT>& str, size_t subStringSize, size_t size)
{
if (str.empty())
return nullptr;
const CharT* searchStart = entry;
while (searchStart = FindChar<CharT, X>(searchStart + 1, str[0], size - 1))
{
size_t i = 0;
for (; i < subStringSize; ++i)
if (CharConversion<CharT, X>::Convert(*(searchStart + i)) != CharConversion<CharT, X>::Convert(str[i]))
break;
if (i == subStringSize)
break;
}
return searchStart;
}
template<class CharT, CharConversionType X> bool CompareStrings(const CharT* str1, const CharT* str2, size_t size)
{
if (!str1 && str2)
return false;
if (!str2 && str1)
return false;
if (!str1 && !str2)
return true;
for (size_t i = 0; i < size; ++i)
if (CharConversion<CharT, X>::Convert(*(str1 + i)) != CharConversion<CharT, X>::Convert(*(str2 + i)))
return false;
return true;
}
}