This file is indexed.

/usr/include/zmqpp/message.hpp is in libzmqpp-dev 4.1.2-0ubuntu2.

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
302
303
304
305
306
307
308
309
310
311
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file is part of zmqpp.
 * Copyright (c) 2011-2015 Contributors as noted in the AUTHORS file.
 */

/**
 * \file
 *
 * \date   9 Aug 2011
 * \author Ben Gray (\@benjamg)
 */

#ifndef ZMQPP_MESSAGE_HPP_
#define ZMQPP_MESSAGE_HPP_

#include <cassert>
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
#include <utility>

#include <zmq.h>

#include "compatibility.hpp"
#include "frame.hpp"
#include "signal.hpp"

namespace zmqpp
{

/**
 * \brief a zmq message with optional multipart support
 *
 * A zmq message is made up of one or more parts which are sent together to
 * the target endpoints. zmq guarantees either the whole message or none
 * of the message will be delivered.
 */
class message
{
public:
	/**
	 * \brief callback to release user allocated data.
	 *
	 * The release function will be called on any void* moved part.
	 * It must be thread safe to the extent that the callback may occur on
	 * one of the context threads.
	 *
	 * The function called will be passed a single variable which is the
	 * pointer to the memory allocated.
	 */
	typedef std::function<void (void*)> release_function;

	message();
	~message();

    template <typename T, typename ...Args>
    message(T const &part, Args &&...args)
        : message()
    {
        add(part, std::forward<Args>(args)...);
    }

	size_t parts() const;
	size_t size(size_t const part) const;
	std::string get(size_t const part) const;

	void get(int8_t& integer, size_t const part) const;
	void get(int16_t& integer, size_t const part) const;
	void get(int32_t& integer, size_t const part) const;
	void get(int64_t& integer, size_t const part) const;	
	void get(signal& sig, size_t const part) const;

	void get(uint8_t& unsigned_integer, size_t const part) const;
	void get(uint16_t& unsigned_integer, size_t const part) const;
	void get(uint32_t& unsigned_integer, size_t const part) const;
	void get(uint64_t& unsigned_integer, size_t const part) const;

	void get(float& floating_point, size_t const part) const;
	void get(double& double_precision, size_t const part) const;
	void get(bool& boolean, size_t const part) const;

	void get(std::string& string, size_t const part) const;

	// Warn: If a pointer type is requested the message (well zmq) still 'owns'
	// the data and will release it when the message object is freed.
	template<typename Type>
	Type get(size_t const part)
	{
		Type value;
		get(value, part);
		return value;
	}

    template<int part=0, typename T, typename ...Args>
    void extract(T &nextpart, Args &...args)
    {
        assert(part < parts());
        get(nextpart,part);
        extract<part+1>(args...);
    }

    template<int part=0, typename T>
    void extract(T &nextpart)
    {
        assert(part < parts());
        get(nextpart,part);
    }

	// Raw get data operations, useful with data structures more than anything else
	// Warn: The message (well zmq) still 'owns' the data and will release it
	// when the message object is freed.
	template<typename Type>
	void get(Type*& value, size_t const part) const
	{
		value = static_cast<Type*>(raw_data(part));
	}

	// Warn: The message (well zmq) still 'owns' the data and will release it
	// when the message object is freed.
	template<typename Type>
	void get(Type** value, size_t const part) const
	{
		*value = static_cast<Type*>(raw_data(part));
	}

	// Move operators will take ownership of message parts without copying
	void move(void* part, size_t const size, release_function const& release);

	// Raw move data operation, useful with data structures more than anything else
	template<typename Object>
	void move(Object *part)
	{
		move(part, sizeof(Object), &deleter_callback<Object>);
	}

	// Copy operators will take copies of any data
	template<typename Type, typename ...Args>
	void add(Type const& part, Args &&...args)
	{
		*this << part;
		add(std::forward<Args>(args)...);
	}

	template<typename Type>
	void add(Type const part)
	{
		*this << part;
	}

	// Copy operators will take copies of any data with a given size
	template<typename Type>
	void add_raw(Type *part, size_t const data_size)
	{
		_parts.push_back( frame( part, data_size ) );
	}

