// ex: se sts=4 sw=4 expandtab:
/**
* Yeti core library - structure default implementation.
*
* Copyright (c) 2010 Madis Janson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package yeti.lang;
import java.io.Serializable;
public abstract class AStruct implements Struct, Serializable {
final String[] names;
private final boolean[] vars;
public AStruct(String[] names_, boolean[] vars_) {
names = names_;
vars = vars_;
}
public int count() {
return names.length;
}
public String name(int field) {
return names[field];
}
public String eqName(int field) {
return names[field];
}
public Object ref(int field, int[] index, int at) {
index[at + 1] = 0;
if (vars != null && vars[field]) {
index[at] = field;
return this;
}
index[at] = -1;
return get(field);
}
public void set(String name, Object value) {
Unsafe.unsafeThrow(new NoSuchFieldException(name));
}
public int hashCode() {
int h = 0;
for (int i = 0, cnt = count(); i < cnt; ++i) {
String name = eqName(i);
if (name != "") {
Object v = get(i);
h += name.hashCode() ^ (v == null ? 0 : v.hashCode());
}
}
return h;
}
public boolean equals(Object o) {
Struct st = (Struct) o;
int acnt = count(), bcnt = st.count(), i = 0, j = 0;
while (i < acnt && j < bcnt) {
String an, bn;
if ((an = eqName(i)) == (bn = st.eqName(j)) && an != "") {
Object a = get(i);
Object b = st.get(j);
if (a != b && (a == null || !a.equals(b)))
return false;
} else {
int cmp = an.compareTo(bn);
if (cmp > 0) --i;
if (cmp < 0) --j;
}
++i;
++j;
}
return true;
}
public String toString() {
StringBuffer sb = new StringBuffer().append('{');
for (int cnt = count(), i = 0; i < cnt; ++i) {
String name = eqName(i);
if (name != "") {
if (i != 0)
sb.append(", ");
sb.append(name).append('=').append(Core.show(get(i)));
}
}
sb.append('}');
return sb.toString();
}
}