parser.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 710 行 · 第 1/2 页
JAVA
710 行
case Aml.AML_FIELDFLAGS_ARG :
case Aml.AML_METHODFLAGS_ARG :
case Aml.AML_SYNCFLAGS_ARG :
// constants, strings, and namestrings are all the same size
arg = new ParseNode(Aml.AML_BYTECONST);
acpi_next_simple(arg, argType);
break;
case Aml.AML_PKGLENGTH_ARG :
// package length, nothing returned
pkg_end = acpi_next_pkg_end();
break;
case Aml.AML_FIELDLIST_ARG :
if (buffer.position() < pkg_end) {
// non-empty list
ParseNode prev = null;
while (buffer.position() < pkg_end) {
ParseNode field = acpi_next_field();
if (field == null) {
break;
}
if (prev != null) {
prev.next = field;
} else {
arg = field;
}
prev = field;
}
// skip to end of byte data
buffer.position(pkg_end);
}
break;
case Aml.AML_BYTELIST_ARG :
if (buffer.position() < pkg_end) {
// non-empty list
arg = new ParseNode(Aml.AML_BYTELIST);
if (arg != null) {
// fill in bytelist data
int oldlimit = buffer.limit();
buffer.limit(pkg_end);
arg.data = buffer.slice();
buffer.limit(oldlimit);
}
// skip to end of byte data
buffer.position(pkg_end);
}
break;
case Aml.AML_TARGET_ARG :
case Aml.AML_SUPERNAME_ARG :
{
int subop = acpi_peek_opcode();
if (subop == 0 || Aml.isLeadChar((byte) subop) || Aml.isPrefixChar((byte) subop)) {
// NullName or NameString
arg = new ParseNode(Aml.AML_NAMEPATH);
acpi_next_namepath(arg, arg_count, false);
} else {
// single complex argument, nothing returned
arg_count.set(1);
}
}
break;
case Aml.AML_DATAOBJECT_ARG :
case Aml.AML_TERMARG_ARG :
// single complex argument, nothing returned
arg_count.set(1);
break;
case Aml.AML_DATAOBJECTLIST_ARG :
case Aml.AML_TERMLIST_ARG :
case Aml.AML_OBJECTLIST_ARG :
if (buffer.position() < pkg_end) {
// non-empty list of variable args, nothing returned
arg_count.set(Aml.ACPI_VAR_ARGS);
}
break;
default :
// Missing a case above after modifying amlop.txt and mkaml
// THROW EXCEPTION *((int *)0) = 0;
}
return arg;
}
/*
* Get next namestring
*/
NameString acpi_next_namestring() {
NameString ns = new NameString();
StringBuffer prefix = new StringBuffer();
if (Aml.isPrefixChar(peekByte())) {
while (Aml.isPrefixChar(peekByte())) {
prefix.append((char) getByteInt());
}
ns.setPrefix(prefix.toString());
}
switch (peekByte()) {
case 0 :
// NullName
if (prefix.length() == 0) {
ns = null;
}
move(1);
break;
case Aml.AML_DUALNAMEPATH :
// two name segments
move(1); // skips the dual name path indicator
ns.addDualNamePath(this.buffer); // buffer is advanced accordingly
break;
case Aml.AML_MULTINAMEPATH :
{
// multiple name segments
move(1);
ns.addMultiNamePath(this.buffer); // buffer is advanced accordingly
}
break;
default :
// single name segment
// assert(acpi_is_lead(readb(end)));
ns.addNamePath(buffer);
break;
}
return ns;
}
/*
* Get next simple argument (constant, string, or namestring)
*/
ParseNode acpi_next_simple(ParseNode arg, char arg_type) {
switch (arg_type) {
case Aml.AML_BYTEDATA_ARG :
arg.opcode = Aml.AML_BYTECONST;
arg.value = new Integer(getByteInt());
break;
case Aml.AML_WORDDATA_ARG :
arg.opcode = Aml.AML_WORDCONST;
arg.value = new Integer(getWord());
break;
case Aml.AML_DWORDDATA_ARG :
arg.opcode = Aml.AML_DWORDCONST;
arg.value = new Integer(getDWord());
break;
case Aml.AML_ASCIICHARLIST_ARG :
arg.opcode = Aml.AML_STRING;
String tmp = new String();
char c = 0;
while ((c = (char) getByte()) != '\0') {
tmp += c;
}
arg.value = tmp;
break;
case Aml.AML_NAMESTRING_ARG :
case Aml.AML_NAME_ARG :
arg.opcode = Aml.AML_NAMEPATH;
arg.setName(acpi_next_namestring());
break;
case Aml.AML_FIELDFLAGS_ARG :
arg.opcode = Aml.AML_FIELDFLAGS;
arg.value = new Integer(getByteInt());
break;
case Aml.AML_REGIONSPACE_ARG :
arg.opcode = Aml.AML_REGIONSPACE;
arg.value = new Integer(getByteInt());
break;
case Aml.AML_METHODFLAGS_ARG :
arg.opcode = Aml.AML_METHODFLAGS;
arg.value = new Integer(getByteInt());
break;
case Aml.AML_SYNCFLAGS_ARG :
arg.opcode = Aml.AML_SYNCFLAGS;
arg.value = new Integer(getByteInt());
break;
}
return arg;
}
public void move(int bytes) {
buffer.position(buffer.position() + bytes);
}
} // END OF PRIVATE INNER CLASS STATE
public Parser() {
}
public void acpi_parse_aml(ParseNode root, ByteBuffer buffer) {
acpi_parse_state state = null; // parser state
ParseNode currentNode = null; // current op
String argsFormat = null; // current op next argument
int argsIndex = 0;
ReferencedInteger arg_count = new ReferencedInteger(0);
// initialize parser state
state = new acpi_parse_state(buffer);
// adds the root scope
state.scope = new Scope(state, root, null, 0, Aml.ACPI_VAR_ARGS);
while (state.buffer.position() < state.buffer.limit()) {
if (currentNode == null) {
int opcode = state.acpi_peek_opcode();
AmlOpcode opc = AmlOpcode.getAmlOpcode(opcode);
if (opc != null) {
// normal opcode
state.move(((opcode & 0xff00) > 0) ? 2 : 1);
argsFormat = opc.argsFormat;
argsIndex = 0;
} else if (Aml.isPrefixChar((byte) opcode) || Aml.isLeadChar((byte) opcode)) {
// convert bare name string to namepath
opcode = Aml.AML_NAMEPATH;
opc = AmlOpcode.getAmlOpcode(opcode);
argsFormat = "n";
argsIndex = 0;
} else {
// skip unknown opcodes
state.move(((opcode & 0xff00) > 0) ? 2 : 1);
continue;
}
// create and append to parent's argument list
if (Aml.isNamedOpcode(opcode)) {
ParseNode preop = null;
while (argsIndex < argsFormat.length() && argsFormat.charAt(argsIndex) != Aml.AML_NAME_ARG) {
ParseNode arg = state.acpi_next_arg(argsFormat.charAt(argsIndex), arg_count);
if (preop == null)
preop = arg;
else
preop.appendArg(arg);
argsIndex++;
}
currentNode = (state.acpi_get_parent_scope()).find(state.acpi_next_namestring(), opcode, true);
argsIndex++;
if (currentNode != null)
currentNode.appendArg(preop);
else
log.debug("Trying to add to an empty node");
} else {
currentNode = new ParseNode(opcode);
state.acpi_get_parent_scope().appendArg(currentNode);
}
if (currentNode == null) {
break;
}
} // if currentNode ==null
arg_count.set(0);
if (argsFormat != null) {
// get arguments
switch (currentNode.opcode) {
case Aml.AML_BYTECONST : // AML_BYTEDATA_ARG
case Aml.AML_WORDCONST : // AML_WORDDATA_ARG
case Aml.AML_DWORDCONST : // AML_DWORDATA_ARG
case Aml.AML_STRING : // AML_ASCIICHARLIST_ARG
// fill in constant or string argument directly
state.acpi_next_simple(currentNode, argsFormat.charAt(argsIndex));
break;
case Aml.AML_NAMEPATH :
state.acpi_next_namepath(currentNode, arg_count, true);
argsFormat = null;
break;
default :
// op is not a constant or string
// append each argument
while (argsIndex < argsFormat.length() && arg_count.get() == 00) {
ParseNode arg = state.acpi_next_arg(argsFormat.charAt(argsIndex), arg_count);
currentNode.appendArg(arg);
argsIndex++;
}
if (currentNode.opcode == Aml.AML_METHOD) {
// skip parsing of method body
currentNode.data = state.buffer.duplicate();
currentNode.data.limit(state.pkg_end);
currentNode.data = currentNode.data.slice();
currentNode.data.rewind();
try {
state.buffer.position(state.pkg_end);
} catch (Exception ex) {
System.err.println(state.buffer.position() + "," + state.buffer.limit() + ":" + state.pkg_end);
}
arg_count.set(0);
}
break;
}
}
if (arg_count.get() == 0) {
// completed op, prepare for next
state.scope.arg_count--;
if (state.acpi_has_completed_scope()) {
Scope newScope = new Scope();
currentNode = state.acpi_pop_scope(newScope);
argsFormat = newScope.argsFormat;
argsIndex = newScope.next_arg;
} else {
currentNode = null;
}
} else {
// complex argument, push op and prepare for argument
state.acpi_push_scope(currentNode, argsFormat, argsIndex, arg_count.get());
currentNode = null;
}
}
// complete any remaining ops
state.acpi_cleanup_scope();
}
public ParseNode parse(ByteBuffer buffer) {
ParseNode root = new ParseNode(Aml.AML_SCOPE);
if (root == null) {
return root;
}
//ParseNode op;
// parse excluding method bodies
acpi_parse_aml(root, buffer);
return root;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?