01: // Copyright (c) 2003, 2004 Per M.A. Bothner
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.kawa.xml;
05:
06: import gnu.mapping.*;
07: import gnu.lists.*;
08: import gnu.expr.*;
09: import gnu.bytecode.*;
10: import gnu.xml.*;
11:
12: public class MakeText extends NodeConstructor {
13: public static final MakeText makeText = new MakeText();
14:
15: public int numArgs() {
16: return 0x1001;
17: }
18:
19: public Object apply1(Object arg) {
20: if (arg == null
21: || (arg instanceof Values && ((Values) arg).isEmpty()))
22: return arg;
23: NodeTree node = new NodeTree();
24: TextUtils.textValue(arg, new XMLFilter(node));
25: return KText.make(node);
26: }
27:
28: public static void text$X(Object arg, CallContext ctx) {
29: if (arg == null
30: || (arg instanceof Values && ((Values) arg).isEmpty()))
31: return;
32: Consumer saved = ctx.consumer;
33: Consumer out = NodeConstructor.pushNodeContext(ctx);
34: try {
35: TextUtils.textValue(arg, out);
36: } finally {
37: NodeConstructor.popNodeContext(saved, ctx);
38: }
39: }
40:
41: public void apply(CallContext ctx) {
42: text$X(ctx.getNextArg(null), ctx);
43: }
44:
45: public void compile(ApplyExp exp, Compilation comp, Target target) {
46: // We can't use NodeConstructor's compile method, because a node
47: // constructor may return a non-node when given an empty sequence. Sigh.
48: ApplyExp.compile(exp, comp, target);
49: }
50:
51: public void compileToNode(ApplyExp exp, Compilation comp,
52: ConsumerTarget target) {
53: // This only gets called via NodeConstructor's compileChild.
54: CodeAttr code = comp.getCode();
55: Expression[] args = exp.getArgs();
56: Expression texp = args[0];
57: Variable cvar = target.getConsumerVariable();
58: if (texp instanceof QuoteExp) {
59: Object tval = ((QuoteExp) texp).getValue();
60: if (tval instanceof String) {
61: String str = (String) tval;
62: String segments = CodeAttr.calculateSplit(str);
63: int numSegments = segments.length();
64: ClassType ctype = (ClassType) cvar.getType();
65: Method writer = ctype.getMethod("write",
66: new Type[] { Type.string_type });
67: int segStart = 0;
68: for (int seg = 0; seg < numSegments; seg++) {
69: code.emitLoad(cvar);
70: int segEnd = segStart + (int) segments.charAt(seg);
71: code
72: .emitPushString(str.substring(segStart,
73: segEnd));
74: code.emitInvoke(writer);
75: segStart = segEnd;
76: }
77: return;
78: }
79: }
80: texp.compile(comp, Target.pushObject);
81: code.emitLoad(cvar);
82: code.emitInvokeStatic(ClassType.make("gnu.xml.TextUtils")
83: .getDeclaredMethod("textValue", 2));
84: }
85: }
|