NEURON
ustring.cpp
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2 #include <../../nrnconf.h>
3 #endif
4 /*
5  * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
6  * Copyright (c) 1991 Silicon Graphics, Inc.
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and
9  * its documentation for any purpose is hereby granted without fee, provided
10  * that (i) the above copyright notices and this permission notice appear in
11  * all copies of the software and related documentation, and (ii) the names of
12  * Stanford and Silicon Graphics may not be used in any advertising or
13  * publicity relating to the software without the specific, prior written
14  * permission of Stanford and Silicon Graphics.
15  *
16  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
21  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
22  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
24  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25  * OF THIS SOFTWARE.
26  */
27 
28 #include <OS/table.h>
29 #include <OS/ustring.h>
30 #include <string.h>
31 
32 /*
33  * UniqueString uses a table for matching strings and a string pool
34  * for storing the string data. A pool is presumably more efficient
35  * than malloc/new, but individual strings cannot be deallocated.
36  */
37 
38 inline unsigned long key_to_hash(String& s) { return s.hash(); }
39 
42 
43 static const unsigned strpoolsize = 800;
44 
46 public:
47  UniqueStringPool(unsigned poolsize = strpoolsize);
49 
50  char* add(const char*, unsigned);
51 private:
52  char* data;
53  unsigned size;
54  unsigned cur;
56 };
57 
60 
62 UniqueString::UniqueString(const char* s) : String() { init(String(s)); }
63 UniqueString::UniqueString(const char* s, int n) : String() {
64  init(String(s, n));
65 }
69 
70 void UniqueString::init(const String& s) {
71  if (table_ == nil) {
72  table_ = new UniqueStringTable(256);
73  }
74  if (!table_->find(*this, s)) {
75  if (pool_ == nil) {
76  pool_ = new UniqueStringPool;
77  }
78  int n = s.length();
79  set_value(pool_->add(s.string(), n), n);
80  table_->insert(*this, *this);
81  }
82 }
83 
84 /*
85  * UniqueString's have a unique data pointer, so we can just use
86  * that for a hash value.
87  */
88 
89 unsigned long UniqueString::hash() const { return key_to_hash(string()); }
90 
91 bool UniqueString::operator ==(const String& s) const {
92  return string() == s.string() && length() == s.length();
93 }
94 
95 bool UniqueString::operator ==(const char* s) const {
96  return String::operator ==(s);
97 }
98 
99 bool UniqueString::null_terminated() const { return false; }
100 
101 /*
102  * UniqueStringPool implementation.
103  */
104 
106  data = new char[poolsize];
107  size = poolsize;
108  cur = 0;
109  prev = nil;
110 }
111 
112 /*
113  * Tail-recursive deletion to walk the list back to the head
114  * of the pool.
115  */
116 
118  delete [] data;
119  delete prev;
120 }
121 
122 /*
123  * Add a string of a given length to the pool. If it won't fit,
124  * create a copy of the current pool and allocate space for a new one.
125  *
126  * No null-padding is implied, so if you want that you must include
127  * the null in the length.
128  */
129 
130 char* UniqueStringPool::add(const char* str, unsigned len) {
131  if (len > strpoolsize) {
132  UniqueStringPool* s = new UniqueStringPool(len);
133  strncpy(s->data, str, len);
134  s->cur = len;
135  s->prev = prev;
136  prev = s;
137  return s->data;
138  }
139  unsigned index = cur;
140  unsigned newcur = index + len;
141  if (newcur > size) {
143  char* newdata = s->data;
144  s->data = data;
145  s->size = size;
146  s->cur = cur;
147  s->prev = prev;
148  data = newdata;
149  prev = s;
150  index = 0;
151  newcur = len;
152  }
153  char* r = &data[index];
154  strncpy(r, str, len);
155  cur = newcur;
156  return r;
157 }
#define data
Definition: rbtqueue.cpp:49
UniqueStringPool * prev
Definition: ustring.cpp:55
virtual bool operator==(const String &) const
Definition: string.cpp:106
void init(const String &)
Definition: ustring.cpp:70
char * add(const char *, unsigned)
Definition: ustring.cpp:130
int length() const
Definition: string.h:140
unsigned size
Definition: ustring.cpp:53
static String const unsigned strpoolsize
Definition: ustring.cpp:43
#define cur
Definition: eion.cpp:338
#define implementTable(Table, Key, Value)
Definition: table.h:113
String()
Definition: string.cpp:52
const char * string() const
Definition: string.h:139
virtual void set_value(const char *)
Definition: string.cpp:212
static UniqueStringPool * pool_
Definition: ustring.h:56
static UniqueStringTable * table_
Definition: ustring.h:55
unsigned long key_to_hash(String &s)
Definition: ustring.cpp:38
Item * prev(Item *item)
Definition: list.cpp:101
int const size_t const size_t n
Definition: nrngsl.h:12
_CONST char * s
Definition: system.cpp:74
virtual bool null_terminated() const
Definition: ustring.cpp:99
virtual unsigned long hash() const
Definition: ustring.cpp:89
#define nil
Definition: enter-scope.h:36
declareTable(UniqueStringTable, String, String) implementTable(UniqueStringTable
UniqueStringPool(unsigned poolsize=strpoolsize)
Definition: ustring.cpp:105
virtual bool operator==(const String &) const
Definition: ustring.cpp:91
virtual ~UniqueString()
Definition: ustring.cpp:68
int index(u_char) const
Definition: string.h:151
Definition: string.h:34
#define UniqueStringPool
Definition: _defines.h:21
#define add
Definition: redef.h:24
virtual unsigned long hash() const
Definition: string.cpp:74
#define UniqueStringTable
Definition: _defines.h:22
unsigned cur
Definition: ustring.cpp:54