package php.runtime.ext.core.classes.util;
import php.runtime.Memory;
import php.runtime.env.Environment;
import php.runtime.ext.core.classes.stream.Stream;
import php.runtime.ext.core.classes.stream.WrapIOException;
import php.runtime.lang.BaseObject;
import php.runtime.lang.ForeachIterator;
import php.runtime.lang.spl.iterator.Iterator;
import php.runtime.lang.support.IComparableObject;
import php.runtime.memory.DoubleMemory;
import php.runtime.memory.LongMemory;
import php.runtime.memory.ObjectMemory;
import php.runtime.memory.StringMemory;
import php.runtime.reflection.ClassEntity;
import java.util.NoSuchElementException;
import java.util.Scanner;
import static php.runtime.annotation.Reflection.*;
@Name("php\\util\\Scanner")
public class WrapScanner extends BaseObject
implements IComparableObject<WrapScanner>, Iterator {
protected Scanner scanner;
protected Memory current = null;
protected Memory key = Memory.CONST_INT_M1;
protected boolean valid = true;
public WrapScanner(Environment env, Scanner scanner) {
super(env);
this.scanner = scanner;
}
public WrapScanner(Environment env, ClassEntity clazz) {
super(env, clazz);
}
public Scanner getScanner() {
return scanner;
}
@Signature({
@Arg("source"),
@Arg(value = "charset", optional = @Optional("null"))
})
public Memory __construct(Environment env, Memory... args) {
if (args[0].instanceOf(Stream.class)) {
if (args[1].isNull())
scanner = new Scanner(Stream.getInputStream(env, args[0]));
else
scanner = new Scanner(Stream.getInputStream(env, args[0]), args[1].toString());
} else {
scanner = new Scanner(args[0].toString());
}
return Memory.NULL;
}
@Signature(@Arg(value = "pattern", nativeType = WrapRegex.class, optional = @Optional("null")))
public Memory hasNext(Environment env, Memory... args) {
if (args[0].isNull())
return scanner.hasNext() ? Memory.TRUE : Memory.FALSE;
else
return scanner.hasNext(args[0].toObject(WrapRegex.class).getMatcher().pattern()) ? Memory.TRUE : Memory.FALSE;
}
@Signature
public Memory getIOException(Environment env, Memory... args) {
if (scanner.ioException() == null)
return Memory.NULL;
else
return new ObjectMemory(new WrapIOException(env, scanner.ioException()));
}
@Override
@Signature
public Memory current(Environment env, Memory... args) {
return current;
}
@Override
@Signature
public Memory key(Environment env, Memory... args) {
return key;
}
@Signature(@Arg(value = "pattern", nativeType = WrapRegex.class, optional = @Optional("null")))
public Memory next(Environment env, Memory... args) {
try {
key = key.inc();
return current = StringMemory.valueOf(args.length == 0 || args[0].isNull()
? scanner.next()
: scanner.next(args[0].toObject(WrapRegex.class).getMatcher().pattern())
);
} catch (NoSuchElementException e) {
valid = false;
current = Memory.NULL;
key = Memory.NULL;
return Memory.NULL;
}
}
@Override
@Signature
public Memory rewind(Environment env, Memory... args) {
if (current != null)
env.exception("Iterator of the scanner can be used only one time");
valid = true;
next(env, Memory.NULL);
return Memory.NULL;
}
@Override
@Signature
public Memory valid(Environment env, Memory... args) {
return valid ? Memory.TRUE : Memory.FALSE;
}
@Signature
public Memory nextLine(Environment env, Memory... args) {
try {
return StringMemory.valueOf(scanner.nextLine());
} catch (NoSuchElementException e) {
return Memory.NULL;
}
}
@Signature
public Memory hasNextLine(Environment env, Memory... args) {
return scanner.hasNextLine() ? Memory.TRUE : Memory.FALSE;
}
@Signature(@Arg(value = "radix", optional = @Optional("null")))
public Memory hasNextInt(Environment env, Memory... args) {
return (args[0].isNull() ? scanner.hasNextLong() : scanner.hasNextInt(args[0].toInteger()))
? Memory.TRUE : Memory.FALSE;
}
@Signature(@Arg(value = "radix", optional = @Optional("null")))
public Memory nextInt(Environment env, Memory... args) {
try {
return LongMemory.valueOf(args[0].isNull()
? scanner.nextLong()
: scanner.nextLong(args[0].toInteger()));
} catch (NoSuchElementException e) {
return Memory.NULL;
}
}
@Signature
public Memory nextDouble(Environment env, Memory... args) {
try {
return new DoubleMemory(scanner.nextDouble());
} catch (NoSuchElementException e) {
return Memory.NULL;
}
}
@Signature
public Memory hasNextDouble(Environment env, Memory... args) {
return scanner.hasNextDouble() ? Memory.TRUE : Memory.FALSE;
}
@Signature(@Arg(value = "pattern", nativeType = WrapRegex.class))
public Memory useDelimiter(Environment env, Memory... args) {
scanner.useDelimiter(args[0].toObject(WrapRegex.class).getMatcher().pattern());
return new ObjectMemory(this);
}
@Signature(@Arg(value = "locale", nativeType = WrapLocale.class))
public Memory useLocale(Environment env, Memory... args) {
scanner.useLocale(args[0].toObject(WrapLocale.class).getLocale());
return new ObjectMemory(this);
}
@Signature(@Arg("value"))
public Memory useRadix(Environment env, Memory... args) {
scanner.useRadix(args[0].toInteger());
return new ObjectMemory(this);
}
@Signature(@Arg(value = "regex", nativeType = WrapRegex.class))
public Memory skip(Environment env, Memory... args) {
try {
scanner.skip(args[0].toObject(WrapRegex.class).getMatcher().pattern());
return Memory.TRUE;
} catch (NoSuchElementException e) {
return Memory.FALSE;
}
}
@Signature
public Memory reset(Environment env, Memory... args) {
scanner.reset();
return Memory.NULL;
}
@Signature
public Memory __destruct(Environment env, Memory... args) {
scanner.close();
return Memory.NULL;
}
@Override
public boolean __equal(WrapScanner iObject) {
return false;
}
@Override
public boolean __identical(WrapScanner iObject) {
return false;
}
@Override
public boolean __greater(WrapScanner iObject) {
return false;
}
@Override
public boolean __greaterEq(WrapScanner iObject) {
return false;
}
@Override
public boolean __smaller(WrapScanner iObject) {
return false;
}
@Override
public boolean __smallerEq(WrapScanner iObject) {
return false;
}
@Signature
private Memory __clone(Environment env, Memory... args) {
return Memory.NULL;
}
@Override
public ForeachIterator getNewIterator(Environment env, boolean getReferences, boolean getKeyReferences) {
return ObjectMemory.valueOf(this).getNewIterator(env, getReferences, getKeyReferences);
}
@Override
public ForeachIterator getNewIterator(Environment env) {
return ObjectMemory.valueOf(this).getNewIterator(env);
}
}