3 Copyright (C) 2005 and later, Cockos Incorporated
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
25 This file provides a simple class for a FIFO queue of bytes. It uses a simple buffer,
26 so should not generally be used for large quantities of data (it can advance the queue
27 pointer, but Compact() needs to be called regularly to keep memory usage down, and when
28 it is called, there's a memcpy() penalty for the remaining data. oh well, is what it is).
30 You may also wish to look at fastqueue.h or circbuf.h if these limitations aren't acceptable.
43 WDL_Queue(int hbgran
=4096) : m_hb(hbgran
), m_pos(0) { }
46 template <class T
> void* AddT(T
* buf
)
48 return Add(buf
, sizeof(T
));
51 void *Add(const void *buf
, int len
)
53 int olen
=m_hb
.GetSize();
54 if (m_pos
>= olen
) m_pos
=olen
=0; // if queue is empty then autoreset it
56 char *newbuf
=(char *)m_hb
.ResizeOK(olen
+len
,false);
60 if (buf
) memcpy(newbuf
,buf
,len
);
65 template <class T
> T
* GetT(T
* val
=0)
67 T
* p
= (T
*) Get(sizeof(T
));
68 if (val
&& p
) *val
= *p
;
81 if (m_pos
>= 0 && m_pos
< m_hb
.GetSize()) return (char *)m_hb
.Get()+m_pos
;
93 return m_hb
.GetSize()-m_pos
;
95 int Available() const { return GetSize(); }
100 m_hb
.Resize(0,false);
103 void Advance(int bytecnt
)
107 else if (m_pos
> m_hb
.GetSize()) m_pos
=m_hb
.GetSize();
110 void Compact(bool allocdown
=false, bool force
=false)
112 int olen
=m_hb
.GetSize();
113 if (m_pos
> (force
? 0 : olen
/2))
118 char *a
=(char*)m_hb
.Get();
119 memmove(a
,a
+m_pos
,olen
);
125 m_hb
.Resize(olen
,allocdown
);
130 void SetGranul(int granul
) { m_hb
.SetGranul(granul
); }
132 void Prealloc(int sz
) { m_hb
.Prealloc(sz
); }
136 // endian-management stuff
138 static void WDL_Queue__bswap_buffer(void *buf
, int len
) // poorly named! only bswaps on BE, deprecated, use wdl_memcpy_le()
140 wdl_memcpy_le(buf
,buf
,1,len
);
143 // older API of static functions (that ended up warning a bit anyway)
144 #define WDL_Queue__AddToLE(q, v) (q)->AddToLE(v)
145 #define WDL_Queue__AddDataToLE(q,d,ds,us) (q)->AddDataToLE(d,ds,us)
146 #define WDL_Queue__GetTFromLE(q,v) (q)->GetTFromLE(v)
147 #define WDL_Queue__GetDataFromLE(q,ds,us) (q)->GetDataFromLE(ds,us)
149 template<class T
> void AddToLE(T
*val
)
151 void *w
= Add(NULL
, sizeof(T
));
152 if (WDL_NORMALLY(w
!= NULL
) && val
!= NULL
)
153 wdl_memcpy_le(w
, val
, 1, sizeof(T
));
155 void AddDataToLE(const void *data
, int datasize
, int unitsize
)
157 char *w
= (char *)Add(NULL
,datasize
);
158 if (WDL_NOT_NORMALLY(w
== NULL
)) return;
160 if (WDL_NOT_NORMALLY(unitsize
<1)) unitsize
=1;
161 WDL_ASSERT((datasize
% unitsize
) == 0);
162 if (data
) wdl_memcpy_le(w
,data
,datasize
/unitsize
,unitsize
);
166 // NOTE: these thrash the contents of the queue if on BE systems, do not use if you
167 // will rewind etc. better to use Get() and wdl_memcpy_le().
168 template<class T
> T
*GetTFromLE(T
* val
=0)
173 wdl_memcpy_le(p
,p
,1,sizeof(T
));
179 void *GetDataFromLE(int datasize
, int unitsize
)
181 void *data
=Get(datasize
);
182 WDL_ASSERT((datasize
% unitsize
) == 0);
183 if (data
&& WDL_NORMALLY(unitsize
>0)) wdl_memcpy_le(data
,data
,datasize
/unitsize
,unitsize
);
192 int __pad
; // keep 8 byte aligned
195 template <class T
> class WDL_TypedQueue
198 WDL_TypedQueue() : m_hb(4096), m_pos(0) { }
199 ~WDL_TypedQueue() { }
201 T
*Add(const T
*buf
, int len
)
203 int olen
=m_hb
.GetSize();
204 if (m_pos
>= olen
) olen
=m_pos
=0;
205 len
*= (int)sizeof(T
);
207 char *newbuf
=(char*)m_hb
.ResizeOK(olen
+len
,false);
211 if (buf
) memcpy(newbuf
,buf
,len
);
218 if (m_pos
>= 0 && m_pos
< m_hb
.GetSize()) return (T
*)((char *)m_hb
.Get()+m_pos
);
224 return m_pos
< m_hb
.GetSize() ? (m_hb
.GetSize()-m_pos
)/sizeof(T
) : 0;
226 int Available() const { return GetSize(); }
231 m_hb
.Resize(0,false);
234 void Advance(int cnt
)
236 m_pos
+=cnt
*(int)sizeof(T
);
238 else if (m_pos
> m_hb
.GetSize()) m_pos
=m_hb
.GetSize();
241 void Compact(bool allocdown
=false, bool force
=false)
243 int olen
=m_hb
.GetSize();
244 if (m_pos
>= (force
? 0 : olen
/2))
249 char *a
=(char*)m_hb
.Get();
250 memmove(a
,a
+m_pos
,olen
);
256 m_hb
.Resize(olen
,allocdown
);
261 void SetGranul(int granul
) { m_hb
.SetGranul(granul
); }
262 void Prealloc(int sz
) { m_hb
.Prealloc(sz
* sizeof(T
)); }
268 int __pad
; // keep 8 byte aligned