1 package gnu.jemacs.buffer; 2 import gnu.mapping.*; 3 4 7 8 public class BufferLocal extends IndirectableLocation 9 { 10 boolean all; 11 12 final Symbol name; 13 14 Buffer cachedBuffer; 15 16 17 int cachedIndex; 18 19 BufferLocal (Symbol name, boolean all) 20 { 21 this.name = name; 22 this.all = all; 23 } 24 25 public final Symbol getKeySymbol () 26 { 27 return name; 28 } 29 30 public static void make(Symbol symbol, boolean all) 31 { 32 Environment env = Environment.getCurrent(); 33 NamedLocation loc = env.getLocation(symbol, null, true); 34 Location base = loc.getBase(); 35 if (base instanceof BufferLocal) 36 { 37 if (all) 38 ((BufferLocal) base).all = true; 39 return; 40 } 41 BufferLocal bloc = new BufferLocal(symbol, all); 42 bloc.base = loc.getBaseForce(); 45 bloc.setAlias(loc); 46 } 47 48 public Object get (Object defaultValue) 49 { 50 Buffer buffer = Buffer.getCurrent(); 51 return buffer == null ? base.get(defaultValue) : get(buffer, defaultValue); 52 } 53 54 public Object get (Buffer buffer, Object defaultValue) 55 { 56 Object [] localBindings = buffer.localBindings; 57 if (buffer == cachedBuffer) 58 { 59 int i = cachedIndex; 60 if (i > 0) 61 return localBindings[i]; 62 } 63 else if (localBindings != null) 64 { 65 Symbol n = this.getKeySymbol(); 66 int len = localBindings.length; 67 cachedBuffer = buffer; 68 for (int i = 0; i < len; i += 2) 69 { 70 if (localBindings[i] == n) 71 { 72 cachedIndex = ++i; 73 return localBindings[i]; 74 } 75 } 76 cachedIndex = 0; 77 } 78 return base != null ? base.get(defaultValue) 79 : value == Location.UNBOUND ? defaultValue : value; 80 } 81 82 public boolean isBound () 83 { 84 Buffer buffer = Buffer.getCurrent(); 85 return buffer == null ? base.isBound() : isBound(buffer); 86 } 87 88 public boolean isBound (Buffer buffer) 89 { 90 Object [] localBindings = buffer.localBindings; 91 Object unb = Location.UNBOUND; 92 if (buffer == cachedBuffer) 93 { 94 int i = cachedIndex; 95 if (i >= 0) 96 return localBindings[i] != unb; 97 } 98 else if (localBindings != null) 99 { 100 Symbol n = this.getKeySymbol(); 101 int len = localBindings.length; 102 cachedBuffer = buffer; 103 for (int i = 0; i < len; i += 2) 104 { 105 if (localBindings[i] == n) 106 { 107 cachedIndex = ++i; 108 return localBindings[i] != unb; 109 } 110 } 111 cachedIndex = 0; 112 } 113 return super.isBound(); 114 } 115 116 public synchronized final void set (Object newValue) 117 { 118 Buffer buffer = Buffer.getCurrent(); 119 if (buffer == null) 120 base.set(newValue); 121 else 122 set(buffer, newValue); 123 } 124 125 public synchronized final void set (Buffer buffer, Object newValue) 126 { 127 Object [] localBindings = buffer.localBindings; 128 int avail = -1; 129 Symbol n = this.getKeySymbol(); 130 if (buffer == cachedBuffer) 131 { 132 int i = cachedIndex; 133 if (i >= 0) 134 { 135 localBindings[i] = newValue; 136 return; 137 } 138 } 139 else if (localBindings != null) 140 { 141 int len = localBindings.length; 142 for (int i = 0; i < len; i += 2) 143 { 144 Object key = localBindings[i]; 145 if (key == n) 146 { 147 cachedBuffer = buffer; 148 cachedIndex = ++i; 149 localBindings[i] = newValue; 150 return; 151 } 152 if (key == null) 153 avail = i; 154 } 155 cachedIndex = 0; 156 } 157 if (all) 158 { 159 if (avail < 0) 160 { 161 if (localBindings == null) 162 { 163 localBindings = new Object [20]; 164 buffer.localBindings = localBindings; 165 avail = 0; 166 } 167 else 168 { 169 avail = localBindings.length; 170 Object [] newBindings = new Object [2 * avail]; 171 System.arraycopy(localBindings, 0, newBindings, 0, avail); 172 buffer.localBindings = localBindings = newBindings; 173 } 174 } 175 localBindings[avail] = n; 176 cachedBuffer = buffer; 177 cachedIndex = ++avail; 178 localBindings[avail] = newValue; 179 } 180 else if (base == null) 181 value = newValue; 182 else 183 base.set(newValue); 184 } 185 } 186 | Popular Tags |