1 4 package gnu.kawa.xml; 5 import gnu.bytecode.*; 6 import gnu.mapping.Procedure; 7 import gnu.lists.*; 8 import java.io.*; 9 import gnu.expr.*; 10 import gnu.xml.*; 11 12 18 19 public class NodeType extends ObjectType implements TypeValue, NodePredicate, Externalizable 20 { 21 public static final int TEXT_OK = 1; 22 public static final int GROUP_OK = 2; 23 public static final int ATTRIBUTE_OK = 4; 24 public static final int DOCUMENT_OK = 8; 25 public static final int COMMENT_OK = 16; 26 public static final int PI_OK = 32; 27 int kinds = -1; 28 29 public NodeType(String name, int kinds) 30 { 31 super(name); 32 this.kinds = kinds; 33 } 34 35 public NodeType(String name) 36 { 37 this(name, -1); 38 } 39 40 public void emitCoerceFromObject (CodeAttr code) 41 { 42 code.emitPushInt(kinds); 43 code.emitInvokeStatic(coerceMethod); 44 } 45 46 public Object coerceFromObject (Object obj) 47 { 48 return coerceForce(obj, kinds); 49 } 50 51 public Type getImplementationType() 52 { 53 return typeKNode; 54 } 55 56 public int compare(Type other) 57 { 58 return getImplementationType().compare(other); 59 } 60 61 public boolean isInstance (Object obj) 62 { 63 if (obj instanceof KNode) 64 { 65 KNode pos = (KNode) obj; 66 return isInstancePos(pos.sequence, pos.getPos()); 67 } 68 return false; 69 } 70 71 public boolean isInstancePos(AbstractSequence seq, int ipos) 72 { 73 return isInstance(seq, ipos, kinds); 74 } 75 76 public static boolean isInstance(AbstractSequence seq, int ipos, int kinds) 77 { 78 int kind = seq.getNextKind(ipos); 79 if (kinds < 0) 80 return kind != Sequence.EOF_VALUE; 81 else 82 { 83 switch (kind) 84 { 85 case Sequence.EOF_VALUE: 86 return false; 87 case Sequence.INT_U8_VALUE: 88 case Sequence.INT_S8_VALUE: 89 case Sequence.INT_U16_VALUE: 90 case Sequence.INT_S16_VALUE: 91 case Sequence.INT_U32_VALUE: 92 case Sequence.INT_S32_VALUE: 93 case Sequence.INT_U64_VALUE: 94 case Sequence.INT_S64_VALUE: 95 case Sequence.FLOAT_VALUE: 96 case Sequence.DOUBLE_VALUE: 97 case Sequence.BOOLEAN_VALUE: 98 case Sequence.TEXT_BYTE_VALUE: 99 case Sequence.CHAR_VALUE: 100 case Sequence.OBJECT_VALUE: 101 return (kinds & TEXT_OK) != 0; 102 case Sequence.GROUP_VALUE: 103 return (kinds & GROUP_OK) != 0; 104 case Sequence.ATTRIBUTE_VALUE: 105 return (kinds & ATTRIBUTE_OK) != 0; 106 case Sequence.DOCUMENT_VALUE: 107 return (kinds & DOCUMENT_OK) != 0; 108 case Sequence.COMMENT_VALUE: 109 return (kinds & COMMENT_OK) != 0; 110 case Sequence.PROCESSING_INSTRUCTION_VALUE: 111 return (kinds & PI_OK) != 0; 112 } 113 } 114 return true; 115 } 116 117 public static KNode coerceForce(Object obj, int kinds) 118 { 119 KNode pos = coerceOrNull(obj, kinds); 120 if (pos == null) 121 throw new ClassCastException ("coerce from "+obj.getClass()); 122 return pos; 123 } 124 125 public static KNode coerceOrNull(Object obj, int kinds) 126 { 127 KNode pos; 128 if (obj instanceof NodeTree) 129 pos = KNode.make((NodeTree) obj); 130 else if (obj instanceof KNode) 131 pos = (KNode) obj; 132 else 133 return null; 134 return isInstance(pos.sequence, pos.ipos, kinds) ? pos : null; 135 } 136 137 protected void emitCoerceOrNullMethod(Variable incoming, 138 Compilation comp) 139 { 140 CodeAttr code = comp.getCode(); 141 if (incoming != null) 142 code.emitLoad(incoming); 143 code.emitPushInt(kinds); 144 code.emitInvokeStatic(coerceOrNullMethod); 145 } 146 147 public void emitTestIf(Variable incoming, Declaration decl, Compilation comp) 148 { 149 CodeAttr code = comp.getCode(); 150 emitCoerceOrNullMethod(incoming, comp); 151 if (decl != null) 152 { 153 code.emitDup(); 154 decl.compileStore(comp); 155 } 156 code.emitIfNotNull(); 157 } 158 159 public void emitIsInstance(Variable incoming, 160 Compilation comp, Target target) 161 { 162 if (target instanceof ConditionalTarget) 163 { 164 ConditionalTarget ctarget = (ConditionalTarget) target; 165 emitCoerceOrNullMethod(incoming, comp); 166 CodeAttr code = comp.getCode(); 167 if (ctarget.trueBranchComesFirst) 168 code.emitGotoIfCompare1(ctarget.ifFalse, 198); else 170 code.emitGotoIfCompare1(ctarget.ifTrue, 199); ctarget.emitGotoFirstBranch(code); 172 } 173 else 174 gnu.kawa.reflect.InstanceOf.emitIsInstance(this, incoming, comp, target); 175 } 176 177 public static final ClassType typeKNode = ClassType.make("gnu.kawa.xml.KNode"); 178 public static final ClassType typeNodeType = ClassType.make("gnu.kawa.xml.NodeType"); 179 public static final NodeType nodeType = new NodeType("gnu.kawa.xml.KNode"); 180 static final Method coerceMethod 181 = typeNodeType.getDeclaredMethod("coerceForce", 2); 182 static final Method coerceOrNullMethod 183 = typeNodeType.getDeclaredMethod("coerceOrNull", 2); 184 185 public Procedure getConstructor () 186 { 187 return null; 188 } 189 190 public String toString () 191 { 192 return "NodeType " + getName(); 193 } 194 195 public void writeExternal(ObjectOutput out) throws IOException 196 { 197 String name = getName(); 198 out.writeUTF(name == null ? "" : name); 199 out.writeInt(kinds); 200 } 201 202 public void readExternal(ObjectInput in) 203 throws IOException, ClassNotFoundException 204 { 205 String name = in.readUTF(); 206 if (name.length() > 0) 207 setName(name); 208 kinds = in.readInt(); 209 } 210 211 public static final NodeType documentNodeTest = 212 new NodeType("document-node", DOCUMENT_OK); 213 public static final NodeType textNodeTest = 214 new NodeType("text", TEXT_OK); 215 public static final NodeType commentNodeTest = 216 new NodeType("comment", COMMENT_OK); 217 public static final NodeType anyNodeTest = 218 new NodeType("node"); 219 } 220 | Popular Tags |