ProteoWizard
cpp_cli_utilities.hpp
Go to the documentation of this file.
1 //
2 // $Id: cpp_cli_utilities.hpp 3949 2012-09-10 23:13:24Z 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 
27 #include <gcroot.h>
28 #include <vcclr.h>
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 
37 namespace pwiz {
38 namespace util {
39 
40 
41 inline std::string ToStdString(System::String^ source)
42 {
43  if (System::String::IsNullOrEmpty(source))
44  return std::string();
45 
46  int len = (( source->Length+1) * 2);
47  char *ch = new char[ len ];
48  bool result ;
49  {
50  pin_ptr<const wchar_t> wch = PtrToStringChars( source );
51  result = wcstombs( ch, wch, len ) != -1;
52  }
53  std::string target = ch;
54  delete ch;
55  if(!result)
56  throw gcnew System::Exception("error converting System::String to std::string");
57  return target;
58 }
59 
60 
61 inline System::String^ ToSystemString(const std::string& source)
62 {
63  return gcnew System::String(source.c_str());
64 }
65 
66 
67 template<typename managed_value_type, typename native_value_type>
68 void ToStdVector(cli::array<managed_value_type>^ managedArray, std::vector<native_value_type>& stdVector)
69 {
70  stdVector.clear();
71  if (managedArray->Length > 0)
72  {
73  cli::pin_ptr<managed_value_type> pin = &managedArray[0];
74  native_value_type* begin = (native_value_type*) pin;
75  stdVector.assign(begin, begin + managedArray->Length);
76  }
77 }
78 
79 
80 /// wraps a managed array in an automation_vector to enable direct access from unmanaged code
81 template<typename managed_value_type, typename native_value_type>
82 void ToAutomationVector(cli::array<managed_value_type>^ managedArray, automation_vector<native_value_type>& automationArray)
83 {
84  VARIANT v;
85  ::VariantInit(&v);
86  System::IntPtr vPtr = (System::IntPtr) &v;
87  System::Runtime::InteropServices::Marshal::GetNativeVariantForObject((System::Object^) managedArray, vPtr);
88  automationArray.attach(v);
89 }
90 
91 
92 } // namespace util
93 } // namespace pwiz
94 
95 
96 /// forwards managed exception to unmanaged code;
97 /// prepends function with a single level of scope,
98 /// e.g. "Reader::read()" instead of "pwiz::data::msdata::Reader::read()"
99 #define CATCH_AND_FORWARD \
100  catch (std::exception&) {throw;} \
101  catch (System::Exception^ e) \
102  { \
103  std::vector<boost::iterator_range<std::string::const_iterator> > tokens; \
104  std::string function(__FUNCTION__); \
105  boost::algorithm::split(tokens, function, boost::is_any_of(":"), boost::algorithm::token_compress_on); \
106  std::string what("["); \
107  if (tokens.size() > 1) \
108  { \
109  boost::range::copy(*(tokens.rbegin()+1), std::back_inserter(what)); \
110  what += "::"; \
111  if (boost::range::equal(*(tokens.rbegin()+1), *tokens.rbegin())) \
112  what += "ctor"; \
113  else if (tokens.rbegin()->front() == '~') \
114  what += "dtor"; \
115  else \
116  boost::range::copy(*tokens.rbegin(), std::back_inserter(what)); \
117  } \
118  else if (tokens.size() > 0) \
119  boost::range::copy(*tokens.rbegin(), std::back_inserter(what)); \
120  what += "] "; \
121  what += pwiz::util::ToStdString(e->Message); \
122  throw std::runtime_error(what); \
123  }
124 
125 
126 #endif // _CPP_CLI_UTILITIES_HPP_