KiCad-utils/src/main/java/com/rusefi/pcb/nodes/PcbNode.java

258 lines
7.6 KiB
Java

package com.rusefi.pcb.nodes;
import com.rusefi.pcb.*;
import com.rusefi.util.FileUtils;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* (c) Andrey Belomutskiy
* 12/8/13
*/
public class PcbNode {
public final String nodeName;
public final int closingIndex;
public final List<Object> children;
public PcbNode(String nodeName, int closingIndex, List<Object> children) {
this.nodeName = nodeName;
this.closingIndex = closingIndex;
this.children = children;
}
/**
* @see #write
*/
public static PcbNode readFromFile(String fileName) throws IOException {
String content = FileUtils.readFile(fileName);
PcbNode node = parse(content);
System.out.println("GND network: " + NetNode.GND_NET_ID);
return node;
}
public static void copy(String inputFileName, String outputFileName) throws IOException {
System.out.println("From " + inputFileName + " to " + outputFileName);
PcbNode node = readFromFile(inputFileName);
PcbMergeTool.removeNodes(node);
node.write(outputFileName);
}
@Override
public String toString() {
return "PcbNode{" +
nodeName +
", children=" + children.size() +
'}';
}
private static PcbNode parse(String s, int index, int depth) {
log("Reading node from " + index, depth);
if (s.charAt(index) != '(')
throw new IllegalStateException("opening bracket expected");
index++;
String nodeName = readToken(s, index, depth);
index += nodeName.length();
List<Object> children = new ArrayList<Object>();
while (true) {
while (isWhitespace(s.charAt(index)))
index++;
char c = s.charAt(index);
if (c == ')')
break;
if (s.charAt(index) == '(') {
PcbNode child = parse(s, index, depth + 1);
children.add(child);
index = child.closingIndex;
continue;
}
String child = readToken(s, index, depth);
children.add(child);
index += child.length();
}
if ("segment".equals(nodeName)) {
return new SegmentNode(nodeName, index + 1, children);
} else if ("pad".equals(nodeName)) {
return PadNode.parse(nodeName, index + 1, children);
} else if ("net".equals(nodeName)) {
return new NetNode(nodeName, index + 1, children);
} else if ("add_net".equals(nodeName)) {
return new AddNetNode(nodeName, index + 1, children);
} else if ("gr_line".equals(nodeName)) {
return new GrLineNode(nodeName, index + 1, children);
} else if ("layer".equals(nodeName)) {
return new LayerNode(nodeName, index + 1, children);
} else if ("module".equals(nodeName)) {
return new ModuleNode(nodeName, index + 1, children);
} else if ("size".equals(nodeName) || "width".equals(nodeName)) {
return new SizeNode(nodeName, index + 1, children);
} else if ("zone".equals(nodeName)) {
return new ZoneNode(nodeName, index + 1, children);
} else if ("via".equals(nodeName)) {
return new ViaNode(nodeName, index + 1, children);
} else if ("start".equals(nodeName) || "end".equals(nodeName) || "at".equals(nodeName)) {
return new PointNode(nodeName, index + 1, children);
}
return new PcbNode(nodeName, index + 1, children);
}
private static String readToken(String s, int index, int depth) {
log("Reading token from " + index, depth);
if (s.charAt(index) == '"') {
String result = s.substring(index, s.indexOf('"', index + 1) + 1);
log("Got quoted token: " + result, depth);
return result;
}
String result = "";
while (index < s.length()) {
char c = s.charAt(index);
if (c == ')' || isWhitespace(c))
break;
result += c;
index++;
}
if (result.length() == 0)
throw new IllegalStateException("Empty token");
log("Got token: " + result, depth);
return result;
}
private static void log(String s, int depth) {
// for (int i = 0; i < depth; i++)
// System.out.print(' ');
// System.out.println(s);
}
private static void log(String s) {
log(s, 0);
}
private static boolean isWhitespace(char c) {
return c == ' ' || c == '\r' || c == '\n';
}
public static PcbNode parse(String content) {
return parse(content, 0, 0);
}
public String pack() {
StringBuilder sb = new StringBuilder();
pack(sb, "");
return sb.toString();
}
private void pack(StringBuilder sb, String prefix) {
sb.append(prefix).append("(").append(nodeName);
for (Object child : children) {
if (child instanceof String) {
sb.append(" ").append(child);
continue;
}
PcbNode p = (PcbNode) child;
if (p == null)
throw new NullPointerException("Null child node");
sb.append("\r\n");
p.pack(sb, prefix + " ");
}
sb.append(")\r\n");
}
public void write(String fileName) throws IOException {
System.out.println("Writing to " + fileName);
String content = pack();
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
bw.write(content);
bw.close();
}
public void setDouble(int i, double value) {
children.set(i, "" + value);
}
public double asDouble(int index) {
return Double.parseDouble((String) children.get(index));
}
public boolean hasChild(String key) {
return !iterate(key).isEmpty();
}
// @Nullable
public PcbNode findIfExists(String key) {
List<PcbNode> r = iterate(key);
if (r.isEmpty())
return null;
return find(key);
}
// @NotNull
public PcbNode find(String key) {
List<PcbNode> r = iterate(key);
if (r.size() != 1)
throw new IllegalStateException("More that one " + key + " in " + nodeName);
return r.get(0);
}
public List<PcbNode> nodes() {
List<PcbNode> result = new ArrayList<PcbNode>();
for (Object child : children) {
if (child instanceof String)
continue;
result.add((PcbNode) child);
}
return result;
}
public List<PcbNode> iterate(String key) {
List<PcbNode> result = new ArrayList<PcbNode>();
for (PcbNode p : nodes()) {
if (p.nodeName.equals(key))
result.add(p);
}
return result;
}
public void addChild(PcbNode node) {
children.add(node);
}
public List<Object> getChildren() {
return Collections.unmodifiableList(children);
}
public String getChild(int index) {
return (String) children.get(index);
}
public void setString(int index, String value) {
children.set(index, value);
}
public void setInt(int index, int value) {
children.set(index, "" + value);
}
public boolean removeChild(Object child) {
return children.remove(child);
}
public boolean isConnected(PointNode point) {
return false;
}
}