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
);
208 int __pad
; // keep 8 byte aligned
211 template <class T
> class WDL_TypedQueue
214 WDL_TypedQueue() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_TypedQueue")), m_pos(0) { }
215 ~WDL_TypedQueue() { }
217 T
*Add(const T
*buf
, int len
)
219 int olen
=m_hb
.GetSize();
220 if (m_pos
>= olen
) olen
=m_pos
=0;
221 len
*= (int)sizeof(T
);
223 char *newbuf
=(char*)m_hb
.ResizeOK(olen
+len
,false);
227 if (buf
) memcpy(newbuf
,buf
,len
);
234 if (m_pos
>= 0 && m_pos
< m_hb
.GetSize()) return (T
*)((char *)m_hb
.Get()+m_pos
);
240 return m_pos
< m_hb
.GetSize() ? (m_hb
.GetSize()-m_pos
)/sizeof(T
) : 0;
242 int Available() const { return GetSize(); }
247 m_hb
.Resize(0,false);
250 void Advance(int cnt
)
252 m_pos
+=cnt
*(int)sizeof(T
);
254 else if (m_pos
> m_hb
.GetSize()) m_pos
=m_hb
.GetSize();
257 void Compact(bool allocdown
=false, bool force
=false)
259 int olen
=m_hb
.GetSize();
260 if (m_pos
> (force
? 0 : olen
/2))
265 char *a
=(char*)m_hb
.Get();
266 memmove(a
,a
+m_pos
,olen
);
272 m_hb
.Resize(olen
,allocdown
);
277 void SetGranul(int granul
) { m_hb
.SetGranul(granul
); }
283 int __pad
; // keep 8 byte aligned