This file is indexed.

/usr/include/SurgSim/Framework/Accessible.h is in libopensurgsim-dev 0.7.0-6ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
// This file is a part of the OpenSurgSim project.
// Copyright 2013-2015, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SURGSIM_FRAMEWORK_ACCESSIBLE_H
#define SURGSIM_FRAMEWORK_ACCESSIBLE_H

#include <boost/any.hpp>
#include <boost/preprocessor.hpp>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <yaml-cpp/yaml.h>

#include "SurgSim/Math/Matrix.h"

namespace SurgSim
{
namespace Framework
{

/// Mixin class for enabling a property system on OSS classes, the instance still needs to initialize properties in
/// the constructor by using either addSetter, addGetter, addAccessors or the macro for each member variable
/// that should be made accessible.
class Accessible
{
public:

	/// Default Constructor
	Accessible();

	/// Destructor
	~Accessible();

	typedef std::function<boost::any(void)> GetterType;
	typedef std::function<void (boost::any)> SetterType;

	typedef std::function<YAML::Node(void)> EncoderType;
	typedef std::function<void(const YAML::Node*)> DecoderType;

	/// Retrieves the value with the name by executing the getter if it is found and tries to convert
	/// it to the given type.
	/// \throws SurgSim::Framework::AssertionFailure If the conversion fails or the property cannot be found.
	/// \tparam T The requested type for the property.
	/// \param	name	The name of the property.
	/// \return	The value of the property if the getter was found
	template <class T>
	T getValue(const std::string& name) const;

	/// Retrieves the value with the name by executing the getter if it is found.
	/// \throws SurgSim::Framework::AssertionFailure if the property cannot be found
	/// \param	name	The name of the property.
	/// \return	The value of the property if the getter was found
	boost::any getValue(const std::string& name) const;

	/// Retrieves the value with the name by executing the getter if it is found, and converts it to
	/// the type of the output parameter. This does not throw.
	/// \tparam T	the type of the property, usually can be deduced automatically
	/// \param	name	The name of the property.
	/// \param [out]	value	If non-null, will receive the value of the given property.
	/// \return	true if value != nullptr and the getter can be found.
	template <class T>
	bool getValue(const std::string& name, T* value) const;

	/// Sets a value of a property that has setter.
	/// \throws SurgSim::Framework::AssertionFailure If the property cannot be found.
	/// \param	name 	The name of the property.
	/// \param	value	The value that it should be set to.
	void setValue(const std::string& name, const boost::any& value);

	/// Check whether a property is readable
	/// \param name Name of the property to be checked.
	/// \return true if the property exists and has a getter
	bool isReadable(const std::string& name) const;

	/// Check whether a property is writable
	/// \param name Name of the property to be checked.
	/// \return true if the property exists and has a setter
	bool isWriteable(const std::string& name) const;

	/// Sets a getter for a given property.
	/// \throws SurgSim::Framework::AssertionFailure if func is a nullptr.
	/// \param	name	The name of the property.
	/// \param	func	The getter function.
	void setGetter(const std::string& name, GetterType func);

	/// Sets a setter for a given property.
	/// \throws SurgSim::Framework::AssertionFailure if func is a nullptr.
	/// \param	name	The name of the property.
	/// \param	func	The setter function.
	void setSetter(const std::string& name, SetterType func);

	/// Sets the accessors getter and setter in one function.
	/// \throws SurgSim::Framework::AssertionFailure if either getter or setter is a nullptr.
	/// \param	name  	The name of the property.
	/// \param	getter	The getter.
	/// \param	setter	The setter.
	void setAccessors(const std::string& name, GetterType getter, SetterType setter);

	/// Removes all the accessors (getter and setter) for a given property
	/// \param name The name of the property
	void removeAccessors(const std::string& name);

	/// Adds a property with the given name that uses the targets accessors, in effect forwarding the value
	/// to the target
	/// \note This will copy the appropriate calls into the local function table of this accessible, in effect
	///       exposing a pointer to the target, if the target goes out of scope, the behavior is undefined
	/// \throws SurgSim::Framework::AssertionFailure if the target does not contain the property named in this call.
	/// \param name The name of the new property
	/// \param target The instance that provides the actual property
	/// \param targetProperty The name of the property that should be used.
	void forwardProperty(const std::string& name, const Accessible& target, const std::string& targetProperty);

	/// Sets the functions used to convert data from and to a YAML::Node. Will throw an exception
	/// if the data type that is passed to YAML cannot be converted into a YAML::Node
	/// \param name The name of the property.
	/// \param encoder The function to be used to put the property into the node.
	/// \param decoder The function to be used to read the property from the node and set it
	///                in the instance.
	void setSerializable(const std::string& name, EncoderType encoder, DecoderType decoder);

	/// Sets the functions used to convert data from a YAML::Node.
	/// This leaves the encoder (class -> YAML) conversion empty, this can be used to let the user decide how to
	/// model the data in the data file, inside the class this should all result in one member to be created/changed.
	/// \param name The name of the property.
	/// \param decoder The function to be used to read the property from the node and set it
	///                in the instance.
	void setDecoder(const std::string& name, DecoderType decoder);


	/// Encode this Accessible to a YAML::Node
	/// \return The encoded version of this instance.
	YAML::Node encode() const;

	/// Decode this Accessible from a YAML::Node, will throw an exception if the data type cannot
	/// be converted.
	/// \throws SurgSim::Framework::AssertionFailure if node is not of YAML::NodeType::Map.
	/// \param node The node that carries the data to be decoded, properties with names that don't
	///             match up with properties in the Accessible will be reported.
	/// \param ignoredProperties Properties that will be ignored.
	void decode(const YAML::Node& node, const std::vector<std::string>& ignoredProperties = std::vector<std::string>());

private:

