23 #ifndef _CPP_CLI_UTILITIES_HPP_
24 #define _CPP_CLI_UTILITIES_HPP_
26 #define WIN32_LEAN_AND_MEAN
40 #include <boost/algorithm/string/split.hpp>
41 #include <boost/range/algorithm/copy.hpp>
42 #include "automation_vector.h"
52 if (System::String::IsNullOrEmpty(source))
55 System::Text::Encoding^ encoding = System::Text::Encoding::UTF8;
56 array<System::Byte>^ encodedBytes = encoding->GetBytes(source);
58 std::string target(
"", encodedBytes->Length);
59 char* buffer = &target[0];
60 unsigned char* unsignedBuffer =
reinterpret_cast<unsigned char*
>(buffer);
61 System::Runtime::InteropServices::Marshal::Copy(encodedBytes, 0, (System::IntPtr) unsignedBuffer, encodedBytes->Length);
66 inline System::String^
ToSystemString(
const std::string& source,
bool utf8=
true)
70 System::Text::Encoding^ encoding = System::Text::Encoding::UTF8;
71 int length = source.length();
72 array<System::Byte>^ buffer =
gcnew array<System::Byte>(length);
73 System::Runtime::InteropServices::Marshal::Copy((System::IntPtr)
const_cast<char*
>(source.c_str()), buffer, 0, length);
74 return encoding->GetString(buffer);
77 return gcnew System::String(source.c_str());
81 template<
typename managed_value_type,
typename native_value_type>
82 void ToStdVector(cli::array<managed_value_type>^ managedArray, std::vector<native_value_type>& stdVector)
85 if (managedArray->Length > 0)
87 cli::pin_ptr<managed_value_type> pin = &managedArray[0];
88 native_value_type* begin = (native_value_type*) pin;
89 stdVector.assign(begin, begin + managedArray->Length);
94 template<
typename managed_value_type>
95 void ToStdVector(cli::array<managed_value_type>^ managedArray, std::vector<std::string>& stdVector)
98 if (managedArray->Length > 0)
100 stdVector.reserve(managedArray->Length);
101 for (
size_t i = 0, end = managedArray->Length; i < end; ++i)
102 stdVector.push_back(
ToStdString(managedArray[i]->ToString()));
107 template<
typename native_value_type,
typename managed_value_type>
108 std::vector<native_value_type>
ToStdVector(cli::array<managed_value_type>^ managedArray)
110 std::vector<native_value_type> result;
116 template<
typename managed_value_type,
typename native_value_type>
117 void ToStdVector(cli::array<managed_value_type>^ managedArray,
int sourceIndex, std::vector<native_value_type>& stdVector,
int destinationIndex,
int count)
120 if (managedArray->Length > 0)
122 cli::pin_ptr<managed_value_type> pin = &managedArray[sourceIndex];
123 native_value_type* begin = (native_value_type*)pin;
124 stdVector.assign(begin + destinationIndex, begin + destinationIndex + count);
129 template<
typename managed_value_type,
typename native_value_type>
130 void ToStdVector(System::Collections::Generic::IList<managed_value_type>^ managedList, std::vector<native_value_type>& stdVector)
133 if (managedList->Count > 0)
135 stdVector.reserve(managedList->Count);
136 for (
size_t i = 0, end = managedList->Count; i < end; ++i)
137 stdVector.push_back((native_value_type) managedList[i]);
143 template<
typename managed_value_type,
typename native_value_type>
144 void ToAutomationVector(cli::array<managed_value_type>^ managedArray, automation_vector<native_value_type>& automationArray)
148 System::IntPtr vPtr = (System::IntPtr) &v;
149 System::Runtime::InteropServices::Marshal::GetNativeVariantForObject((System::Object^) managedArray, vPtr);
150 automationArray.attach(v);
154 template<
typename managed_value_type,
typename native_value_type>
157 typedef System::Runtime::InteropServices::GCHandle GCHandle;
159 #ifdef PWIZ_MANAGED_PASSTHROUGH
160 GCHandle handle = GCHandle::Alloc(managedArray);
161 binaryData = ((System::IntPtr)handle).ToPointer();
164 ToBinaryData(managedArray, 0, binaryData, 0, managedArray->Length);
169 template<
typename managed_value_type,
typename native_value_type>
173 if (managedArray->Length > 0)
175 cli::pin_ptr<managed_value_type> pin = &managedArray[sourceIndex];
176 native_value_type* begin = (native_value_type*)pin;
177 binaryData.
assign(begin + destinationIndex, begin + destinationIndex + count);
182 template<
typename managed_value_type,
typename native_value_type>
186 if (managedList->Count > 0)
188 binaryData.
reserve(managedList->Count);
189 for (
size_t i = 0, end = managedList->Count; i < end; ++i)
190 binaryData.
push_back((native_value_type)managedList[i]);
214 template <
typename T>
215 std::string trimFunctionMacro(
const char*
function,
const T& param)
217 std::vector<boost::iterator_range<std::string::const_iterator> > tokens;
218 std::string functionStr(
function);
219 boost::algorithm::split(tokens, functionStr, boost::is_any_of(
":"), boost::algorithm::token_compress_on);
220 std::string what(
"[");
221 if (tokens.size() > 1)
223 boost::range::copy(*(tokens.rbegin() + 1), std::back_inserter(what));
225 if (boost::range::equal(*(tokens.rbegin() + 1), *tokens.rbegin()))
227 else if (tokens.rbegin()->front() ==
'~')
230 boost::range::copy(*tokens.rbegin(), std::back_inserter(what));
232 else if (tokens.size() > 0)
233 boost::range::copy(*tokens.rbegin(), std::back_inserter(what));
234 what +=
"(" + lexical_cast<std::string>(param) +
")] ";
244 #define CATCH_AND_FORWARD_EX(param) \
245 catch (std::exception&) {throw;} \
246 catch (_com_error& e) {throw std::runtime_error(std::string("COM error: ") + e.ErrorMessage());} \
248 catch (System::AggregateException^ e) { throw std::runtime_error(trimFunctionMacro(__FUNCTION__, (param)) + pwiz::util::ToStdString(e->ToString())); } \
249 catch (System::Exception^ e) { throw std::runtime_error(trimFunctionMacro(__FUNCTION__, (param)) + pwiz::util::ToStdString(e->Message)); }
251 #define CATCH_AND_FORWARD CATCH_AND_FORWARD_EX("")
253 #endif // _CPP_CLI_UTILITIES_HPP_