Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef __ARENA_H__
00025 #define __ARENA_H__
00026 
00027 
00028 #include <sys/types.h>
00029 #include <memory.h>
00030 #include "ink_assert.h"
00031 
00032 
00033 struct ArenaBlock
00034 {
00035   ArenaBlock *next;
00036   char *m_heap_end;
00037   char *m_water_level;
00038   char data[8];
00039 };
00040 
00041 
00042 class Arena
00043 {
00044 public:
00045   Arena():m_blocks(NULL)
00046   {
00047   }
00048    ~Arena()
00049   {
00050     reset();
00051   }
00052 
00053   inkcoreapi void *alloc(size_t size, size_t alignment = sizeof(double));
00054   void free(void *mem, size_t size);
00055   size_t str_length(const char *str);
00056   char *str_alloc(size_t len);
00057   void str_free(char *str);
00058   char *str_store(const char *str, size_t len);
00059 
00060   inkcoreapi void reset();
00061 
00062 private:
00063   ArenaBlock * m_blocks;
00064 };
00065 
00066 
00067 
00068 
00069 
00070 inline size_t
00071 Arena::str_length(const char *str)
00072 {
00073   unsigned char *s, *e;
00074   size_t len;
00075 
00076   e = (unsigned char *) str;
00077   s = e - 1;
00078 
00079   while (*s >= 128) {
00080     s -= 1;
00081   }
00082 
00083   len = *s++;
00084   while (s != e) {
00085     len = (len * 128) + (255 - *s++);
00086   }
00087 
00088   return len;
00089 }
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 inline char *
00109 Arena::str_alloc(size_t len)
00110 {
00111   unsigned char *mem, *p;
00112   size_t size;
00113   size_t tmp;
00114 
00115   size = len + 1 + 1;
00116   tmp = len;
00117 
00118   while (tmp >= 128) {
00119     size += 1;
00120     tmp /= 128;
00121   }
00122 
00123   mem = (unsigned char *) alloc(size, 1);
00124 
00125   mem += (size - len - 1);
00126   p = mem - 1;
00127   tmp = len;
00128 
00129   while (tmp >= 128) {
00130     *p-- = (unsigned char) (255 - (tmp % 128));
00131     tmp /= 128;
00132   }
00133   *p = (unsigned char) tmp;
00134 
00135   return (char *) mem;
00136 }
00137 
00138 
00139 
00140 
00141 inline void
00142 Arena::str_free(char *str)
00143 {
00144   unsigned char *p, *s, *e;
00145   size_t len;
00146 
00147   e = (unsigned char *) str;
00148   s = e - 1;
00149 
00150   while (*s >= 128) {
00151     s -= 1;
00152   }
00153 
00154   p = s;
00155 
00156   len = *s++;
00157   while (s != e) {
00158     len = (len * 128) + (255 - *s++);
00159   }
00160 
00161   len += (e - p) + 1;
00162   free(p, len);
00163 }
00164 
00165 
00166 
00167 
00168 inline char *
00169 Arena::str_store(const char *str, size_t len)
00170 {
00171   char *mem;
00172 
00173   mem = str_alloc(len);
00174   memcpy(mem, str, len);
00175   mem[len] = '\0';
00176 
00177   return mem;
00178 }
00179 
00180 
00181 #endif 
00182