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