/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
* Free SoftwareFoundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.es;
/**
* JavaScript object
*/
class NativeRegexp extends Native {
static ESId INDEX = ESId.intern("index");
static ESId INPUT = ESId.intern("input");
static final int NEW = 1;
static final int COMPILE = NEW + 1;
static final int EXEC = COMPILE + 1;
static final int TEST = EXEC + 1;
static final int TO_STRING = TEST + 1;
/**
* Create a new object based on a prototype
*/
private NativeRegexp(String name, int n, int len)
{
super(name, len);
this.n = n;
}
/**
* Creates the native Regexp object
*/
static ESRegexpWrapper create(Global resin)
{
NativeRegexp nativeRegexp = new NativeRegexp("Regexp", NEW, 1);
ESRegexp proto;
try {
proto = new ESRegexp("", "");
} catch (Exception e) {
throw new RuntimeException();
}
proto.prototype = resin.objProto;
resin.regexpProto = proto;
ESRegexpWrapper regexp = new ESRegexpWrapper(resin, nativeRegexp, proto);
put(proto, "exec", EXEC, 1);
put(proto, "compile", COMPILE, 2);
put(proto, "test", TEST, 1);
put(proto, "toString", TO_STRING, 0);
proto.setClean();
regexp.setClean();
return regexp;
}
static private void put(ESObject proto, String name, int n, int len)
{
ESId id = ESId.intern(name);
NativeRegexp fun = new NativeRegexp(name, n, len);
proto.put(id, fun, DONT_ENUM);
}
public ESBase call(Call eval, int length) throws Throwable
{
switch (n) {
case NEW:
return create(eval, length);
case TO_STRING:
try {
ESRegexp regexp = (ESRegexp) eval.getThis();
String s = regexp.pattern.toString();
String f = regexp.flags.toString();
return ESString.create("/" + s + "/" + f);
} catch (ClassCastException e) {
throw new ESException("toString expected regexp object");
}
case EXEC:
return exec(eval, length);
case COMPILE:
return compile(eval, length);
case TEST:
return test(eval, length);
default:
throw new ESException("Unknown object function");
}
}
private ESBase create(Call eval, int length) throws Throwable
{
ESString pattern;
ESString flags = null;
if (length == 0)
pattern = ESString.NULL;
else
pattern = eval.getArg(0).toStr();
if (length > 1)
flags = eval.getArg(1).toStr();
else
flags = ESString.NULL;
ESObject obj;
obj = new ESRegexp(pattern, flags);
return obj;
}
private ESBase compile(Call eval, int length) throws Throwable
{
ESString pattern;
ESString flags = null;
ESBase arg = eval.getArg(-1);
if (arg instanceof ESThunk)
arg = ((ESThunk) arg).toObject();
if (! (arg instanceof ESRegexp))
throw new ESException("compile must be bound to regexp");
ESRegexp regexp = (ESRegexp) arg;
if (length == 0)
return esUndefined;
else
pattern = eval.getArg(0).toStr();
if (length > 1)
flags = eval.getArg(1).toStr();
else
flags = ESString.NULL;
regexp.compile(pattern, flags);
return regexp;
}
static ESBase exec(Call eval, int length) throws Throwable
{
ESBase reg = eval.getArg(-1);
ESRegexp regexp;
if (reg instanceof ESThunk)
reg = ((ESThunk) reg).toObject();
if (reg instanceof ESRegexp)
regexp = (ESRegexp) reg;
else
regexp = new ESRegexp(reg.toStr(), ESString.NULL);
if (regexp.prototype == null)
throw new RuntimeException();
ESString string;
Global global = Global.getGlobalProto();
if (length == 0)
string = global.getRegexp().getProperty(global.getRegexp().INPUT).toStr();
else
string = eval.getArg(0).toStr();
global.getRegexp().setRegexp(regexp);
if (! regexp.exec(string))
return esNull;
return esNull;
/* java.util.regex
ESArray array = global.createArray();
for (int i = 0; i < regexp.regexp.length(); i++) {
int begin = regexp.regexp.getBegin(i);
int end = regexp.regexp.getEnd(i);
if (begin < end && begin >= 0)
array.setProperty(i, string.substring(begin, end));
else
array.setProperty(i, ESString.create("")); // XXX: possible?
}
// java.util.regex
// array.setProperty(INDEX, ESNumber.create(regexp.regexp.getBegin(0)));
array.setProperty(INPUT, string);
return array;
*/
}
private ESBase test(Call eval, int length) throws Throwable
{
ESBase reg = eval.getArg(-1);
ESRegexp regexp;
if (reg instanceof ESThunk)
reg = ((ESThunk) reg).toObject();
if (reg instanceof ESRegexp)
regexp = (ESRegexp) reg;
else
regexp = new ESRegexp(reg.toStr(), ESString.NULL);
if (regexp.prototype == null)
throw new RuntimeException();
ESString string;
ESRegexpWrapper globalRegexp = Global.getGlobalProto().getRegexp();
if (length == 0)
string = globalRegexp.getProperty(globalRegexp.INPUT).toStr();
else
string = eval.getArg(0).toStr();
globalRegexp.setRegexp(regexp);
return ESBoolean.create(regexp.exec(string));
}
}