	/// @{
	/// Prevent default copy construction and default assignment
	Accessible(const Accessible& other) /*= delete*/;
	Accessible& operator=(const Accessible& other) /*= delete*/;
	/// @}

	/// Private struct to keep the map under control
	struct Functors
	{
		Functors() : getter(nullptr), setter(nullptr), encoder(nullptr), decoder(nullptr) {}
		GetterType getter;
		SetterType setter;
		EncoderType encoder;
		DecoderType decoder;
	};

	std::unordered_map<std::string, Functors> m_functors;

};

/// Public struct to pair an accessible with its appropriate property
struct Property
{
	std::weak_ptr<Accessible> accessible;
	std::string name;
};

template <>
boost::any Accessible::getValue(const std::string& name) const;


/// Wrap boost::any_cast to use in std::bind, for some reason it does not work by itself. This function will
/// throw an exception if the cast does not work, this usually means that the types do not match up at all.
/// \tparam T target type for conversion.
/// \param val The value to be converted.
/// \return An object converted from boost::any to T, will throw an exception if the conversion fails
template <class T>
T convert(boost::any val);

/// Specialization for convert<T>() to correctly cast Matrix44d to Matrix44f, will throw if the val is not casteable to
/// Matrix44[fd]. This is necessary as we need Matrix44f as outputs in some cases but all our Matrices are Matrix44d.
/// This lets the user define a property that does a type conversion, without having to implement an accessor.
/// \param val The value to be converted, should be a Matrix44[df].
/// \return A matrix val converted to Matrix44f.
template <>
SurgSim::Math::Matrix44f convert(boost::any val);

/// Specialization for convert<T>() to correctly cast const char* to std::string
/// \param val The value to be converted, should be a const char*
/// \return A std::string
template <>
std::string convert(boost::any val);

/// A macro to register getter and setter for a property that is readable and writeable,
/// order of getter and setter agrees with 'RW'. Note that the property should not be quoted in the original
/// macro call.
#define SURGSIM_ADD_RW_PROPERTY(class, type, property, getter, setter) \
	setAccessors(#property, \
				std::bind(&class::getter, this),\
				std::bind(&class::setter, this, std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)))

/// A macro to register a getter for a property that is read only
#define SURGSIM_ADD_RO_PROPERTY(class, type, property, getter) \
	setGetter(#property, \
	std::bind(&class::getter, this))

/// A macro to register a serializable property, this needs to support reading, writing and all the
/// conversions to and from YAML::Node
#define SURGSIM_ADD_SERIALIZABLE_PROPERTY(class, type, property, getter, setter) \
	setAccessors(#property, \
				std::bind(&class::getter, this),\
				std::bind(&class::setter, this, std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)));\
	setSerializable(#property,\
				std::bind(&YAML::convert<type>::encode, std::bind(&class::getter, this)),\
				std::bind(&class::setter, this, std::bind(&YAML::Node::as<type>,std::placeholders::_1)))

/// A macro to register a setter that can be used from YAML, and as a writeable property
/// use this to provide alternatives to more complicated values, e.g. setModelFilename() vs generate and set Model
/// Enables the alternative use of the model file instead of the actual mesh object
#define SURGSIM_ADD_SETTER(class, type, property, setter) \
	{\
		setDecoder(#property, std::bind((void(class::*)(const type&))&class::setter, this,\
					std::bind(&YAML::Node::as<type>,std::placeholders::_1))); \
		setSetter(#property, std::bind((void(class::*)(const type&))&class::setter, this,\
					std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)));\
	}


}; // Framework
}; // SurgSim

#define SURGSIM_ENUM_TOSTRING(r, data, elem)    \
	case data::elem: \
		result = BOOST_PP_STRINGIZE(elem); \
		break;

#define SURGSIM_ENUM_FROMSTRING(r, data, elem)    \
	if (value == BOOST_PP_STRINGIZE(elem)) \
	{ \
		rhs = data::elem; \
		return true; \
	}

/// Required type of enums used by SURGSIM_SERIALIZABLE_ENUM
#define SURGSIM_ENUM_TYPE int8_t

/// A macro to create an enum that can be easily serialized
/// During serialization, the enum will be converted to its string based named,
/// back to an enum during deserialization. The enum must already be forward
/// declared in its namespace before calling this macro in the global namespace.
#define SURGSIM_SERIALIZABLE_ENUM(name, enumerators) \
	enum name : SURGSIM_ENUM_TYPE\
	{ \
		BOOST_PP_SEQ_ENUM(enumerators) \
	}; \
	namespace YAML \
	{ \
	template <> \
	struct convert<name> \
	{ \
		static Node encode(const name& rhs) \
		{ \
			Node result; \
			switch (rhs) \
			{ \
				BOOST_PP_SEQ_FOR_EACH(SURGSIM_ENUM_TOSTRING, name, enumerators) \
				default: \
					SURGSIM_FAILURE() << "Can not find enum value in " << #name  << ": " << rhs; \
			} \
			return result; \
		} \
		static bool decode(const Node& node, name& rhs) \
		{ \
			std::string value = node.as<std::string>(); \
			std::transform(value.begin(), value.end(), value.begin(), ::toupper); \
			BOOST_PP_SEQ_FOR_EACH(SURGSIM_ENUM_FROMSTRING, name, enumerators) \
			SURGSIM_FAILURE() << "Unknown " <<  #name << ": " << value; \
			return false; \
		} \
	}; \
	}

#include "SurgSim/Framework/Accessible-inl.h"

#endif