Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

obstack.h

00001 // This may look like C code, but it is really -*- C++ -*-
00002 /* 
00003 Copyright (C) 1988 Free Software Foundation
00004     written by Doug Lea (dl@rocky.oswego.edu)
00005 
00006 This file is part of the GNU C++ Library.  This library is free
00007 software; you can redistribute it and/or modify it under the terms of
00008 the GNU Library General Public License as published by the Free
00009 Software Foundation; either version 2 of the License, or (at your
00010 option) any later version.  This library is distributed in the hope
00011 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00012 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00013 PURPOSE.  See the GNU Library General Public License for more details.
00014 You should have received a copy of the GNU Library General Public
00015 License along with this library; if not, write to the Free Software
00016 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 
00020 #ifndef _obstack_h
00021 #define _obstack_h 1
00022 
00023 #include <string.h>
00024 
00025 #undef OK
00026 
00027 class Obstack
00028 {
00029   struct _obstack_chunk
00030   {
00031     char*           limit;
00032     _obstack_chunk* prev;
00033     char            contents[4];
00034   };
00035 
00036 protected:
00037   long            m_chunksize;
00038   _obstack_chunk* mp_chunk;
00039   char*           mp_objectbase;
00040   char*           mp_nextfree;
00041   char*           mp_chunklimit;
00042   int             m_alignmentmask;
00043 
00044   void  _free(void* obj);
00045   void  newchunk(int size);
00046 
00047 public:
00048   Obstack(int size = 4080, int alignment = 4); // 4080=4096-mallocslop
00049   
00050   ~Obstack();
00051 
00052   void* base();
00053   void* next_free();
00054   int   alignment_mask();
00055   int   chunk_size();
00056   int   size();
00057   int   room();
00058   int   contains(void* p);      // does Obstack hold pointer p?
00059 
00060   void  grow(const void* data, int size);
00061   void  grow(const void* data, int size, char terminator);
00062   void  grow(const char* s);
00063   void  grow(char c);
00064   void  grow_fast(char c);
00065   void  blank(int size);
00066   void  blank_fast(int size);
00067 
00068   void* finish();
00069   void* finish(char terminator);
00070 
00071   void* copy(const void* data, int size);
00072   void* copy(const void* data, int size, char terminator);
00073   void* copy(const char* s);
00074   void* copy(char c);
00075   void* alloc(int size);
00076 
00077   void  free(void* obj);
00078   void  shrink(int size = 1); // suggested by ken@cs.rochester.edu
00079 
00080   int   OK();                   // rep invariant
00081 };
00082 
00083 
00084 inline Obstack::~Obstack()
00085 {
00086   _free(0); 
00087 }
00088 
00089 inline void* Obstack::base()
00090 {
00091   return mp_objectbase; 
00092 }
00093 
00094 inline void* Obstack::next_free()
00095 {
00096   return mp_nextfree; 
00097 }
00098 
00099 inline int Obstack::alignment_mask()
00100 {
00101   return m_alignmentmask; 
00102 }
00103 
00104 inline int Obstack::chunk_size()
00105 {
00106   return m_chunksize; 
00107 }
00108 
00109 inline int Obstack::size()
00110 {
00111   return mp_nextfree - mp_objectbase; 
00112 }
00113 
00114 inline int Obstack::room()
00115 {
00116   return mp_chunklimit - mp_nextfree; 
00117 }
00118 
00119 inline void Obstack:: grow(const void* data, int size)
00120 {
00121   if (mp_nextfree+size > mp_chunklimit) 
00122     newchunk(size);
00123   memcpy(mp_nextfree, data, size);
00124   mp_nextfree += size; 
00125 }
00126 
00127 inline void Obstack:: grow(const void* data, int size, char terminator)
00128 {
00129   if (mp_nextfree+size+1 > mp_chunklimit) 
00130     newchunk(size+1);
00131   memcpy(mp_nextfree, data, size);
00132   mp_nextfree += size; 
00133   *(mp_nextfree)++ = terminator; 
00134 }
00135 
00136 inline void Obstack:: grow(const char* s)
00137 {
00138   grow((const void*)s, strlen(s), 0); 
00139 }
00140 
00141 inline void Obstack:: grow(char c)
00142 {
00143   if (mp_nextfree+1 > mp_chunklimit) 
00144     newchunk(1); 
00145   *(mp_nextfree)++ = c; 
00146 }
00147 
00148 inline void Obstack:: blank(int size)
00149 {
00150   if (mp_nextfree+size > mp_chunklimit) 
00151     newchunk(size);
00152   mp_nextfree += size; 
00153 }
00154 
00155 inline void* Obstack::finish(char terminator)
00156 {
00157   grow(terminator); 
00158   return finish(); 
00159 }
00160 
00161 inline void* Obstack::copy(const void* data, int size)
00162 {
00163   grow (data, size);
00164   return finish(); 
00165 }
00166 
00167 inline void* Obstack::copy(const void* data, int size, char terminator)
00168 {
00169   grow(data, size, terminator); 
00170   return finish(); 
00171 }
00172 
00173 inline void* Obstack::copy(const char* s)
00174 {
00175   grow((const void*)s, strlen(s), 0); 
00176   return finish(); 
00177 }
00178 
00179 inline void* Obstack::copy(char c)
00180 {
00181   grow(c);
00182   return finish(); 
00183 }
00184 
00185 inline void* Obstack::alloc(int size)
00186 {
00187   blank(size);
00188   return finish(); 
00189 }
00190 
00191 inline void Obstack:: free(void* obj)     
00192 {
00193   if (obj >= (void*)mp_chunk && obj<(void*)mp_chunklimit)
00194     mp_nextfree = mp_objectbase = (char *) obj;
00195   else 
00196     _free(obj); 
00197 }
00198 
00199 inline void Obstack:: grow_fast(char c)
00200 {
00201   *(mp_nextfree)++ = c; 
00202 }
00203 
00204 inline void Obstack:: blank_fast(int size)
00205 {
00206   mp_nextfree += size; 
00207 }
00208 
00209 inline void Obstack:: shrink(int size) // from ken@cs.rochester.edu
00210 {
00211   if (mp_nextfree >= mp_objectbase + size)
00212     mp_nextfree -= size;
00213 }
00214 
00215 #endif



Project Hosted By:
SourceForge.net Logo