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() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_Queue")), m_pos(0) { }
44 WDL_Queue(int hbgran
) : m_hb(hbgran
WDL_HEAPBUF_TRACEPARM("WDL_Queue")), m_pos(0) { }
47 template <class T
> void* AddT(T
* buf
)
49 return Add(buf
, sizeof(T
));
52 void *Add(const void *buf
, int len
)
54 int olen
=m_hb
.GetSize();
55 if (m_pos
>= olen
) m_pos
=olen
=0; // if queue is empty then autoreset it
57 char *newbuf
=(char *)m_hb
.ResizeOK(olen
+len
,false);
61 if (buf
) memcpy(newbuf
,buf
,len
);
66 template <class T
> T
* GetT(T
* val
=0)
68 T
* p
= (T
*) Get(sizeof(T
));
69 if (val
&& p
) *val
= *p
;
82 if (m_pos
>= 0 && m_pos
< m_hb
.GetSize()) return (char *)m_hb
.Get()+m_pos
;
94 return m_hb
.GetSize()-m_pos
;
96 int Available() const { return GetSize(); }
101 m_hb
.Resize(0,false);
104 void Advance(int bytecnt
)
108 else if (m_pos
> m_hb
.GetSize()) m_pos
=m_hb
.GetSize();
111 void Compact(bool allocdown
=false, bool force
=false)
113 int olen
=m_hb
.GetSize();
114 if (m_pos
> (force
? 0 : olen
/2))
119 char *a
=(char*)m_hb
.Get();
120 memmove(a
,a
+m_pos
,olen
);
126 m_hb
.Resize(olen
,allocdown
);
131 void SetGranul(int granul
) { m_hb
.SetGranul(granul
); }
136 // endian-management stuff
138 static void WDL_Queue__bswap_buffer(void *buf
, int len
)
143 while ((len
-=2) >= 0)
145 char tmp
=*p
; *p
++=*--ep
; *ep
=tmp
;
150 // older API of static functions (that endedu p warning a bit anyway)
151 #define WDL_Queue__AddToLE(q, v) (q)->AddToLE(v)
152 #define WDL_Queue__AddDataToLE(q,d,ds,us) (q)->AddDataToLE(d,ds,us)
153 #define WDL_Queue__GetTFromLE(q,v) (q)->GetTFromLE(v)
154 #define WDL_Queue__GetDataFromLE(q,ds,us) (q)->GetDataFromLE(ds,us)
156 template<class T
> void AddToLE(T
*val
)
158 WDL_Queue__bswap_buffer(AddT(val
),sizeof(T
));
160 void AddDataToLE(void *data
, int datasize
, int unitsize
)
163 char *dout
= (char *)Add(data
,datasize
);
164 while (datasize
>= unitsize
)
166 WDL_Queue__bswap_buffer(dout
,unitsize
);
176 // NOTE: these thrash the contents of the queue if on LE systems. So for example if you are going to rewind it later or use it elsewhere,
177 // then get ready to get unhappy.
178 template<class T
> T
*GetTFromLE(T
* val
=0)
182 WDL_Queue__bswap_buffer(p
,sizeof(T
));
188 void *GetDataFromLE(int datasize
, int unitsize
)
190 void *data
=Get(datasize
);
192 char *dout
=(char *)data
;
193 if (dout
) while (datasize
>= unitsize
)
195 WDL_Queue__bswap_buffer(dout
,unitsize
);
207 int __pad
; // keep 8 byte aligned
210 template <class T
> class WDL_TypedQueue
213 WDL_TypedQueue() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_TypedQueue")), m_pos(0) { }
214 ~WDL_TypedQueue() { }
216 T
*Add(const T
*buf
, int len
)
218 int olen
=m_hb
.GetSize();
219 if (m_pos
>= olen
) olen
=m_pos
=0;
220 len
*= (int)sizeof(T
);
222 char *newbuf
=(char*)m_hb
.ResizeOK(olen
+len
,false);
226 if (buf
) memcpy(newbuf
,buf
,len
);
233 if (m_pos
>= 0 && m_pos
< m_hb
.GetSize()) return (T
*)((char *)m_hb
.Get()+m_pos
);
239 return m_pos
< m_hb
.GetSize() ? (m_hb
.GetSize()-m_pos
)/sizeof(T
) : 0;
241 int Available() const { return GetSize(); }
246 m_hb
.Resize(0,false);
249 void Advance(int cnt
)
251 m_pos
+=cnt
*(int)sizeof(T
);
253 else if (m_pos
> m_hb
.GetSize()) m_pos
=m_hb
.GetSize();
256 void Compact(bool allocdown
=false, bool force
=false)
258 int olen
=m_hb
.GetSize();
259 if (m_pos
> (force
? 0 : olen
/2))
264 char *a
=(char*)m_hb
.Get();
265 memmove(a
,a
+m_pos
,olen
);
271 m_hb
.Resize(olen
,allocdown
);
276 void SetGranul(int granul
) { m_hb
.SetGranul(granul
); }
281 int __pad
; // keep 8 byte aligned