1 | #ifndef __STRUTIL_HPP__ |
---|
2 | #define __STRUTIL_HPP__ |
---|
3 | |
---|
4 | #include <algorithm> |
---|
5 | #include <functional> |
---|
6 | #include <string> |
---|
7 | #include <memory> |
---|
8 | #include <iostream> |
---|
9 | #include <cctype> |
---|
10 | #include <locale> |
---|
11 | #include "optional.h" |
---|
12 | |
---|
13 | #import <Foundation/NSString.h> |
---|
14 | |
---|
15 | #include <CoreFoundation/CoreFoundation.h> |
---|
16 | #include <CoreFoundation/CFArray.h> |
---|
17 | #include <CoreFoundation/CFString.h> |
---|
18 | |
---|
19 | inline std::string strprintf(const char *fromat, ...) |
---|
20 | { |
---|
21 | std::string s; |
---|
22 | s.resize(128); // best guess |
---|
23 | char *buff = const_cast<char *>(s.data()); |
---|
24 | |
---|
25 | va_list arglist; |
---|
26 | va_start(arglist, fromat); |
---|
27 | auto len = vsnprintf(buff, 128, fromat, arglist); |
---|
28 | va_end(arglist); |
---|
29 | |
---|
30 | if (len > 127) |
---|
31 | { |
---|
32 | va_start(arglist, fromat); |
---|
33 | s.resize(len + 1); // leave room for null terminator |
---|
34 | buff = const_cast<char *>(s.data()); |
---|
35 | len = vsnprintf(buff, len+1, fromat, arglist); |
---|
36 | va_end(arglist); |
---|
37 | } |
---|
38 | s.resize(len); |
---|
39 | return s; // move semantics FTW |
---|
40 | } |
---|
41 | |
---|
42 | inline std::string extractString(CFStringRef value) |
---|
43 | { |
---|
44 | const char * data = CFStringGetCStringPtr(value, kCFStringEncodingUTF8); |
---|
45 | if (data != NULL) |
---|
46 | { |
---|
47 | return std::string(data, strlen(data)); |
---|
48 | } else { |
---|
49 | CFIndex strSize = CFStringGetLength(value)+1; |
---|
50 | char * retry = (char *)malloc((int)strSize); |
---|
51 | if (CFStringGetCString(value, retry, strSize, kCFStringEncodingUTF8)) { |
---|
52 | return std::string(retry, strlen(retry)); |
---|
53 | } |
---|
54 | return std::string("[null]"); |
---|
55 | } |
---|
56 | } |
---|
57 | |
---|
58 | inline bool replace(std::string& str, const std::string& from, const std::string& to) { |
---|
59 | size_t start_pos = str.find(from); |
---|
60 | if(start_pos == std::string::npos) |
---|
61 | return false; |
---|
62 | str.replace(start_pos, from.length(), to); |
---|
63 | return true; |
---|
64 | } |
---|
65 | |
---|
66 | |
---|
67 | // trim from start (in place) |
---|
68 | static inline void ltrim(std::string &s) { |
---|
69 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), |
---|
70 | std::not1(std::ptr_fun<int, int>(std::isspace)))); |
---|
71 | } |
---|
72 | |
---|
73 | // trim from end (in place) |
---|
74 | static inline void rtrim(std::string &s) { |
---|
75 | s.erase(std::find_if(s.rbegin(), s.rend(), |
---|
76 | std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); |
---|
77 | } |
---|
78 | |
---|
79 | // trim from both ends (in place) |
---|
80 | static inline void trim(std::string &s) { |
---|
81 | ltrim(s); |
---|
82 | rtrim(s); |
---|
83 | } |
---|
84 | |
---|
85 | // trim from start (copying) |
---|
86 | static inline std::string ltrim_copy(std::string s) { |
---|
87 | ltrim(s); |
---|
88 | return s; |
---|
89 | } |
---|
90 | |
---|
91 | // trim from end (copying) |
---|
92 | static inline std::string rtrim_copy(std::string s) { |
---|
93 | rtrim(s); |
---|
94 | return s; |
---|
95 | } |
---|
96 | |
---|
97 | // trim from both ends (copying) |
---|
98 | static inline std::string trim_copy(std::string s) { |
---|
99 | trim(s); |
---|
100 | return s; |
---|
101 | } |
---|
102 | |
---|
103 | NSString* stdStringToNSString(std::string &stdstr) { |
---|
104 | return [NSString stringWithUTF8String:stdstr.c_str()]; |
---|
105 | } |
---|
106 | |
---|
107 | std::string nsStringToStd(NSString* nsStr) { |
---|
108 | const char *charlist = [nsStr UTF8String]; |
---|
109 | return std::string(charlist); |
---|
110 | } |
---|
111 | |
---|
112 | #if __cplusplus > 201402L |
---|
113 | |
---|
114 | |
---|
115 | using std::optional; |
---|
116 | |
---|
117 | // Use CFStringRef instead of NSString*, otherwise disable ARC |
---|
118 | inline optional<CFStringRef> optionalString(bool val) { |
---|
119 | optional<CFStringRef> myOptString; |
---|
120 | if(val) { |
---|
121 | // Cast to corresponding CoreFoundation object |
---|
122 | myOptString = (CFStringRef)@"String"; |
---|
123 | } |
---|
124 | return myOptString; |
---|
125 | } |
---|
126 | |
---|
127 | #endif |
---|
128 | |
---|
129 | |
---|
130 | #endif |
---|