langpackedit: sorting fixes, 0.015 -- from 8f06f769
[wdl.git] / WDL / queue.h
blobe04e697ad24f82fe5c3c09e248802547c2489d61
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(int hbgran=4096) : m_hb(hbgran), m_pos(0) { }
44 ~WDL_Queue() { }
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);
57 if (newbuf)
59 newbuf += olen;
60 if (buf) memcpy(newbuf,buf,len);
62 return newbuf;
65 template <class T> T* GetT(T* val=0)
67 T* p = (T*) Get(sizeof(T));
68 if (val && p) *val = *p;
69 return p;
72 void* Get(int size)
74 void* p = Get();
75 if (p) Advance(size);
76 return p;
79 void *Get() const
81 if (m_pos >= 0 && m_pos < m_hb.GetSize()) return (char *)m_hb.Get()+m_pos;
82 return NULL;
85 void* Rewind()
87 m_pos = 0;
88 return m_hb.Get();
91 int GetSize() const
93 return m_hb.GetSize()-m_pos;
95 int Available() const { return GetSize(); }
97 void Clear()
99 m_pos=0;
100 m_hb.Resize(0,false);
103 void Advance(int bytecnt)
105 m_pos+=bytecnt;
106 if (m_pos<0)m_pos=0;
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))
115 olen -= m_pos;
116 if (olen > 0)
118 char *a=(char*)m_hb.Get();
119 memmove(a,a+m_pos,olen);
121 else
123 olen = 0;
125 m_hb.Resize(olen,allocdown);
126 m_pos=0;
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)
170 T *p = GetT(val);
171 if (p)
173 wdl_memcpy_le(p,p,1,sizeof(T));
174 if (val) *val = *p;
176 return p;
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);
184 return data;
188 private:
189 WDL_HeapBuf m_hb;
190 int m_pos;
191 public:
192 int __pad; // keep 8 byte aligned
195 template <class T> class WDL_TypedQueue
197 public:
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);
208 if (newbuf)
210 newbuf += olen;
211 if (buf) memcpy(newbuf,buf,len);
213 return (T*) newbuf;
216 T *Get() const
218 if (m_pos >= 0 && m_pos < m_hb.GetSize()) return (T*)((char *)m_hb.Get()+m_pos);
219 return NULL;
222 int GetSize() const
224 return m_pos < m_hb.GetSize() ? (m_hb.GetSize()-m_pos)/sizeof(T) : 0;
226 int Available() const { return GetSize(); }
228 void Clear()
230 m_pos=0;
231 m_hb.Resize(0,false);
234 void Advance(int cnt)
236 m_pos+=cnt*(int)sizeof(T);
237 if (m_pos<0)m_pos=0;
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))
246 olen -= m_pos;
247 if (olen > 0)
249 char *a=(char*)m_hb.Get();
250 memmove(a,a+m_pos,olen);
252 else
254 olen = 0;
256 m_hb.Resize(olen,allocdown);
257 m_pos=0;
261 void SetGranul(int granul) { m_hb.SetGranul(granul); }
262 void Prealloc(int sz) { m_hb.Prealloc(sz * sizeof(T)); }
264 private:
265 WDL_HeapBuf m_hb;
266 int m_pos;
267 public:
268 int __pad; // keep 8 byte aligned
271 #endif