| 
							- /*
 -     WDL - heapbuf.h
 -     Copyright (C) 2005 and later Cockos Incorporated
 - 
 -     This software is provided 'as-is', without any express or implied
 -     warranty.  In no event will the authors be held liable for any damages
 -     arising from the use of this software.
 - 
 -     Permission is granted to anyone to use this software for any purpose,
 -     including commercial applications, and to alter it and redistribute it
 -     freely, subject to the following restrictions:
 - 
 -     1. The origin of this software must not be misrepresented; you must not
 -        claim that you wrote the original software. If you use this software
 -        in a product, an acknowledgment in the product documentation would be
 -        appreciated but is not required.
 -     2. Altered source versions must be plainly marked as such, and must not be
 -        misrepresented as being the original software.
 -     3. This notice may not be removed or altered from any source distribution.
 -       
 - */
 - 
 - /*
 - 
 -   This file provides the interface and implementation for WDL_HeapBuf, a simple 
 -   malloc() wrapper for resizeable blocks.
 - 
 -   Also in this file is WDL_TypedBuf which is a templated version WDL_HeapBuf 
 -   that manages type and type-size.
 -  
 - */
 - 
 - #ifndef _WDL_HEAPBUF_H_
 - #define _WDL_HEAPBUF_H_
 - 
 - #ifndef WDL_HEAPBUF_IMPL_ONLY
 - 
 - #ifdef WDL_HEAPBUF_TRACE
 - #include <windows.h>
 - #define WDL_HEAPBUF_TRACEPARM(x) ,(x)
 - #else
 - #define WDL_HEAPBUF_TRACEPARM(x)
 - #endif
 - 
 - #include "wdltypes.h"
 - 
 - class WDL_HeapBuf
 - {
 -   public:
 -     // interface 
 - #ifdef WDL_HEAPBUF_INTF_ONLY
 -     void *Resize(int newsize, bool resizedown=true);
 -     void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false);
 - #endif
 -     void *Get() const { return m_size?m_buf:NULL; }
 -     int GetSize() const { return m_size; }
 -     void *GetAligned(int align) const {  return (void *)(((UINT_PTR)Get() + (align-1)) & ~(UINT_PTR)(align-1)); }
 - 
 -     void SetGranul(int granul) { m_granul = granul; }
 -     int GetGranul() const { return m_granul; }
 - 
 -     void *ResizeOK(int newsize, bool resizedown = true) { void *p=Resize(newsize, resizedown); return GetSize() == newsize ? p : NULL; }
 -     
 -     WDL_HeapBuf(const WDL_HeapBuf &cp)
 -     {
 -       m_buf=0;
 -       CopyFrom(&cp,true);
 -     }
 -     WDL_HeapBuf &operator=(const WDL_HeapBuf &cp)
 -     {
 -       CopyFrom(&cp,false);
 -       return *this;
 -     }
 - 
 - 
 - 
 -   #ifndef WDL_HEAPBUF_TRACE
 -     explicit WDL_HeapBuf(int granul=4096) : m_buf(NULL), m_alloc(0), m_size(0), m_granul(granul)
 -     {
 -     }
 -     ~WDL_HeapBuf()
 -     {
 -       free(m_buf);
 -     }
 -   #else
 -     explicit WDL_HeapBuf(int granul=4096, const char *tracetype="WDL_HeapBuf"
 -       ) : m_buf(NULL), m_alloc(0), m_size(0), m_granul(granul)
 -     {
 -       m_tracetype = tracetype;
 -       char tmp[512];
 -       wsprintf(tmp,"WDL_HeapBuf: created type: %s granul=%d\n",tracetype,granul);
 -       OutputDebugString(tmp);
 -     }
 -     ~WDL_HeapBuf()
 -     {
 -       char tmp[512];
 -       wsprintf(tmp,"WDL_HeapBuf: destroying type: %s (alloc=%d, size=%d)\n",m_tracetype,m_alloc,m_size);
 -       OutputDebugString(tmp);
 -       free(m_buf);
 -     }
 -   #endif
 - 
 - #endif // !WDL_HEAPBUF_IMPL_ONLY
 - 
 -     // implementation bits
 - #ifndef WDL_HEAPBUF_INTF_ONLY
 -     #ifdef WDL_HEAPBUF_IMPL_ONLY
 -       void *WDL_HeapBuf::Resize(int newsize, bool resizedown)
 -     #else
 -       void *Resize(int newsize, bool resizedown=true)
 -     #endif
 -       {
 -         if (newsize<0) newsize=0;
 -         #ifdef DEBUG_TIGHT_ALLOC // horribly slow, do not use for release builds
 -           if (newsize == m_size) return m_buf;
 - 
 -           int a = newsize; 
 -           if (a > m_size) a=m_size;
 -           void *newbuf = newsize ? malloc(newsize) : 0;
 -           if (!newbuf && newsize) 
 -           {
 -             #ifdef WDL_HEAPBUF_ONMALLOCFAIL
 -                 WDL_HEAPBUF_ONMALLOCFAIL(newsize)
 -             #endif
 -             return m_buf;
 -           }
 -           if (newbuf&&m_buf) memcpy(newbuf,m_buf,a);
 -           m_size=m_alloc=newsize;
 -           free(m_buf);
 -           return m_buf=newbuf;
 -         #endif
 - 
 -           if (newsize!=m_size || (resizedown && newsize < m_alloc/2))
 -           {
 -             int resizedown_under = 0;
 -             if (resizedown && newsize < m_size)
 -             {
 -               // shrinking buffer: only shrink if allocation decreases to min(alloc/2, alloc-granul*4) or 0
 -               resizedown_under = m_alloc - (m_granul<<2);
 -               if (resizedown_under > m_alloc/2) resizedown_under = m_alloc/2;
 -               if (resizedown_under < 1) resizedown_under=1;
 -             }
 -   
 -             if (newsize > m_alloc || newsize < resizedown_under)
 -             {
 -               int granul=newsize/2;
 -               int newalloc;
 -               if (granul < m_granul) granul=m_granul;
 -   
 -               if (newsize<1) newalloc=0;
 -               else if (m_granul<4096) newalloc=newsize+granul;
 -               else
 -               {
 -                 granul &= ~4095;
 -                 if (granul< 4096) granul=4096;
 -                 else if (granul>4*1024*1024) granul=4*1024*1024;
 -                 newalloc = ((newsize + granul + 96)&~4095)-96;
 -               }
 -          
 -               if (newalloc != m_alloc)
 -               {
 - 
 -                 #ifdef WDL_HEAPBUF_TRACE
 -                   char tmp[512];
 -                   wsprintf(tmp,"WDL_HeapBuf: type %s realloc(%d) from %d\n",m_tracetype,newalloc,m_alloc);
 -                   OutputDebugString(tmp);
 -                 #endif
 -                 if (newalloc <= 0)
 -                 {
 -                   free(m_buf);
 -                   m_buf=0;
 -                   m_alloc=0;
 -                   m_size=0;
 -                   return 0;
 -                 }
 -                 void *nbuf=realloc(m_buf,newalloc);
 -                 if (!nbuf)
 -                 {
 -                   if (!(nbuf=malloc(newalloc))) 
 -                   {
 -                     #ifdef WDL_HEAPBUF_ONMALLOCFAIL
 -                       WDL_HEAPBUF_ONMALLOCFAIL(newalloc);
 -                     #endif
 -                     return m_size?m_buf:0; // failed, do not resize
 -                   }
 - 
 -                   if (m_buf) 
 -                   {
 -                     int sz=newsize<m_size?newsize:m_size;
 -                     if (sz>0) memcpy(nbuf,m_buf,sz);
 -                     free(m_buf);
 -                   }
 -                 }
 -   
 -                 m_buf=nbuf;
 -                 m_alloc=newalloc;
 -               } // alloc size change
 -             } // need size up or down
 -             m_size=newsize;
 -           } // size change
 -           return m_size?m_buf:0;
 -       }
 - 
 -     #ifdef WDL_HEAPBUF_IMPL_ONLY
 -       void WDL_HeapBuf::CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig)
 -     #else
 -       void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false)
 -     #endif
 -       {
 -         if (exactCopyOfConfig) // copy all settings
 -         {
 -           free(m_buf);
 - 
 -           #ifdef WDL_HEAPBUF_TRACE
 -             m_tracetype = hb->m_tracetype;
 -           #endif
 -           m_granul = hb->m_granul;
 - 
 -           m_size=m_alloc=0;
 -           m_buf=hb->m_buf && hb->m_alloc>0 ? malloc(m_alloc = hb->m_alloc) : NULL;
 -           #ifdef WDL_HEAPBUF_ONMALLOCFAIL
 -             if (!m_buf && m_alloc) { WDL_HEAPBUF_ONMALLOCFAIL(m_alloc) } ;
 -           #endif
 -           if (m_buf) memcpy(m_buf,hb->m_buf,m_size = hb->m_size);
 -           else m_alloc=0;
 -         }
 -         else // copy just the data + size
 -         {
 -           const int newsz=hb->GetSize();
 -           Resize(newsz,true);
 -           if (GetSize()!=newsz) Resize(0);
 -           else memcpy(Get(),hb->Get(),newsz);
 -         }
 -       }
 - 
 - #endif // ! WDL_HEAPBUF_INTF_ONLY
 - 
 - #ifndef WDL_HEAPBUF_IMPL_ONLY
 - 
 -   private:
 -     void *m_buf;
 -     int m_alloc;
 -     int m_size;
 -     int m_granul;
 - 
 -   #if defined(_WIN64) || defined(__LP64__)
 -   public:
 -     int ___pad; // keep size 8 byte aligned
 -   #endif
 - 
 -   #ifdef WDL_HEAPBUF_TRACE
 -     const char *m_tracetype;
 -   #endif
 - 
 - };
 - 
 - template<class PTRTYPE> class WDL_TypedBuf 
 - {
 -   public:
 -     PTRTYPE *Get() const { return (PTRTYPE *) m_hb.Get(); }
 -     int GetSize() const { return m_hb.GetSize()/(unsigned int)sizeof(PTRTYPE); }
 - 
 -     PTRTYPE *Resize(int newsize, bool resizedown = true) { return (PTRTYPE *)m_hb.Resize(newsize*sizeof(PTRTYPE),resizedown); }
 -     PTRTYPE *ResizeOK(int newsize, bool resizedown = true) { return (PTRTYPE *)m_hb.ResizeOK(newsize*sizeof(PTRTYPE), resizedown);  }
 - 
 -     PTRTYPE *GetAligned(int align) const  { return (PTRTYPE *) m_hb.GetAligned(align); }
 - 
 -     PTRTYPE *Add(PTRTYPE val) 
 -     {
 -       const int sz=GetSize();
 -       PTRTYPE* p=ResizeOK(sz+1,false);
 -       if (p)
 -       {
 -         p[sz]=val;
 -         return p+sz;
 -       }
 -       return NULL;
 -     }
 -     PTRTYPE *Add(const PTRTYPE *buf, int bufsz) 
 -     {
 -       if (bufsz>0)
 -       {
 -         const int sz=GetSize();
 -         PTRTYPE* p=ResizeOK(sz+bufsz,false);
 -         if (p)
 -         {
 -           p+=sz;
 -           if (buf) memcpy(p,buf,bufsz*sizeof(PTRTYPE));
 -           else memset(p,0,bufsz*sizeof(PTRTYPE));
 -           return p;
 -         }
 -       }
 -       return NULL;
 -     }
 -     PTRTYPE *Set(const PTRTYPE *buf, int bufsz) 
 -     {
 -       if (bufsz>=0)
 -       {
 -         PTRTYPE* p=ResizeOK(bufsz,false);
 -         if (p)
 -         {
 -           if (buf) memcpy(p,buf,bufsz*sizeof(PTRTYPE));
 -           else memset(p,0,bufsz*sizeof(PTRTYPE));
 -           return p;
 -         }
 -       }
 -       return NULL;
 -     }
 -     PTRTYPE* Insert(PTRTYPE val, int idx)
 -     {
 -       const int sz=GetSize();
 -       if (idx >= 0 && idx <= sz)
 -       {
 -         PTRTYPE* p=ResizeOK(sz+1,false);
 -         if (p)
 -         {
 -           memmove(p+idx+1, p+idx, (sz-idx)*sizeof(PTRTYPE));
 -           p[idx]=val;
 -           return p+idx;
 -         }
 -       }
 -       return NULL;
 -     }
 - 
 -     void Delete(int idx)
 -     {
 -       PTRTYPE* p=Get();
 -       const int sz=GetSize();
 -       if (idx >= 0 && idx < sz)
 -       {
 -         memmove(p+idx, p+idx+1, (sz-idx-1)*sizeof(PTRTYPE));
 -         Resize(sz-1,false);
 -       }
 -     }
 - 
 -     void SetGranul(int gran) { m_hb.SetGranul(gran); }
 - 
 -     int Find(PTRTYPE val) const
 -     {
 -       const PTRTYPE* p=Get();
 -       const int sz=GetSize();
 -       int i;
 -       for (i=0; i < sz; ++i) if (p[i] == val) return i;
 -       return -1;
 -     }
 - 
 - #ifndef WDL_HEAPBUF_TRACE
 -     explicit WDL_TypedBuf(int granul=4096) : m_hb(granul) { }
 - #else
 -     explicit WDL_TypedBuf(int granul=4096, const char *tracetype="WDL_TypedBuf") : m_hb(granul WDL_HEAPBUF_TRACEPARM(tracetype)) { }
 - #endif
 -     ~WDL_TypedBuf()
 -     {
 -     }
 - 
 - 	PTRTYPE* begin() const { return static_cast<PTRTYPE*>(m_hb.Get()); }
 - 	PTRTYPE* end() const 
 - 	{ 
 - 		PTRTYPE* temp = static_cast<PTRTYPE*>(m_hb.Get());
 - 		return temp + m_hb.GetSize() / sizeof(PTRTYPE);
 - 	}
 - 
 - 
 -     WDL_HeapBuf *GetHeapBuf() { return &m_hb; }
 -     const WDL_HeapBuf *GetHeapBuf() const { return &m_hb; }
 - 
 - 
 -   private:
 -     WDL_HeapBuf m_hb;
 - };
 - 
 - #endif // ! WDL_HEAPBUF_IMPL_ONLY
 - 
 - #endif // _WDL_HEAPBUF_H_
 
 
  |