private long byteCount;
- /**
- * Standard constructor
- */
- protected GeneralDigest()
- {
- xBuf = new byte[4];
- xBufOff = 0;
- }
-
- /**
- * Copy constructor. We are using copy constructors in place
- * of the Object.clone() interface as this interface is not
- * supported by J2ME.
- */
- protected GeneralDigest(GeneralDigest t)
- {
+ /**
+ * Standard constructor
+ */
+ protected GeneralDigest()
+ {
+ xBuf = new byte[4];
+ xBufOff = 0;
+ }
+
+ /**
+ * Copy constructor. We are using copy constructors in place
+ * of the Object.clone() interface as this interface is not
+ * supported by J2ME.
+ */
+ protected GeneralDigest(GeneralDigest t)
+ {
xBuf = new byte[t.xBuf.length];
- System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
+ System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
- xBufOff = t.xBufOff;
- byteCount = t.byteCount;
- }
+ xBufOff = t.xBufOff;
+ byteCount = t.byteCount;
+ }
public void update(
byte in)
byteCount = 0;
xBufOff = 0;
- for ( int i = 0; i < xBuf.length; i++ ) {
- xBuf[i] = 0;
- }
+ for ( int i = 0; i < xBuf.length; i++ ) {
+ xBuf[i] = 0;
+ }
}
protected abstract void processWord(byte[] in, int inOff);
-package org.bouncycastle.crypto.digests;\r
+package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.Digest;
/**
* implementation of MD2
* as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992
*/
-public class MD2Digest\r
- implements Digest\r
-{\r
- private static final int DIGEST_LENGTH = 16;\r
-\r
- /* X buffer */\r
- private byte[] X = new byte[48];\r
+public class MD2Digest
+ implements Digest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ /* X buffer */
+ private byte[] X = new byte[48];
private int xOff;
-\r /* M buffer */
-\r private byte[] M = new byte[16];\r
+ /* M buffer */
+ private byte[] M = new byte[16];
private int mOff;
-\r /* check sum */
-\r private byte[] C = new byte[16];
+ /* check sum */
+ private byte[] C = new byte[16];
private int COff;
- public MD2Digest()\r
- {\r
- reset();\r
- }\r
- public MD2Digest(MD2Digest t)\r
- {
- System.arraycopy(t.X, 0, X, 0, t.X.length);
- xOff = t.xOff;
- System.arraycopy(t.M, 0, M, 0, t.M.length);
- mOff = t.mOff;
- System.arraycopy(t.C, 0, C, 0, t.C.length);
- COff = t.COff;
- }
- /**\r
+ public MD2Digest()
+ {
+ reset();
+ }
+ public MD2Digest(MD2Digest t)
+ {
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ System.arraycopy(t.M, 0, M, 0, t.M.length);
+ mOff = t.mOff;
+ System.arraycopy(t.C, 0, C, 0, t.C.length);
+ COff = t.COff;
+ }
+ /**
* return the algorithm name
*
* @return the algorithm name
*
* @return the size, in bytes, of the digest produced by this message digest.
*/
- public int getDigestSize()
+ public int getDigestSize()
{
return DIGEST_LENGTH;
}
* @param out the array the digest is to be copied into.
* @param outOff the offset into the out array the digest is to start at.
*/
- public int doFinal(byte[] out, int outOff)
+ public int doFinal(byte[] out, int outOff)
{
// add padding
byte paddingByte = (byte)(M.length-mOff);
/**
* reset the digest back to it's initial state.
*/
- public void reset()\r
- {\r
- xOff = 0;\r
+ public void reset()
+ {
+ xOff = 0;
for (int i = 0; i != X.length; i++)
{
X[i] = 0;
}
- mOff = 0;\r
+ mOff = 0;
for (int i = 0; i != M.length; i++)
{
M[i] = 0;
}
- COff = 0;\r
+ COff = 0;
for (int i = 0; i != C.length; i++)
{
C[i] = 0;
}
- }\r
- /**\r
+ }
+ /**
* update the message digest with a single byte.
*
* @param in the input byte to be entered.
*/
- public void update(byte in)
+ public void update(byte in)
{
M[mOff++] = in;
* @param inOff the offset into the byte array where the data starts.
* @param len the length of the data.
*/
- public void update(byte[] in, int inOff, int len)\r
- {\r
- //\r
+ public void update(byte[] in, int inOff, int len)
+ {
+ //
// fill the current word
//
while ((mOff != 0) && (len > 0))
update(in[inOff]);
inOff++;
len--;
- }\r
- }\r
- protected void processCheckSum(byte[] m)\r
- {\r
- int L = C[15];\r
- for (int i=0;i<16;i++)\r
- {\r
- C[i] ^= S[(m[i] ^ L) & 0xff];\r
- L = C[i];\r
- }\r
- }\r
- protected void processBlock(byte[] m)\r
+ }
+ }
+ protected void processCheckSum(byte[] m)
+ {
+ int L = C[15];
+ for (int i=0;i<16;i++)
+ {
+ C[i] ^= S[(m[i] ^ L) & 0xff];
+ L = C[i];
+ }
+ }
+ protected void processBlock(byte[] m)
{
for (int i=0;i<16;i++)
{
}
}
// 256-byte random permutation constructed from the digits of PI
- private static final byte[] S = {\r
- (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124,\r
- (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240,\r
- (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192,\r
- (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217,\r
- (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87,\r
- (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66,\r
- (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190,\r
- (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73,\r
- (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238,\r
- (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178,\r
- (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11,\r
- (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154,\r
- (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204,\r
- (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25,\r
- (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215,\r
- (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198,\r
- (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125,\r
- (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116,\r
- (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100,\r
- (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101,\r
- (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37,\r
- (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70,\r
- (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85,\r
- (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58,\r
- (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234,\r
- (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40,\r
- (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65,\r
- (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200,\r
- (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123,\r
- (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136,\r
- (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233,\r
- (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57,\r
- (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208,\r
- (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117,\r
- (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143,\r
- (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51,\r
- (byte)159,(byte)17,(byte)131,(byte)20\r
- };\r
-}\r
+ private static final byte[] S = {
+ (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124,
+ (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240,
+ (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192,
+ (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217,
+ (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87,
+ (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66,
+ (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190,
+ (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73,
+ (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238,
+ (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178,
+ (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11,
+ (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154,
+ (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204,
+ (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25,
+ (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215,
+ (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198,
+ (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125,
+ (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116,
+ (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100,
+ (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101,
+ (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37,
+ (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70,
+ (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85,
+ (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58,
+ (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234,
+ (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40,
+ (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65,
+ (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200,
+ (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123,
+ (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136,
+ (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233,
+ (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57,
+ (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208,
+ (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117,
+ (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143,
+ (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51,
+ (byte)159,(byte)17,(byte)131,(byte)20
+ };
+}
private int[] X = new int[16];
private int xOff;
- /**
- * Standard constructor
- */
+ /**
+ * Standard constructor
+ */
public MD5Digest()
{
reset();
}
- /**
- * Copy constructor. This will copy the state of the provided
- * message digest.
- */
- public MD5Digest(MD5Digest t)
- {
- super(t);
-
- H1 = t.H1;
- H2 = t.H2;
- H3 = t.H3;
- H4 = t.H4;
-
- System.arraycopy(t.X, 0, X, 0, t.X.length);
- xOff = t.xOff;
- }
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public MD5Digest(MD5Digest t)
+ {
+ super(t);
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
public String getAlgorithmName()
{
private int[] X = new int[80];
private int xOff;
- /**
- * Standard constructor
- */
+ /**
+ * Standard constructor
+ */
public SHA1Digest()
{
reset();
}
- /**
- * Copy constructor. This will copy the state of the provided
- * message digest.
- */
- public SHA1Digest(SHA1Digest t)
- {
- super(t);
-
- H1 = t.H1;
- H2 = t.H2;
- H3 = t.H3;
- H4 = t.H4;
- H5 = t.H5;
-
- System.arraycopy(t.X, 0, X, 0, t.X.length);
- xOff = t.xOff;
- }
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public SHA1Digest(SHA1Digest t)
+ {
+ super(t);
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+ H5 = t.H5;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
public String getAlgorithmName()
{
import org.bouncycastle.crypto.CipherParameters;
public class AsymmetricKeyParameter
- implements CipherParameters
+ implements CipherParameters
{
boolean privateKey;
import org.bouncycastle.crypto.CipherParameters;
public class KeyParameter
- implements CipherParameters
+ implements CipherParameters
{
private byte[] key;
public class Base64
{
- private static final byte[] encodingTable =
- {
- (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ private static final byte[] encodingTable =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
- (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+ (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v',
- (byte)'w', (byte)'x', (byte)'y', (byte)'z',
- (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
+ (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
(byte)'7', (byte)'8', (byte)'9',
- (byte)'+', (byte)'/'
- };
-
- /**
- * encode the input data producong a base 64 encoded byte array.
- *
- * @return a byte array containing the base 64 encoded data.
- */
- public static byte[] encode(
- byte[] data)
- {
- byte[] bytes;
-
- int modulus = data.length % 3;
- if (modulus == 0)
- {
- bytes = new byte[4 * data.length / 3];
- }
- else
- {
- bytes = new byte[4 * ((data.length / 3) + 1)];
- }
+ (byte)'+', (byte)'/'
+ };
+
+ /**
+ * encode the input data producong a base 64 encoded byte array.
+ *
+ * @return a byte array containing the base 64 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ byte[] bytes;
+
+ int modulus = data.length % 3;
+ if (modulus == 0)
+ {
+ bytes = new byte[4 * data.length / 3];
+ }
+ else
+ {
+ bytes = new byte[4 * ((data.length / 3) + 1)];
+ }
int dataLength = (data.length - modulus);
- int a1, a2, a3;
- for (int i = 0, j = 0; i < dataLength; i += 3, j += 4)
- {
- a1 = data[i] & 0xff;
- a2 = data[i + 1] & 0xff;
- a3 = data[i + 2] & 0xff;
-
- bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
- bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
- bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
- bytes[j + 3] = encodingTable[a3 & 0x3f];
- }
-
- /*
- * process the tail end.
- */
- int b1, b2, b3;
- int d1, d2;
-
- switch (modulus)
- {
- case 0: /* nothing left to do */
- break;
- case 1:
- d1 = data[data.length - 1] & 0xff;
- b1 = (d1 >>> 2) & 0x3f;
- b2 = (d1 << 4) & 0x3f;
-
- bytes[bytes.length - 4] = encodingTable[b1];
- bytes[bytes.length - 3] = encodingTable[b2];
- bytes[bytes.length - 2] = (byte)'=';
- bytes[bytes.length - 1] = (byte)'=';
- break;
- case 2:
- d1 = data[data.length - 2] & 0xff;
- d2 = data[data.length - 1] & 0xff;
-
- b1 = (d1 >>> 2) & 0x3f;
- b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
- b3 = (d2 << 2) & 0x3f;
-
- bytes[bytes.length - 4] = encodingTable[b1];
- bytes[bytes.length - 3] = encodingTable[b2];
- bytes[bytes.length - 2] = encodingTable[b3];
- bytes[bytes.length - 1] = (byte)'=';
- break;
- }
-
- return bytes;
- }
-
- /*
- * set up the decoding table.
- */
- private static final byte[] decodingTable;
-
- static
- {
- decodingTable = new byte[128];
-
- for (int i = 'A'; i <= 'Z'; i++)
- {
- decodingTable[i] = (byte)(i - 'A');
- }
-
- for (int i = 'a'; i <= 'z'; i++)
- {
- decodingTable[i] = (byte)(i - 'a' + 26);
- }
-
- for (int i = '0'; i <= '9'; i++)
- {
- decodingTable[i] = (byte)(i - '0' + 52);
- }
-
- decodingTable['+'] = 62;
- decodingTable['/'] = 63;
- }
-
- /**
- * decode the base 64 encoded input data.
- *
- * @return a byte array representing the decoded data.
- */
- public static byte[] decode(
- byte[] data)
- {
- byte[] bytes;
- byte b1, b2, b3, b4;
-
- if (data[data.length - 2] == '=')
- {
- bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
- }
- else if (data[data.length - 1] == '=')
- {
- bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
- }
- else
- {
- bytes = new byte[((data.length / 4) * 3)];
- }
-
- for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3)
- {
- b1 = decodingTable[data[i]];
- b2 = decodingTable[data[i + 1]];
- b3 = decodingTable[data[i + 2]];
- b4 = decodingTable[data[i + 3]];
-
- bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[j + 2] = (byte)((b3 << 6) | b4);
- }
-
- if (data[data.length - 2] == '=')
- {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
-
- bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
- }
- else if (data[data.length - 1] == '=')
- {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- b3 = decodingTable[data[data.length - 2]];
-
- bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
- }
- else
- {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- b3 = decodingTable[data[data.length - 2]];
- b4 = decodingTable[data[data.length - 1]];
-
- bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
- }
-
- return bytes;
- }
-
- /**
- * decode the base 64 encoded String data.
- *
- * @return a byte array representing the decoded data.
- */
- public static byte[] decode(
- String data)
- {
- byte[] bytes;
- byte b1, b2, b3, b4;
-
- if (data.charAt(data.length() - 2) == '=')
- {
- bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
- }
- else if (data.charAt(data.length() - 1) == '=')
- {
- bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
- }
- else
- {
- bytes = new byte[((data.length() / 4) * 3)];
- }
-
- for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3)
- {
- b1 = decodingTable[data.charAt(i)];
- b2 = decodingTable[data.charAt(i + 1)];
- b3 = decodingTable[data.charAt(i + 2)];
- b4 = decodingTable[data.charAt(i + 3)];
-
- bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[j + 2] = (byte)((b3 << 6) | b4);
- }
-
- if (data.charAt(data.length() - 2) == '=')
- {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
-
- bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
- }
- else if (data.charAt(data.length() - 1) == '=')
- {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- b3 = decodingTable[data.charAt(data.length() - 2)];
-
- bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
- }
- else
- {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- b3 = decodingTable[data.charAt(data.length() - 2)];
- b4 = decodingTable[data.charAt(data.length() - 1)];
-
- bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
- }
-
- return bytes;
- }
+ int a1, a2, a3;
+ for (int i = 0, j = 0; i < dataLength; i += 3, j += 4)
+ {
+ a1 = data[i] & 0xff;
+ a2 = data[i + 1] & 0xff;
+ a3 = data[i + 2] & 0xff;
+
+ bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
+ bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
+ bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
+ bytes[j + 3] = encodingTable[a3 & 0x3f];
+ }
+
+ /*
+ * process the tail end.
+ */
+ int b1, b2, b3;
+ int d1, d2;
+
+ switch (modulus)
+ {
+ case 0: /* nothing left to do */
+ break;
+ case 1:
+ d1 = data[data.length - 1] & 0xff;
+ b1 = (d1 >>> 2) & 0x3f;
+ b2 = (d1 << 4) & 0x3f;
+
+ bytes[bytes.length - 4] = encodingTable[b1];
+ bytes[bytes.length - 3] = encodingTable[b2];
+ bytes[bytes.length - 2] = (byte)'=';
+ bytes[bytes.length - 1] = (byte)'=';
+ break;
+ case 2:
+ d1 = data[data.length - 2] & 0xff;
+ d2 = data[data.length - 1] & 0xff;
+
+ b1 = (d1 >>> 2) & 0x3f;
+ b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
+ b3 = (d2 << 2) & 0x3f;
+
+ bytes[bytes.length - 4] = encodingTable[b1];
+ bytes[bytes.length - 3] = encodingTable[b2];
+ bytes[bytes.length - 2] = encodingTable[b3];
+ bytes[bytes.length - 1] = (byte)'=';
+ break;
+ }
+
+ return bytes;
+ }
+
+ /*
+ * set up the decoding table.
+ */
+ private static final byte[] decodingTable;
+
+ static
+ {
+ decodingTable = new byte[128];
+
+ for (int i = 'A'; i <= 'Z'; i++)
+ {
+ decodingTable[i] = (byte)(i - 'A');
+ }
+
+ for (int i = 'a'; i <= 'z'; i++)
+ {
+ decodingTable[i] = (byte)(i - 'a' + 26);
+ }
+
+ for (int i = '0'; i <= '9'; i++)
+ {
+ decodingTable[i] = (byte)(i - '0' + 52);
+ }
+
+ decodingTable['+'] = 62;
+ decodingTable['/'] = 63;
+ }
+
+ /**
+ * decode the base 64 encoded input data.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ byte[] bytes;
+ byte b1, b2, b3, b4;
+
+ if (data[data.length - 2] == '=')
+ {
+ bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
+ }
+ else if (data[data.length - 1] == '=')
+ {
+ bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
+ }
+ else
+ {
+ bytes = new byte[((data.length / 4) * 3)];
+ }
+
+ for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3)
+ {
+ b1 = decodingTable[data[i]];
+ b2 = decodingTable[data[i + 1]];
+ b3 = decodingTable[data[i + 2]];
+ b4 = decodingTable[data[i + 3]];
+
+ bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[j + 2] = (byte)((b3 << 6) | b4);
+ }
+
+ if (data[data.length - 2] == '=')
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+
+ bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
+ }
+ else if (data[data.length - 1] == '=')
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+ b3 = decodingTable[data[data.length - 2]];
+
+ bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
+ }
+ else
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+ b3 = decodingTable[data[data.length - 2]];
+ b4 = decodingTable[data[data.length - 1]];
+
+ bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
+ }
+
+ return bytes;
+ }
+
+ /**
+ * decode the base 64 encoded String data.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ byte[] bytes;
+ byte b1, b2, b3, b4;
+
+ if (data.charAt(data.length() - 2) == '=')
+ {
+ bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
+ }
+ else if (data.charAt(data.length() - 1) == '=')
+ {
+ bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
+ }
+ else
+ {
+ bytes = new byte[((data.length() / 4) * 3)];
+ }
+
+ for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3)
+ {
+ b1 = decodingTable[data.charAt(i)];
+ b2 = decodingTable[data.charAt(i + 1)];
+ b3 = decodingTable[data.charAt(i + 2)];
+ b4 = decodingTable[data.charAt(i + 3)];
+
+ bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[j + 2] = (byte)((b3 << 6) | b4);
+ }
+
+ if (data.charAt(data.length() - 2) == '=')
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+
+ bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
+ }
+ else if (data.charAt(data.length() - 1) == '=')
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+ b3 = decodingTable[data.charAt(data.length() - 2)];
+
+ bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
+ }
+ else
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+ b3 = decodingTable[data.charAt(data.length() - 2)];
+ b4 = decodingTable[data.charAt(data.length() - 1)];
+
+ bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
+ }
+
+ return bytes;
+ }
}
/** returns the actual font that should be used to render this box */
private String font() {
- if (font != null) return font;
- if (font == null && cachedFont != null) return cachedFont;
- if (getParent() != null) return cachedFont = getParent().font();
- return cachedFont = Platform.getDefaultFont();
+ if (font != null) return font;
+ if (font == null && cachedFont != null) return cachedFont;
+ if (getParent() != null) return cachedFont = getParent().font();
+ return cachedFont = Platform.getDefaultFont();
}
/** this must be called when a box's font changes */
void fontChanged() {
- textupdate();
- for(Box b = getChild(0); b != null; b = b.nextSibling())
- if (b.font == null) {
- b.cachedFont = font();
- b.fontChanged();
- }
+ textupdate();
+ for(Box b = getChild(0); b != null; b = b.nextSibling())
+ if (b.font == null) {
+ b.cachedFont = font();
+ b.fontChanged();
+ }
}
/** This must be called when font or text is changed */
if (str.indexOf(':') == -1) {
String s = str;
byte[] b = Resources.getResource(Resources.resolve(s + ".png", null));
- if (b != null) return PNG.decode(new ByteArrayInputStream(b), str);
+ if (b != null) return PNG.decode(new ByteArrayInputStream(b), str);
b = Resources.getResource(Resources.resolve(s + ".jpeg", null));
- if (b != null) return Platform.decodeJPEG(new ByteArrayInputStream(b), str);
- return null;
+ if (b != null) return Platform.decodeJPEG(new ByteArrayInputStream(b), str);
+ return null;
} else {
Thread thread = Thread.currentThread();
ThreadMessage.newthread(new JS.Callable() {
public Object call(JS.Array args_) throws JS.Exn {
try {
- JS.Array args = new JS.Array();
- args.addElement(new Double(bytesDownloaded));
- args.addElement(new Double(contentLength));
- callback.call(args);
+ JS.Array args = new JS.Array();
+ args.addElement(new Double(bytesDownloaded));
+ args.addElement(new Double(contentLength));
+ callback.call(args);
} finally {
clear = true;
}
if (str.endsWith(".gif")) return GIF.decode(is, str);
else if (str.endsWith(".jpeg") || str.endsWith(".jpg")) return Platform.decodeJPEG(is, str);
- else return PNG.decode(is, str);
+ else return PNG.decode(is, str);
} catch (IOException e) {
if (Log.on) Log.log(Box.class, "error while trying to load an image from " + str);
if (image == null) {
if (Log.on) Log.log(Box.class, "unable to load image " + s + " at " + Context.getCurrentSourceNameAndLine());
return;
- }
+ }
if (sizetoimage) syncSizeToImage();
dirty();
}
if (surface.sizePosChangesSinceLastRender == 500) {
if (Log.on) Log.log(this, "Warning, more than 500 SizeChange/PosChange traps triggered since last complete render");
if (Log.on) Log.log(this, " interpreter is at " + Context.getCurrentSourceNameAndLine());
- /*
+ /*
try {
Trap t = sizechange ? Trap.getTrap(this, "SizeChange") : Trap.getTrap(this, "PosChange");
InterpretedJS.Callable f = (InterpretedJS.Callable)t.f;
if (Log.on) Log.log(this, "Current trap is at " + f.getSourceName() + ":" + f.getLineNumbers()[0]);
} catch (Throwable t) { }
- */
+ */
}
} else {
if (sizechange) put("SizeChange", Boolean.TRUE);
* WARNING: O(n) runtime, unless i == numChildren()
*/
public void put(int i, Object value) {
- if (i < 0) return;
+ if (i < 0) return;
if (value != null && !(value instanceof Box)) {
if (Log.on) Log.log(this, "attempt to set a numerical property on a box to anything other than a box at " + Context.getCurrentSourceNameAndLine());
for(Box cur = newnode.getParent(); cur != null; cur = cur.getParent())
if (cur.redirect == newnode) {
if (Log.on) Log.log(this, "attempt to move a box that is the target of a redirect at "+
- Context.getCurrentSourceNameAndLine());
+ Context.getCurrentSourceNameAndLine());
return;
}
for(Box cur = this; cur != null; cur = cur.getParent())
if (cur == newnode) {
if (Log.on) Log.log(this, "attempt to make a node a parent of its own ancestor at " +
- Context.getCurrentSourceNameAndLine());
+ Context.getCurrentSourceNameAndLine());
if (Log.on) Log.log(this, "box == " + this + " ancestor == " + newnode);
return;
}
public Object get(Object name) { return get(name, false); }
public Object get(Object name_, boolean ignoretraps) {
- if (name_ instanceof Number) return get(((Number)name_).intValue());
+ if (name_ instanceof Number) return get(((Number)name_).intValue());
- String name = (String)name_;
+ String name = (String)name_;
if (name.equals("")) return null;
// See if we're reading back the function value of a trap
public void put(Object name, Object value) { put(name, value, false, null); }
public void put(Object name, Object value, boolean ignoretraps) { put(name, value, ignoretraps, null); }
public void put(Object name_, Object value, boolean ignoretraps, RootProxy rp) {
- if (name_ instanceof Number) { put(((Number)name_).intValue(), value); return; }
- String name = (String)name_;
- if (name == null) return; // FIXME, shouldn't be necessary
+ if (name_ instanceof Number) { put(((Number)name_).intValue(), value); return; }
+ String name = (String)name_;
+ if (name == null) return; // FIXME, shouldn't be necessary
if (name.startsWith("xwt_")) {
if (Log.on) Log.log(this, "attempt to set reserved property " + name + " at " + Context.getCurrentSourceNameAndLine());
return;
- }
+ }
if (!ignoretraps && traps != null) {
Trap t = (Trap)traps.get(name);
if (t != null) {
JS.Array arg = new JS.Array();
- arg.addElement(value);
+ arg.addElement(value);
t.perform(arg);
arg.setElementAt(null, 0);
return;
if (name.charAt(0) == '_') {
if (value != null && !(value instanceof JS.Callable)) {
if (Log.on) Log.log(this, "attempt to put a non function value (" + value + ") to " +
- name + " at " + Context.getCurrentSourceNameAndLine());
- } else if (value != null && !(value instanceof JS.CompiledFunction)) {
+ name + " at " + Context.getCurrentSourceNameAndLine());
+ } else if (value != null && !(value instanceof JS.CompiledFunction)) {
if (Log.on) Log.log(this, "attempt to put a non-compiled function value (" + value + ") to " +
- name + " at " + Context.getCurrentSourceNameAndLine());
+ name + " at " + Context.getCurrentSourceNameAndLine());
} else if (name.charAt(1) == '_') {
name = name.substring(2).intern();
Trap t = Trap.getTrap(this, name);
return;
}
- super.put(name, value);
+ super.put(name, value);
// a bit of a hack, since titlebar is the only 'special' property stored in JSObject
if (getParent() == null && surface != null) {
/** remove this node from its parent; INVARIANT: whenever the parent of a node is changed, remove() gets called. */
public void remove() {
- cachedFont = null;
+ cachedFont = null;
if (parent == null) {
if (surface != null) surface.dispose(true);
return;
public String toString() { return "ByteStream, source=" + (file == null ? "memory" : file.getAbsolutePath()); }
public Object get(Object name) {
- if (name.equals("getUTF")) return getUTF;
+ if (name.equals("getUTF")) return getUTF;
else if (name.equals("getDOM")) return getDOM;
else if (name.equals("fileName")) return file == null ? null : file.getAbsolutePath();
else return null;
if (Platform.detectProxy() == null) throw new HTTPException("could not resolve hostname \"" + host + "\" and no proxy configured");
if (Log.on) Log.log(this, " could not resolve host " + host + "; using xmlrpc.xwt.org to ensure security");
try {
- JS.Array args = new JS.Array();
- args.addElement(host);
+ JS.Array args = new JS.Array();
+ args.addElement(host);
Object ret = new XMLRPC("http://xmlrpc.xwt.org/RPC2/", "dns.resolve").call(args);
if (ret == null || !(ret instanceof String)) throw new Exception(" xmlrpc.xwt.org returned non-String: " + ret);
resolvedHosts.put(host, ret);
if (Log.verbose) Log.log(this, "evaluating PAC script");
String pac = null;
try {
- org.xwt.js.JS.Array args = new org.xwt.js.JS.Array();
- args.addElement(url.toString());
- args.addElement(url.getHost());
+ org.xwt.js.JS.Array args = new org.xwt.js.JS.Array();
+ args.addElement(url.toString());
+ args.addElement(url.getHost());
Object obj = pacFunc.call(args);
if (Log.verbose) Log.log(this, " PAC script returned \"" + obj + "\"");
pac = obj.toString();
this.length = length == -1 ? 0 : length;
}
- public boolean markSupported() { return false; }
- public int read(byte[] b) throws IOException { return read(b, 0, b.length); }
- public long skip(long n) throws IOException { return read(null, -1, (int)n); }
- public int available() throws IOException {
- if (contentLength == -1) return java.lang.Math.min(super.available(), length);
- return super.available();
- }
+ public boolean markSupported() { return false; }
+ public int read(byte[] b) throws IOException { return read(b, 0, b.length); }
+ public long skip(long n) throws IOException { return read(null, -1, (int)n); }
+ public int available() throws IOException {
+ if (contentLength == -1) return java.lang.Math.min(super.available(), length);
+ return super.available();
+ }
- public int read() throws IOException {
- byte[] b = new byte[1];
- int ret = read(b, 0, 1);
- return ret == -1 ? -1 : b[0] & 0xff;
- }
+ public int read() throws IOException {
+ byte[] b = new byte[1];
+ int ret = read(b, 0, 1);
+ return ret == -1 ? -1 : b[0] & 0xff;
+ }
private void readChunk() throws IOException {
if (chunkedDone) return;
boolean good = false;
try {
if (length == 0 && contentLength == -1) {
- readChunk();
- if (chunkedDone) { good = true; return -1; }
- } else {
- if (length == 0) { good = true; return -1; }
- }
+ readChunk();
+ if (chunkedDone) { good = true; return -1; }
+ } else {
+ if (length == 0) { good = true; return -1; }
+ }
if (len > length) len = length;
int ret = b == null ? (int)super.skip(len) : super.read(b, off, len);
- if (ret >= 0) {
- length -= ret;
- good = true;
- }
+ if (ret >= 0) {
+ length -= ret;
+ good = true;
+ }
return ret;
} finally {
if (!good) invalid = true;
ThreadMessage.newthread(new JS.Callable() {
public Object call(JS.Array args) throws JS.Exn {
new Box(initialTemplate_f, null);
- doneInitializing = true;
- if (Surface.allSurfaces.size() == 0) {
- Log.log(this, "exiting because all surfaces are gone");
- Platform.exit();
- }
+ doneInitializing = true;
+ if (Surface.allSurfaces.size() == 0) {
+ Log.log(this, "exiting because all surfaces are gone");
+ Platform.exit();
+ }
return null;
}
});
} else {
where = org.xwt.js.Context.getSourceNameAndLineForThread(MessageQueue.singleton);
what = "script";
- }
- long howlong = (System.currentTimeMillis() - t) / 1000;
- if (howlong >= 5)
- if (Log.on) Log.log(this, "note: executing same " + what + " for " + howlong + "s" + " at " + where);
+ }
+ long howlong = (System.currentTimeMillis() - t) / 1000;
+ if (howlong >= 5)
+ if (Log.on) Log.log(this, "note: executing same " + what + " for " + howlong + "s" + " at " + where);
} else {
m = MessageQueue.currentlyPerforming;
t = System.currentTimeMillis();
};
}
- /** Called once XWT is initialized and the application is running. */
- protected void _running() {}
+ /** Called once XWT is initialized and the application is running. */
+ protected void _running() {}
/** quits XWT */
protected void _exit() { System.exit(0); }
/** returns an InputStream to the builtin xwar */
protected InputStream _getBuiltinInputStream() {
- return Platform.class.getClassLoader().getResourceAsStream("org/xwt/builtin.xwar");
+ return Platform.class.getClassLoader().getResourceAsStream("org/xwt/builtin.xwar");
}
/** returns the value of the environment variable key, or null if no such key exists */
/** returns an InputStream to the builtin xwar */
public static InputStream getBuiltinInputStream() { return platform._getBuiltinInputStream(); }
-
+
/** creates and returns a picture */
public static Picture createPicture(ImageDecoder i) { return platform._createPicture(i.getData(), i.getWidth(), i.getHeight()); }
platform._newBrowserWindow(url);
}
- /** Called once XWT is initialized and the application is running. */
- public static void running() {
- Log.log(Platform.class, "XWT is running");
- platform._running();
- }
-
+ /** Called once XWT is initialized and the application is running. */
+ public static void running() {
+ Log.log(Platform.class, "XWT is running");
+ platform._running();
+ }
+
/** quits XWT */
public static void exit() {
Log.log(Platform.class, "exiting via Platform.exit()");
}
public static synchronized ImageDecoder decodeJPEG(InputStream is, String name) {
- return platform._decodeJPEG(is, name);
+ return platform._decodeJPEG(is, name);
}
// Helpful font parsing stuff //////////////////////////////////////////////////////
if (Log.on) Log.log(Proxy.class, script);
}
- JS.CompiledFunction scr = JS.parse("PAC script at " + url, 0, new StringReader(script));
+ JS.CompiledFunction scr = JS.parse("PAC script at " + url, 0, new StringReader(script));
scr.call(new JS.Array(), proxyAutoConfigRootScope);
return (JS.Callable)proxyAutoConfigRootScope.get("FindProxyForURL");
} catch (Exception e) {
if (Log.on) {
Log.log(Platform.class, "WPAD detection failed due to:");
if (e instanceof JS.Exn) {
- try {
- org.xwt.js.JS.Array arr = new org.xwt.js.JS.Array();
- arr.addElement(((JS.Exn)e).getObject());
- // FIXME
- //XWT.recursivePrintObject.call();
- } catch (Exception e2) {
- Log.log(Platform.class, e);
- }
- }
+ try {
+ org.xwt.js.JS.Array arr = new org.xwt.js.JS.Array();
+ arr.addElement(((JS.Exn)e).getObject());
+ // FIXME
+ //XWT.recursivePrintObject.call();
+ } catch (Exception e2) {
+ Log.log(Platform.class, e);
+ }
+ }
else Log.log(Platform.class, e);
}
return null;
public static class ProxyAutoConfigRootScope extends JS.Scope {
- public ProxyAutoConfigRootScope() { super(null); }
+ public ProxyAutoConfigRootScope() { super(null); }
- // FIXME: needs "standard objects"
+ // FIXME: needs "standard objects"
public Object get(Object name) {
if (name.equals("isPlainHostName")) return isPlainHostName;
/** Load a directory as if it were an archive */
public static synchronized void loadDirectory(File dir) throws IOException { loadDirectory(dir, ""); }
private static synchronized void loadDirectory(File dir, String prefix) throws IOException {
- String n = prefix.replace(File.separatorChar, '.');
- if (n.endsWith(".")) n = n.substring(0, n.length() - 1);
+ String n = prefix.replace(File.separatorChar, '.');
+ if (n.endsWith(".")) n = n.substring(0, n.length() - 1);
new Static(n);
String[] subfiles = dir.list();
for(int i=0; i<subfiles.length; i++) {
ThreadMessage.newthread(new JS.Callable() {
public Object call(JS.Array args_) throws JS.Exn {
try {
- JS.Array args = new JS.Array();
- args.addElement(new Double(bytesDownloaded));
- args.addElement(new Double(length));
+ JS.Array args = new JS.Array();
+ args.addElement(new Double(bytesDownloaded));
+ args.addElement(new Double(length));
callback.call(args);
} finally {
clear = true;
// placeholder so resolveResource() works properly
bytes.put(name.replace('/', '.'), new byte[] { });
name = name.substring(0, name.length() - 4);
- Static.createStatic(name.replace('/', '.'), false);
- Template.buildTemplate(zis, name.replace('/', '.'), t);
+ Static.createStatic(name.replace('/', '.'), false);
+ Template.buildTemplate(zis, name.replace('/', '.'), t);
} else {
bytes.put(name.replace('/', '.'), isToByteArray(zis));
String s = value == null ? null : value.toString();
if (value == null) newcolor = 0x00000000;
else if (s.length() > 0 && s.charAt(0) == '#')
- try {
- newcolor = 0xFF000000 |
- (Integer.parseInt(s.substring(1, 3), 16) << 16) |
- (Integer.parseInt(s.substring(3, 5), 16) << 8) |
- Integer.parseInt(s.substring(5, 7), 16);
- } catch (NumberFormatException e) {
- Log.log(this, "invalid color " + s);
- return;
- }
+ try {
+ newcolor = 0xFF000000 |
+ (Integer.parseInt(s.substring(1, 3), 16) << 16) |
+ (Integer.parseInt(s.substring(3, 5), 16) << 8) |
+ Integer.parseInt(s.substring(5, 7), 16);
+ } catch (NumberFormatException e) {
+ Log.log(this, "invalid color " + s);
+ return;
+ }
else if (s.equals("black")) newcolor = black;
else if (s.equals("blue")) newcolor = blue;
else if (s.equals("green")) newcolor = green;
return;
}
- // FEATURE: try removing the following line; it appears to be redundant
+ // FEATURE: try removing the following line; it appears to be redundant
b.dirty();
b.text = t;
b.textupdate();
specialBoxProperties.put("static", new SpecialBoxProperty() {
public Object get(Box b) {
- String cfsn = Context.getContextForThread(Thread.currentThread()).getCurrentFunction().getSourceName();
+ String cfsn = Context.getContextForThread(Thread.currentThread()).getCurrentFunction().getSourceName();
for(int i=0; i<cfsn.length() - 1; i++)
if (cfsn.charAt(i) == '.' && (cfsn.charAt(i+1) == '_' || Character.isDigit(cfsn.charAt(i+1)))) {
cfsn = cfsn.substring(0, i);
public Static(String resourcename) { this(resourcename, true); }
public Object get(Object name_) {
- String name = name_.toString();
+ String name = name_.toString();
if (!ispackage) return super.get(name);
return getStatic(resourcename + (resourcename.length() == 0 ? "" : ".") + name);
}
}
for(int i=0; keys != null && i<keys.length; i++) {
- // FIXME: make sure that if exceptions are thrown in here, the line number of the offending XML is logged
+ // FIXME: make sure that if exceptions are thrown in here, the line number of the offending XML is logged
if (keys[i] == null) { }
else if (keys[i].equals("border") || keys[i].equals("image") &&
!vals[i].toString().startsWith("http://") && !vals[i].toString().startsWith("https://")) {
if (callback != null)
try {
- JS.Array args = new JS.Array();
- args.addElement(new Double(numerator));
- args.addElement(new Double(denominator));
+ JS.Array args = new JS.Array();
+ args.addElement(new Double(numerator));
+ args.addElement(new Double(denominator));
callback.call(args);
} catch (JS.Exn e) {
if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e);
}
if (Thread.currentThread() instanceof ThreadMessage) try {
- XWT.sleep(0);
+ XWT.sleep(0);
} catch (JS.Exn e) {
- if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e);
+ if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e);
}
}
if (callback != null)
try {
- JS.Array args = new JS.Array();
- args.addElement(new Double(1.0));
- args.addElement(new Double(1.0));
+ JS.Array args = new JS.Array();
+ args.addElement(new Double(1.0));
+ args.addElement(new Double(1.0));
callback.call(args);
} catch (JS.Exn ex) {
if (Log.on) Log.log(Template.class, "WARNING: uncaught ecmascript exception: " + ex.getMessage());
/** template reapplication procedure */
private static void reapply(Box b) {
- Log.log(Template.class, "Template.reapply() not implemented");
- /*
+ Log.log(Template.class, "Template.reapply() not implemented");
+ /*
// Ref 7.5.1: check if we need to retemplatize
boolean retemplatize = false;
if (b.templatename != null) {
// Recurse
for(Box j = b.getChild(0); j != null; j = j.nextSibling()) reapply(j);
- */
+ */
}
/** runs statics, resolves string references to other templates into actual Template instance references, and sets <tt>change</tt> as needed */
JS.CompiledFunction temp = staticscript;
staticscript = null;
- // we layer a transparent scope over the Static so that we can catch requests for the xwt object
- // yet not screw up paths that include a package called xwt (ie xwt.static.org.xwt.foo)
- JS.Scope varScope = new JS.Scope(s) {
- public boolean isTransparent() { return true; }
- public Object get(Object key) {
- if ("xwt".equals(key)) return XWT.singleton; else return super.get(key);
- } };
+ // we layer a transparent scope over the Static so that we can catch requests for the xwt object
+ // yet not screw up paths that include a package called xwt (ie xwt.static.org.xwt.foo)
+ JS.Scope varScope = new JS.Scope(s) {
+ public boolean isTransparent() { return true; }
+ public Object get(Object key) {
+ if ("xwt".equals(key)) return XWT.singleton; else return super.get(key);
+ } };
- temp.call(new JS.Array(), varScope);
+ temp.call(new JS.Array(), varScope);
}
} catch (JS.Exn e) {
if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage());
}
// find out what script is currently running
- JS.CompiledFunction placer = Context.getContextForThread(Thread.currentThread()).getCurrentFunction();
- if (placer == null) { Log.log(Trap.class, "placer is null"); return; }
+ JS.CompiledFunction placer = Context.getContextForThread(Thread.currentThread()).getCurrentFunction();
+ if (placer == null) { Log.log(Trap.class, "placer is null"); return; }
String placerNodeName = placer.getSourceName();
// check if this script has already placed a trap on this property
return ret;
}
- Object ret = f.call(args);
-
+ Object ret = f.call(args);
+
// autocascade if required
if (args.length() > 0 && !isreadtrap && !tc.putCascadeHappened) cascadeFunction.call(args, f);
return ret;
} catch (JS.Exn e) {
- if (Log.on) Log.log(this, e);
+ if (Log.on) Log.log(this, e);
} finally {
// restore the thread-locals
// Methods to Recieve and parse XML-RPC Response ////////////////////////////////////////////////////
private class Helper extends XML {
- public Helper() { super(BUFFER_SIZE); }
-
- public void startElement(XML.Element c) {
- content.reset();
- if (c.localName.equals("fault")) fault = true;
- else if (c.localName.equals("struct")) objects.setElementAt(new JS.Obj(), objects.size() - 1);
- else if (c.localName.equals("array")) objects.setElementAt(null, objects.size() - 1);
- else if (c.localName.equals("value")) objects.addElement("");
- }
-
- public void endElement(XML.Element c) {
-
- if (c.localName.equals("int") || c.localName.equals("i4"))
- objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
-
- else if (c.localName.equals("boolean"))
- objects.setElementAt(content.getBuf()[0] == '1' ? Boolean.TRUE : Boolean.FALSE, objects.size() - 1);
-
- else if (c.localName.equals("string"))
- objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
-
- else if (c.localName.equals("double"))
- objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
-
- else if (c.localName.equals("base64"))
- objects.setElementAt(new ByteStream(Base64.decode(new String(content.getBuf(), 0, content.size()))), objects.size() - 1);
-
- else if (c.localName.equals("name"))
- objects.addElement(new String(content.getBuf(), 0, content.size()));
-
- else if (c.localName.equals("value") && "".equals(objects.lastElement()))
- objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
-
- else if (c.localName.equals("dateTime.iso8601")) {
- throw new Error("not implemented");
- /*
- String s = new String(content.getBuf(), 0, content.size());
-
- // strip whitespace
- int i=0;
- while(Character.isWhitespace(s.charAt(i))) i++;
- if (i > 0) s = s.substring(i);
-
- try {
- NativeDate nd = (NativeDate)Context.enter().newObject(org.xwt.util.JS.Obj.defaultObjects, "Date");
- double date = NativeDate.date_msecFromDate(Double.valueOf(s.substring(0, 4)).doubleValue(),
- Double.valueOf(s.substring(4, 6)).doubleValue() - 1,
- Double.valueOf(s.substring(6, 8)).doubleValue(),
- Double.valueOf(s.substring(9, 11)).doubleValue(),
- Double.valueOf(s.substring(12, 14)).doubleValue(),
- Double.valueOf(s.substring(15, 17)).doubleValue(),
- (double)0
- );
- nd.jsFunction_setTime(NativeDate.internalUTC(date));
- objects.setElementAt(nd, objects.size() - 1);
-
- } catch (Exception e) {
- if (Log.on) Log.log(this, "error parsing date : " + s);
- if (Log.on) Log.log(this, e);
- }
- */
-
- } else if (c.localName.equals("member")) {
- Object memberValue = objects.elementAt(objects.size() - 1);
- String memberName = (String)objects.elementAt(objects.size() - 2);
- JS struct = (JS)objects.elementAt(objects.size() - 3);
- struct.put(memberName, memberValue);
- objects.setSize(objects.size() - 2);
-
- } else if (c.localName.equals("data")) {
- int i;
- for(i=objects.size() - 1; objects.elementAt(i) != null; i--);
- JS.Array arr = new JS.Array();
- for(int j = i + 1; j<objects.size(); j++) arr.put(new Integer(j - i - 1), objects.elementAt(j));
- objects.setElementAt(arr, i);
- objects.setSize(i + 1);
-
- }
-
- content.reset();
- }
-
- public void characters(char[] ch, int start, int length) {
- try { content.write(ch, start, length); }
- catch (Exception e) {
- if (Log.on) Log.log(this, "Exception in XMLRPC.content() -- this should never happen");
- if (Log.on) Log.log(this, e);
- }
- }
-
- public void whitespace(char[] ch, int start, int length) {}
+ public Helper() { super(BUFFER_SIZE); }
+
+ public void startElement(XML.Element c) {
+ content.reset();
+ if (c.localName.equals("fault")) fault = true;
+ else if (c.localName.equals("struct")) objects.setElementAt(new JS.Obj(), objects.size() - 1);
+ else if (c.localName.equals("array")) objects.setElementAt(null, objects.size() - 1);
+ else if (c.localName.equals("value")) objects.addElement("");
+ }
+
+ public void endElement(XML.Element c) {
+
+ if (c.localName.equals("int") || c.localName.equals("i4"))
+ objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+
+ else if (c.localName.equals("boolean"))
+ objects.setElementAt(content.getBuf()[0] == '1' ? Boolean.TRUE : Boolean.FALSE, objects.size() - 1);
+
+ else if (c.localName.equals("string"))
+ objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
+
+ else if (c.localName.equals("double"))
+ objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+
+ else if (c.localName.equals("base64"))
+ objects.setElementAt(new ByteStream(Base64.decode(new String(content.getBuf(), 0, content.size()))), objects.size() - 1);
+
+ else if (c.localName.equals("name"))
+ objects.addElement(new String(content.getBuf(), 0, content.size()));
+
+ else if (c.localName.equals("value") && "".equals(objects.lastElement()))
+ objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
+
+ else if (c.localName.equals("dateTime.iso8601")) {
+ throw new Error("not implemented");
+ /*
+ String s = new String(content.getBuf(), 0, content.size());
+
+ // strip whitespace
+ int i=0;
+ while(Character.isWhitespace(s.charAt(i))) i++;
+ if (i > 0) s = s.substring(i);
+
+ try {
+ NativeDate nd = (NativeDate)Context.enter().newObject(org.xwt.util.JS.Obj.defaultObjects, "Date");
+ double date = NativeDate.date_msecFromDate(Double.valueOf(s.substring(0, 4)).doubleValue(),
+ Double.valueOf(s.substring(4, 6)).doubleValue() - 1,
+ Double.valueOf(s.substring(6, 8)).doubleValue(),
+ Double.valueOf(s.substring(9, 11)).doubleValue(),
+ Double.valueOf(s.substring(12, 14)).doubleValue(),
+ Double.valueOf(s.substring(15, 17)).doubleValue(),
+ (double)0
+ );
+ nd.jsFunction_setTime(NativeDate.internalUTC(date));
+ objects.setElementAt(nd, objects.size() - 1);
+
+ } catch (Exception e) {
+ if (Log.on) Log.log(this, "error parsing date : " + s);
+ if (Log.on) Log.log(this, e);
+ }
+ */
+
+ } else if (c.localName.equals("member")) {
+ Object memberValue = objects.elementAt(objects.size() - 1);
+ String memberName = (String)objects.elementAt(objects.size() - 2);
+ JS struct = (JS)objects.elementAt(objects.size() - 3);
+ struct.put(memberName, memberValue);
+ objects.setSize(objects.size() - 2);
+
+ } else if (c.localName.equals("data")) {
+ int i;
+ for(i=objects.size() - 1; objects.elementAt(i) != null; i--);
+ JS.Array arr = new JS.Array();
+ for(int j = i + 1; j<objects.size(); j++) arr.put(new Integer(j - i - 1), objects.elementAt(j));
+ objects.setElementAt(arr, i);
+ objects.setSize(i + 1);
+
+ }
+
+ content.reset();
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ try { content.write(ch, start, length); }
+ catch (Exception e) {
+ if (Log.on) Log.log(this, "Exception in XMLRPC.content() -- this should never happen");
+ if (Log.on) Log.log(this, e);
+ }
+ }
+
+ public void whitespace(char[] ch, int start, int length) {}
}
// Methods to make outbound XML-RPC request ///////////////////////////////////////////////////
}
sb.append("</string></value>\n");
- /*
+ /*
} else if (o instanceof org.xwt.js.Date) {
sb.append(" <value><dateTime.iso8601>");
- FIXME
- org.xwt.js.Date d = (org.xwt.js.Date)o;
+ FIXME
+ org.xwt.js.Date d = (org.xwt.js.Date)o;
Date d = new Date(nd.getRawTime());
sb.append(d.getYear() + 1900);
if (d.getMonth() + 1 < 10) sb.append('0');
if (d.getSeconds() < 10) sb.append('0');
sb.append(d.getSeconds());
sb.append("</dateTime.iso8601></value>\n");
- */
+ */
} else if (o instanceof JS.Array) {
if (tracker.get(o) != null) throw new JS.Exn("attempted to send multi-ref data structure via XML-RPC");
throw new JS.Exn("socket exception: " + se);
} catch (JS.Exn jse) {
- if (Log.on) Log.log(this, jse.toString());
+ if (Log.on) Log.log(this, jse.toString());
throw jse;
} finally {
ThreadMessage.resumeThread();
private static Hashtable safeFiles = new Hashtable();
public Object get(Object name) {
- if (name.equals("alt")) return Surface.alt ? Boolean.TRUE : Boolean.FALSE;
+ if (name.equals("alt")) return Surface.alt ? Boolean.TRUE : Boolean.FALSE;
else if (name.equals("control")) return Surface.control ? Boolean.TRUE : Boolean.FALSE;
else if (name.equals("shift")) return Surface.shift ? Boolean.TRUE : Boolean.FALSE;
else if (name.equals("clipboard")) return Platform.getClipBoard();
- else if (name.equals("static")) return Static.getStatic("");
+ else if (name.equals("static")) return Static.getStatic("");
else if (name.equals("button")) {
if (Surface.button1 && !Surface.button2 && !Surface.button3) return new Integer(1);
else if (!Surface.button1 && Surface.button2 && !Surface.button3) return new Integer(1);
else if (!Surface.button1 && !Surface.button2 && Surface.button3) return new Integer(1);
else return new Integer(0);
- }
+ }
else if (name.equals("encodeURI")) throw new Error("not implemented");
else if (name.equals("encodeURIComponent")) throw new Error("not implemented");
else if (name.equals("decodeURI")) throw new Error("not implemented");
else if (name.equals("decodeURIComponent")) throw new Error("not implemented");
- else return super.get(name);
+ else return super.get(name);
}
public void put(Object name, Object value) {
- if (name.equals("thread") && value != null && value instanceof JS.Callable) ThreadMessage.newthread((JS.Callable)value);
+ if (name.equals("thread") && value != null && value instanceof JS.Callable) ThreadMessage.newthread((JS.Callable)value);
else if (name.equals("clipboard")) Platform.setClipBoard(value.toString());
else if (name.equals("proxyAuthorization")) {
- // FIXME: undocumented, possibly insecure
+ // FIXME: undocumented, possibly insecure
Proxy.Authorization.authorization = value.toString();
Proxy.Authorization.waitingForUser.release();
} else super.put(name, value);
}
private XWT() {
- put("maxdim", new Integer(Short.MAX_VALUE));
+ put("maxdim", new Integer(Short.MAX_VALUE));
put("origin", Main.origin);
put("altKeyName", Platform.altKeyName());
put("screenWidth", new Integer(Platform.getScreenWidth()));
put("fileSeparator", File.separator);
put("homeDir", System.getProperty("user.home"));
put("tempDir", System.getProperty("java.io.tempdir"));
- put("math", org.xwt.js.Math.singleton);
-
- put("newBrowserWindow", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 1 || args.elementAt(0) == null) return null;
- Platform.newBrowserWindow(args.elementAt(0).toString());
- return null;
- }});
-
- put("parseFloat", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 1 || args.elementAt(0) == null) return null;
- return new Float(args.elementAt(0).toString());
- }});
-
- put("parseInt", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 1 || args.elementAt(0) == null) return null;
- return new Float(args.elementAt(0).toString());
- }});
-
- put("yield", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- sleep(0);
- return null;
- }});
-
- put("theme", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 2) return null;
- if (args.elementAt(0) == null || args.elementAt(1) == null) return null;
- for(int i=1; i<args.length(); i++) {
- if (args.elementAt(i) instanceof String) {
- String from = (String)args.elementAt(0);
- String to = (String)args.elementAt(i);
- if (Log.on) Log.log(this, "retheming from " + from + " to " + to);
- Resources.mapFrom.addElement(from);
- Resources.mapTo.addElement(to);
- }
- }
- JS.Callable callback = args.elementAt(args.length() - 1) instanceof JS.Callable ?
- (JS.Callable)args.elementAt(args.length() - 1) : null;
- Template.retheme(callback);
- return null;
- }});
-
- put("println", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 1) return null;
- if (Log.on) Log.log(this, Context.getCurrentSourceNameAndLine() + " " +
- (args.elementAt(0) == null ? "**null**" : args.elementAt(0).toString()));
- return null;
- }});
-
- put("date", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- Log.log(XWT.class, "date not implemented");
- //throw new Error("not implemented");
- return null;
+ put("math", org.xwt.js.Math.singleton);
+
+ put("newBrowserWindow", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 1 || args.elementAt(0) == null) return null;
+ Platform.newBrowserWindow(args.elementAt(0).toString());
+ return null;
+ }});
+
+ put("parseFloat", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 1 || args.elementAt(0) == null) return null;
+ return new Float(args.elementAt(0).toString());
+ }});
+
+ put("parseInt", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 1 || args.elementAt(0) == null) return null;
+ return new Float(args.elementAt(0).toString());
+ }});
+
+ put("yield", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ sleep(0);
+ return null;
+ }});
+
+ put("theme", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 2) return null;
+ if (args.elementAt(0) == null || args.elementAt(1) == null) return null;
+ for(int i=1; i<args.length(); i++) {
+ if (args.elementAt(i) instanceof String) {
+ String from = (String)args.elementAt(0);
+ String to = (String)args.elementAt(i);
+ if (Log.on) Log.log(this, "retheming from " + from + " to " + to);
+ Resources.mapFrom.addElement(from);
+ Resources.mapTo.addElement(to);
+ }
+ }
+ JS.Callable callback = args.elementAt(args.length() - 1) instanceof JS.Callable ?
+ (JS.Callable)args.elementAt(args.length() - 1) : null;
+ Template.retheme(callback);
+ return null;
+ }});
+
+ put("println", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 1) return null;
+ if (Log.on) Log.log(this, Context.getCurrentSourceNameAndLine() + " " +
+ (args.elementAt(0) == null ? "**null**" : args.elementAt(0).toString()));
+ return null;
+ }});
+
+ put("date", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ Log.log(XWT.class, "date not implemented");
+ //throw new Error("not implemented");
+ return null;
+ }});
+
+ put("regexp", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ //throw new Error("not implemented");
+ Log.log(XWT.class, "regexp not implemented");
+ return null;
+ }});
+
+ put("listfonts", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ Object[] fonts = Platform.listFonts();
+ JS.Array ret = new JS.Array();
+ for(int i=0; i<fonts.length; i++) ret.addElement(fonts[i]);
+ return ret;
+ }});
+
+ put("xmlrpc", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 1 || args.elementAt(0) == null) return null;
+ return new XMLRPC(args.elementAt(0).toString(), "");
+ }});
+
+ put("soap", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() == 1 && args.elementAt(0) != null) return new SOAP(args.elementAt(0).toString(), "", null, null);
+ else if (args.length() == 2 && args.elementAt(0) != null && args.elementAt(1) != null)
+ return new SOAP(args.elementAt(0).toString(), "", args.elementAt(1).toString(), null);
+ else if (args.length() == 3 && args.elementAt(0) != null && args.elementAt(1) != null && args.elementAt(2) != null)
+ return new SOAP(args.elementAt(0).toString(), "", args.elementAt(1).toString(), args.elementAt(2).toString());
+ else return null;
+ }});
+
+ put("textwidth", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() < 1 || args.length() > 2) return null;
+ if (args.elementAt(0) == null || (args.length() == 2 && args.elementAt(1) == null)) return null;
+ String font = args.length() == 1 ? Platform.getDefaultFont() : args.elementAt(0).toString();
+ String text = args.length() == 1 ? args.elementAt(0).toString() : args.elementAt(1).toString();
+ XWF xwf = XWF.getXWF(font);
+ if (xwf == null) return new Integer(Platform.stringWidth(font, text));
+ else return new Integer(xwf.stringWidth(text));
}});
- put("regexp", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- //throw new Error("not implemented");
- Log.log(XWT.class, "regexp not implemented");
- return null;
- }});
-
- put("listfonts", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- Object[] fonts = Platform.listFonts();
- JS.Array ret = new JS.Array();
- for(int i=0; i<fonts.length; i++) ret.addElement(fonts[i]);
- return ret;
- }});
-
- put("xmlrpc", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 1 || args.elementAt(0) == null) return null;
- return new XMLRPC(args.elementAt(0).toString(), "");
- }});
-
- put("soap", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() == 1 && args.elementAt(0) != null) return new SOAP(args.elementAt(0).toString(), "", null, null);
- else if (args.length() == 2 && args.elementAt(0) != null && args.elementAt(1) != null)
- return new SOAP(args.elementAt(0).toString(), "", args.elementAt(1).toString(), null);
- else if (args.length() == 3 && args.elementAt(0) != null && args.elementAt(1) != null && args.elementAt(2) != null)
- return new SOAP(args.elementAt(0).toString(), "", args.elementAt(1).toString(), args.elementAt(2).toString());
- else return null;
- }});
-
- put("textwidth", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() < 1 || args.length() > 2) return null;
- if (args.elementAt(0) == null || (args.length() == 2 && args.elementAt(1) == null)) return null;
- String font = args.length() == 1 ? Platform.getDefaultFont() : args.elementAt(0).toString();
- String text = args.length() == 1 ? args.elementAt(0).toString() : args.elementAt(1).toString();
- XWF xwf = XWF.getXWF(font);
- if (xwf == null) return new Integer(Platform.stringWidth(font, text));
- else return new Integer(xwf.stringWidth(text));
- }});
-
- put("textheight", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() > 1) return null;
- if (args.length() == 1 && args.elementAt(0) == null) return null;
- String font = args.length() == 0 || args.elementAt(0) == null ? Platform.getDefaultFont() : args.elementAt(0).toString();
- XWF xwf = XWF.getXWF(font);
- if (xwf == null) return new Integer(Platform.getMaxAscent(font) + Platform.getMaxDescent(font));
- else return new Integer(xwf.getMaxAscent() + xwf.getMaxDescent());
- }});
-
- put("newBox", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() > 0) Log.log(XWT.class, "DEPRECATED: xwt.newBox() with multiple arguments is deprecated; use xwt.newBox().apply()");
- JS.Callable callback = null;
- for(int i=1; i<args.length(); i++)
- if (args.elementAt(i) instanceof JS.Callable && callback == null)
- callback = (JS.Callable)args.elementAt(i);
- Box ret = new Box(args.length() == 0 || args.elementAt(0) == null ? "box" : args.elementAt(0).toString(),
- Template.defaultImportList, callback);
- for(int i=1; i<args.length(); i++)
- if (args.elementAt(i) instanceof Box)
- ret.put(ret.numChildren(), (Box)args.elementAt(i));
- for(int i=1; i<args.length(); i++)
- if (args.elementAt(i) instanceof JS && !(args.elementAt(i) instanceof Box) && !(args.elementAt(i) instanceof JS.Callable)) {
- JS s = (JS)args.elementAt(i);
- Object[] keys = s.keys();
- for(int j=0; j<keys.length; j++) ret.put(keys[j].toString(), s.get(keys[j].toString()));
- }
- return ret;
- }});
-
- put("sleep", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args != null && (args.length() != 1 || args.elementAt(0) == null)) return null;
- int i = args == null ? 0 : SpecialBoxProperty.stoi(args.elementAt(0).toString());
- sleep(i);
- return null;
- }});
-
- put("openFile", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 1) return null;
- String file = Platform.fileDialog(args.elementAt(0).toString(), false);
- return file == null ? null : new ByteStream(file);
- }});
-
- put("saveFile", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 2) return null;
- if (!(args.elementAt(1) instanceof ByteStream)) return null;
- String file = args.elementAt(0).toString();
- if (safeFiles.get(Platform.isCaseSensitive() ? file : file.toLowerCase()) == null) {
- file = Platform.fileDialog(file, true);
- if (file == null) return null;
- safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object());
- }
- try {
- ((ByteStream)args.elementAt(1)).writeTo(new FileOutputStream(file));
- return null;
- } catch (IOException e) {
- if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file");
- if (Log.on) Log.log(ByteStream.class, e);
- throw new JS.Exn("error while writing a ByteStream to a file");
- }
- }});
-
- put("saveFileAs", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args.length() != 2) return null;
- if (!(args.elementAt(1) instanceof ByteStream)) return null;
- String file = args.elementAt(0).toString();
- file = Platform.fileDialog(file, true);
- if (file == null) return null;
- safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object());
- try {
- ((ByteStream)args.elementAt(1)).writeTo(new FileOutputStream(file));
- return null;
- } catch (IOException e) {
- if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file");
- if (Log.on) Log.log(ByteStream.class, e);
- throw new JS.Exn("error while writing a ByteStream to a file");
- }
- }});
-
- put("utfEncode", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args == null || args.length() != 1) return null;
- return new ByteStream(args.elementAt(0).toString().getBytes());
- }});
-
- put("parseHTML", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ put("textheight", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() > 1) return null;
+ if (args.length() == 1 && args.elementAt(0) == null) return null;
+ String font = args.length() == 0 || args.elementAt(0) == null ? Platform.getDefaultFont() : args.elementAt(0).toString();
+ XWF xwf = XWF.getXWF(font);
+ if (xwf == null) return new Integer(Platform.getMaxAscent(font) + Platform.getMaxDescent(font));
+ else return new Integer(xwf.getMaxAscent() + xwf.getMaxDescent());
+ }});
+
+ put("newBox", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() > 0) Log.log(XWT.class, "DEPRECATED: xwt.newBox() with multiple arguments is deprecated; use xwt.newBox().apply()");
+ JS.Callable callback = null;
+ for(int i=1; i<args.length(); i++)
+ if (args.elementAt(i) instanceof JS.Callable && callback == null)
+ callback = (JS.Callable)args.elementAt(i);
+ Box ret = new Box(args.length() == 0 || args.elementAt(0) == null ? "box" : args.elementAt(0).toString(),
+ Template.defaultImportList, callback);
+ for(int i=1; i<args.length(); i++)
+ if (args.elementAt(i) instanceof Box)
+ ret.put(ret.numChildren(), (Box)args.elementAt(i));
+ for(int i=1; i<args.length(); i++)
+ if (args.elementAt(i) instanceof JS && !(args.elementAt(i) instanceof Box) && !(args.elementAt(i) instanceof JS.Callable)) {
+ JS s = (JS)args.elementAt(i);
+ Object[] keys = s.keys();
+ for(int j=0; j<keys.length; j++) ret.put(keys[j].toString(), s.get(keys[j].toString()));
+ }
+ return ret;
+ }});
+
+ put("sleep", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args != null && (args.length() != 1 || args.elementAt(0) == null)) return null;
+ int i = args == null ? 0 : SpecialBoxProperty.stoi(args.elementAt(0).toString());
+ sleep(i);
+ return null;
+ }});
+
+ put("openFile", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 1) return null;
+ String file = Platform.fileDialog(args.elementAt(0).toString(), false);
+ return file == null ? null : new ByteStream(file);
+ }});
+
+ put("saveFile", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 2) return null;
+ if (!(args.elementAt(1) instanceof ByteStream)) return null;
+ String file = args.elementAt(0).toString();
+ if (safeFiles.get(Platform.isCaseSensitive() ? file : file.toLowerCase()) == null) {
+ file = Platform.fileDialog(file, true);
+ if (file == null) return null;
+ safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object());
+ }
+ try {
+ ((ByteStream)args.elementAt(1)).writeTo(new FileOutputStream(file));
+ return null;
+ } catch (IOException e) {
+ if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file");
+ if (Log.on) Log.log(ByteStream.class, e);
+ throw new JS.Exn("error while writing a ByteStream to a file");
+ }
+ }});
+
+ put("saveFileAs", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args.length() != 2) return null;
+ if (!(args.elementAt(1) instanceof ByteStream)) return null;
+ String file = args.elementAt(0).toString();
+ file = Platform.fileDialog(file, true);
+ if (file == null) return null;
+ safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object());
+ try {
+ ((ByteStream)args.elementAt(1)).writeTo(new FileOutputStream(file));
+ return null;
+ } catch (IOException e) {
+ if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file");
+ if (Log.on) Log.log(ByteStream.class, e);
+ throw new JS.Exn("error while writing a ByteStream to a file");
+ }
+ }});
+
+ put("utfEncode", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
+ if (args == null || args.length() != 1) return null;
+ return new ByteStream(args.elementAt(0).toString().getBytes());
+ }});
+
+ put("parseHTML", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
if (args == null || args.length() != 1 || args.elementAt(0) == null) return null;
try {
if (args.elementAt(0) instanceof ByteStream) {
});
put("recursivePrintObject", new JS.Callable() { public Object call(JS.Array args) {
- if (args.length() != 1) return null;
- recurse("", "", args.elementAt(0));
- return null;
+ if (args.length() != 1) return null;
+ recurse("", "", args.elementAt(0));
+ return null;
}});
put("loadArchive", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (!ThreadMessage.suspendThread()) return null;
- try {
- if (args == null || args.length() < 1 || args.elementAt(0) == null) return null;
- URL u = new URL(args.elementAt(0).toString());
-
- JS.Callable callback = null;
- if (args.length() == 2 && args.elementAt(1) != null && args.elementAt(1) instanceof JS.Callable)
- callback = (JS.Callable)args.elementAt(1);
-
- if (!u.getFile().endsWith(".xwar")) {
- if (Log.on) Log.log(this, "Error: archive names must end with .xwar: " + u.getFile());
- throw new JS.Exn("Error: archive names must end with .xwar: " + u.getFile());
- }
-
- if (u.getProtocol().equals("http")) {
- HTTP http = new HTTP(u.toString());
- if (Main.originAddr == null) {
- try {
- Main.originAddr = InetAddress.getByName(u.getHost());
- } catch (UnknownHostException e) {
- if (Log.on) Log.log(this, "couldn't resolve " + u.getHost() + "; proceeding without permissions");
- Main.originAddr = InetAddress.getByName("0.0.0.0");
- }
- } else {
- Main.originAddr = InetAddress.getByName("0.0.0.0");
- }
- HTTP.HTTPInputStream in = http.GET();
- Resources.loadArchive(in, in.getContentLength(), callback);
-
- } else if (u.getProtocol().equals("file")) {
- if (Main.originAddr != null) {
- if (Log.on) Log.log(this, "scripts downloaded from the network may not load xwars from the local filesystem");
- throw new JS.Exn("scripts downloaded from the network may not load xwars from the local filesystem");
- }
- Resources.loadArchive(new FileInputStream(u.getFile()), (int)new File(u.getFile()).length(), callback);
-
- } else {
- if (Log.on) Log.log(this, "unknown protocol \"" + u.getProtocol() + "\"");
- throw new JS.Exn("unknown protocol \"" + u.getProtocol() + "\"");
- }
-
- } catch (MalformedURLException me) {
- if (Log.on) Log.log(this, "Malformed URL: " + args.elementAt(0));
- if (Log.on) Log.log(this, me);
- throw new JS.Exn(me.toString());
-
- } catch (IOException ioe) {
- if (Log.on) Log.log(this, "IOException while loading archive:");
- if (Log.on) Log.log(this, ioe);
- throw new JS.Exn(ioe.toString());
-
- } finally {
- ThreadMessage.resumeThread();
-
- }
- return null;
+ if (!ThreadMessage.suspendThread()) return null;
+ try {
+ if (args == null || args.length() < 1 || args.elementAt(0) == null) return null;
+ URL u = new URL(args.elementAt(0).toString());
+
+ JS.Callable callback = null;
+ if (args.length() == 2 && args.elementAt(1) != null && args.elementAt(1) instanceof JS.Callable)
+ callback = (JS.Callable)args.elementAt(1);
+
+ if (!u.getFile().endsWith(".xwar")) {
+ if (Log.on) Log.log(this, "Error: archive names must end with .xwar: " + u.getFile());
+ throw new JS.Exn("Error: archive names must end with .xwar: " + u.getFile());
+ }
+
+ if (u.getProtocol().equals("http")) {
+ HTTP http = new HTTP(u.toString());
+ if (Main.originAddr == null) {
+ try {
+ Main.originAddr = InetAddress.getByName(u.getHost());
+ } catch (UnknownHostException e) {
+ if (Log.on) Log.log(this, "couldn't resolve " + u.getHost() + "; proceeding without permissions");
+ Main.originAddr = InetAddress.getByName("0.0.0.0");
+ }
+ } else {
+ Main.originAddr = InetAddress.getByName("0.0.0.0");
+ }
+ HTTP.HTTPInputStream in = http.GET();
+ Resources.loadArchive(in, in.getContentLength(), callback);
+
+ } else if (u.getProtocol().equals("file")) {
+ if (Main.originAddr != null) {
+ if (Log.on) Log.log(this, "scripts downloaded from the network may not load xwars from the local filesystem");
+ throw new JS.Exn("scripts downloaded from the network may not load xwars from the local filesystem");
+ }
+ Resources.loadArchive(new FileInputStream(u.getFile()), (int)new File(u.getFile()).length(), callback);
+
+ } else {
+ if (Log.on) Log.log(this, "unknown protocol \"" + u.getProtocol() + "\"");
+ throw new JS.Exn("unknown protocol \"" + u.getProtocol() + "\"");
+ }
+
+ } catch (MalformedURLException me) {
+ if (Log.on) Log.log(this, "Malformed URL: " + args.elementAt(0));
+ if (Log.on) Log.log(this, me);
+ throw new JS.Exn(me.toString());
+
+ } catch (IOException ioe) {
+ if (Log.on) Log.log(this, "IOException while loading archive:");
+ if (Log.on) Log.log(this, ioe);
+ throw new JS.Exn(ioe.toString());
+
+ } finally {
+ ThreadMessage.resumeThread();
+
+ }
+ return null;
}});
put("prefetchImage", new JS.Callable() { public Object call(JS.Array args) throws JS.Exn {
- if (args == null || args.length() < 1 || args.elementAt(0) == null) return null;
- Box.getImage(args.elementAt(0).toString(),
- args.length() > 1 && args.elementAt(1) instanceof JS.Callable ? (JS.Callable)args.elementAt(1) : null);
- return null;
+ if (args == null || args.length() < 1 || args.elementAt(0) == null) return null;
+ Box.getImage(args.elementAt(0).toString(),
+ args.length() > 1 && args.elementAt(1) instanceof JS.Callable ? (JS.Callable)args.elementAt(1) : null);
+ return null;
}});
}
for(int i=0; i<keys.length; i++)
recurse(indent + " ", keys[i].toString(),
(keys[i] instanceof Integer) ?
- s.get(((Integer)keys[i])) : s.get(keys[i].toString()));
+ s.get(((Integer)keys[i])) : s.get(keys[i].toString()));
} else {
Log.log(Context.getCurrentSourceNameAndLine(), indent + name + o);
public static void sleep(int i) {
- Thread thread = Thread.currentThread();
- if (!(thread instanceof ThreadMessage)) {
- if (Log.on) Log.log(XWT.class, "cannot sleep() or yield() in the foreground thread");
- } else {
- ThreadMessage mythread = (ThreadMessage)thread;
- mythread.done.release();
- if (i > 0) try { Thread.sleep(i); } catch (Exception e) { }
- MessageQueue.add(mythread);
- mythread.go.block();
- }
+ Thread thread = Thread.currentThread();
+ if (!(thread instanceof ThreadMessage)) {
+ if (Log.on) Log.log(XWT.class, "cannot sleep() or yield() in the foreground thread");
+ } else {
+ ThreadMessage mythread = (ThreadMessage)thread;
+ mythread.done.release();
+ if (i > 0) try { Thread.sleep(i); } catch (Exception e) { }
+ MessageQueue.add(mythread);
+ mythread.go.block();
+ }
}
}
public ArrayImpl() { }
public ArrayImpl(int size) { vec.setSize(size); }
private static int intVal(Object o) {
- if (o instanceof Number) {
- int intVal = ((Number)o).intValue();
- if (intVal == ((Number)o).doubleValue()) return intVal;
- return Integer.MIN_VALUE;
- }
- if (!(o instanceof String)) return Integer.MIN_VALUE;
- String s = (String)o;
- for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
- return Integer.parseInt(s);
+ if (o instanceof Number) {
+ int intVal = ((Number)o).intValue();
+ if (intVal == ((Number)o).doubleValue()) return intVal;
+ return Integer.MIN_VALUE;
+ }
+ if (!(o instanceof String)) return Integer.MIN_VALUE;
+ String s = (String)o;
+ for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
+ return Integer.parseInt(s);
}
public Object get(Object key) throws JS.Exn {
- // FIXME: HACK!
- if (key.equals("cascade")) return org.xwt.Trap.cascadeFunction;
- if (key.equals("trapee")) return org.xwt.Trap.currentTrapee();
- if (key.equals("length")) return new Long(vec.size());
- int i = intVal(key);
- if (i == Integer.MIN_VALUE) return super.get(key);
- try {
- return vec.elementAt(i);
- } catch (ArrayIndexOutOfBoundsException e) {
- return null;
- }
+ // FIXME: HACK!
+ if (key.equals("cascade")) return org.xwt.Trap.cascadeFunction;
+ if (key.equals("trapee")) return org.xwt.Trap.currentTrapee();
+ if (key.equals("length")) return new Long(vec.size());
+ int i = intVal(key);
+ if (i == Integer.MIN_VALUE) return super.get(key);
+ try {
+ return vec.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
}
public void put(Object key, Object val) {
- if (key.equals("length")) vec.setSize(toNumber(val).intValue());
- int i = intVal(key);
- if (i == Integer.MIN_VALUE) super.put(key, val);
- else {
- if (i >= vec.size()) vec.setSize(i+1);
- vec.setElementAt(val, i);
- }
+ if (key.equals("length")) vec.setSize(toNumber(val).intValue());
+ int i = intVal(key);
+ if (i == Integer.MIN_VALUE) super.put(key, val);
+ else {
+ if (i >= vec.size()) vec.setSize(i+1);
+ vec.setElementAt(val, i);
+ }
}
public Object[] keys() {
- Object[] sup = super.keys();
- Object[] ret = new Object[vec.size() + 1 + sup.length];
- System.arraycopy(sup, 0, ret, vec.size(), sup.length);
- for(int i=0; i<vec.size(); i++) ret[i] = new Integer(i);
- ret[vec.size()] = "length";
- return ret;
+ Object[] sup = super.keys();
+ Object[] ret = new Object[vec.size() + 1 + sup.length];
+ System.arraycopy(sup, 0, ret, vec.size(), sup.length);
+ for(int i=0; i<vec.size(); i++) ret[i] = new Integer(i);
+ ret[vec.size()] = "length";
+ return ret;
}
public void setSize(int i) { vec.setSize(i); }
public int length() { return vec.size(); }
/** the first line of this function */
private int firstLine;
public int getFirstLine() throws JS.Exn { return firstLine; }
-
+
/** the line numbers */
private int[] line = new int[10];
// Constructors ////////////////////////////////////////////////////////
private CompiledFunctionImpl cloneWithNewParentScope(JS.Scope s) throws IOException {
- CompiledFunctionImpl ret = new JS.CompiledFunction(sourceName, firstLine, null, s);
- ret.paste(this);
- return ret;
+ CompiledFunctionImpl ret = new JS.CompiledFunction(sourceName, firstLine, null, s);
+ ret.paste(this);
+ return ret;
}
protected CompiledFunctionImpl(String sourceName, int firstLine, Reader sourceCode, JS.Scope parentScope) throws IOException {
- this.sourceName = sourceName;
- this.firstLine = firstLine;
- this.parentScope = parentScope;
- if (sourceCode == null) return;
- Parser p = new Parser(sourceCode, sourceName, firstLine);
- try {
- while(true) {
- int s = size();
- p.parseStatement(this, null);
- if (s == size()) break;
- }
- add(-1, Tokens.RETURN);
- } catch (Exception e) {
- if (Log.on) Log.log(Parser.class, e);
- }
+ this.sourceName = sourceName;
+ this.firstLine = firstLine;
+ this.parentScope = parentScope;
+ if (sourceCode == null) return;
+ Parser p = new Parser(sourceCode, sourceName, firstLine);
+ try {
+ while(true) {
+ int s = size();
+ p.parseStatement(this, null);
+ if (s == size()) break;
+ }
+ add(-1, Tokens.RETURN);
+ } catch (Exception e) {
+ if (Log.on) Log.log(Parser.class, e);
+ }
}
public Object call(JS.Array args) throws JS.Exn { return call(args, new FunctionScope(sourceName, parentScope)); }
public Object call(JS.Array args, JS.Scope scope) throws JS.Exn {
- CompiledFunctionImpl saved = (CompiledFunctionImpl)Context.currentFunction.get(Thread.currentThread());
- try {
- Context.currentFunction.put(Thread.currentThread(), this);
- Context cx = Context.getContextForThread(Thread.currentThread());
- int size = cx.stack.size();
- cx.stack.push(new Context.CallMarker());
- cx.stack.push(args);
- eval(scope);
- Object ret = cx.stack.pop();
- if (cx.stack.size() > size)
- Log.log(this, "warning, stack grew by " + (cx.stack.size() - size) +
- " elements during call to " + Context.getCurrentSourceNameAndLine());
- return ret;
- } finally {
- if (saved == null) Context.currentFunction.remove(Thread.currentThread());
- else Context.currentFunction.put(Thread.currentThread(), saved);
- }
+ CompiledFunctionImpl saved = (CompiledFunctionImpl)Context.currentFunction.get(Thread.currentThread());
+ try {
+ Context.currentFunction.put(Thread.currentThread(), this);
+ Context cx = Context.getContextForThread(Thread.currentThread());
+ int size = cx.stack.size();
+ cx.stack.push(new Context.CallMarker());
+ cx.stack.push(args);
+ eval(scope);
+ Object ret = cx.stack.pop();
+ if (cx.stack.size() > size)
+ Log.log(this, "warning, stack grew by " + (cx.stack.size() - size) +
+ " elements during call to " + Context.getCurrentSourceNameAndLine());
+ return ret;
+ } finally {
+ if (saved == null) Context.currentFunction.remove(Thread.currentThread());
+ else Context.currentFunction.put(Thread.currentThread(), saved);
+ }
}
Object[] arg2 = new Object[op.length * 2]; System.arraycopy(arg, 0, arg2, 0, arg.length); arg = arg2;
int[] op2 = new int[op.length * 2]; System.arraycopy(op, 0, op2, 0, op.length); op = op2;
}
- this.line[size] = line;
+ this.line[size] = line;
op[size] = op_;
arg[size] = arg_;
size++;
int pc = 0;
void eval(JS.Scope s) {
- final Vec t = Context.getContextForThread(Thread.currentThread()).stack;
+ final Vec t = Context.getContextForThread(Thread.currentThread()).stack;
OUTER: for(pc=0; pc<size; pc++) {
- String label = null;
- switch(op[pc]) {
+ String label = null;
+ switch(op[pc]) {
case LITERAL: t.push(arg[pc]); break;
case OBJECT: t.push(new JS.Obj()); break;
case ARRAY: t.push(new JS.Array(JS.toNumber(arg[pc]).intValue())); break;
case SWAP: { Object o1 = t.pop(); Object o2 = t.pop(); t.push(o1); t.push(o2); break; }
case DUP: t.push(t.peek()); break;
case NEWSCOPE: /*s = new JS.Scope(s);*/ break;
- case OLDSCOPE: /*s = s.getParentScope();*/ break;
+ case OLDSCOPE: /*s = s.getParentScope();*/ break;
case ASSERT: if (!JS.toBoolean(t.pop())) throw je("assertion failed"); break;
case BITNOT: t.push(new Long(~JS.toLong(t.pop()))); break;
case BANG: t.push(new Boolean(!JS.toBoolean(t.pop()))); break;
case TYPEOF: {
- Object o = t.pop();
- if (o == null) t.push(null);
- else if (o instanceof org.xwt.Box) t.push("Box");
- else if (o instanceof JS) t.push("Object");
- else if (o instanceof String) t.push("String");
- else if (o instanceof Number) t.push("Number");
- else if (o.getClass().getName().startsWith("org.xwt.js.")) t.push(o.getClass().getName().substring(11));
- else t.push("unknown");
- break;
- }
+ Object o = t.pop();
+ if (o == null) t.push(null);
+ else if (o instanceof org.xwt.Box) t.push("Box");
+ else if (o instanceof JS) t.push("Object");
+ else if (o instanceof String) t.push("String");
+ else if (o instanceof Number) t.push("Number");
+ else if (o.getClass().getName().startsWith("org.xwt.js.")) t.push(o.getClass().getName().substring(11));
+ else t.push("unknown");
+ break;
+ }
case NEWFUNCTION: {
- try {
- t.push(((CompiledFunctionImpl)arg[pc]).cloneWithNewParentScope(s));
- } catch (IOException e) {
- throw new Error("this should never happen");
- }
- break;
- }
+ try {
+ t.push(((CompiledFunctionImpl)arg[pc]).cloneWithNewParentScope(s));
+ } catch (IOException e) {
+ throw new Error("this should never happen");
+ }
+ break;
+ }
case PUSHKEYS: {
Object o = t.peek();
case LABEL: break;
case LOOP: {
- t.push(s);
- t.push(new Context.LoopMarker(pc, pc > 0 && op[pc - 1] == LABEL ? (String)arg[pc - 1] : (String)null));
- t.push(Boolean.TRUE);
- break;
- }
+ t.push(s);
+ t.push(new Context.LoopMarker(pc, pc > 0 && op[pc - 1] == LABEL ? (String)arg[pc - 1] : (String)null));
+ t.push(Boolean.TRUE);
+ break;
+ }
case BREAK:
- case CONTINUE:
- while(t.size() > 0) {
- Object o = t.pop();
- if (o instanceof Context.CallMarker) ee("break or continue not within a loop");
- if (o != null && o instanceof Context.LoopMarker) {
- if (arg[pc] == null || arg[pc].equals(((Context.LoopMarker)o).label)) {
- int loopInstructionLocation = ((Context.LoopMarker)o).location;
- int endOfLoop = ((Integer)arg[loopInstructionLocation]).intValue() + loopInstructionLocation;
- s = (JS.Scope)t.pop();
- if (op[pc] == CONTINUE) { t.push(s); t.push(o); t.push(Boolean.FALSE); }
- pc = op[pc] == BREAK ? endOfLoop - 1 : loopInstructionLocation;
- continue OUTER;
- }
- }
- }
- throw new Error("CONTINUE/BREAK invoked but couldn't find a LoopMarker at " + sourceName + ":" + line);
+ case CONTINUE:
+ while(t.size() > 0) {
+ Object o = t.pop();
+ if (o instanceof Context.CallMarker) ee("break or continue not within a loop");
+ if (o != null && o instanceof Context.LoopMarker) {
+ if (arg[pc] == null || arg[pc].equals(((Context.LoopMarker)o).label)) {
+ int loopInstructionLocation = ((Context.LoopMarker)o).location;
+ int endOfLoop = ((Integer)arg[loopInstructionLocation]).intValue() + loopInstructionLocation;
+ s = (JS.Scope)t.pop();
+ if (op[pc] == CONTINUE) { t.push(s); t.push(o); t.push(Boolean.FALSE); }
+ pc = op[pc] == BREAK ? endOfLoop - 1 : loopInstructionLocation;
+ continue OUTER;
+ }
+ }
+ }
+ throw new Error("CONTINUE/BREAK invoked but couldn't find a LoopMarker at " + sourceName + ":" + line);
case TRY: {
- t.push(new Context.TryMarker(pc + ((Integer)arg[pc]).intValue(), s));
- break;
- }
+ t.push(new Context.TryMarker(pc + ((Integer)arg[pc]).intValue(), s));
+ break;
+ }
case RETURN: {
- Object retval = t.pop();
- while(t.size() > 0) {
- Object o = t.pop();
- if (o != null && o instanceof Context.CallMarker) {
- t.push(retval);
- return;
- }
- }
- throw new Error("error: RETURN invoked but couldn't find a CallMarker!");
- }
+ Object retval = t.pop();
+ while(t.size() > 0) {
+ Object o = t.pop();
+ if (o != null && o instanceof Context.CallMarker) {
+ t.push(retval);
+ return;
+ }
+ }
+ throw new Error("error: RETURN invoked but couldn't find a CallMarker!");
+ }
case PUT: {
Object val = t.pop();
Object key = t.pop();
- Object target = t.peek();
+ Object target = t.peek();
if (target == null)
- throw je("tried to put a value to the " + key + " property on the null value");
+ throw je("tried to put a value to the " + key + " property on the null value");
if (!(target instanceof JS))
- throw je("tried to put a value to the " + key + " property on a " + target.getClass().getName());
+ throw je("tried to put a value to the " + key + " property on a " + target.getClass().getName());
((JS)target).put(key, val);
t.push(val);
break;
case GET:
case GET_PRESERVE: {
- Object o, v;
- if (op[pc] == GET) {
- v = t.pop();
- o = t.pop();
- } else {
- v = t.pop();
- o = t.peek();
- t.push(v);
- }
- Object ret = null;
- if (o == null) throw je("tried to get property \"" + v + "\" from the null value");
- if (v == null) throw je("tried to get the null key from " + v);
- if (o instanceof String) {
- ret = getFromString((String)o, v);
- } else if (o instanceof Boolean) {
- throw je("Not Implemented: properties on Boolean objects");
- } else if (o instanceof Number) {
- Log.log(this, "Not Implemented: properties on Number objects");
- } else if (o instanceof JS) {
- ret = ((JS)o).get(v);
- }
+ Object o, v;
+ if (op[pc] == GET) {
+ v = t.pop();
+ o = t.pop();
+ } else {
+ v = t.pop();
+ o = t.peek();
+ t.push(v);
+ }
+ Object ret = null;
+ if (o == null) throw je("tried to get property \"" + v + "\" from the null value");
+ if (v == null) throw je("tried to get the null key from " + v);
+ if (o instanceof String) {
+ ret = getFromString((String)o, v);
+ } else if (o instanceof Boolean) {
+ throw je("Not Implemented: properties on Boolean objects");
+ } else if (o instanceof Number) {
+ Log.log(this, "Not Implemented: properties on Number objects");
+ } else if (o instanceof JS) {
+ ret = ((JS)o).get(v);
+ }
t.push(ret);
break;
}
for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(t.pop(), j);
JS.Callable f = (JS.Callable)t.pop();
if (f == null) throw je("attempted to call null");
- try {
- t.push(f.call(arguments));
- break;
- } catch (JS.Exn e) {
- t.push(e);
- }
+ try {
+ t.push(f.call(arguments));
+ break;
+ } catch (JS.Exn e) {
+ t.push(e);
+ }
}
// fall through if exception was thrown
- case THROW: {
- Object exn = t.pop();
- while(t.size() > 0) {
- Object o = t.pop();
- if (o instanceof Context.TryMarker) {
- t.push(exn);
- pc = ((Context.TryMarker)o).location - 1;
- s = ((Context.TryMarker)o).scope;
- continue OUTER;
- }
- }
- throw new JS.Exn(exn);
- }
+ case THROW: {
+ Object exn = t.pop();
+ while(t.size() > 0) {
+ Object o = t.pop();
+ if (o instanceof Context.TryMarker) {
+ t.push(exn);
+ pc = ((Context.TryMarker)o).location - 1;
+ s = ((Context.TryMarker)o).scope;
+ continue OUTER;
+ }
+ }
+ throw new JS.Exn(exn);
+ }
case INC: case DEC: {
boolean isPrefix = JS.toBoolean(arg[pc]);
case URSH: t.push(new Long(JS.toLong(left) >>> JS.toLong(right))); break;
case LT: case LE: case GT: case GE: {
- if (left == null) left = new Integer(0);
- if (right == null) right = new Integer(0);
- int result = 0;
- if (left instanceof String || right instanceof String) {
- result = left.toString().compareTo(right.toString());
- } else {
- result = (int)java.lang.Math.ceil(JS.toDouble(left) - JS.toDouble(right));
- }
- t.push(new Boolean((op[pc] == LT && result < 0) || (op[pc] == LE && result <= 0) ||
- (op[pc] == GT && result > 0) || (op[pc] == GE && result >= 0)));
- break;
- }
+ if (left == null) left = new Integer(0);
+ if (right == null) right = new Integer(0);
+ int result = 0;
+ if (left instanceof String || right instanceof String) {
+ result = left.toString().compareTo(right.toString());
+ } else {
+ result = (int)java.lang.Math.ceil(JS.toDouble(left) - JS.toDouble(right));
+ }
+ t.push(new Boolean((op[pc] == LT && result < 0) || (op[pc] == LE && result <= 0) ||
+ (op[pc] == GT && result > 0) || (op[pc] == GE && result >= 0)));
+ break;
+ }
case EQ:
- case NE: {
+ case NE: {
Object l = left;
Object r = right;
boolean ret;
default: throw new Error("unknown opcode " + op[pc]);
} }
}
- }
+ }
}
// Helpers for Number, String, and Boolean ////////////////////////////////////////
private Object getFromString(final String o, final Object v) {
- if (v.equals("length")) return new Integer(((String)o).length());
- else if (v.equals("substring")) return new JS.Callable() {
- public Object call(JS.Array args) {
- if (args.length() == 1) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue());
- else if (args.length() == 2) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue(),
- JS.toNumber(args.elementAt(1)).intValue());
- else throw je("String.substring() can only take one or two arguments");
- }
- };
- else if (v.equals("toLowerCase")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return ((String)o).toLowerCase();
- } };
- else if (v.equals("toUpperCase")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return ((String)o).toString().toUpperCase();
- } };
- else if (v.equals("charAt")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return ((String)o).charAt(JS.toNumber(args.elementAt(0)).intValue()) + "";
- } };
- else if (v.equals("lastIndexOf")) return new JS.Callable() {
- public Object call(JS.Array args) {
- if (args.length() != 1) return null;
- return new Integer(((String)o).lastIndexOf(args.elementAt(0).toString()));
- } };
- else if (v.equals("indexOf")) return new JS.Callable() {
- public Object call(JS.Array args) {
- if (args.length() != 1) return null;
- return new Integer(((String)o).indexOf(args.elementAt(0).toString()));
- } };
- throw je("Not Implemented: propery " + v + " on String objects");
+ if (v.equals("length")) return new Integer(((String)o).length());
+ else if (v.equals("substring")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ if (args.length() == 1) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue());
+ else if (args.length() == 2) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue(),
+ JS.toNumber(args.elementAt(1)).intValue());
+ else throw je("String.substring() can only take one or two arguments");
+ }
+ };
+ else if (v.equals("toLowerCase")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ return ((String)o).toLowerCase();
+ } };
+ else if (v.equals("toUpperCase")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ return ((String)o).toString().toUpperCase();
+ } };
+ else if (v.equals("charAt")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ return ((String)o).charAt(JS.toNumber(args.elementAt(0)).intValue()) + "";
+ } };
+ else if (v.equals("lastIndexOf")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ if (args.length() != 1) return null;
+ return new Integer(((String)o).lastIndexOf(args.elementAt(0).toString()));
+ } };
+ else if (v.equals("indexOf")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ if (args.length() != 1) return null;
+ return new Integer(((String)o).indexOf(args.elementAt(0).toString()));
+ } };
+ throw je("Not Implemented: propery " + v + " on String objects");
}
// FunctionScope /////////////////////////////////////////////////////////////////
private class FunctionScope extends JS.Scope {
- String sourceName;
- public FunctionScope(String sourceName, Scope parentScope) { super(parentScope); this.sourceName = sourceName; }
- public String getSourceName() { return sourceName; }
- public Object get(Object key) throws JS.Exn {
- if (key.equals("trapee")) return org.xwt.Trap.currentTrapee();
- else if (key.equals("cascade")) return org.xwt.Trap.cascadeFunction;
- return super.get(key);
- }
+ String sourceName;
+ public FunctionScope(String sourceName, Scope parentScope) { super(parentScope); this.sourceName = sourceName; }
+ public String getSourceName() { return sourceName; }
+ public Object get(Object key) throws JS.Exn {
+ if (key.equals("trapee")) return org.xwt.Trap.currentTrapee();
+ else if (key.equals("cascade")) return org.xwt.Trap.cascadeFunction;
+ return super.get(key);
+ }
}
}
/** returns the current file and line number; intended for displaying to the user */
public static String getCurrentSourceNameAndLine() {
- return getContextForThread(Thread.currentThread()).getCurrentFunction().getSourceName() + ":??";
+ return getContextForThread(Thread.currentThread()).getCurrentFunction().getSourceName() + ":??";
}
public static String getSourceNameAndLineForThread(Thread t) {
- JS.CompiledFunction cf = getContextForThread(t).getCurrentFunction();
- if (cf == null) return "null";
- return cf.getSourceName() + ":??";
+ JS.CompiledFunction cf = getContextForThread(t).getCurrentFunction();
+ if (cf == null) return "null";
+ return cf.getSourceName() + ":??";
}
/** fetches the currently-executing javascript function */
public JS.CompiledFunction getCurrentFunction() { return (JS.CompiledFunction)currentFunction.get(Thread.currentThread()); }
public static Context getContextForThread(Thread t) {
- Context ret = (Context)javaThreadToContextMap.get(t);
- if (ret == null) {
- ret = new Context();
- ret.bindToCurrentThread();
- }
- return ret;
+ Context ret = (Context)javaThreadToContextMap.get(t);
+ if (ret == null) {
+ ret = new Context();
+ ret.bindToCurrentThread();
+ }
+ return ret;
}
public static class CallMarker { public CallMarker() { } }
public static class LoopMarker {
- public int location;
- public String label;
- public LoopMarker(int location, String label) {
- this.location = location;
- this.label = label;
- }
+ public int location;
+ public String label;
+ public LoopMarker(int location, String label) {
+ this.location = location;
+ this.label = label;
+ }
}
public static class TryMarker {
- public int location;
- public JS.Scope scope;
- public TryMarker(int location, JS.Scope scope) {
- this.location = location;
- this.scope = scope;
- }
+ public int location;
+ public JS.Scope scope;
+ public TryMarker(int location, JS.Scope scope) {
+ this.location = location;
+ this.scope = scope;
+ }
}
}
/** parse and compile a function */
public static CompiledFunction parse(String sourceName, int firstLine, Reader sourceCode) throws IOException {
- return new CompiledFunction(sourceName, firstLine, sourceCode, null);
+ return new CompiledFunction(sourceName, firstLine, sourceCode, null);
}
/** coerce an object to a Boolean */
public static boolean toBoolean(Object o) {
- if (o == null) return false;
- if (o instanceof Boolean) return ((Boolean)o).booleanValue();
- if (o instanceof Number) return o.equals(new Integer(0));
- return true;
+ if (o == null) return false;
+ if (o instanceof Boolean) return ((Boolean)o).booleanValue();
+ if (o instanceof Number) return o.equals(new Integer(0));
+ return true;
}
/** coerce an object to a Long */
/** coerce an object to a Number */
public static Number toNumber(Object o) {
- if (o == null) return new Long(0);
- if (o instanceof Number) return ((Number)o);
- if (o instanceof String) try { return new Double((String)o); } catch (NumberFormatException e) { return new Double(0); }
- if (o instanceof Boolean) return ((Boolean)o).booleanValue() ? new Long(1) : new Long(0);
- if (o instanceof JS) return ((JS)o).coerceToNumber();
- throw new Error("toNumber() got object of type " + o.getClass().getName() + " which we don't know how to handle");
+ if (o == null) return new Long(0);
+ if (o instanceof Number) return ((Number)o);
+ if (o instanceof String) try { return new Double((String)o); } catch (NumberFormatException e) { return new Double(0); }
+ if (o instanceof Boolean) return ((Boolean)o).booleanValue() ? new Long(1) : new Long(0);
+ if (o instanceof JS) return ((JS)o).coerceToNumber();
+ throw new Error("toNumber() got object of type " + o.getClass().getName() + " which we don't know how to handle");
}
/** A sensible implementation of the abstract methods in the JS class */
public static class Obj extends JS {
- private Hash entries = new Hash();
- private boolean sealed = false;
- public Obj() { this(false); }
- public Obj(boolean sealed) { this.sealed = sealed; }
- public void setSeal(boolean sealed) { this.sealed = sealed; }
- public Object get(Object key) { return entries.get(key); }
- public void put(Object key, Object val) { if (!sealed) entries.put(key, val); }
- public Object[] keys() { return(entries.keys()); }
+ private Hash entries = new Hash();
+ private boolean sealed = false;
+ public Obj() { this(false); }
+ public Obj(boolean sealed) { this.sealed = sealed; }
+ public void setSeal(boolean sealed) { this.sealed = sealed; }
+ public Object get(Object key) { return entries.get(key); }
+ public void put(Object key, Object val) { if (!sealed) entries.put(key, val); }
+ public Object[] keys() { return(entries.keys()); }
}
/** An exception which can be thrown and caught by JavaScript code */
public static class Exn extends RuntimeException {
- private Object js = null;
- public Exn(Object js) { this.js = js; }
- public String toString() { return "JS.Exn: " + js; }
- public String getMessage() { return toString(); }
- public Object getObject() { return js; }
+ private Object js = null;
+ public Exn(Object js) { this.js = js; }
+ public String toString() { return "JS.Exn: " + js; }
+ public String getMessage() { return toString(); }
+ public Object getObject() { return js; }
}
/** The publicly-visible face of JavaScript Array objects */
public static class Array extends ArrayImpl {
- public Array() { }
- public Array(int size) { super(size); }
- public void setSize(int i) { super.setSize(i); }
- public int length() { return super.length(); }
- public Object elementAt(int i) { return super.elementAt(i); }
- public void addElement(Object o) { super.addElement(o); }
- public void setElementAt(Object o, int i) { super.setElementAt(o, i); }
+ public Array() { }
+ public Array(int size) { super(size); }
+ public void setSize(int i) { super.setSize(i); }
+ public int length() { return super.length(); }
+ public Object elementAt(int i) { return super.elementAt(i); }
+ public void addElement(Object o) { super.addElement(o); }
+ public void setElementAt(Object o, int i) { super.setElementAt(o, i); }
}
/** Any object which becomes part of the scope chain must support this interface */
public static class Scope extends ScopeImpl {
- public Scope(Scope parentScope) { this(parentScope, false); }
- public Scope(Scope parentScope, boolean sealed) { super(parentScope, sealed); }
- public Scope getParentScope() { return super.getParentScope(); }
- public boolean isTransparent() { return super.isTransparent(); }
- public boolean has(Object key) { return super.has(key); }
- public void declare(String s) { super.declare(s); }
+ public Scope(Scope parentScope) { this(parentScope, false); }
+ public Scope(Scope parentScope, boolean sealed) { super(parentScope, sealed); }
+ public Scope getParentScope() { return super.getParentScope(); }
+ public boolean isTransparent() { return super.isTransparent(); }
+ public boolean has(Object key) { return super.has(key); }
+ public void declare(String s) { super.declare(s); }
}
/** anything that is callable with the () operator */
public static abstract class Callable extends JS.Obj {
- public abstract Object call(JS.Array args) throws JS.Exn;
+ public abstract Object call(JS.Array args) throws JS.Exn;
}
/** a Callable which was compiled from JavaScript code */
public static class CompiledFunction extends CompiledFunctionImpl {
- public Object call(JS.Array args, JS.Scope scope) throws JS.Exn { return super.call(args, scope); }
- CompiledFunction(String sourceName, int firstLine, Reader sourceCode, Scope scope) throws IOException {
- super(sourceName, firstLine, sourceCode, scope);
- }
+ public Object call(JS.Array args, JS.Scope scope) throws JS.Exn { return super.call(args, scope); }
+ CompiledFunction(String sourceName, int firstLine, Reader sourceCode, Scope scope) throws IOException {
+ super(sourceName, firstLine, sourceCode, scope);
+ }
}
}
/** for debugging */
public static void main(String[] s) throws Exception {
- Lexer l = new Lexer(new InputStreamReader(System.in), "stdin", 0);
- int tok = 0;
- while((tok = l.getToken()) != -1) System.out.println(codeToString[tok]);
+ Lexer l = new Lexer(new InputStreamReader(System.in), "stdin", 0);
+ int tok = 0;
+ while((tok = l.getToken()) != -1) System.out.println(codeToString[tok]);
}
/** the token that was just parsed */
private SmartReader in;
public Lexer(Reader r, String sourceName, int line) throws IOException {
- this.sourceName = sourceName;
- this.line = line;
- this.parserLine = line;
- in = new SmartReader(r);
+ this.sourceName = sourceName;
+ this.line = line;
+ this.parserLine = line;
+ in = new SmartReader(r);
}
// Token Subtype Handlers /////////////////////////////////////////////////////////
private int getKeyword(String s) throws IOException {
- char c;
- switch (s.length()) {
+ char c;
+ switch (s.length()) {
case 2: c=s.charAt(1);
if (c=='f') { if (s.charAt(0)=='i') return IF; }
else if (c=='n') { if (s.charAt(0)=='i') return IN; }
case 'c': c=s.charAt(3);
if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') return CASE; }
else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') return RESERVED; }
- return -1;
+ return -1;
case 'e': c=s.charAt(3);
if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') return ELSE; }
else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') return RESERVED; }
- return -1;
+ return -1;
case 'g': return s.equals("goto") ? RESERVED : -1;
- case 'l': return s.equals("long") ? RESERVED : -1;
+ case 'l': return s.equals("long") ? RESERVED : -1;
case 'n': return s.equals("null") ? NULL : -1;
case 't': c=s.charAt(3);
if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') return TRUE; }
else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') return THIS; }
- return -1;
- case 'w': if (s.equals("with")) return RESERVED; else return -1;
- case 'v': if (s.equals("void")) return RESERVED; else return -1;
+ return -1;
+ case 'w': if (s.equals("with")) return RESERVED; else return -1;
+ case 'v': if (s.equals("void")) return RESERVED; else return -1;
} break;
case 5: switch (s.charAt(2)) {
case 'a': return s.equals("class") ? RESERVED : -1;
- case 'e': return s.equals("break") ? BREAK : -1;
+ case 'e': return s.equals("break") ? BREAK : -1;
case 'i': return s.equals("while") ? WHILE : -1;
- case 'l': return s.equals("false") ? FALSE : -1;
+ case 'l': return s.equals("false") ? FALSE : -1;
case 'n': c=s.charAt(0);
- if (s.equals("const")) return RESERVED;
+ if (s.equals("const")) return RESERVED;
else if (s.equals("final")) return RESERVED;
- return -1;
- case 'o': c=s.charAt(0);
- if (c == 'c') return s.equals("float") ? RESERVED : -1;
- else if (c=='s') return s.equals("final") ? RESERVED : -1;
- break;
- case 'p': return s.equals("super") ? RESERVED : -1;
+ return -1;
+ case 'o': c=s.charAt(0);
+ if (c == 'c') return s.equals("float") ? RESERVED : -1;
+ else if (c=='s') return s.equals("final") ? RESERVED : -1;
+ break;
+ case 'p': return s.equals("super") ? RESERVED : -1;
case 'r': return s.equals("throw") ? THROW : -1;
case 't': return s.equals("catch") ? CATCH : -1;
} break;
case 6: switch (s.charAt(1)) {
- case 'a': return s.equals("class") ? RESERVED : -1;
+ case 'a': return s.equals("class") ? RESERVED : -1;
case 'e': c=s.charAt(0);
if (s.equals("delete")) return RESERVED;
else if (c=='r') return s.equals("return") ? RETURN : -1;
break;
- case 'h': return s.equals("throws") ? RESERVED : -1;
+ case 'h': return s.equals("throws") ? RESERVED : -1;
case 'o': return s.equals("double") ? RESERVED : -1;
case 's': return s.equals("assert") ? ASSERT : -1;
case 'u': return s.equals("public") ? RESERVED : -1;
break;
case 12: return s.equals("synchronized") ? RESERVED : -1;
}
- return -1;
+ return -1;
}
private int getIdentifier(int c) throws IOException {
in.unread();
String str = in.getString();
int result = getKeyword(str);
- if (result == RESERVED) throw new LexerException("The reserved word \"" + str + "\" is not permitted in XWT scripts");
+ if (result == RESERVED) throw new LexerException("The reserved word \"" + str + "\" is not permitted in XWT scripts");
if (result != -1) return result;
this.string = str.intern();
return NAME;
if (isInteger) {
longval = Long.parseLong(numString, base);
dval = (double)longval;
- } else {
+ } else {
dval = Double.parseDouble(numString);
longval = (long) dval;
if (longval == dval) isInteger = true;
case 't': c = '\t'; break;
case 'v': c = '\u000B'; break;
case '\\': c = '\\'; break;
- case 'u': {
- int v = 0;
- for(int i=0; i<4; i++) {
- int ci = in.read();
- if (!((ci >= '0' && ci <= '9') || (ci >= 'a' && ci <= 'f') || (ci >= 'A' && ci <= 'F')))
- throw new LexerException("illegal character '" + ((char)c) + "' in \\u unicode escape sequence");
- v = (v << 8) | Integer.parseInt(ci + "", 16);
- }
- c = (char)v;
- break;
- }
+ case 'u': {
+ int v = 0;
+ for(int i=0; i<4; i++) {
+ int ci = in.read();
+ if (!((ci >= '0' && ci <= '9') || (ci >= 'a' && ci <= 'f') || (ci >= 'A' && ci <= 'F')))
+ throw new LexerException("illegal character '" + ((char)c) + "' in \\u unicode escape sequence");
+ v = (v << 8) | Integer.parseInt(ci + "", 16);
+ }
+ c = (char)v;
+ break;
+ }
default:
- // just use the character that was escaped
- break;
+ // just use the character that was escaped
+ break;
}
}
if (stringBuf != null) stringBuf.append((char) c);
case '*': return in.match('=') ? ASSIGN_MUL : MUL;
case '<': return !in.match('<') ? (in.match('=') ? LE : LT) : in.match('=') ? ASSIGN_LSH : LSH;
case '>': return !in.match('>') ? (in.match('=') ? GE : GT) :
- in.match('>') ? (in.match('=') ? ASSIGN_URSH : URSH) : (in.match('=') ? ASSIGN_RSH : RSH);
+ in.match('>') ? (in.match('=') ? ASSIGN_URSH : URSH) : (in.match('=') ? ASSIGN_RSH : RSH);
case '/':
if (in.match('=')) return ASSIGN_DIV;
if (in.match('/')) { while ((c = in.read()) != -1 && c != '\n'); in.unread(); return getToken(); }
public SmartReader(Reader r) { reader = new PushbackReader(r); }
public void unread() throws IOException { unread((char)lastread); }
public void unread(char c) throws IOException {
- reader.unread(c);
- if (accumulator != null) accumulator.setLength(accumulator.length() - 1);
- }
+ reader.unread(c);
+ if (accumulator != null) accumulator.setLength(accumulator.length() - 1);
+ }
public boolean match(char c) throws IOException { if (peek() == c) { reader.read(); return true; } else return false; }
public int peek() throws IOException {
int peeked = reader.read();
public int read() throws IOException {
lastread = reader.read();
if (accumulator != null) accumulator.append((char)lastread);
- if (lastread != '\n' && lastread != '\r') col++;
- if (lastread == '\n') { parserLine = ++line; col = 0; }
+ if (lastread != '\n' && lastread != '\r') col++;
+ if (lastread == '\n') { parserLine = ++line; col = 0; }
return lastread;
}
// FEATURE: could be much more efficient
StringBuffer accumulator = null;
public void startString() {
- accumulator = new StringBuffer();
- accumulator.append((char)lastread);
- }
+ accumulator = new StringBuffer();
+ accumulator.append((char)lastread);
+ }
public String getString() throws IOException {
String ret = accumulator.toString();
accumulator = null;
/** push back a token */
public void pushBackToken(int op, Object obj) {
- if (pushBackDepth >= pushBackInts.length - 1) {
- int[] newInts = new int[pushBackInts.length * 2];
- System.arraycopy(pushBackInts, 0, newInts, 0, pushBackInts.length);
- pushBackInts = newInts;
- Object[] newObjects = new Object[pushBackObjects.length * 2];
- System.arraycopy(pushBackObjects, 0, newObjects, 0, pushBackObjects.length);
- pushBackObjects = newObjects;
- }
- pushBackInts[pushBackDepth] = op;
- pushBackObjects[pushBackDepth] = obj;
- pushBackDepth++;
+ if (pushBackDepth >= pushBackInts.length - 1) {
+ int[] newInts = new int[pushBackInts.length * 2];
+ System.arraycopy(pushBackInts, 0, newInts, 0, pushBackInts.length);
+ pushBackInts = newInts;
+ Object[] newObjects = new Object[pushBackObjects.length * 2];
+ System.arraycopy(pushBackObjects, 0, newObjects, 0, pushBackObjects.length);
+ pushBackObjects = newObjects;
+ }
+ pushBackInts[pushBackDepth] = op;
+ pushBackObjects[pushBackDepth] = obj;
+ pushBackDepth++;
}
/** push back the most recently read token */
/** read a token but leave it in the stream */
public int peekToken() throws IOException {
- int ret = getToken();
- pushBackToken();
- return ret;
+ int ret = getToken();
+ pushBackToken();
+ return ret;
}
/** read a token */
public int getToken() throws IOException {
- number = null;
- string = null;
- if (pushBackDepth == 0) {
- mostRecentlyReadToken = op;
- return op = _getToken();
- }
- pushBackDepth--;
- op = pushBackInts[pushBackDepth];
- if (pushBackObjects[pushBackDepth] != null) {
- number = pushBackObjects[pushBackDepth] instanceof Number ? (Number)pushBackObjects[pushBackDepth] : null;
- string = pushBackObjects[pushBackDepth] instanceof String ? (String)pushBackObjects[pushBackDepth] : null;
- }
- return op;
+ number = null;
+ string = null;
+ if (pushBackDepth == 0) {
+ mostRecentlyReadToken = op;
+ return op = _getToken();
+ }
+ pushBackDepth--;
+ op = pushBackInts[pushBackDepth];
+ if (pushBackObjects[pushBackDepth] != null) {
+ number = pushBackObjects[pushBackDepth] instanceof Number ? (Number)pushBackObjects[pushBackDepth] : null;
+ string = pushBackObjects[pushBackDepth] instanceof String ? (String)pushBackObjects[pushBackDepth] : null;
+ }
+ return op;
}
class LexerException extends IOException {
- public LexerException(String s) { super(sourceName + ":" + line + "," + col + ": " + s); }
+ public LexerException(String s) { super(sourceName + ":" + line + "," + col + ": " + s); }
}
}
private Math() { setSeal(true); }
public Object get(Object name) {
- if ("ceil".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
- { if (args.elementAt(0) == null) return null;
- return new Long((long)java.lang.Math.ceil(Double.parseDouble(args.elementAt(0).toString()))); } };
- else if ("floor".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
- { if (args.elementAt(0) == null) return null;
- return new Long((long)java.lang.Math.floor(Double.parseDouble(args.elementAt(0).toString()))); } };
- else if ("round".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
- { if (args.elementAt(0) == null) return null;
- return new Long((long)java.lang.Math.round(Double.parseDouble(args.elementAt(0).toString()))); } };
- else if ("abs".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
- { if (args.elementAt(0) == null) return null;
- return new Long((long)java.lang.Math.abs(Double.parseDouble(args.elementAt(0).toString()))); } };
- else if ("min".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- if (args.length() < 2 || args.elementAt(0) == null || args.elementAt(1) == null) return args.elementAt(0);
- return new Double(java.lang.Math.min(((Number)args.elementAt(0)).doubleValue(),
- ((Number)args.elementAt(1)).doubleValue())); } };
- else if ("max".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- if (args.length() < 2) return args.elementAt(0);
- return new Double(java.lang.Math.max(((Number)args.elementAt(0)).doubleValue(),
- ((Number)args.elementAt(1)).doubleValue())); } };
- else if ("cos".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.cos(((Number)args.elementAt(0)).doubleValue())); } };
- else if ("sin".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.sin(((Number)args.elementAt(0)).doubleValue())); } };
- else if ("tan".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.tan(((Number)args.elementAt(0)).doubleValue())); } };
- else if ("acos".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.acos(((Number)args.elementAt(0)).doubleValue())); } };
- else if ("asin".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.asin(((Number)args.elementAt(0)).doubleValue())); } };
- else if ("atan".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.atan(((Number)args.elementAt(0)).doubleValue())); } };
- else if ("sqrt".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
- return new Double(java.lang.Math.sqrt(((Number)args.elementAt(0)).doubleValue())); } };
- return null;
+ if ("ceil".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
+ { if (args.elementAt(0) == null) return null;
+ return new Long((long)java.lang.Math.ceil(Double.parseDouble(args.elementAt(0).toString()))); } };
+ else if ("floor".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
+ { if (args.elementAt(0) == null) return null;
+ return new Long((long)java.lang.Math.floor(Double.parseDouble(args.elementAt(0).toString()))); } };
+ else if ("round".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
+ { if (args.elementAt(0) == null) return null;
+ return new Long((long)java.lang.Math.round(Double.parseDouble(args.elementAt(0).toString()))); } };
+ else if ("abs".equals(name)) return new JS.Callable() { public Object call(JS.Array args)
+ { if (args.elementAt(0) == null) return null;
+ return new Long((long)java.lang.Math.abs(Double.parseDouble(args.elementAt(0).toString()))); } };
+ else if ("min".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ if (args.length() < 2 || args.elementAt(0) == null || args.elementAt(1) == null) return args.elementAt(0);
+ return new Double(java.lang.Math.min(((Number)args.elementAt(0)).doubleValue(),
+ ((Number)args.elementAt(1)).doubleValue())); } };
+ else if ("max".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ if (args.length() < 2) return args.elementAt(0);
+ return new Double(java.lang.Math.max(((Number)args.elementAt(0)).doubleValue(),
+ ((Number)args.elementAt(1)).doubleValue())); } };
+ else if ("cos".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.cos(((Number)args.elementAt(0)).doubleValue())); } };
+ else if ("sin".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.sin(((Number)args.elementAt(0)).doubleValue())); } };
+ else if ("tan".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.tan(((Number)args.elementAt(0)).doubleValue())); } };
+ else if ("acos".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.acos(((Number)args.elementAt(0)).doubleValue())); } };
+ else if ("asin".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.asin(((Number)args.elementAt(0)).doubleValue())); } };
+ else if ("atan".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.atan(((Number)args.elementAt(0)).doubleValue())); } };
+ else if ("sqrt".equals(name)) return new JS.Callable() { public Object call(JS.Array args) {
+ return new Double(java.lang.Math.sqrt(((Number)args.elementAt(0)).doubleValue())); } };
+ return null;
}
}
static boolean[] isRightAssociative = new boolean[MAX_TOKEN + 1];
static {
isRightAssociative[ASSIGN] =
- isRightAssociative[ASSIGN_BITOR] =
- isRightAssociative[ASSIGN_BITXOR] =
- isRightAssociative[ASSIGN_BITAND] =
- isRightAssociative[ASSIGN_LSH] =
- isRightAssociative[ASSIGN_RSH] =
- isRightAssociative[ASSIGN_URSH] =
- isRightAssociative[ASSIGN_ADD] =
- isRightAssociative[ASSIGN_SUB] =
- isRightAssociative[ASSIGN_MUL] =
- isRightAssociative[ASSIGN_DIV] =
- isRightAssociative[ASSIGN_MOD] = true;
+ isRightAssociative[ASSIGN_BITOR] =
+ isRightAssociative[ASSIGN_BITXOR] =
+ isRightAssociative[ASSIGN_BITAND] =
+ isRightAssociative[ASSIGN_LSH] =
+ isRightAssociative[ASSIGN_RSH] =
+ isRightAssociative[ASSIGN_URSH] =
+ isRightAssociative[ASSIGN_ADD] =
+ isRightAssociative[ASSIGN_SUB] =
+ isRightAssociative[ASSIGN_MUL] =
+ isRightAssociative[ASSIGN_DIV] =
+ isRightAssociative[ASSIGN_MOD] = true;
precedence[ASSIGN] =
- precedence[ASSIGN_BITOR] =
- precedence[ASSIGN_BITXOR] =
- precedence[ASSIGN_BITAND] =
- precedence[ASSIGN_LSH] =
- precedence[ASSIGN_RSH] =
- precedence[ASSIGN_URSH] =
- precedence[ASSIGN_ADD] =
- precedence[ASSIGN_SUB] =
- precedence[ASSIGN_MUL] =
- precedence[ASSIGN_DIV] =
- precedence[ASSIGN_MOD] = 1;
+ precedence[ASSIGN_BITOR] =
+ precedence[ASSIGN_BITXOR] =
+ precedence[ASSIGN_BITAND] =
+ precedence[ASSIGN_LSH] =
+ precedence[ASSIGN_RSH] =
+ precedence[ASSIGN_URSH] =
+ precedence[ASSIGN_ADD] =
+ precedence[ASSIGN_SUB] =
+ precedence[ASSIGN_MUL] =
+ precedence[ASSIGN_DIV] =
+ precedence[ASSIGN_MOD] = 1;
precedence[HOOK] = 2;
precedence[COMMA] = 3;
precedence[OR] = precedence[AND] = 4;
* appended bytecodes MUST grow the stack by exactly one element.
*/
private void startExpr(CompiledFunctionImpl appendTo, int minPrecedence) throws IOException {
- int saveParserLine = parserLine;
- _startExpr(appendTo, minPrecedence);
- parserLine = saveParserLine;
+ int saveParserLine = parserLine;
+ _startExpr(appendTo, minPrecedence);
+ parserLine = saveParserLine;
}
private void _startExpr(CompiledFunctionImpl appendTo, int minPrecedence) throws IOException {
int tok = getToken();
}
case INC: case DEC: { // prefix (not postfix)
startExpr(b, precedence[tok]);
- if (b.get(b.size() - 1) != GET)
- throw new ParserException("prefixed increment/decrement can only be performed on a valid assignment target");
+ if (b.get(b.size() - 1) != GET)
+ throw new ParserException("prefixed increment/decrement can only be performed on a valid assignment target");
b.set(b.size() - 1, tok, new Boolean(true));
break;
}
break;
}
case NAME: {
- b.add(parserLine, TOPSCOPE);
- b.add(parserLine, LITERAL, string);
- continueExprAfterAssignable(b);
- break;
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, LITERAL, string);
+ continueExprAfterAssignable(b);
+ break;
}
case FUNCTION: {
consume(LP);
* decreases the stack depth by exactly one element.
*/
private void continueExprAfterAssignable(CompiledFunctionImpl b) throws IOException {
- int saveParserLine = parserLine;
- _continueExprAfterAssignable(b);
- parserLine = saveParserLine;
+ int saveParserLine = parserLine;
+ _continueExprAfterAssignable(b);
+ parserLine = saveParserLine;
}
private void _continueExprAfterAssignable(CompiledFunctionImpl b) throws IOException {
if (b == null) throw new Error("got null b; this should never happen");
int tok = getToken();
- switch(tok) {
+ switch(tok) {
case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
case ASSIGN_ADD: case ASSIGN_SUB: case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: {
- b.add(parserLine, GET_PRESERVE);
+ b.add(parserLine, GET_PRESERVE);
startExpr(b, -1);
b.add(parserLine, tok - 1);
b.add(parserLine, PUT);
break;
}
case INC: case DEC: { // postfix
- b.add(parserLine, GET_PRESERVE);
- b.add(parserLine, LITERAL, new Integer(1));
- b.add(parserLine, tok == INC ? ADD : SUB);
- b.add(parserLine, PUT);
- b.add(parserLine, SWAP);
- b.add(parserLine, POP);
- b.add(parserLine, LITERAL, new Integer(1));
- b.add(parserLine, tok == INC ? SUB : ADD);
- break;
- }
- case ASSIGN: {
+ b.add(parserLine, GET_PRESERVE);
+ b.add(parserLine, LITERAL, new Integer(1));
+ b.add(parserLine, tok == INC ? ADD : SUB);
+ b.add(parserLine, PUT);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, POP);
+ b.add(parserLine, LITERAL, new Integer(1));
+ b.add(parserLine, tok == INC ? SUB : ADD);
+ break;
+ }
+ case ASSIGN: {
startExpr(b, -1);
- b.add(parserLine, PUT);
- b.add(parserLine, SWAP);
- b.add(parserLine, POP);
- break;
- }
- default: {
- pushBackToken();
- b.add(parserLine, GET);
- return;
- }
- }
+ b.add(parserLine, PUT);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, POP);
+ break;
+ }
+ default: {
+ pushBackToken();
+ b.add(parserLine, GET);
+ return;
+ }
+ }
}
* depth.
*/
private void continueExpr(CompiledFunctionImpl b, int minPrecedence) throws IOException {
- int saveParserLine = parserLine;
- _continueExpr(b, minPrecedence);
- parserLine = saveParserLine;
+ int saveParserLine = parserLine;
+ _continueExpr(b, minPrecedence);
+ parserLine = saveParserLine;
}
private void _continueExpr(CompiledFunctionImpl b, int minPrecedence) throws IOException {
if (b == null) throw new Error("got null b; this should never happen");
startExpr(b, precedence[tok]); // otherwise check the second value
b.add(parserLine, JMP, new Integer(2)); // leave the second value on the stack and jump to the end
b.add(parserLine, LITERAL, tok == AND ?
- new Boolean(false) : new Boolean(true)); // target of the short-circuit jump is here
+ new Boolean(false) : new Boolean(true)); // target of the short-circuit jump is here
b.set(size - 1, new Integer(b.size() - size)); // write the target of the short-circuit jump
break;
}
case DOT: {
consume(NAME);
- b.add(parserLine, LITERAL, string);
- continueExprAfterAssignable(b);
- break;
+ b.add(parserLine, LITERAL, string);
+ continueExprAfterAssignable(b);
+ break;
}
case LB: { // subscripting (not array constructor)
startExpr(b, -1);
consume(RB);
- continueExprAfterAssignable(b);
- break;
+ continueExprAfterAssignable(b);
+ break;
}
case HOOK: {
b.add(parserLine, JF, new Integer(0)); // jump to the if-false expression
/** Parse a block of statements which must be surrounded by LC..RC. */
void parseBlock(CompiledFunctionImpl b) throws IOException { parseBlock(b, null); }
void parseBlock(CompiledFunctionImpl b, String label) throws IOException {
- int saveParserLine = parserLine;
- _parseBlock(b, label);
- parserLine = saveParserLine;
+ int saveParserLine = parserLine;
+ _parseBlock(b, label);
+ parserLine = saveParserLine;
}
void _parseBlock(CompiledFunctionImpl b, String label) throws IOException {
if (peekToken() == -1) return;
/** Parse a single statement, consuming the RC or SEMI which terminates it. */
void parseStatement(CompiledFunctionImpl b, String label) throws IOException {
- int saveParserLine = parserLine;
- _parseStatement(b, label);
- parserLine = saveParserLine;
+ int saveParserLine = parserLine;
+ _parseStatement(b, label);
+ parserLine = saveParserLine;
}
void _parseStatement(CompiledFunctionImpl b, String label) throws IOException {
int tok = peekToken();
if (label != null) b.add(parserLine, LABEL, label);
b.add(parserLine, LOOP);
int size = b.size();
- b.add(parserLine, POP); // discard the first-iteration indicator
+ b.add(parserLine, POP); // discard the first-iteration indicator
startExpr(b, -1);
b.add(parserLine, JT, new Integer(2)); // if the while() clause is true, jump over the BREAK
b.add(parserLine, BREAK);
case LC: { // blocks are statements too
pushBackToken();
- b.add(parserLine, NEWSCOPE);
+ b.add(parserLine, NEWSCOPE);
parseBlock(b, label);
- b.add(parserLine, OLDSCOPE);
+ b.add(parserLine, OLDSCOPE);
break;
}
private static Object NULL = new Object();
public ScopeImpl(JS.Scope parentScope) { this(parentScope, false); }
public ScopeImpl(JS.Scope parentScope, boolean sealed) {
- super(sealed);
- if (parentScope == this) throw new Error("can't make a scope its own parent!");
- this.parentScope = parentScope;
+ super(sealed);
+ if (parentScope == this) throw new Error("can't make a scope its own parent!");
+ this.parentScope = parentScope;
}
public JS.Scope getParentScope() { return parentScope; }
public boolean has(Object key) { return super.get(key) != null; }
public Object get(Object key) {
- if (!has(key)) return parentScope == null ? null : getParentScope().get(key);
- Object ret = super.get(key); return ret == NULL ? null : ret;
+ if (!has(key)) return parentScope == null ? null : getParentScope().get(key);
+ Object ret = super.get(key); return ret == NULL ? null : ret;
}
public void put(Object key, Object val) {
- if (!has(key) && parentScope != null) getParentScope().put(key, val);
- else super.put(key, val == null ? NULL : val);
+ if (!has(key) && parentScope != null) getParentScope().put(key, val);
+ else super.put(key, val == null ? NULL : val);
}
public Object[] keys() { throw new Error("you can't enumerate the properties of a Scope"); }
public void declare(String s) {
- if (isTransparent()) getParentScope().declare(s);
- else super.put(s, NULL);
+ if (isTransparent()) getParentScope().declare(s);
+ else super.put(s, NULL);
}
}