ProteoWizard
cpp_cli_utilities.hpp
Go to the documentation of this file.
1 //
2 // $Id$
3 //
4 //
5 // Original author: Matt Chambers <matt.chambers .@. vanderbilt.edu>
6 //
7 // Copyright 2010 Vanderbilt University - Nashville, TN 37232
8 //
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 //
13 // http://www.apache.org/licenses/LICENSE-2.0
14 //
15 // Unless required by applicable law or agreed to in writing, software
16 // distributed under the License is distributed on an "AS IS" BASIS,
17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 // See the License for the specific language governing permissions and
19 // limitations under the License.
20 //
21 
22 
23 #ifndef _CPP_CLI_UTILITIES_HPP_
24 #define _CPP_CLI_UTILITIES_HPP_
25 
26 #define WIN32_LEAN_AND_MEAN
27 #define NOGDI
28 
29 #ifndef NOMINMAX
30 # define NOMINMAX
31 #endif
32 
33 #include <gcroot.h>
34 #include <vcclr.h>
35 #pragma unmanaged
36 #include <comdef.h> // _com_error
37 #include <vector>
38 #include <string>
39 #include <stdexcept>
40 #include <boost/algorithm/string/split.hpp>
41 #include <boost/range/algorithm/copy.hpp>
42 #include "automation_vector.h"
43 #pragma managed
44 #include "BinaryData.hpp"
45 
46 namespace pwiz {
47 namespace util {
48 
49 
50 inline std::string ToStdString(System::String^ source)
51 {
52  if (System::String::IsNullOrEmpty(source))
53  return std::string();
54 
55  System::Text::Encoding^ encoding = System::Text::Encoding::UTF8;
56  array<System::Byte>^ encodedBytes = encoding->GetBytes(source);
57 
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);
62  return target;
63 }
64 
65 
66 inline System::String^ ToSystemString(const std::string& source, bool utf8=true)
67 {
68  if (utf8)
69  {
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);
75  }
76  else
77  return gcnew System::String(source.c_str());
78 }
79 
80 
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)
83 {
84  stdVector.clear();
85  if (managedArray->Length > 0)
86  {
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);
90  }
91 }
92 
93 
94 template<typename managed_value_type>
95 void ToStdVector(cli::array<managed_value_type>^ managedArray, std::vector<std::string>& stdVector)
96 {
97  stdVector.clear();
98  if (managedArray->Length > 0)
99  {
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()));
103  }
104 }
105 
106 
107 template<typename native_value_type, typename managed_value_type>
108 std::vector<native_value_type> ToStdVector(cli::array<managed_value_type>^ managedArray)
109 {
110  std::vector<native_value_type> result;
111  ToStdVector(managedArray, result);
112  return result;
113 }
114 
115 
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)
118 {
119  stdVector.clear();
120  if (managedArray->Length > 0)
121  {
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);
125  }
126 }
127 
128 
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)
131 {
132  stdVector.clear();
133  if (managedList->Count > 0)
134  {
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]);
138  }
139 }
140 
141 
142 /// wraps a managed array in an automation_vector to enable direct access from unmanaged code
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)
145 {
146  VARIANT v;
147  ::VariantInit(&v);
148  System::IntPtr vPtr = (System::IntPtr) &v;
149  System::Runtime::InteropServices::Marshal::GetNativeVariantForObject((System::Object^) managedArray, vPtr);
150  automationArray.attach(v);
151 }
152 
153 
154 template<typename managed_value_type, typename native_value_type>
155 void ToBinaryData(cli::array<managed_value_type>^ managedArray, BinaryData<native_value_type>& binaryData)
156 {
157  typedef System::Runtime::InteropServices::GCHandle GCHandle;
158 
159 #ifdef PWIZ_MANAGED_PASSTHROUGH
160  GCHandle handle = GCHandle::Alloc(managedArray);
161  binaryData = ((System::IntPtr)handle).ToPointer();
162  handle.Free();
163 #else
164  ToBinaryData(managedArray, 0, binaryData, 0, managedArray->Length);
165 #endif
166 }
167 
168 
169 template<typename managed_value_type, typename native_value_type>
170 void ToBinaryData(cli::array<managed_value_type>^ managedArray, int sourceIndex, BinaryData<native_value_type>& binaryData, int destinationIndex, int count)
171 {
172  binaryData.clear();
173  if (managedArray->Length > 0)
174  {
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);
178  }
179 }
180 
181 
182 template<typename managed_value_type, typename native_value_type>
183 void ToBinaryData(System::Collections::Generic::IList<managed_value_type>^ managedList, BinaryData<native_value_type>& binaryData)
184 {
185  binaryData.clear();
186  if (managedList->Count > 0)
187  {
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]);
191  }
192 }
193 
194 
195 
196 ref class Lock
197 {
198  System::Object^ m_pObject;
199 
200  public:
201  Lock(System::Object^ pObject) : m_pObject(pObject) { System::Threading::Monitor::Enter(m_pObject); }
202  ~Lock() { System::Threading::Monitor::Exit(m_pObject); }
203 };
204 
205 
206 } // namespace util
207 } // namespace pwiz
208 
209 
210 namespace {
211 
212 /// prepends function with a single level of scope,
213 /// e.g. "Reader::read()" instead of "pwiz::data::msdata::Reader::read()"
214 template <typename T>
215 std::string trimFunctionMacro(const char* function, const T& param)
216 {
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)
222  {
223  boost::range::copy(*(tokens.rbegin() + 1), std::back_inserter(what));
224  what += "::";
225  if (boost::range::equal(*(tokens.rbegin() + 1), *tokens.rbegin()))
226  what += "ctor";
227  else if (tokens.rbegin()->front() == '~')
228  what += "dtor";
229  else
230  boost::range::copy(*tokens.rbegin(), std::back_inserter(what));
231  }
232  else if (tokens.size() > 0)
233  boost::range::copy(*tokens.rbegin(), std::back_inserter(what));
234  what += "(" + lexical_cast<std::string>(param) + ")] ";
235  return what;
236 }
237 
238 } // namespace
239 
240 
241 /// forwards managed exception to unmanaged code;
242 /// prepends function with a single level of scope,
243 /// e.g. "Reader::read()" instead of "pwiz::data::msdata::Reader::read()"
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());} \
247  /*catch (CException* e) {std::auto_ptr<CException> exceptionDeleter(e); char message[1024]; e->GetErrorMessage(message, 1024); throw std::runtime_error(string("MFC error: ") + message);}*/ \
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)); }
250 
251 #define CATCH_AND_FORWARD CATCH_AND_FORWARD_EX("")
252 
253 #endif // _CPP_CLI_UTILITIES_HPP_
pwiz::util::BinaryData::assign
void assign(const Iter &first, const Iter &last)
Definition: BinaryData.hpp:293
pwiz
Definition: ChromatogramList_Filter.hpp:36
pwiz::util::Lock::Lock
Lock(System::Object^ pObject)
Definition: cpp_cli_utilities.hpp:201
pwiz::util::Lock::~Lock
~Lock()
Definition: cpp_cli_utilities.hpp:202
pwiz::util::BinaryData::push_back
void push_back(const T &value)
Definition: BinaryData.hpp:362
pwiz::util::BinaryData
A custom vector class that can store its contents in either a std::vector or a cli::array (when compi...
Definition: BinaryData.hpp:45
pwiz::util::ToBinaryData
void ToBinaryData(cli::array< managed_value_type >^ managedArray, BinaryData< native_value_type > &binaryData)
Definition: cpp_cli_utilities.hpp:155
pwiz::util::BinaryData::clear
void clear()
Definition: BinaryData.hpp:373
pwiz::util::BinaryData::reserve
void reserve(size_type n)
Definition: BinaryData.hpp:155
pwiz::util::Lock::m_pObject
System::Object m_pObject
Definition: cpp_cli_utilities.hpp:198
pwiz::util::ToStdString
std::string ToStdString(System::String^ source)
Definition: cpp_cli_utilities.hpp:50
BinaryData.hpp
pwiz::util::Lock
Definition: cpp_cli_utilities.hpp:197
pwiz::util::ToStdVector
void ToStdVector(cli::array< managed_value_type >^ managedArray, std::vector< native_value_type > &stdVector)
Definition: cpp_cli_utilities.hpp:82
pwiz::util::ToAutomationVector
void ToAutomationVector(cli::array< managed_value_type >^ managedArray, automation_vector< native_value_type > &automationArray)
wraps a managed array in an automation_vector to enable direct access from unmanaged code
Definition: cpp_cli_utilities.hpp:144
pwiz::util::ToSystemString
System::String ToSystemString(const std::string &source, bool utf8=true)
Definition: cpp_cli_utilities.hpp:66