]>
Commit | Line | Data |
---|---|---|
43d1bbe4 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
43d1bbe4 | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
43d1bbe4 FC |
7 | */ |
8 | ||
9 | #ifndef SQUID_MEMBLOB_H_ | |
10 | #define SQUID_MEMBLOB_H_ | |
11 | ||
12 | #define MEMBLOB_DEBUGSECTION 24 | |
13 | ||
14 | #include "base/InstanceId.h" | |
8bf217bd | 15 | #include "base/RefCount.h" |
ed6e9fb9 | 16 | #include "mem/forward.h" |
43d1bbe4 FC |
17 | |
18 | /// Various MemBlob class-wide statistics. | |
19 | class MemBlobStats | |
20 | { | |
21 | public: | |
22 | MemBlobStats(); | |
23 | ||
24 | /// dumps class-wide statistics | |
25 | std::ostream& dump(std::ostream& os) const; | |
26 | ||
412da427 FC |
27 | MemBlobStats& operator += (const MemBlobStats&); |
28 | ||
43d1bbe4 | 29 | public: |
b6aa37ec FC |
30 | uint64_t alloc; ///< number of MemBlob instances created so far |
31 | uint64_t live; ///< number of MemBlob instances currently alive | |
32 | uint64_t append; ///< number of MemBlob::append() calls | |
33 | uint64_t liveBytes; ///< the total size of currently allocated storage | |
43d1bbe4 FC |
34 | }; |
35 | ||
43d1bbe4 FC |
36 | /** Refcountable, fixed-size, content-agnostic memory buffer. |
37 | * | |
b59e6847 | 38 | * Allocated memory block is divided into two sequential areas: |
43d1bbe4 FC |
39 | * "used memory" and "available space". The used area can be filled during |
40 | * construction, grows via the append() call, and can be clear()ed. | |
41 | * | |
42 | * MemBlob users can cooperate to safely share the used area. However, MemBlob | |
43 | * provides weak use accounting and no sharing protections besides refcounting. | |
44 | */ | |
45 | class MemBlob: public RefCountable | |
46 | { | |
741c2986 AJ |
47 | MEMPROXY_CLASS(MemBlob); |
48 | ||
43d1bbe4 FC |
49 | public: |
50 | typedef RefCount<MemBlob> Pointer; | |
50827187 | 51 | typedef uint32_t size_type; |
43d1bbe4 | 52 | |
43d1bbe4 FC |
53 | /// obtain a const view of class-wide statistics |
54 | static const MemBlobStats& GetStats(); | |
55 | ||
56 | /// create a new MemBlob with at least reserveSize capacity | |
57 | explicit MemBlob(const size_type reserveSize); | |
58 | ||
59 | /// create a MemBlob containing a copy of the buffer of a given size | |
60 | MemBlob(const char *buffer, const size_type bufferSize); | |
61 | ||
337b9aa4 | 62 | ~MemBlob() override; |
43d1bbe4 FC |
63 | |
64 | /// the number unused bytes at the end of the allocated blob | |
65 | size_type spaceSize() const { return capacity - size; } | |
66 | ||
67 | /** check whether the caller can successfully append() n bytes | |
68 | * | |
69 | * \return true the caller may append() n bytes to this blob now | |
70 | * \param off the end of the blob area currently used by the caller | |
71 | * \param n the total number of bytes the caller wants to append | |
72 | */ | |
b59e6847 | 73 | bool canAppend(const size_type off, const size_type n) const { |
43d1bbe4 | 74 | // TODO: ignore offset (and adjust size) when the blob is not shared? |
1bd99854 | 75 | return (isAppendOffset(off) && willFit(n)) || !n; |
43d1bbe4 FC |
76 | } |
77 | ||
6bba9bf1 AR |
78 | /** adjusts internal object state as if exactly n bytes were append()ed |
79 | * | |
80 | * \throw TextException if there was not enough space in the blob | |
81 | * \param n the number of bytes that were appended | |
82 | */ | |
83 | void appended(const size_type n); | |
84 | ||
43d1bbe4 FC |
85 | /** copies exactly n bytes from the source to the available space area, |
86 | * enlarging the used area by n bytes | |
87 | * | |
88 | * \throw TextException if there is not enough space in the blob | |
89 | * \param source raw buffer to be copied | |
90 | * \param n the number of bytes to copy from the source buffer | |
91 | */ | |
92 | void append(const char *source, const size_type n); | |
93 | ||
963caaa7 AR |
94 | /* non-const methods below require exclusive object ownership */ |
95 | ||
43d1bbe4 FC |
96 | /// extends the available space to the entire allocated blob |
97 | void clear() { size = 0; } | |
98 | ||
963caaa7 AR |
99 | /// keep the first n bytes and forget the rest of data |
100 | /// cannot be used to increase our size; use append*() methods for that | |
101 | void syncSize(const size_type n); | |
102 | ||
103 | /// forget the first n bytes, moving the rest of data (if any) to the start | |
104 | /// forgets all data (i.e. empties the buffer) if n exceeds size | |
105 | void consume(const size_type n); | |
106 | ||
43d1bbe4 FC |
107 | /// dump debugging information |
108 | std::ostream & dump(std::ostream &os) const; | |
109 | ||
110 | public: | |
111 | /* MemBlob users should avoid these and must treat them as read-only */ | |
112 | char *mem; ///< raw allocated memory block | |
113 | size_type capacity; ///< size of the raw allocated memory block | |
114 | size_type size; ///< maximum allocated memory in use by callers | |
115 | const InstanceId<MemBlob> id; ///< blob identifier | |
116 | ||
117 | private: | |
118 | static MemBlobStats Stats; ///< class-wide statistics | |
119 | ||
120 | void memAlloc(const size_type memSize); | |
43d1bbe4 FC |
121 | |
122 | /// whether the offset points to the end of the used area | |
123 | bool isAppendOffset(const size_type off) const { return off == size; } | |
124 | ||
125 | /// whether n more bytes can be appended | |
126 | bool willFit(const size_type n) const { return n <= spaceSize(); } | |
127 | ||
128 | /* copying is not implemented */ | |
129 | MemBlob(const MemBlob &); | |
130 | MemBlob& operator =(const MemBlob &); | |
131 | }; | |
132 | ||
43d1bbe4 | 133 | #endif /* SQUID_MEMBLOB_H_ */ |
f53969cc | 134 |