	// Use exact data past, neither zmqpp nor 0mq will copy, alter or delete
	// this data. It must remain as valid for at least the lifetime of the
	// 0mq message, recommended only with const data.
	template<typename Type>
	void add_const(Type *part, size_t const data_size)
	{
		_parts.push_back( frame( part, data_size, nullptr, nullptr ) );
	}

	// Stream reader style
	void reset_read_cursor();

	template<typename Type>
	message& operator>>(Type& value)
	{
		get(value, _read_cursor++);
		return *this;
	}

	// Stream writer style - these all use copy styles
	message& operator<<(int8_t const integer);
	message& operator<<(int16_t const integer);
	message& operator<<(int32_t const integer);
	message& operator<<(int64_t const integer);
	message& operator<<(signal const sig);

	message& operator<<(uint8_t const unsigned_integer);
	message& operator<<(uint16_t const unsigned_integer);
	message& operator<<(uint32_t const unsigned_integer);
	message& operator<<(uint64_t const unsigned_integer);

	message& operator<<(float const floating_point);
	message& operator<<(double const double_precision);
	message& operator<<(bool const boolean);

	message& operator<<(char const* c_string);
	message& operator<<(std::string const& string);

	// Queue manipulation
	void push_front(void const* part, size_t const size);

	// TODO: unify conversion of types with the stream operators
	void push_front(int8_t const integer);
	void push_front(int16_t const integer);
	void push_front(int32_t const integer);
	void push_front(int64_t const integer);
	void push_front(signal const sig);

	void push_front(uint8_t const unsigned_integer);
	void push_front(uint16_t const unsigned_integer);
	void push_front(uint32_t const unsigned_integer);
	void push_front(uint64_t const unsigned_integer);

	void push_front(float const floating_point);
	void push_front(double const double_precision);
	void push_front(bool const boolean);

	void push_front(char const* c_string);
	void push_front(std::string const& string);

	void pop_front();

	void push_back(void const* part, size_t const data_size)
	{
		add_raw( part, data_size );
	}

	template<typename Type>
	void push_back(Type const part)
	{
		*this << part;
	}

	void pop_back();

	void remove(size_t const part);

	// Move supporting
	message(message&& source) NOEXCEPT;
	message& operator=(message&& source) NOEXCEPT;

	// Copy support
	message copy() const;
	void copy(message const& source);

	// Used for internal tracking
	void sent(size_t const part);

	// Access to raw zmq details
	void const* raw_data(size_t const part = 0) const;
	zmq_msg_t& raw_msg(size_t const part = 0);
	zmq_msg_t& raw_new_msg();
	zmq_msg_t& raw_new_msg(size_t const reserve_data_size);
	
	/**
	 * Check if the message is a signal.
	 * If the message has 1 part, has the correct size and if the 7 first bytes match
	 * the signal header we consider the message a signal.
	 * @return true if the message is a signal, false otherwise
	 */
	bool is_signal() const;

	/**
	 * Gets the read cursor. For using get_raw() with stream-style reading.
	 */
	size_t read_cursor() const NOEXCEPT { return _read_cursor; }

	/**
	 * Gets the remaining number of parts in the message.
	 */
	size_t remaining() const NOEXCEPT { return  _parts.size() - _read_cursor; }

	/**
	 * Moves the read cursor to the next element.
	 * @return the new read_cursor
	 */
	size_t next() NOEXCEPT { return ++_read_cursor; }


#if (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR >= 1)
	/**
	* Attemps to retrieve a metadata property from a message.
	* The underlying call is `zmq_msg_gets()`.
	*
	* @note The message MUST have at least one frame, otherwise this wont work.
	*/
	bool get_property(const std::string &property, std::string &out);
#endif

private:
	typedef std::vector<frame> parts_type;
	parts_type _parts;
	size_t _read_cursor;

	// Disable implicit copy support, code must request a copy to clone
	message(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
	message& operator=(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;

	static void release_callback(void* data, void* hint);

	template<typename Object>
	static void deleter_callback(void* data)
	{
		delete static_cast<Object*>(data);
	}
};

}

#endif /* ZMQPP_MESSAGE_HPP_ */