1818 */
1919
2020/* *
21- * @file AampGrowableBuffer.h
22- * @brief Header file of helper functions for Growable Buffer class
21+ * @file AampGrowableBuffer.cpp
22+ * @brief Implementation file of helper functions for Growable Buffer class
2323 */
2424
2525#include " AampGrowableBuffer.h"
2626#include " AampConfig.h"
27+ #include " AampLogManager.h"
2728#include < assert.h>
28- #include < glib.h>
2929
3030bool AampGrowableBuffer::gbEnableLogging = false ;
3131int AampGrowableBuffer::gNetMemoryCount = 0 ;
3232int AampGrowableBuffer::gNetMemoryHighWatermark = 0 ;
3333
34-
35- void AampGrowableBuffer::EnableLogging ( bool enable )
34+ void AampGrowableBuffer::EnableLogging (bool enable)
3635{
37- gbEnableLogging = enable;
36+ gbEnableLogging = enable;
3837}
3938
4039AampGrowableBuffer::~AampGrowableBuffer ( void )
@@ -47,89 +46,87 @@ AampGrowableBuffer::~AampGrowableBuffer( void )
4746 */
4847void AampGrowableBuffer::Free ( void )
4948{
50- if ( ptr )
49+ if ( buffer. capacity () > 0 )
5150 {
5251 NETMEMORY_MINUS ();
53- if ( gbEnableLogging )
54- {
55- printf (" AampGrowableBuffer::%s(%s:%d)\n " , " Free" ,name,gNetMemoryCount );
56- }
57- g_free (ptr);
58- ptr = NULL ;
52+ if ( gbEnableLogging )
53+ {
54+ printf (" AampGrowableBuffer::%s(%s:%d)\n " , " Free" ,name,gNetMemoryCount );
55+ }
56+ buffer.clear ();
5957 }
60- len = 0 ;
61- avail = 0 ;
58+ buffer.shrink_to_fit (); // Release the allocated memory
6259}
6360
6461void AampGrowableBuffer::ReserveBytes ( size_t numBytes )
6562{
66- assert ( ptr==NULL && avail == 0 );
67- ptr = (char *)g_malloc ( numBytes );
68- if ( ptr )
63+ assert ( buffer.empty () && buffer.capacity () == 0 );
64+ if ( numBytes > 0 )
6965 {
70- NETMEMORY_PLUS ();
71- if ( gbEnableLogging )
66+ try {
67+ buffer.reserve (numBytes);
68+ NETMEMORY_PLUS ();
69+ if ( gbEnableLogging )
70+ {
71+ printf (" AampGrowableBuffer::%s(%s:%d)\n " , " ReserveBytes" ,name,gNetMemoryCount );
72+ }
73+ }
74+ catch (const std::bad_alloc&)
7275 {
73- printf ( " AampGrowableBuffer::%s(%s:%d) \n " , " ReserveBytes " ,name, gNetMemoryCount );
76+ AAMPLOG_ERR ( " Memory allocation failed!! Requested capacity: %zu " , numBytes );
7477 }
75- avail = numBytes;
7678 }
7779}
7880
7981void AampGrowableBuffer::AppendBytes ( const void *srcPtr, size_t srcLen )
8082{
81- size_t required = len + srcLen;
82- if ( avail < required )
83- { // more memory needed - grow
84- size_t numBytes = avail*2 ; // first try doubling size of existing reserved memory
85- if ( numBytes < required )
86- { // if still not enough, reallocate based on required
87- numBytes = required*2 ;
83+ if ( srcLen == 0 )
84+ {
85+ return ;
86+ }
87+
88+ bool isFirstAllocation = buffer.empty () && (buffer.capacity () == 0 );
89+ size_t required = buffer.size () + srcLen;
90+
91+ if ( buffer.capacity () < required )
92+ { // more memory needed - grow with same strategy as original implementation
93+ size_t newCapacity = buffer.capacity () * 2 ; // first try doubling
94+ if ( newCapacity < required )
95+ { // if still not enough, allocate double what's required
96+ newCapacity = required * 2 ;
8897 }
89- gpointer mem = g_realloc (ptr, numBytes );
90- if ( mem )
98+
99+ try
91100 {
92- if ( !ptr )
93- { // first allocation
101+ buffer.reserve (newCapacity);
102+
103+ if ( isFirstAllocation )
104+ {
94105 NETMEMORY_PLUS ();
95106 if ( gbEnableLogging )
96107 {
97108 printf (" AampGrowableBuffer::%s(%s:%d)\n " , " AppendBytes" ,name,gNetMemoryCount );
98109 }
99110 }
100- ptr = mem;
101- avail = numBytes;
102111 }
103- else if (numBytes != 0 )
112+ catch ( const std::bad_alloc& )
104113 {
105- AAMPLOG_ERR (" Memory re-allocation failed!! Requested numBytes: %zu" , numBytes);
114+ AAMPLOG_ERR (" Memory re-allocation failed!! Requested capacity: %zu" , newCapacity);
115+ return ;
106116 }
107117 }
108- if ( ptr )
109- {
110- memcpy ( len + (char *)ptr, srcPtr, srcLen);
111- len = required;
112- }
113- }
114118
115- /* *
116- * @brief replace contents of AampGrowableBuffer
117- * @param srcPtr pointer to memory (may be subset of existing AampGrowableBuffer)
118- * @param srcLen new logical size for AampGrowableBuffer reflecting memory being copied/moved
119- */
120- void AampGrowableBuffer::MoveBytes ( const void *srcPtr, size_t srcLen )
121- { // this API assumes AampGrowableBuffer is already big enough to fit
122- assert ( ptr && srcPtr && avail >= srcLen );
123- memmove ( ptr, srcPtr, srcLen );
124- len = srcLen;
119+ // Append the data (reserve guarantees this won't throw or reallocate)
120+ const uint8_t * bytes = static_cast <const uint8_t *>(srcPtr);
121+ buffer.insert (buffer.end (), bytes, bytes + srcLen);
125122}
126123
127124/* *
128125 * @brief reset AampGrowableBuffer logical length without releasing reserved memory
129126 */
130127void AampGrowableBuffer::Clear ( void )
131128{
132- len = 0 ;
129+ buffer. clear () ;
133130}
134131
135132/* *
@@ -138,31 +135,35 @@ void AampGrowableBuffer::Clear( void )
138135 */
139136void AampGrowableBuffer::Replace ( AampGrowableBuffer *src )
140137{
141- assert ( ptr == NULL ); // only replace if empty!
142- ptr = src->GetPtr ();
143- len = src->GetLen ();
144- avail = src->GetAvail ();
145-
146- src->ptr = NULL ;
147- src->len = 0 ;
148- src->avail = 0 ;
138+ buffer = std::move (src->buffer );
139+ src->buffer .clear ();
140+ src->buffer .shrink_to_fit ();
149141}
150142
151143/* *
152- * @brief called when internal memory is transferred (i.e. as part of GStreamer injection)
144+ * @brief Extract the internal vector for ownership transfer to external code (e.g., GStreamer)
145+ * @return vector object (moved) containing the buffer data
146+ * @note The internal buffer is moved out and the AampGrowableBuffer is reset to known empty state
153147 */
154- void AampGrowableBuffer::Transfer ( void )
148+ std::vector< uint8_t > AampGrowableBuffer::ExtractVector ( void )
155149{
156- assert ( ptr );
157- if ( ptr )
150+ assert ( !buffer.empty () );
151+
152+ if ( buffer.capacity () > 0 )
158153 {
159154 NETMEMORY_MINUS ();
160155 if ( gbEnableLogging )
161156 {
162- printf (" AampGrowableBuffer::%s(%s:%d)\n " , " Transfer " ,name,gNetMemoryCount );
157+ printf (" AampGrowableBuffer::%s(%s:%d)\n " , " ExtractVector " ,name,gNetMemoryCount );
163158 }
164159 }
165- ptr = NULL ;
166- len = 0 ;
167- avail = 0 ;
160+
161+ // Move our data into a temporary vector for return
162+ std::vector<uint8_t > extracted (std::move (buffer));
163+
164+ // Explicitly clear to ensure known empty state (not just moved-from state)
165+ buffer.clear ();
166+ buffer.shrink_to_fit ();
167+
168+ return extracted; // Move constructor will be used for efficient return
168169}
0 commit comments