Make duplicate script compatible with Python 3
[wdl/wdl-ol.git] / WDL / queue.h
blobe16ea1052da2949e2b31977f9ba24cb059246621
1 /*
2 WDL - queue.h
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.
34 #ifndef _WDL_QUEUE_H_
35 #define _WDL_QUEUE_H_
37 #include "heapbuf.h"
40 class WDL_Queue
42 public:
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) { }
45 ~WDL_Queue() { }
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);
58 if (newbuf)
60 newbuf += olen;
61 if (buf) memcpy(newbuf,buf,len);
63 return newbuf;
66 template <class T> T* GetT(T* val=0)
68 T* p = (T*) Get(sizeof(T));
69 if (val && p) *val = *p;
70 return p;
73 void* Get(int size)
75 void* p = Get();
76 if (p) Advance(size);
77 return p;
80 void *Get() const
82 if (m_pos >= 0 && m_pos < m_hb.GetSize()) return (char *)m_hb.Get()+m_pos;
83 return NULL;
86 void* Rewind()
88 m_pos = 0;
89 return m_hb.Get();
92 int GetSize() const
94 return m_hb.GetSize()-m_pos;
96 int Available() const { return GetSize(); }
98 void Clear()
100 m_pos=0;
101 m_hb.Resize(0,false);
104 void Advance(int bytecnt)
106 m_pos+=bytecnt;
107 if (m_pos<0)m_pos=0;
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))
116 olen -= m_pos;
117 if (olen > 0)
119 char *a=(char*)m_hb.Get();
120 memmove(a,a+m_pos,olen);
122 else
124 olen = 0;
126 m_hb.Resize(olen,allocdown);
127 m_pos=0;
131 void SetGranul(int granul) { m_hb.SetGranul(granul); }
136 // endian-management stuff
138 static void WDL_Queue__bswap_buffer(void *buf, int len)
140 #ifdef __ppc__
141 char *p=(char *)buf;
142 char *ep=p+len;
143 while ((len-=2) >= 0)
145 char tmp=*p; *p++=*--ep; *ep=tmp;
147 #endif
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)
162 #ifdef __ppc__
163 char *dout = (char *)Add(data,datasize);
164 while (datasize >= unitsize)
166 WDL_Queue__bswap_buffer(dout,unitsize);
167 dout+=unitsize;
168 datasize-=unitsize;
170 #else
171 Add(data,datasize);
172 #endif
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)
180 T *p = GetT(val);
181 if (p) {
182 WDL_Queue__bswap_buffer(p,sizeof(T));
183 if (val) *val = *p;
185 return p;
188 void *GetDataFromLE(int datasize, int unitsize)
190 void *data=Get(datasize);
191 #ifdef __ppc__
192 char *dout=(char *)data;
193 if (dout) while (datasize >= unitsize)
195 WDL_Queue__bswap_buffer(dout,unitsize);
196 dout+=unitsize;
197 datasize-=unitsize;
199 #endif
200 return data;
204 private:
205 WDL_HeapBuf m_hb;
206 int m_pos;
207 int __pad; // keep 8 byte aligned
210 template <class T> class WDL_TypedQueue
212 public:
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);
223 if (newbuf)
225 newbuf += olen;
226 if (buf) memcpy(newbuf,buf,len);
228 return (T*) newbuf;
231 T *Get() const
233 if (m_pos >= 0 && m_pos < m_hb.GetSize()) return (T*)((char *)m_hb.Get()+m_pos);
234 return NULL;
237 int GetSize() const
239 return m_pos < m_hb.GetSize() ? (m_hb.GetSize()-m_pos)/sizeof(T) : 0;
241 int Available() const { return GetSize(); }
243 void Clear()
245 m_pos=0;
246 m_hb.Resize(0,false);
249 void Advance(int cnt)
251 m_pos+=cnt*(int)sizeof(T);
252 if (m_pos<0)m_pos=0;
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))
261 olen -= m_pos;
262 if (olen > 0)
264 char *a=(char*)m_hb.Get();
265 memmove(a,a+m_pos,olen);
267 else
269 olen = 0;
271 m_hb.Resize(olen,allocdown);
272 m_pos=0;
276 void SetGranul(int granul) { m_hb.SetGranul(granul); }
278 private:
279 WDL_HeapBuf m_hb;
280 int m_pos;
281 int __pad; // keep 8 byte aligned
284 #endif