ProteoWizard
cpp_cli_utilities.hpp
Go to the documentation of this file.
1 //
2 // $Id: cpp_cli_utilities.hpp 6478 2014-07-08 20:01:38Z chambm $
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 #include <gcroot.h>
27 #include <vcclr.h>
28 #include <comdef.h> // _com_error
29 #include <vector>
30 #include <string>
31 #include <stdexcept>
32 #include <boost/algorithm/string/split.hpp>
33 #include <boost/range/algorithm/copy.hpp>
34 #include "automation_vector.h"
35 
36 namespace pwiz {
37 namespace util {
38 
39 
40 inline std::string ToStdString(System::String^ source)
41 {
42  if (System::String::IsNullOrEmpty(source))
43  return std::string();
44 
45  System::Text::Encoding^ encoding = System::Text::Encoding::UTF8;
46  array<System::Byte>^ encodedBytes = encoding->GetBytes(source);
47 
48  std::string target("", encodedBytes->Length);
49  char* buffer = &target[0];
50  unsigned char* unsignedBuffer = reinterpret_cast<unsigned char*>(buffer);
51  System::Runtime::InteropServices::Marshal::Copy(encodedBytes, 0, (System::IntPtr) unsignedBuffer, encodedBytes->Length);
52  return target;
53 }
54 
55 
56 inline System::String^ ToSystemString(const std::string& source, bool utf8=true)
57 {
58  if (utf8)
59  {
60  System::Text::Encoding^ encoding = System::Text::Encoding::UTF8;
61  int length = source.length();
62  array<System::Byte>^ buffer = gcnew array<System::Byte>(length);
63  System::Runtime::InteropServices::Marshal::Copy((System::IntPtr) const_cast<char*>(source.c_str()), buffer, 0, length);
64  return encoding->GetString(buffer);
65  }
66  else
67  return gcnew System::String(source.c_str());
68 }
69 
70 
71 template<typename managed_value_type, typename native_value_type>
72 void ToStdVector(cli::array<managed_value_type>^ managedArray, std::vector<native_value_type>& stdVector)
73 {
74  stdVector.clear();
75  if (managedArray->Length > 0)
76  {
77  cli::pin_ptr<managed_value_type> pin = &managedArray[0];
78  native_value_type* begin = (native_value_type*) pin;
79  stdVector.assign(begin, begin + managedArray->Length);
80  }
81 }
82 
83 
84 template<typename managed_value_type, typename native_value_type>
85 void ToStdVector(System::Collections::Generic::IList<managed_value_type>^ managedList, std::vector<native_value_type>& stdVector)
86 {
87  stdVector.clear();
88  if (managedList->Count > 0)
89  {
90  stdVector.reserve(managedList->Count);
91  for (size_t i = 0, end = managedList->Count; i < end; ++i)
92  stdVector.push_back((native_value_type) managedList[i]);
93  }
94 }
95 
96 
97 /// wraps a managed array in an automation_vector to enable direct access from unmanaged code
98 template<typename managed_value_type, typename native_value_type>
99 void ToAutomationVector(cli::array<managed_value_type>^ managedArray, automation_vector<native_value_type>& automationArray)
100 {
101  VARIANT v;
102  ::VariantInit(&v);
103  System::IntPtr vPtr = (System::IntPtr) &v;
104  System::Runtime::InteropServices::Marshal::GetNativeVariantForObject((System::Object^) managedArray, vPtr);
105  automationArray.attach(v);
106 }
107 
108 
109 } // namespace util
110 } // namespace pwiz
111 
112 
113 /// forwards managed exception to unmanaged code;
114 /// prepends function with a single level of scope,
115 /// e.g. "Reader::read()" instead of "pwiz::data::msdata::Reader::read()"
116 #define CATCH_AND_FORWARD \
117  catch (std::exception&) {throw;} \
118  catch (_com_error& e) {throw std::runtime_error(string("COM error: ") + e.ErrorMessage());} \
119  /*catch (CException* e) {std::auto_ptr<CException> exceptionDeleter(e); char message[1024]; e->GetErrorMessage(message, 1024); throw std::runtime_error(string("MFC error: ") + message);}*/ \
120  catch (System::Exception^ e) \
121  { \
122  std::vector<boost::iterator_range<std::string::const_iterator> > tokens; \
123  std::string function(__FUNCTION__); \
124  boost::algorithm::split(tokens, function, boost::is_any_of(":"), boost::algorithm::token_compress_on); \
125  std::string what("["); \
126  if (tokens.size() > 1) \
127  { \
128  boost::range::copy(*(tokens.rbegin()+1), std::back_inserter(what)); \
129  what += "::"; \
130  if (boost::range::equal(*(tokens.rbegin()+1), *tokens.rbegin())) \
131  what += "ctor"; \
132  else if (tokens.rbegin()->front() == '~') \
133  what += "dtor"; \
134  else \
135  boost::range::copy(*tokens.rbegin(), std::back_inserter(what)); \
136  } \
137  else if (tokens.size() > 0) \
138  boost::range::copy(*tokens.rbegin(), std::back_inserter(what)); \
139  what += "] "; \
140  what += pwiz::util::ToStdString(e->Message); \
141  throw std::runtime_error(what); \
142  }
143 
144 
145 #endif // _CPP_CLI_UTILITIES_HPP_
std::string ToStdString(System::String^ source)
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 ...
void ToStdVector(cli::array< managed_value_type >^ managedArray, std::vector< native_value_type > &stdVector)
System::String ToSystemString(const std::string &source, bool utf8=true)