- DOM parser replaced by SAX parser
git-svn-id: https://svn.code.sf.net/p/libusbjava/code/trunk@117 94ad28fe-ef68-46b1-9651-e7ae4fcf1c4c
This commit is contained in:
@@ -6,66 +6,48 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.parsers.SAXParser;
|
||||||
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.xml.sax.Attributes;
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.ErrorHandler;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
/**
|
public abstract class RegisterDict extends DefaultHandler {
|
||||||
* Representation of a register dictionary. All registers are read from an
|
|
||||||
* xml-file specified by <code>registerDictionary.dtd</code>. Note that the
|
|
||||||
* type values are implementation specific. Therefore each <i>Register</i> has
|
|
||||||
* its own <i>registerDictionary.dtd</i> definition. For an example see
|
|
||||||
* <code>MPC555Register</code> and the corresponding
|
|
||||||
* <code>resources/targets/mpc555/registerDictionary.dtd</code> file.
|
|
||||||
*
|
|
||||||
* @author schlaepfer
|
|
||||||
*/
|
|
||||||
public abstract class RegisterDict {
|
|
||||||
|
|
||||||
private LinkedList registers;
|
|
||||||
|
|
||||||
private Class<? extends Register> regClass;
|
|
||||||
|
|
||||||
private Method regClassGetTypesMethod;
|
|
||||||
|
|
||||||
private static final String GetTypes_METHOD_NAME = "getTypes";
|
|
||||||
|
|
||||||
private String[] types;
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -582382284126896830L;
|
private static final long serialVersionUID = -582382284126896830L;
|
||||||
|
|
||||||
private static final String REGISTER_DEFINITIONS = "registerDefinitions";
|
private Class<? extends Register> regClass;
|
||||||
|
private Method regClassGetTypesMethod;
|
||||||
|
private static final String GetTypes_METHOD_NAME = "getTypes";
|
||||||
|
|
||||||
private static final String REGISTER_GROUP = "registerGroup";
|
private LinkedList registers;
|
||||||
|
|
||||||
private static final String REG_GROUP_ATTR_BASEADDR = "baseAddress";
|
private String[] types;
|
||||||
|
|
||||||
private static final String REGISTER = "register";
|
private static final String ELEMENT_REGISTER = "register";
|
||||||
|
private static final String ELEMENT_DESCRIPTION = "description";
|
||||||
|
|
||||||
private static final String DESCRIPTION = "description";
|
private static final String ATTR_MNEMONIC = "mnemonic";
|
||||||
|
private static final String ATTR_ALTMNEMONIC = "altmnemonic";
|
||||||
|
private static final String ATTR_TYPE = "type";
|
||||||
|
private static final String ATTR_VALUE = "value";
|
||||||
|
private static final String ATTR_SIZE = "size";
|
||||||
|
private static final String ATTR_ACCESSMODE = "accessmode";
|
||||||
|
private static final String ATTR_ACCESSATTR = "accessattr";
|
||||||
|
|
||||||
private static final String REG_ATTR_MNEMONIC = "mnemonic";
|
private Register reg;
|
||||||
|
private StringBuffer cdata;
|
||||||
private static final String REG_ATTR_TYPE = "type";
|
|
||||||
|
|
||||||
private static final String REG_ATTR_VALUE = "value";
|
|
||||||
|
|
||||||
private static final String REG_ATTR_SIZE = "size";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor which takes the Class object from a
|
* Default constructor which takes the Class object from a
|
||||||
* <code>Register</code> subclass as argument. The registerDict will be of
|
* <code>Register</code> subclass as argument. The registerDict will be of
|
||||||
* this Register-type.<br>
|
* this Register-type.<br>
|
||||||
* An example:<br>
|
* An example:<br>
|
||||||
* MPC555Register extends Register -> use MPC555Register.class as parameter.
|
* MPC555Register extends Register -> use <code>MPC555Register.class</code>
|
||||||
|
* as parameter.
|
||||||
*
|
*
|
||||||
* @param registerClass
|
* @param registerClass
|
||||||
* subclass of Register
|
* subclass of Register
|
||||||
@@ -85,44 +67,13 @@ public abstract class RegisterDict {
|
|||||||
this.registers = new LinkedList();
|
this.registers = new LinkedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private int convertType(String typeStr) throws SAXException {
|
||||||
* Add a new register to the registerDict.
|
for (int index = 0; index < types.length; index++) {
|
||||||
*
|
if (typeStr.equals(types[index])) {
|
||||||
* @param name
|
return index;
|
||||||
* name of the register. Registers are identified by this value.
|
|
||||||
* @param type
|
|
||||||
* register specific type
|
|
||||||
* @param value
|
|
||||||
* address or a register specific value (e.g. BDI-identifier)
|
|
||||||
* @param size
|
|
||||||
* size in bytes
|
|
||||||
* @param description
|
|
||||||
* a string description of the register
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void add(String name, int type, int value, int size,
|
|
||||||
String description) {
|
|
||||||
// remove before add for updates
|
|
||||||
for (Iterator i = registers.iterator(); i.hasNext();) {
|
|
||||||
Register r = (Register) i.next();
|
|
||||||
if (r.getMnemonic().equals(name) || r.getAltmnemonic().equals(name)) {
|
|
||||||
i.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Register reg = null;
|
throw new SAXException("invalid register definition: " + typeStr);
|
||||||
try {
|
|
||||||
reg = (Register) regClass.newInstance();
|
|
||||||
reg.setMnemonic(name);
|
|
||||||
reg.setType(type);
|
|
||||||
reg.setValue(value);
|
|
||||||
reg.setSize(size);
|
|
||||||
reg.setDescription(description);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
// TODO exception handling
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
registers.add(reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int parseInt(String s) {
|
private int parseInt(String s) {
|
||||||
@@ -146,20 +97,37 @@ public abstract class RegisterDict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a register by its name.
|
* Adds the registers from the specified xml-file to the register
|
||||||
|
* dictionary. <br>
|
||||||
|
* The xml-file must be structured according to
|
||||||
|
* <code>registerDictionary.dtd</code>. The dtd-file must be adapted to
|
||||||
|
* the type values specific to this register. Include
|
||||||
|
* <code><!DOCTYPE registerDefinitions SYSTEM "registerDictionary.dtd"></code>
|
||||||
|
* in your xml file.
|
||||||
*
|
*
|
||||||
* @param name
|
* @param xmlPathname
|
||||||
* the register name
|
* path to the xml file
|
||||||
* @return register on null if no register is found
|
* @throws IOException
|
||||||
|
* throws an IOException if the file is not found
|
||||||
|
* @throws SAXException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
* throws an ParserConfigurationException if the SAX parser
|
||||||
|
* can't be configured
|
||||||
|
* @throws SAXException
|
||||||
|
* throws an SAXException if the file could not be successfully
|
||||||
|
* parsed
|
||||||
*/
|
*/
|
||||||
public Register getRegister(String name) {
|
public void addRegistersFromFile(String xmlPathname) throws IOException,
|
||||||
for (Iterator i = registers.iterator(); i.hasNext();) {
|
ParserConfigurationException, SAXException {
|
||||||
Register r = (Register) i.next();
|
// reset temporary register variable
|
||||||
if (r.getMnemonic().equals(name) || r.getAltmnemonic().equals(name)) {
|
reg = null;
|
||||||
return r;
|
// Use the default (non-validating) parser
|
||||||
}
|
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||||
}
|
factory.setValidating(true);
|
||||||
return null;
|
// Parse the input
|
||||||
|
SAXParser saxParser = factory.newSAXParser();
|
||||||
|
saxParser.parse(new File(xmlPathname), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,122 +149,112 @@ public abstract class RegisterDict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the registers from the specified xml-file to the register
|
* Get a register by its name.
|
||||||
* dictionary. <br>
|
|
||||||
* The xml-file must be structured according to
|
|
||||||
* <code>registerDictionary.dtd</code>. The dtd-file must be adapted to
|
|
||||||
* the type values specific to this register. Include
|
|
||||||
* <code><!DOCTYPE registerDefinitions SYSTEM "registerDictionary.dtd"></code>
|
|
||||||
* in your xml file.
|
|
||||||
*
|
*
|
||||||
* @param xmlPathname
|
* @param name
|
||||||
* path to the xml file
|
* the register name
|
||||||
* @throws IOException
|
* @return register on null if no register is found
|
||||||
* throws an IOException if the file is not found
|
|
||||||
* @throws ParserConfigurationException
|
|
||||||
* throws an ParserConfigurationException if the SAX parser
|
|
||||||
* can't be configured
|
|
||||||
* @throws SAXException
|
|
||||||
* throws an SAXException if the file could not be successfully
|
|
||||||
* parsed
|
|
||||||
*/
|
*/
|
||||||
public void addRegistersFromFile(String xmlPathname) throws IOException,
|
public Register getRegister(String name) {
|
||||||
ParserConfigurationException, SAXException {
|
for (Iterator i = registers.iterator(); i.hasNext();) {
|
||||||
Document document;
|
Register r = (Register) i.next();
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
if (r.getMnemonic().equals(name) || r.getAltmnemonic().equals(name)) {
|
||||||
factory.setValidating(true);
|
return r;
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
||||||
builder.setErrorHandler(new ErrorHandler() {
|
|
||||||
// ignore fatal errors (an exception is guaranteed)
|
|
||||||
public void fatalError(SAXParseException exception)
|
|
||||||
throws SAXException {
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// treat validation errors as fatal error
|
// ===========================================================
|
||||||
public void error(SAXParseException e) throws SAXParseException {
|
// SAX DocumentHandler methods
|
||||||
throw e;
|
// ===========================================================
|
||||||
}
|
|
||||||
|
|
||||||
// treat warnings as fatal error
|
public void startDocument() throws SAXException {
|
||||||
public void warning(SAXParseException e) throws SAXParseException {
|
}
|
||||||
throw e;
|
|
||||||
}
|
public void endDocument() throws SAXException {
|
||||||
});
|
}
|
||||||
document = builder.parse(new File(xmlPathname));
|
|
||||||
NodeList list = document.getElementsByTagName(REGISTER_DEFINITIONS);
|
public void startElement(String namespaceURI, String lName, // local name
|
||||||
for (int i = 0; i < list.getLength(); i++) {
|
String qName, // qualified name
|
||||||
if (list.item(i).getNodeName().equals(REGISTER_DEFINITIONS)) {
|
Attributes attrs) throws SAXException {
|
||||||
list = list.item(i).getChildNodes();
|
if (qName.equals(ELEMENT_REGISTER)) {
|
||||||
}
|
if (attrs != null) {
|
||||||
for (int j = 0; j < list.getLength(); j++) {
|
// instantiate new register
|
||||||
if (list.item(j).getNodeName().equals(REGISTER_GROUP)) {
|
try {
|
||||||
NamedNodeMap attributes = list.item(j).getAttributes();
|
reg = (Register) regClass.newInstance();
|
||||||
for (int k = 0; k < attributes.getLength(); k++) {
|
} catch (Exception e) {
|
||||||
if (attributes.item(k).getNodeName().equals(
|
throw new SAXException(e.getMessage());
|
||||||
REG_GROUP_ATTR_BASEADDR)) {
|
|
||||||
int baseAddr = parseInt(attributes.item(k)
|
|
||||||
.getNodeValue());
|
|
||||||
parseRegisterGroup(list.item(j), baseAddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (list.item(j).getNodeName().equals(REGISTER)) {
|
|
||||||
NamedNodeMap attributes = list.item(j).getAttributes();
|
|
||||||
// attributes: name, type, offset, size
|
|
||||||
Node n = attributes.getNamedItem(REG_ATTR_MNEMONIC);
|
|
||||||
String name = n.getNodeValue();
|
|
||||||
n = attributes.getNamedItem(REG_ATTR_TYPE);
|
|
||||||
String typeStr = n.getNodeValue();
|
|
||||||
int type = convertType(typeStr);
|
|
||||||
n = attributes.getNamedItem(REG_ATTR_VALUE);
|
|
||||||
int value = parseInt(n.getNodeValue());
|
|
||||||
n = attributes.getNamedItem(REG_ATTR_SIZE);
|
|
||||||
int size = parseInt(n.getNodeValue());
|
|
||||||
parseRegister(list.item(j), name, type, value, size);
|
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < attrs.getLength(); i++) {
|
||||||
|
String attr_qName = attrs.getQName(i);
|
||||||
|
String attr_value = attrs.getValue(i);
|
||||||
|
if (attr_qName.equals(ATTR_MNEMONIC)) {
|
||||||
|
reg.setMnemonic(attr_value);
|
||||||
|
} else if (attr_qName.equals(ATTR_ALTMNEMONIC)) {
|
||||||
|
reg.setAltmnemonic(attr_value);
|
||||||
|
} else if (attr_qName.equals(ATTR_TYPE)) {
|
||||||
|
reg.setType(convertType(attr_value));
|
||||||
|
} else if (attr_qName.equals(ATTR_SIZE)) {
|
||||||
|
reg.setSize(parseInt(attr_value));
|
||||||
|
} else if (attr_qName.equals(ATTR_VALUE)) {
|
||||||
|
reg.setValue(parseInt(attr_value));
|
||||||
|
} else if (attr_qName.equals(ATTR_ACCESSMODE)) {
|
||||||
|
reg.setAccessmode(Register.Accessmode
|
||||||
|
.valueOf(attr_value));
|
||||||
|
} else if (attr_qName.equals(ATTR_ACCESSATTR)) {
|
||||||
|
reg.setAccessattr(Register.Accessattr
|
||||||
|
.valueOf(attr_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new SAXException("attributes expected");
|
||||||
}
|
}
|
||||||
|
} else if (qName.equals(ELEMENT_DESCRIPTION)) {
|
||||||
|
// reset the cdata for descriptions
|
||||||
|
cdata = new StringBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int convertType(String typeStr) throws SAXException {
|
@SuppressWarnings("unchecked")
|
||||||
for (int index = 0; index < types.length; index++) {
|
public void endElement(String namespaceURI, String sName, // simple
|
||||||
if (typeStr.equals(types[index])) {
|
// name
|
||||||
return index;
|
String qName // qualified name
|
||||||
}
|
) throws SAXException {
|
||||||
|
if (qName.equals(ELEMENT_DESCRIPTION)) {
|
||||||
|
reg.setDescription(cdata.toString().trim());
|
||||||
}
|
}
|
||||||
throw new SAXException("invalid register definition: " + typeStr);
|
if (reg != null) {
|
||||||
}
|
registers.add(reg);
|
||||||
|
reg = null;
|
||||||
private void parseRegisterGroup(Node registerGroup, int baseAddr)
|
|
||||||
throws SAXException {
|
|
||||||
NodeList list = registerGroup.getChildNodes();
|
|
||||||
for (int i = 0; i < list.getLength(); i++) {
|
|
||||||
if (list.item(i).getNodeName().equals(REGISTER)) {
|
|
||||||
NamedNodeMap attributes = list.item(i).getAttributes();
|
|
||||||
// attributes: name, type, offset, size
|
|
||||||
Node n = attributes.getNamedItem(REG_ATTR_MNEMONIC);
|
|
||||||
String name = n.getNodeValue();
|
|
||||||
n = attributes.getNamedItem(REG_ATTR_TYPE);
|
|
||||||
String typeStr = n.getNodeValue();
|
|
||||||
int type = convertType(typeStr);
|
|
||||||
n = attributes.getNamedItem(REG_ATTR_VALUE);
|
|
||||||
int offset = parseInt(n.getNodeValue());
|
|
||||||
n = attributes.getNamedItem(REG_ATTR_SIZE);
|
|
||||||
int size = parseInt(n.getNodeValue());
|
|
||||||
|
|
||||||
parseRegister(list.item(i), name, type, baseAddr + offset, size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRegister(Node register, String name, int type, int addr,
|
public void characters(char buf[], int offset, int len) throws SAXException {
|
||||||
int size) throws SAXException {
|
int startOffset = offset;
|
||||||
NodeList list = register.getChildNodes();
|
while ((offset < startOffset + len) && (buf[offset] <= ' ')) {
|
||||||
String description = "";
|
offset++;
|
||||||
for (int i = 0; i < list.getLength(); i++) {
|
|
||||||
if (list.item(i).getNodeName().equals(DESCRIPTION)) {
|
|
||||||
description = list.item(i).getTextContent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
add(name, type, addr, size, description);
|
len -= offset - startOffset;
|
||||||
|
while ((len > 0) && (buf[offset + len - 1] <= ' ')) {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
cdata.append(buf, offset, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// SAX ErrorHandler methods
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
// treat validation errors as fatal
|
||||||
|
public void error(SAXParseException e) throws SAXParseException {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dump warnings too
|
||||||
|
public void warning(SAXParseException err) throws SAXParseException {
|
||||||
|
System.out.println("** Warning" + ", line " + err.getLineNumber()
|
||||||
|
+ ", uri " + err.getSystemId());
|
||||||
|
System.out.println(" " + err.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,15 +32,15 @@ public class IMCBTargetBoard {
|
|||||||
logger.info("writeRegister: " + name + ", value: 0x"
|
logger.info("writeRegister: " + name + ", value: 0x"
|
||||||
+ Integer.toHexString(value));
|
+ Integer.toHexString(value));
|
||||||
MC68332Register r = (MC68332Register) regDict.getRegister(name);
|
MC68332Register r = (MC68332Register) regDict.getRegister(name);
|
||||||
switch (r.type) {
|
switch (r.getType()) {
|
||||||
case MC68332Register.CtrlReg:
|
case MC68332Register.CtrlReg:
|
||||||
bdi.writeMem(r.value, value, r.size);
|
bdi.writeMem(r.getValue(), value, r.getSize());
|
||||||
break;
|
break;
|
||||||
case MC68332Register.SysReg:
|
case MC68332Register.SysReg:
|
||||||
bdi.writeSysReg(r.value, value);
|
bdi.writeSysReg(r.getValue(), value);
|
||||||
break;
|
break;
|
||||||
case MC68332Register.UserReg:
|
case MC68332Register.UserReg:
|
||||||
bdi.writeUserReg(r.value, value);
|
bdi.writeUserReg(r.getValue(), value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,13 +49,13 @@ public class IMCBTargetBoard {
|
|||||||
DispatchException, BDIException {
|
DispatchException, BDIException {
|
||||||
logger.info("readRegister: " + name);
|
logger.info("readRegister: " + name);
|
||||||
MC68332Register r = (MC68332Register) regDict.getRegister(name);
|
MC68332Register r = (MC68332Register) regDict.getRegister(name);
|
||||||
switch (r.type) {
|
switch (r.getType()) {
|
||||||
case MC68332Register.CtrlReg:
|
case MC68332Register.CtrlReg:
|
||||||
return bdi.readMem(r.value, r.size);
|
return bdi.readMem(r.getValue(), r.getSize());
|
||||||
case MC68332Register.SysReg:
|
case MC68332Register.SysReg:
|
||||||
return bdi.readSysReg(r.value);
|
return bdi.readSysReg(r.getValue());
|
||||||
case MC68332Register.UserReg:
|
case MC68332Register.UserReg:
|
||||||
return bdi.readUserReg(r.value);
|
return bdi.readUserReg(r.getValue());
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user