parser.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 710 行 · 第 1/2 页
JAVA
710 行
/*
* $Id: Parser.java,v 1.1 2003/11/25 11:42:34 epr Exp $
*/
package org.jnode.driver.acpi.aml;
import java.nio.ByteBuffer;
import org.apache.log4j.Logger;
/**
* Parser.
*
* <p>
* Title:
* </p>
* <p>
* Description:
* </p>
* <p>
* Copyright: Copyright (c) 2003
* </p>
* <p>
* Company:
* </p>
*
* @author not attributable
* @version 1.0
*/
public class Parser {
private final Logger log = Logger.getLogger(getClass());
private class ReferencedInteger {
int value;
public ReferencedInteger() {
}
public ReferencedInteger(int value) {
this.value = value;
}
public int increment() {
value++;
return value;
}
public int decrement() {
value--;
return value;
}
public void set(int value) {
this.value = value;
}
public int get() {
return value;
}
}
private class Scope {
ParseNode originNode; // current op being parsed
ByteBuffer buffer;
String argsFormat;
int next_arg; // next argument to parse in argsFormat String
int arg_count = 0; // # fixed arguments
int arg_end; // current argument end
int pkg_end; // current package end
Scope parent = null; // parent scope
public Scope() {
}
public Scope(acpi_parse_state state, ParseNode scopeRoot, String argsFormat, int next_arg, int arg_count) {
this.originNode = scopeRoot;
this.buffer = state.buffer.duplicate();
this.arg_count = arg_count;
this.argsFormat = argsFormat;
this.next_arg = next_arg;
this.arg_end = (arg_count == Aml.ACPI_VAR_ARGS) ? state.pkg_end : Aml.ACPI_MAX_AML;
this.pkg_end = state.pkg_end;
}
public ParseNode getOp() {
return originNode;
}
}
private class acpi_parse_state {
ByteBuffer buffer;
Scope scope; // current scope
Scope scope_avail; // unused (extra) scope structs
int pkg_end; // current package end
public acpi_parse_state(ByteBuffer buf) {
this.buffer = buf;
this.pkg_end = buf.limit();
}
public void acpi_cleanup_scope() {
// destroy available list
while (scope_avail != null) {
Scope scopeTmp = scope_avail;
scope_avail = scopeTmp.parent;
scopeTmp = null;
}
// destroy scope stack
while (scope != null) {
//Scope scopeTmp = scope;
scope = scope.parent;
//scopeTmp = null;
}
}
public ParseNode acpi_pop_scope(Scope newScope) {
Scope prevScope = scope;
ParseNode node = null;
if (prevScope.parent != null) {
// return to parsing previous op
node = scope.getOp();
newScope.argsFormat = scope.argsFormat;
newScope.next_arg = scope.next_arg;
pkg_end = prevScope.pkg_end;
this.scope = prevScope.parent;
// add scope to available list
prevScope.parent = this.scope_avail;
this.scope_avail = prevScope;
} else {
// empty parse stack, prepare to fetch next opcode
newScope.next_arg = 0;
}
return node;
}
public void acpi_push_scope(ParseNode pushedNode, String argsFormat, int next_arg, int arg_count) {
Scope newScope = this.scope_avail;
if (newScope != null) {
// grabbed scope from available list
scope_avail = newScope.parent;
} else {
// allocate scope from the heap
newScope = new Scope();
}
newScope.originNode = pushedNode;
newScope.buffer = buffer.duplicate();
newScope.argsFormat = argsFormat;
newScope.next_arg = next_arg;
newScope.arg_count = arg_count;
newScope.arg_end = (arg_count == Aml.ACPI_VAR_ARGS) ? pkg_end : Aml.ACPI_MAX_AML;
newScope.pkg_end = pkg_end;
newScope.parent = this.scope;
this.scope = newScope;
}
public void acpi_next_namepath(ParseNode arg, ReferencedInteger arg_count, boolean method_calls) {
NameString path = acpi_next_namestring();
ParseNode method = null;
if (method_calls) {
method = acpi_get_parent_scope().find(path, Aml.AML_METHOD, false);
}
if (method != null) {
// method call
ParseNode count = method.getArg(0);
if (count != null && count.opcode == Aml.AML_BYTECONST) {
ParseNode name = new ParseNode(Aml.AML_NAMEPATH);
if (name != null) {
arg.opcode = Aml.AML_METHODCALL;
name.opcode = Aml.AML_NAMEPATH;
name.setName(path);
arg.appendArg(name);
arg_count.set(((Integer) count.value).intValue() & Aml.ACPI_METHOD_ARG_MASK);
}
}
} else {
// variable/name access
arg.opcode = Aml.AML_NAMEPATH;
arg.setName(path);
}
}
public boolean acpi_has_completed_scope() {
return buffer.position() >= scope.arg_end || scope.arg_count == 0;
}
public ParseNode acpi_get_parent_scope() {
return scope.getOp();
}
public byte peekByte() {
return buffer.get(buffer.position());
}
public int peekByteInt() {
return (buffer.get(buffer.position()) & 0xff);
}
public byte getByte() {
return buffer.get();
}
public int getByteInt() {
return (buffer.get()) & 0xff;
}
public int getWord() {
// should use getShort but not implemented in JNode...
int value = peekWord();
move(2);
return value;
}
public int getDWord() {
int value = peekDWord();
move(4);
return value;
}
public String getNameseg() {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 4; i++)
buffer.append((char) (getByteInt()));
return buffer.toString();
}
public int peekWord() {
int tmp;
tmp = (buffer.get(buffer.position() + 1) & 0xff) << 8;
tmp |= buffer.get(buffer.position()) & 0xff;
return tmp;
}
public int peekDWord() {
int tmp;
tmp = (buffer.get(buffer.position() + 3) & 0xff) << 24;
tmp |= (buffer.get(buffer.position() + 2) & 0xff) << 16;
tmp |= (buffer.get(buffer.position() + 1) & 0xff) << 8;
tmp |= buffer.get(buffer.position()) & 0xff;
return tmp;
}
public int acpi_next_pkg_end() {
int start = buffer.position();
int byte1, byte2, byte3, byte4, len = 0;
byte1 = getByteInt();
switch (byte1 >> 6) // bits 6-7 contain encoding scheme
{
case 0 : // 1-byte encoding (bits 0-5)
len = (byte1 & 0x3f);
break;
case 1 : // 2-byte encoding (next byte + bits 0-3)
byte2 = getByteInt();
len = (byte2 << 4) | (byte1 & 0xf);
break;
case 2 : // 3-byte encoding (next 2 bytes + bits 0-3)
byte2 = getByteInt();
byte3 = getByteInt();
len = (byte3 << 12) | (byte2 << 4) | (byte1 & 0xf);
break;
case 3 : // 4-byte encoding (next 3 bytes + bits 0-3)
byte2 = getByteInt();
byte3 = getByteInt();
byte4 = getByteInt();
len = (byte4 << 20) | (byte3 << 12) | (byte2 << 4) | (byte1 & 0xf);
break;
}
return (start + len); // end of package
}
ParseNode acpi_next_field() {
ParseNode field;
int opcode;
// determine field type
switch (this.peekByte()) {
default :
// assert(acpi_is_lead(readb(state->aml)));
opcode = Aml.AML_NAMEDFIELD;
break;
case 0x00 :
opcode = Aml.AML_RESERVEDFIELD;
getByte();
break;
case 0x01 :
opcode = Aml.AML_ACCESSFIELD;
getByte();
break;
}
field = new ParseNode(opcode);
if (field != null) {
int start = buffer.position();
switch (opcode) {
case Aml.AML_NAMEDFIELD :
{
field.setName(getNameseg());
field.value = new Integer(acpi_next_pkg_end() - start);
}
break;
case Aml.AML_RESERVEDFIELD :
field.value = new Integer(acpi_next_pkg_end() - start);
break;
case Aml.AML_ACCESSFIELD :
field.value = new Integer(getWord());
break;
}
}
return field;
}
public int acpi_peek_opcode() {
int opcode = peekByteInt();
int nextOpcode = 0;
if (buffer.position() < buffer.limit() - 1) {
int wordOpcode = peekWord();
nextOpcode = wordOpcode >> 8;
}
if (opcode == Aml.AML_EXTOP || (opcode == Aml.AML_LNOT && (nextOpcode == Aml.AML_LEQUAL || nextOpcode == Aml.AML_LGREATER || nextOpcode == Aml.AML_LLESS))) {
// extended opcode, !=, <=, or >=
opcode = opcode << 8 | nextOpcode;
}
// don't convert bare name to a namepath
return opcode;
}
public ParseNode acpi_next_arg(char argType, ReferencedInteger arg_count) {
ParseNode arg = null;
switch (argType) {
case Aml.AML_BYTEDATA_ARG :
case Aml.AML_WORDDATA_ARG :
case Aml.AML_DWORDDATA_ARG :
case Aml.AML_ASCIICHARLIST_ARG :
case Aml.AML_NAMESTRING_ARG :
case Aml.AML_NAME_ARG :
case Aml.AML_REGIONSPACE_ARG :
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?