inital commit

This commit is contained in:
2021-11-02 13:38:59 -05:00
commit 01dd8525b1
65 changed files with 5267 additions and 0 deletions
@@ -0,0 +1,14 @@
package com.reliancy.rec;
/** Similar to a SAX interface used by parsers for XML and JSON to assemble DOM structures.
* Simply gets notified of events during parsing.
* @author amer
*/
public interface DecoderSink {
void beginDocument(Rec init);
Rec endDocument();
void beginElement(String name);
void endElement(String name);
void setKey(String name);
void setValue(CharSequence seq);
}
+126
View File
@@ -0,0 +1,126 @@
package com.reliancy.rec;
import java.util.ArrayList;
import java.util.ListIterator;
/** Base class of meta objects.
* We use it to describe certain meta information. We derive from it Slot.
* We define keys list of slots on the header level to describe slots.
*/
public class Hdr {
public static final int FLAG_ARRAY =0x0001;
public static final int FLAG_CHANGED =0x0002;
public static final int FLAG_HIDDEN =0x0004;
public static final int FLAG_LOCKED =0x0008;
int flags;
String name;
String label;
Class<?> type;
final ArrayList<Slot> keys;
public Hdr(String name) {
this.name=name;
keys=new ArrayList<>();
}
public Hdr(String name,Class<?> type) {
this.name=name;
this.type=type;
keys=new ArrayList<>();
}
@Override
public String toString(){
StringBuilder ret=new StringBuilder();
ret.append("{").append("flags:").append(flags).append(",name:").append(name);
ret.append(",dim:").append(keys.size()).append("}");
return ret.toString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
return label!=null?label:name;
}
public void setLabel(String name) {
this.label = name;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
public Hdr raiseFlags(int f){
flags|=f;
return this;
}
public Hdr clearFlags(int f){
flags&=~f;
return this;
}
public boolean checkFlags(int f){
return (flags & f)!=0;
}
public <T extends Hdr> T castAs(Class<T> clazz){
return clazz.cast(this);
}
public int findSlot(String name){
return findSlot(name,0);
}
public int findSlot(String name,int ofs){
ListIterator<Slot> it=keys.listIterator(ofs);
while(it.hasNext()){
int index=it.nextIndex();
Slot e=it.next();
if(e.getName().equalsIgnoreCase(name)) return index;
}
return -1;
}
public int findSlot(Slot s,int ofs){
ListIterator<Slot> it=keys.listIterator(ofs);
while(it.hasNext()){
int index=it.nextIndex();
Slot e=it.next();
if(e==s) return index;
}
return -1;
}
/**
* this version will get or create a slot by given name.
* @param name
* @return
*/
public Slot getSlot(String name){
int index=findSlot(name);
if(index<0){
return new Slot(name);
}else{
return getSlot(index);
}
}
public Slot getSlot(int pos){
return keys.get(pos);
}
public Hdr removeSlot(int pos){
keys.remove(pos);
return this;
}
public Hdr addSlot(Slot s){
keys.add(s);
return this;
}
public Hdr setSlot(int index,Slot s){
keys.set(index,s);
return this;
}
public Slot[] slots(Slot... slots){
if(slots!=null && slots.length>0){
keys.clear();
for(int i=0;i<slots.length;i++) keys.add(slots[i]);
}
return keys.toArray(new Slot[keys.size()]);
}
}
+22
View File
@@ -0,0 +1,22 @@
package com.reliancy.rec;
import java.io.IOException;
/**
* Static methods related to JSON format.
*/
public class JSON {
private JSON(){
}
public static final Rec reads(CharSequence seq){
JSONDecoder dec=new JSONDecoder();
dec.beginDocument();
dec.parse(0, seq);
return dec.endDocument();
}
public static final void writes(Rec rec,Appendable sink) throws IOException{
JSONEncoder.encode(rec, sink);
}
}
@@ -0,0 +1,331 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.reliancy.rec;
import java.util.LinkedList;
import com.reliancy.util.Tokenizer;
import com.reliancy.util.Handy;
/** Special class which will tokenize string according to rules for JSON and feed the info to a listener.
*
* @author amer
*/
public class JSONDecoder implements TextDecoder,DecoderSink {
DecoderSink handler;
String[] inBody;
String[] sets;
String lastToken=null;
StringBuilder out = new StringBuilder();
public JSONDecoder(DecoderSink h){
handler=h;
String delimChars="{}[],;:=";
String escapeChars="'\"";
String whiteChars=" \t\r\f\n";//" \t\r\f\n";
inBody = new String[]{delimChars,escapeChars,whiteChars};
sets=inBody;
}
public JSONDecoder(){
this(null);
handler=this;
}
@Override
public int parse(int offset,CharSequence in){
int noffset=0;
while((noffset = Tokenizer.nextToken(offset, in, out, sets))!=offset){
offset=noffset;
if(out.length()==0) continue;
String token=out.toString();
out.setLength(0);
if("{".equals(token)){
if(lastToken!=null){
if(lastToken.startsWith("/*") || lastToken.startsWith("//")){
handler.setValue(lastToken); // support comments in our stream
}else{
handler.setKey(lastToken); // we consider string before { a key or name unless comment
}
lastToken=null;
}
handler.beginElement("object");
}else if("}".equals(token)){
if(lastToken!=null){
handler.setValue(lastToken);
lastToken=null;
}
handler.endElement("object");
}else if("[".equals(token)){
if(lastToken!=null){
handler.setValue(lastToken);
lastToken=null;
}
handler.beginElement("array");
}else if("]".equals(token)){
if(lastToken!=null){
handler.setValue(lastToken);
lastToken=null;
}
handler.endElement("array");
}else if(",".equals(token) || ";".equals(token)){
if(lastToken!=null){
handler.setValue(lastToken);
lastToken=null;
}
}else if(":".equals(token) || "=".equals(token)){
if(lastToken!=null){
handler.setKey(lastToken);
lastToken=null;
}
}else{
lastToken=token;
}
}
if(lastToken!=null){
handler.setValue(lastToken);
lastToken=null;
}
return offset;
}
Slot KEY=new Slot("__key",String.class);
/** We use a stack structure to manage recusion. */
LinkedList<Rec> stack=new LinkedList<Rec>();
/** will not add white space only nodes. */
boolean whitespaceIgnored=true;
boolean entitycharsIgnored=false;
public boolean isWhitespaceIgnored() {
return whitespaceIgnored;
}
public void setWhitespaceIgnored(boolean whitespaceIgnored) {
this.whitespaceIgnored = whitespaceIgnored;
}
public boolean isEntitycharsIgnored() {
return entitycharsIgnored;
}
public void setEntitycharsIgnored(boolean entitycharsIgnored) {
this.entitycharsIgnored = entitycharsIgnored;
}
public Rec getRoot() {
return stack.getLast();
}
public Rec getSubject(){
if(stack.isEmpty()) return null;
return stack.getFirst();
}
public void pushSubject(Rec n){
stack.push(n);
}
public Rec popSubject(){
Rec child=stack.pop();
Rec parent=getSubject();
if(parent==null) return child;
if(parent.isArray()){
parent.add(child);
}else{
String key=(String) parent.get(KEY,null);
Slot keyslot=parent.getSlot(key);
parent.remove(KEY).set(keyslot,child);
// if array and has key it should bomb
//parent.setArray(false);
}
return child;
}
public void beginDocument() {
beginDocument(null);
}
@Override
public void beginDocument(Rec init) {
sets=inBody;
out.setLength(0);
lastToken=null;
stack.clear();
Rec arr=new Obj(true);
stack.push(arr);
//System.out.println("BeginDoc");
}
@Override
public Rec endDocument() {
// need to set the actual parent
while(stack.getFirst()!=stack.getLast()){
popSubject();
}
// now adjust the root if it is array with only one child - one we added in start document as first element
Rec root=getSubject();
if(root.isArray() && root.count()==1 && root.get(0) instanceof Rec){
// ok we collapse our array from above - since we only have one object
Object bb=root.get(0);
Rec b=(Rec)bb ;
popSubject();
pushSubject(b);
}
//System.out.println("EndDoc");
return getRoot();
}
@Override
public void beginElement(String name) {
Rec element=new Obj("array".equals(name));
//element.setAttr(0);
pushSubject(element);
//System.out.println("BeginElement:"+name);
}
@Override
public void endElement(String name) {
// check if the correct end element is sent
Rec sub=this.getSubject();
if(!sub.isArray()) sub.remove(KEY);
// finally pop the root
popSubject();
//System.out.println("EndElement:"+name);
}
@Override
public void setKey(String name) {
Rec sub=this.getSubject();
String key=(String) sub.get(KEY,null);
if(key!=null){
// something is wrong - our tokizer might have ignored escape char or input has forgotten a delimiter
// we try to split name because it would contain key and value merged
int split=0;
if(name.startsWith("\"")) split=name.indexOf('\"', 1);
if(name.startsWith("'")) split=name.indexOf('\'', 1);
String val=name.substring(0,split+1);
setValue(val);
name=name.substring(split+1);
}
int start=0;int stop=name.length();
while(start<stop && (name.charAt(start)=='"' || name.charAt(start)=='\'')) start++;
while(start<stop && (name.charAt(stop-1)=='"' || name.charAt(stop-1)=='\'')) stop--;
sub.set(KEY, name.subSequence(start, stop));
//System.out.println("BeginAttribute:"+name);
}
@Override
public void setValue(CharSequence seq) {
if(seq==null) return;
Rec sub=this.getSubject();
String key=(String) sub.get(KEY,null);
if(key==null){
if(isWhitespaceIgnored() && Handy.isEmpty(seq)){
// skip empty strings
return;
}
// now key we are adding to body
Object val=interpretString(seq);
sub.add(val);
}else{
// we are setting attribute
Object val=interpretString(seq);
Slot keyslot=sub.getSlot(key);
sub.remove(KEY).set(keyslot,val);
// it should bomb if array and comes with key
//sub.setArray(false); // if it needs to be array why does it have a key
}
//System.out.println("Data:"+seq);
}
public Object interpretString(CharSequence seq){
int start=0;int stop=seq.length();
while(start<stop && seq.charAt(start)=='"' && seq.charAt(stop-1)=='"'){
start++;
stop--;
}
if(start==0 && stop==seq.length()){
// we do not trim single quotes unless double are missing
while(start<stop && seq.charAt(start)=='\'' && seq.charAt(stop-1)=='\''){
start++;
stop--;
}
}
seq=seq.subSequence(start, stop);
Object val=seq;
if(start==0){
String sVal=String.valueOf(seq);
// we did not have quotes - so try to interpet a few things
if("null".equalsIgnoreCase(sVal)){
val=null;
}else
if("true".equalsIgnoreCase(sVal)){
val=Boolean.TRUE;
}else
if("false".equalsIgnoreCase(sVal)){
val=Boolean.FALSE;
}else
if(Handy.isNumeric(sVal)){
if (sVal.indexOf(".") >= 0) {
val = Double.parseDouble(sVal);
} else {
val = Integer.parseInt(sVal);
}
}else if(this.isEntitycharsIgnored()==false && seq!=null && seq.length()>0){
// maybe it is a string after all
val=unescape(seq);
}
}else if(this.isEntitycharsIgnored()==false && seq!=null && seq.length()>0){
// we had quotes so lets decode escaed chars
val=unescape(seq);
}
return val;
}
public static CharSequence unescape(CharSequence str) {
StringBuilder buf = null;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch == '\\' && i < (str.length() - 1)) {
i = i + 1;
char ch2 = str.charAt(i);
switch (ch2) {
case '"':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\"");
break;
case '\\':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\\");
break;
case '/':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("/");
break;
case 'b':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\b");
break;
case 'f':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\f");
break;
case 'n':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\n");
break;
case 'r':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\r");
break;
case 't':
if(buf==null) buf=new StringBuilder(i>0?str.subSequence(0, i-1):"");
buf.append("\t");
break;
default:
if(buf!=null) buf.append(ch);
}
} else {
if(buf!=null) buf.append(ch);
}
}
return buf!=null?buf.toString():str;
}
}
@@ -0,0 +1,287 @@
package com.reliancy.rec;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class JSONEncoder{
public JSONEncoder(){
}
/**
* We encode into an appendable various primitives and Rec.
* If appendable null then we just compute expected size.
* keys are not escaped they better not contain any special chars.
* values are quoted and escaped unless we detect a string that looks like a json object those are passed thru.
* in the past we tried to deduce if quoting was needed, but this is not the place to do so because we do not know how many times
* value was escaped so the only thing we can assume is that it needs to be escaped. So feeding a value that is quoted and
* escaped will return back on parse the same and will need to dequoted and descaped once more but that shoudl work fine with
* whoever quoted it in the upstream in the first place.
* @param val property value
* @param o encoding output
* @return length in characters of encoded result
* @throws IOException
*/
public static int encode(Object val,Appendable o) throws IOException {
int len = 0;
/*
// first key
if (key != null) {
if (o != null) {
o.append('"').append(key).append("\":");
}
len += 3 + key.length();
}
*/
// now value
if (val instanceof Object[]) {
Object[] valval = (Object[]) val;
if (o != null) {
o.append('[');
}
int index = 0;
for (Object obj : valval) {
if (index++ > 0) {
len += 1;
if (o != null) {
o.append(",");
}
}
len += encode(obj, o);
}
if (o != null) {
o.append(']');
}
len += 2;
} else if (val instanceof List) {
List<?> valval = (List<?>) val;
if (o != null) {
o.append('[');
}
int index = 0;
for (Object obj : valval) {
if (index++ > 0) {
len += 1;
if (o != null) {
o.append(",");
}
}
len += encode(obj, o);
}
if (o != null) {
o.append(']');
}
len += 2;
} else if (val instanceof Map) {
len+=encodeMap((Map<?,?>)val,o);
} else if (val instanceof Rec) {
len += encodeRec((Rec) val, o);
} else if (val instanceof Number || val instanceof Boolean) {
String str = val.toString();
if (o != null) {
o.append(str);
}
len += str.length();
}else if(val instanceof int[]){
int[] valval = (int[]) val;
if (o != null) {
o.append('[');
}
int index = 0;
for (int obj : valval) {
if (index++ > 0) {
len += 1;
if (o != null) {
o.append(",");
}
}
if(o!=null) o.append(String.valueOf(obj));
len += 1;
}
if (o != null) {
o.append(']');
}
len += 2;
}else if(val instanceof float[]){
float[] valval = (float[]) val;
if (o != null) {
o.append('[');
}
int index = 0;
for (float obj : valval) {
if (index++ > 0) {
len += 1;
if (o != null) {
o.append(",");
}
}
if(o!=null) o.append(String.valueOf(obj));
len += 1;
}
if (o != null) {
o.append(']');
}
len += 2;
}else if (val instanceof Object) {
String str = val.toString();
boolean jsontxt = false;
jsontxt |= str.length() > 0 && str.startsWith("{") && str.endsWith("}");
jsontxt |= str.length() > 0 && str.startsWith("[") && str.endsWith("]");
//boolean quoted=str.length() > 1 && str.startsWith("\"") && str.endsWith("\"");
// embedded json is not quoted and not escaped
// all other text is quoted otherwise we will prevent quoted quotes (those would be swallowed)
// we will not try to be smart if someone added an item that is quoted already it will be escaped and queotes retained
// we must be consistent so that repeated parse and encode works and not too smart here
// we need to put quotes around unless
if (!jsontxt) {
str = escape(str);
if (o != null) {
o.append('"');
}
len += 1;
}
if (o != null) {
o.append(str);
}
len += str.length();
if (!jsontxt) {
if (o != null) {
o.append('"');
}
len += 1;
}
} else if (val == null) {
String str = "null";
if (o != null) {
o.append(str);
}
len += str.length();
}
return len;
}
public static int encodeMap(Map<?,?> valval,Appendable o) throws IOException{
int len=0;
if (o != null) {
o.append('{');
}
int index = 0;
for (Object obj : valval.keySet()) {
if (index++ > 0) {
len += 1;
if (o != null) {
o.append(",");
}
}
String key=obj.toString();
if (o != null) {
o.append('"').append(key).append("\":");
}
len += 3 + key.length();
len += encode(valval.get(obj), o);
}
if (o != null) {
o.append('}');
}
len += 2;
return len;
}
public static int encodeRec(Rec val,Appendable o) throws IOException{
int len=0;
if (o != null) {
o.append(val.isArray()?"[":"{");
}
for (int i=0;i<val.count();i++) {
Slot k=val.getSlot(i);
Object v=val.get(i);
if (i > 0) {
len += 1;
if (o != null) {
o.append(",");
}
}
if(k!=null){
String key=k.getName();
if (o != null) {
o.append('"').append(key).append("\":");
}
len += 3 + key.length();
}
len += encode(v, o);
}
if (o != null) {
o.append(val.isArray()?"]":"}");
}
len += 2;
return len;
}
/**
* @param str
* @return true if the string includes any of the special chars.
*/
public static boolean needsEscaping(String str) {
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
switch (ch) {
case '"':
case '\\':
case '/':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
return true;
}
}
return false;
}
/**
* this helper method handle quotes and control chars.
* @param str input string
* @return output after encoding special chars
*/
public static String escape(String str) {
StringBuilder buf = null;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
switch (ch) {
case '"':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\\"");
break;
case '\\':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\\\");
break;
case '/':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\/");
break;
case '\b':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\b");
break;
case '\f':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\f");
break;
case '\n':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\n");
break;
case '\r':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\r");
break;
case '\t':
if(buf==null) buf=new StringBuilder(str.substring(0,i));
buf.append("\\t");
break;
default:
if(buf!=null) buf.append(ch);
}
}
return buf!=null?buf.toString():str;
}
}
+153
View File
@@ -0,0 +1,153 @@
package com.reliancy.rec;
import java.util.ArrayList;
import java.util.List;
/**
* Default implementation of a Rec.
* We separate keys and values because Obj could just be an array.
* If object is declated an array keys are nonexistant and rec related methods will return null or crash.
* Our setters return this object to main the calls chainable.
* Also positional calls accept negative values which reference from end backward.
*/
public class Obj implements Rec{
final List<Object> values;
final Hdr meta;
public Obj() {
values=new ArrayList<>();
meta=new Slot(null);
}
public Obj(boolean is_array) {
values=new ArrayList<>();
meta=new Slot(null);
if(is_array) meta.raiseFlags(Hdr.FLAG_ARRAY);
}
public Obj(List<Slot> k,List<Object> v) {
values=v;
meta=new Slot(null);
meta.keys.addAll(k);
}
/**
* This ctor is reserved for derivations with fixed slot definitions.
* This constructor will inspect static Slot members and construct keys that way
* if meta named.
* @param def
*/
protected Obj(Hdr def){
values=new ArrayList<>();
meta=def;
}
@Override
public String toString(){
StringBuilder buf=new StringBuilder();
toString(buf);
return buf.toString();
}
public int toString(StringBuilder buf){
boolean is_arr=isArray();
int length0=buf.length();// length before anything done
//StringBuffer indent=new StringBuffer(); // detect indent
//for(int i=length0;i>0 && Character.isWhitespace(buf.charAt(i));i--){
// indent.append(buf.codePointAt(i));
//}
buf.append(is_arr?"[":"{");
if(is_arr){
for(int pos=0;pos<count();pos++){
if(pos>0) buf.append(",");
Object val=this.get(pos);
if(val instanceof Obj) ((Obj)val).toString(buf);
else if(val!=null) buf.append(val.toString());
else buf.append("null");
}
}else{
for(int pos=0;pos<count();pos++){
if(pos>0) buf.append(",");
Slot s=getSlot(pos);
buf.append(s.getName()+":");
Object val=this.get(pos);
if(val!=null) s.toString(val,buf); else buf.append("null");
}
}
buf.append(is_arr?"]":"}");
return buf.length()-length0;
}
@Override
public Hdr meta(){
return meta;
}
@Override
public boolean isArray(){
return meta==null || meta.checkFlags(Hdr.FLAG_ARRAY);
}
@Override
public int count() {
return values.size();
}
@Override
public Rec set(int pos, Object val) {
if(pos<0) pos=count()+pos;
values.set(pos,val);
return this;
}
@Override
public Object get(int pos) {
if(pos<0) pos=count()+pos;
return values.get(pos);
}
@Override
public Rec add(Object val) {
values.add(val);
if(!isArray()) meta.addSlot(new Slot("arg"+count(),Object.class));
return this;
}
@Override
public Rec remove(int s) {
values.remove(s);
if(!isArray()) meta.removeSlot(s);
return this;
}
@Override
public Rec set(Slot s, Object val) {
if(s==null) throw new IllegalArgumentException("invalid key provided");
if(isArray()) throw new IllegalStateException("array not mappable with:"+s.getName());
int index=s.getPosition(); // try slot position
if(index<0) index=meta.findSlot(s.getName());// fall back to search if slot not set
if(index<0){
values.add(val);
meta.addSlot(s);
}else{
values.set(index,val);
meta.setSlot(index,s);
}
return this;
}
/**
* Returns value by slot key.
* If the underlying rec is a vec/array this method might work if slot is positioned else it will
* return def value.
*/
@Override
public Object get(Slot s, Object def) {
if(s==null) throw new IllegalArgumentException("invalid key provided");
//if(keys==null) throw new IllegalStateException("array not mappable with:"+s.getName());
int index=s.getPosition(); // try slot position
if(index<0 && !isArray()) index=meta.findSlot(s.getName());// fall back to search if slot not set
return index<0?def:values.get(index);
}
@Override
public Rec remove(Slot s) {
int index=s.getPosition(); // try slot position
if(index<0 && !isArray()) index=meta.findSlot(s.getName());// fall back to search if slot not set
if(index>=0) remove(index);
return this;
}
}
+20
View File
@@ -0,0 +1,20 @@
package com.reliancy.rec;
/**
* A record representation like in JSON.
* This is either an array or a map of fields.
* Each field definition we call a slot.
*/
public interface Rec extends Vec{
public Rec set(Slot s,Object val);
public Object get(Slot s,Object def);
public Rec remove(Slot s);
public default Slot getSlot(String name){
Hdr m=meta();
return m!=null?m.getSlot(name):null;
}
public default Slot getSlot(int pos){
Hdr m=meta();
return m!=null?m.getSlot(pos):null;
}
}
+60
View File
@@ -0,0 +1,60 @@
package com.reliancy.rec;
/**
* Slot is a definition of a value start with the name.
* We use it to define columns/fields of records.
* It is also used as header of actual records.
*/
public class Slot extends Hdr {
public static interface Initializer{
Object getInitalValue(Slot s,Rec rec);
}
public static final Initializer DEFAULT_INITIALIZER=new Initializer(){
public Object getInitalValue(Slot s,Rec rec) {return s.getDefaultValue();}
};
int position;
Object defaultValue;
Initializer initValue;
public Slot(String name){
this(name,Object.class);
}
public Slot(String name,Class<?> type){
super(name,type);
this.position=-1;
this.initValue=DEFAULT_INITIALIZER;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public Object getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
}
public Initializer getInitValue() {
return initValue;
}
public void setInitValue(Initializer initValue) {
this.initValue = initValue;
}
public int toString(Object val, StringBuilder buf) {
int length0=buf.length();
if(val instanceof Obj) ((Obj)val).toString(buf);
else if(val!=null) buf.append(val.toString());
else buf.append("null");
return buf.length()-length0;
}
public Object get(Rec r,Object def){
return r.get(this, def);
}
public Slot set(Rec r,Object val){
r.set(this, val);
return this;
}
}
@@ -0,0 +1,17 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.reliancy.rec;
/** An interface used in parser implementation.
*
* @author amer
*/
public interface TextDecoder {
void beginDocument(Rec init);
Rec endDocument();
public int parse(int offset,CharSequence in);
}
+18
View File
@@ -0,0 +1,18 @@
package com.reliancy.rec;
/**
* dimensioned container of values.
* Our setters return this object to make the calls chainable.
* Also positional calls accept negative values which reference from end backward.
*
*/
public interface Vec {
public default boolean isArray(){
return meta().checkFlags(Hdr.FLAG_ARRAY);
}
public Hdr meta();
public int count();
public Rec set(int pos,Object val);
public Object get(int pos);
public Rec add(Object val);
public Rec remove(int s);
}