blob: bf60026fd8239e70cab67c56c06f8e1b1af0153f (
plain)
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
|
// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
#ifndef INCLUDED_GRAS_SBUFFER_HPP
#define INCLUDED_GRAS_SBUFFER_HPP
#include <gras/gras.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/function.hpp>
namespace gras
{
struct SBufferImpl;
struct SBuffer;
//! The callback function type when buffers dereference
typedef boost::function<void(SBuffer &)> SBufferDeleter;
//! The token type held by the caller
typedef boost::shared_ptr<SBufferDeleter> SBufferToken;
//! The token type weak ptr help by buffer
typedef boost::weak_ptr<SBufferDeleter> SBufferTokenWeak;
struct GRAS_API SBufferConfig
{
//! Default constructor zeros out buffer config
SBufferConfig(void);
//! pointer to the memory start
void *memory;
//! length of the memory in bytes
size_t length;
//! memory affinity - meta information
long affinity;
//! index number for custom allocation purposes
size_t user_index;
//! deleter callback, may be used to free
SBufferDeleter deleter;
//! token object, called if set under deref condition
SBufferTokenWeak token;
};
/*!
* SBuffer is a smart/shared reference counted handler of memory.
* Thank you boost smart/shared pointers for the disambiguation!
*
* Default allocator:
* To use the default system allocator, set the memory to NULL,
* and set length and affinity to the desired values.
* The deleter will be automaically configured by the allocator.
*
* Custom allocator:
* Set all config struct members. Its all you!
*
* Token usage:
* When a token is set, the buffer will not cleanup and call the deleter.
* Rather, the bound function in the token will be called with the buffer.
* A parent object should hold the shared pointer to the token.
* When the parent object deconstructs, the weak pointer will die,
* and the normal buffer cleanup/freeing/deconstruction will happen.
*
* Length and offset usage:
* Length and offset are intentionally object members
* and not part of the ref-counted intrusive_ptr guts.
* These members should be modified carefully
* to pass a subset of the memory downstream.
*
* Length and offset recommendation:
* These values should probably be reset by the
* bound token or when a fresh buffer is popped.
*/
struct GRAS_API SBuffer : boost::intrusive_ptr<SBufferImpl>
{
//! Default constructor, zeros things
SBuffer(void);
/*!
* Create a new buffer.
* The config object represents a chunk of memory,
* or instructions for the default allocator.
*/
SBuffer(const SBufferConfig &config);
/*!
* Get a pointer to the start of the underlying memory
*/
void *get_actual_memory(void) const;
/*!
* Get the length of the underlying memory in bytes
*/
size_t get_actual_length(void) const;
//! Get a pointer into valid memory
void *get(const ptrdiff_t delta_bytes = 0) const;
//! The offset into valid memory in bytes
size_t offset;
//! The number of valid bytes past offset
size_t length;
//! Get the affinity of the memory
long get_affinity(void) const;
//! Get the user index number
size_t get_user_index(void) const;
//! Unique if caller holds the only reference count
bool unique(void) const;
//! Get the number of reference holders
size_t use_count(void) const;
};
} //namespace gras
#include <gras/sbuffer.ipp>
#endif /*INCLUDED_GRAS_SBUFFER_HPP*/
|