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 + -
显示快捷键?