// Copyright 2001-2004, FreeHEP.
package org.freehep.postscript;
/**
* Type, Attribute and Conversion Operators for PostScript Processor
*
* @author Mark Donszelmann
* @version $Id: ConversionOperator.java 8958 2006-09-12 23:37:43Z duns $
*/
public class ConversionOperator extends PSOperator {
public static Class[] operators = {
Type.class, CvLit.class, CvX.class, XCheck.class,
ExecuteOnly.class, NoAccess.class, ReadOnly.class,
RCheck.class, WCheck.class, CvI.class, CvN.class,
CvR.class, CvRS.class, CvS.class
};
public boolean execute(OperandStack os) {
throw new RuntimeException("Cannot execute class: "+getClass());
}
}
class Type extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class}; }
public boolean execute(OperandStack os) {
PSObject o = os.popObject();
os.push(new PSName(o.getType()));
return true;
}
}
class CvLit extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class}; }
public boolean execute(OperandStack os) {
PSObject o = os.popObject();
o.setLiteral();
os.push(o);
return true;
}
}
class CvX extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class}; }
public boolean execute(OperandStack os) {
PSObject o = os.popObject();
o.setExecutable();
os.push(o);
return true;
}
}
class XCheck extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class}; }
public boolean execute(OperandStack os) {
PSObject o = os.popObject();
os.push(o.isExecutable());
return true;
}
}
class ExecuteOnly extends ConversionOperator {
{ operandTypes = new Class[] {PSComposite.class}; }
public boolean execute(OperandStack os) {
PSComposite o = os.popComposite();
o.changeAccess(PSComposite.EXECUTE_ONLY);
os.push(o);
return true;
}
}
class NoAccess extends ConversionOperator {
{ operandTypes = new Class[] {PSComposite.class}; }
public boolean execute(OperandStack os) {
PSComposite o = os.popComposite();
// FIXME: handle dictionary case
// FIXME: handle InvalidAccess
o.changeAccess(PSComposite.NONE);
os.push(o);
return true;
}
}
class ReadOnly extends ConversionOperator {
{ operandTypes = new Class[] {PSComposite.class}; }
public boolean execute(OperandStack os) {
PSComposite o = os.popComposite();
// FIXME: handle dictionary case
o.changeAccess(PSComposite.READ_ONLY);
os.push(o);
return true;
}
}
class RCheck extends ConversionOperator {
{ operandTypes = new Class[] {PSComposite.class}; }
public boolean execute(OperandStack os) {
PSComposite o = os.popComposite();
os.push(o.accessRead());
return true;
}
}
class WCheck extends ConversionOperator {
{ operandTypes = new Class[] {PSComposite.class}; }
public boolean execute(OperandStack os) {
PSComposite o = os.popComposite();
os.push(o.accessWrite());
return true;
}
}
class CvI extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class}; }
public boolean execute(OperandStack os) {
try {
if (os.checkType(PSNumber.class)) {
PSNumber n = os.popNumber();
os.push(n.getInt());
} else if (os.checkType(PSString.class)) {
PSString s = os.popString();
PSNumber n = PSUtils.parseNumber(s.getValue());
os.push(n.getInt());
} else {
error(os, new TypeCheck());
}
} catch (NumberFormatException e) {
error(os, new UndefinedResult());
} catch (RangeException e) {
error(os, new RangeCheck());
}
return true;
}
}
class CvN extends ConversionOperator {
{ operandTypes = new Class[] {PSString.class}; }
public boolean execute(OperandStack os) {
PSString s = os.popString();
os.push(new PSName(s.getValue(), s.isLiteral()));
return true;
}
}
class CvR extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class}; }
public boolean execute(OperandStack os) {
if (os.checkType(PSNumber.class)) {
PSNumber n = os.popNumber();
os.push(n.getDouble());
} else if (os.checkType(PSString.class)) {
PSString s = os.popString();
try {
PSNumber n = PSUtils.parseNumber(s.getValue());
os.push(n.getDouble());
} catch (NumberFormatException e) {
error(os, new UndefinedResult());
}
} else {
error(os, new TypeCheck());
}
return true;
}
}
class CvRS extends ConversionOperator {
{ operandTypes = new Class[] {PSNumber.class, PSInteger.class, PSString.class}; }
public boolean execute(OperandStack os) {
try {
PSString s = os.popString();
PSInteger r = os.popInteger();
PSNumber n = os.popNumber();
byte[] b;
if (r.getValue() == 10) {
b = n.cvs().getBytes();
} else {
b = Integer.toString(n.getInt(), r.getValue()).getBytes();
}
if (b.length > s.size()) {
error(os, new RangeCheck());
} else {
for (int i=0; i<b.length; i++) {
s.set(i, b[i]);
}
os.push(s.subString(0, b.length));
}
} catch (RangeException e) {
error(os, new RangeCheck());
}
return true;
}
}
class CvS extends ConversionOperator {
{ operandTypes = new Class[] {PSObject.class, PSString.class}; }
public boolean execute(OperandStack os) {
PSString s = os.popString();
PSObject o = os.popObject();
byte[] b = o.cvs().getBytes();
if (b.length > s.size()) {
error(os, new RangeCheck());
} else {
for (int i=0; i<b.length; i++) {
s.set(i, b[i]);
}
os.push(s.subString(0, b.length));
}
return true;
}
}