diff --git a/group11/1178243325/DataStructure/build.gradle b/group11/1178243325/DataStructure/build.gradle deleted file mode 100644 index 9c6bc859e6..0000000000 --- a/group11/1178243325/DataStructure/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ - -apply plugin: 'java' -apply plugin: 'eclipse' - -jar { - from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }} - manifest { - attributes 'Main-Class' : 'com.Main' - } -} - -repositories { - mavenCentral() -} - -dependencies { - compile 'junit:junit:4.12' - compile 'dom4j:dom4j:1.6.1' -} - diff --git a/group11/1178243325/DataStructure/readme.md b/group11/1178243325/DataStructure/readme.md deleted file mode 100644 index 29ad9d5c06..0000000000 --- a/group11/1178243325/DataStructure/readme.md +++ /dev/null @@ -1 +0,0 @@ -实现基本的数据结构ArrayList,LinkList,Stack,Queue,Tree,Iterator diff --git a/group11/1178243325/DataStructure/src/main/java/com/Main.java b/group11/1178243325/DataStructure/src/main/java/com/Main.java deleted file mode 100644 index f5e5a36ebd..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/Main.java +++ /dev/null @@ -1,56 +0,0 @@ -package com; - -import java.util.*; -import com.coderising.litestruts.*; -import com.coderising.array.*; -public class Main { - public static void main(String[] args) { - int[] array = {1, 2, 3, 4, 5}; - System.out.print("reverseArray测试:"); - ArrayUtil.reverseArray(array); - for (int i : array) - System.out.print(i + " "); - System.out.print("\nremoveZero测试:"); - - int[] oldArray = {1, 3, 4, 5, 0, 0, 8 , 0, 9}; - oldArray = ArrayUtil.removeZero(oldArray); - for (int i : oldArray) { - System.out.print(i + " "); - } - - System.out.print("\nmerge测试:"); - int[] a1 = {3, 5,8}; - int[] a2 = {4, 5, 6,7}; - int[] arrays = ArrayUtil.merge(a1, a2); - for (int i : arrays) - System.out.print(i + " "); - - System.out.print("\ngrow测试:"); - - int[] growArray = ArrayUtil.grow(a1, 5); - for (int i : growArray) - System.out.print(i + " "); - - System.out.print("\nfibonacci测试"); - int[] fArray = ArrayUtil.fibonacci(1); - System.out.print(fArray); - System.out.println(); - fArray = ArrayUtil.fibonacci(15); - for (int i : fArray) - System.out.print(i + " "); - System.out.print("\ngetPrimes测试:"); - int[] primesArray = ArrayUtil.getPrimes(23); - for (int i : primesArray) - System.out.print(i + " "); - System.out.print("\ngetPerfectNumbers测试:"); - int[] pArray = ArrayUtil.getPerfectNumbers(100); - for (int i : pArray) - System.out.print(i + " "); - System.out.print("\njoin测试:"); - int[] jArray = new int[]{2, 3, 8}; - System.out.print(ArrayUtil.join(jArray, "-")); - Map map = new HashMap<>(); - Struts.runAction("login", map); - - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/LoginAction.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/LoginAction.java deleted file mode 100644 index 1005f35a29..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/LoginAction.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.coderising.litestruts; - -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @author liuxin - * - */ -public class LoginAction{ - private String name ; - private String password; - private String message; - - public String getName() { - return name; - } - - public String getPassword() { - return password; - } - - public String execute(){ - if("test".equals(name) && "1234".equals(password)){ - this.message = "login successful"; - return "success"; - } - this.message = "login failed,please check your user/pwd"; - return "fail"; - } - - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/Struts.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/Struts.java deleted file mode 100644 index b3bd421435..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/Struts.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.coderising.litestruts; - -import java.util.Map; -import java.util.HashMap; -import java.lang.reflect.Method; -public class Struts { - - public static View runAction(String actionName, Map parameters) { - - /* - - 0. 读取配置文件struts.xml*/ - /* - 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) - 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 - ("name"="test" , "password"="1234") , - 那就应该调用 setName和setPassword方法 - - 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" - - 3. 通过反射找到对象的所有getter方法(例如 getMessage), - 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , - 放到View对象的parameters - - 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, - 放到View对象的jsp字段中。 - - */ - try { - String targetClassName = XmlUtil.parseXML("struts.xml", actionName); - Class targetClass = Class.forName(targetClassName); - - Method setName = targetClass.getMethod("setName", String.class); - Method setPassword = targetClass.getMethod("setPassword", String.class); - Object object = targetClass.newInstance(); - - setName.invoke(object, parameters.get("name")); - setPassword.invoke(object, parameters.get("password")); - - Method execute = targetClass.getMethod("execute"); - String result = (String)execute.invoke(object); - - Method getMessage = targetClass.getMethod("getMessage"); - String message = (String)getMessage.invoke(object); - - Map params = new HashMap(); - params.put("message", message); - String jspUrl = XmlUtil.getJspUrl("struts.xml", actionName, result); - View view = new View(); - view.setJsp(jspUrl); - view.setParameters(params); - return view; - - } catch (Exception e) { - e.printStackTrace(); - } - - - return null; - } - -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/StrutsTest.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/StrutsTest.java deleted file mode 100644 index a44c1878ac..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/StrutsTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.coderising.litestruts; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; - - - - - -public class StrutsTest { - - @Test - public void testLoginActionSuccess() { - - String actionName = "login"; - - Map params = new HashMap(); - params.put("name","test"); - params.put("password","1234"); - - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); - Assert.assertEquals("login successful", view.getParameters().get("message")); - } - - @Test - public void testLoginActionFailed() { - String actionName = "login"; - Map params = new HashMap(); - params.put("name","test"); - params.put("password","123456"); //密码和预设的不一致 - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); - Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/XmlUtil.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/XmlUtil.java deleted file mode 100644 index d200452cc8..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/XmlUtil.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.coderising.litestruts; - -import java.io.*; -import java.util.*; -import org.dom4j.Attribute; -import org.dom4j.Document; -import org.dom4j.Element; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; -public class XmlUtil { - - public static String parseXML(String filePath, String actionName) { - try { - File file = new File(filePath); - SAXReader reader = new SAXReader(); - Document doc = reader.read(file); - Element root = doc.getRootElement(); - for (Iterator iter = root.elementIterator("action"); iter.hasNext();) { - Element element = (Element)iter.next(); - Attribute nameAttr = element.attribute("name"); - if (nameAttr.getValue().equals(actionName)) { - Attribute classAttr = element.attribute("class"); - return classAttr.getValue(); - } - } - } catch (Exception e) { - e.printStackTrace(); - System.out.println("parse error"); - } - return null; - } - - public static String getJspUrl(String filePath, String actionName, String resultName) { - try { - File file = new File(filePath); - SAXReader reader = new SAXReader(); - Document doc = reader.read(file); - Element root = doc.getRootElement(); - for (Iterator iter = root.elementIterator("action"); iter.hasNext();) { - Element element = (Element)iter.next(); - Attribute nameAttr = element.attribute("name"); - if (nameAttr.getValue().equals(actionName)) { - for (Iterator ite = element.elementIterator("result"); ite.hasNext();) { - Element ele = (Element)ite.next(); - Attribute resultAttr = ele.attribute("name"); - if (resultAttr.getValue().equals(resultName)) { - return ele.getText(); - } - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/struts.xml b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/struts.xml deleted file mode 100644 index ae0ce37fd8..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group11/1178243325/DataStructure/src/main/resources/struts.xml b/group11/1178243325/DataStructure/src/main/resources/struts.xml deleted file mode 100644 index ae0ce37fd8..0000000000 --- a/group11/1178243325/DataStructure/src/main/resources/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group11/1178243325/DataStructure/struts.xml b/group11/1178243325/DataStructure/struts.xml deleted file mode 100644 index 0582b7d4ea..0000000000 --- a/group11/1178243325/DataStructure/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group11/1178243325/week01/build.gradle b/group11/1178243325/week01/build.gradle new file mode 100644 index 0000000000..50d1380b3f --- /dev/null +++ b/group11/1178243325/week01/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'java' + +repositories { + mavenCentral(); +} + +dependencies { + testCompile("junit:junit:4.12") +} diff --git a/group11/1178243325/week01/readme.md b/group11/1178243325/week01/readme.md new file mode 100644 index 0000000000..314098dd59 --- /dev/null +++ b/group11/1178243325/week01/readme.md @@ -0,0 +1,16 @@ +## 讲课内容: +- 17-2-15: 社群kickoff +- 17-2-19:讲解Java自测题和基本数据结构 +- 17-2-22:计算机组成原理和计算机编程语言 +- 17-2-26:程序的机器级表示 + +## 第一周作业(2-15 至 2-26) +- 实现各种基本数据结构(ArrayList, Stack, LinkedList, Queue, Tree, Iterator) +- 写一篇介绍CPU,内存,硬盘,指令以及他们之间的关系 + +## 完成情况: +- 基本数据结构已完成 +- [文章地址](http://www.jianshu.com/p/8d8379aa1281) + +## 我的收获: +- [漫谈计算机组成原理和编程语言](http://www.jianshu.com/p/07df48adf338) diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/Iterator.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/Iterator.java new file mode 100644 index 0000000000..1e73a2a4b9 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/Iterator.java @@ -0,0 +1,6 @@ +package com.sprint.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java new file mode 100644 index 0000000000..c91c388bbd --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java @@ -0,0 +1,9 @@ +package com.sprint.basic.exception; + +public class ConcurrentModificationException extends RuntimeException { + public ConcurrentModificationException() {} + public ConcurrentModificationException(String msg) { + super(msg); + } +} + diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyQueueException.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyQueueException.java similarity index 81% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyQueueException.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyQueueException.java index 2ee7aa4ee7..ddf89ac120 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyQueueException.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyQueueException.java @@ -1,4 +1,4 @@ -package com.coding.basic.exception; +package com.sprint.basic.exception; public class EmptyQueueException extends RuntimeException { public EmptyQueueException() {} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyStackException.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyStackException.java similarity index 81% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyStackException.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyStackException.java index 2a5ae4055d..d654c7cd16 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyStackException.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyStackException.java @@ -1,4 +1,4 @@ -package com.coding.basic.exception; +package com.sprint.basic.exception; public class EmptyStackException extends RuntimeException { public EmptyStackException() {} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/ArrayList.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/ArrayList.java similarity index 86% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/ArrayList.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/list/ArrayList.java index f6cd4c38fc..fb64e93f36 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/ArrayList.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/ArrayList.java @@ -1,6 +1,7 @@ -package com.coding.basic; +package com.sprint.basic.list; -import com.coding.basic.exception.*; +import com.sprint.basic.exception.ConcurrentModificationException; +import com.sprint.basic.Iterator; public class ArrayList implements List { private int size; @@ -11,11 +12,12 @@ public ArrayList () { elementData = new Object[100]; } - public void add(Object o){ + public boolean add(Object o) { add(size(), o); + return true; } - public void add(int index, Object o){ + public boolean add(int index, Object o){ if (size() == elementData.length) ensureCapacity( size() * 2 + 1); if (index > size() || index < 0) { //index == size时相当于在尾后插入 @@ -26,7 +28,7 @@ public void add(int index, Object o){ } elementData[index] = o; size++; - + return true; } private void ensureCapacity(int newCapacity) { diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/LinkedList.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/LinkedList.java similarity index 72% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/LinkedList.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/list/LinkedList.java index d82349089b..503f41f65b 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/LinkedList.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/LinkedList.java @@ -1,6 +1,8 @@ -package com.coding.basic; +package com.sprint.basic.list; -import com.coding.basic.exception.*; +import com.sprint.basic.exception.ConcurrentModificationException; +import com.sprint.basic.Iterator; +import java.util.Objects; public class LinkedList implements List { private Node head; @@ -10,11 +12,12 @@ public LinkedList() { size = 0; } - public void add(Object o){ + public boolean add(Object o) { add(size, o); + return true; } - public void add(int index , Object o){ + public boolean add(int index , Object o) { if (index > size || index < 0) { throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } @@ -22,9 +25,10 @@ public void add(int index , Object o){ Node newNode = new Node(o, frontNode.next); frontNode.next = newNode; size++; - + return true; } + /*getNode getPreNodeByElement getNextNodeByElement的效率低些*/ private Node getNode(int index) { Node node = head; int i = 0; @@ -35,6 +39,28 @@ private Node getNode(int index) { return node; } + private Node getPreNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i-1); + } + } + } + return null; + } + + private Node getNextNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i+1); + } + } + } + return null; + } + public Object get(int index){ if (index >= size || index < 0) { throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); @@ -60,7 +86,6 @@ public int size(){ } public void addFirst(Object o){ - //就是这么硬! add(0, o); } diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/list/List.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/List.java new file mode 100644 index 0000000000..0e90471a48 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/List.java @@ -0,0 +1,10 @@ +package com.sprint.basic.list; +import com.sprint.basic.Iterator; +public interface List { + public boolean add(Object o); + public boolean add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); + public Iterator iterator(); +} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Queue.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/queue/Queue.java similarity index 62% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/Queue.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/queue/Queue.java index a5c31f5a09..47f7b98d96 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Queue.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/queue/Queue.java @@ -1,5 +1,6 @@ -package com.coding.basic; -import com.coding.basic.exception.*; +package com.sprint.basic.queue; +import com.sprint.basic.exception.EmptyQueueException; +import com.sprint.basic.list.LinkedList; public class Queue { private LinkedList elementData; @@ -8,8 +9,9 @@ public Queue() { elementData = new LinkedList(); } - public void enQueue(Object o){ - elementData.addLast(o); + public boolean enQueue(Object o){ + elementData.addLast(o); + return true; } public Object deQueue(){ diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Stack.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/stack/Stack.java similarity index 72% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/Stack.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/stack/Stack.java index e41c662792..e399dcb850 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Stack.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/stack/Stack.java @@ -1,6 +1,7 @@ -package com.coding.basic; +package com.sprint.basic.stack; -import com.coding.basic.exception.*; +import com.sprint.basic.exception.EmptyStackException; +import com.sprint.basic.list.ArrayList; public class Stack { private ArrayList elementData; @@ -8,8 +9,9 @@ public Stack() { elementData = new ArrayList(); } - public void push(Object o){ + public boolean push(Object o){ elementData.add(o); + return true; } public Object pop(){ diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/tree/BinaryTreeNode.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/tree/BinaryTreeNode.java new file mode 100644 index 0000000000..efaf261521 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/tree/BinaryTreeNode.java @@ -0,0 +1,122 @@ +package com.sprint.basic.tree; + +public class BinaryTreeNode { + + private T data; + private BinaryTreeNode left; + private BinaryTreeNode right; + private int size; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public BinaryTreeNode getLeft() { + return left; + } + + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + + public BinaryTreeNode getRight() { + return right; + } + + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(T data) { + if (this.data == null) { + this.data = data; + return this; + } + int compareResult = this.data.compareTo(data); + if (compareResult > 0) { + if (this.left == null) { + this.left = new BinaryTreeNode(); + this.left.data = data; + return this.left; + } else { + return this.left.insert(data); + } + } else if (compareResult < 0) { + if (this.right == null) { + this.right = new BinaryTreeNode(); + this.right.data = data; + return this.right; + } else { + return this.right.insert(data); + } + } else { + return this; + } + } + + /*没看懂*/ + public BinaryTreeNode delete(T data) { + BinaryTreeNode treeNode = search(data); + if (treeNode == null) { + return null; + } + int compareResult = this.data.compareTo(data); + if (compareResult > 0) { + return this.left.delete(data); + } else if (compareResult < 0) { + return this.right.delete(data); + } else { + if (treeNode.right == null) { + if (this.left == null) { + this.data = null; + } else { + this.left = this; + } + } else { + this.data = (T) this.right.findMin().data; + + this.right.delete(this.data); + } + } + + return this; + } + + private BinaryTreeNode findMin() { + if (this.data == null) { + return null; + } + if (this.left == null) { + return this; + } + return this.left.findMin(); + } + + public BinaryTreeNode search(T data) { + if (this.data == null) { + return null; + } + int compareResult = this.data.compareTo(data); + if (compareResult > 0) { + if (this.left == null) { + return null; + } else { + return this.left.search(data); + } + } else if (compareResult < 0) { + if (this.right == null) { + return null; + } else { + return this.right.search(data); + } + } else { + return this; + } + } + + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/list/ArrayListTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/ArrayListTest.java new file mode 100644 index 0000000000..63936c288c --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/ArrayListTest.java @@ -0,0 +1,56 @@ +package com.sprint.basic.list; + +import com.sprint.basic.Iterator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ArrayListTest { + private List list; + + @Before + public void init() { + list = new ArrayList(); + } + + @Test + public void add() { + for (int i = 0; i < 5; i++) { + list.add(i); + } + /*Assert.assertTrue(args): if (args != true) to failed*/ + System.out.println(list); + Assert.assertTrue(list.add(5)); + Assert.assertEquals(6, list.size()); + Assert.assertTrue(list.add(3, 10)); + Assert.assertEquals(7, list.size()); + + } + + @Test + public void remove() { + add(); + Assert.assertEquals(5, list.remove(6)); + Assert.assertEquals(6, list.size()); + } + + @Test + public void get() { + add(); + Assert.assertEquals(5, list.get(6)); + } + + @Test + public void testIterator() { + for (int i = 0; i < 10; i++) { + Assert.assertTrue(list.add(i)); + } + Iterator iter = list.iterator(); + int count = 0; + while(iter.hasNext()) { + Assert.assertEquals(count, iter.next()); + count++; + } + } + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/list/LinkedListTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/LinkedListTest.java new file mode 100644 index 0000000000..c5ab12aa4e --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/LinkedListTest.java @@ -0,0 +1,56 @@ +package com.sprint.basic.list; + +import com.sprint.basic.Iterator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class LinkedListTest { + private List list; + + @Before + public void init() { + list = new LinkedList(); + } + + @Test + public void add() { + for (int i = 0; i < 5; i++) { + list.add(i); + } + /*Assert.assertTrue(args): if (args != true) to failed*/ + System.out.println(list); + Assert.assertTrue(list.add(5)); + Assert.assertEquals(6, list.size()); + Assert.assertTrue(list.add(3, 10)); + Assert.assertEquals(7, list.size()); + + } + + @Test + public void remove() { + add(); + Assert.assertEquals(5, list.remove(6)); + Assert.assertEquals(6, list.size()); + } + + @Test + public void get() { + add(); + Assert.assertEquals(5, list.get(6)); + } + + @Test + public void testIterator() { + for (int i = 0; i < 10; i++) { + Assert.assertTrue(list.add(i)); + } + Iterator iter = list.iterator(); + int count = 0; + while(iter.hasNext()) { + Assert.assertEquals(count, iter.next()); + count++; + } + } + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/queue/QueueTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/queue/QueueTest.java new file mode 100644 index 0000000000..b7cfe4b32f --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/queue/QueueTest.java @@ -0,0 +1,20 @@ +package com.sprint.basic.queue; + +import org.junit.Assert; +import org.junit.Test; +public class QueueTest { + + private Queue queue = new Queue(); + + @Test + public void testQueueApi() { + Assert.assertTrue(queue.enQueue(1)); + Assert.assertTrue(queue.enQueue(2)); + Assert.assertFalse(queue.isEmpty()); + Assert.assertEquals(2, queue.size()); + Assert.assertEquals(1, queue.deQueue()); + Assert.assertEquals(2, queue.deQueue()); + Assert.assertEquals(0, queue.size()); + Assert.assertTrue(queue.isEmpty()); + } +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/stack/StackTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/stack/StackTest.java new file mode 100644 index 0000000000..e267c59971 --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/stack/StackTest.java @@ -0,0 +1,23 @@ +package com.sprint.basic.stack; + +import org.junit.Assert; +import org.junit.Test; + +public class StackTest { + + private Stack stack = new Stack(); + + @Test + public void testStack() { + Assert.assertTrue(stack.push(1)); + Assert.assertEquals(1, stack.pop()); + Assert.assertTrue(stack.push(2)); + Assert.assertTrue(stack.push(3)); + Assert.assertTrue(stack.push(4)); + Assert.assertEquals(4, stack.pop()); + Assert.assertEquals(2, stack.peek()); + Assert.assertEquals(2, stack.size()); + Assert.assertFalse(stack.isEmpty()); + } + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/tree/BinaryTreeNodeTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/tree/BinaryTreeNodeTest.java new file mode 100644 index 0000000000..d9a27ab211 --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/tree/BinaryTreeNodeTest.java @@ -0,0 +1,54 @@ +package com.sprint.basic.tree; + +import org.junit.Assert; +/*参考程序*/ +public class BinaryTreeNodeTest { + + private BinaryTreeNode treeNode; + + @org.junit.Before + public void setUp() throws Exception { + treeNode = new BinaryTreeNode<>(); + treeNode.insert(5); + treeNode.insert(3); + treeNode.insert(7); + treeNode.insert(1); + treeNode.insert(4); + treeNode.insert(2); + treeNode.insert(8); + treeNode.insert(6); + } + + @org.junit.Test + public void insert() { + Assert.assertEquals(treeNode.getData().intValue(), 5); + Assert.assertEquals(treeNode.getLeft().getData(), 3); + Assert.assertEquals(treeNode.getRight().getData(), 7); + Assert.assertEquals(treeNode.getLeft().getLeft().getData(), 1); + Assert.assertEquals(treeNode.getLeft().getRight().getData(), 4); + Assert.assertEquals(treeNode.getLeft().getLeft().getRight().getData(), 2); + Assert.assertEquals(treeNode.getRight().getRight().getData(), 8); + Assert.assertEquals(treeNode.getRight().getLeft().getData(), 6); + } + + @org.junit.Test + public void delete() throws Exception { + treeNode.delete(3); + for (int i = 1; i < 9; i++) { + if (i != 3) { + Assert.assertNotNull(treeNode.search(i)); + } else { + Assert.assertNull(treeNode.search(i)); + } + } + } + + @org.junit.Test + public void search() throws Exception { + for (int i = 1; i < 9; i++) { + Assert.assertNotNull(treeNode.search(i)); + } + Assert.assertNull(treeNode.search(0)); + Assert.assertNull(treeNode.search(9)); + } +} diff --git a/group11/1178243325/week02/build.gradle b/group11/1178243325/week02/build.gradle new file mode 100644 index 0000000000..f6ebbb892e --- /dev/null +++ b/group11/1178243325/week02/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'java' + + +repositories { + maven { url "http://maven.aliyun.com/nexus/content/groups/public" } + mavenCentral() +} + +dependencies { + compile("org.jdom:jdom2:2.0.5") + testCompile("junit:junit:4.12") +} diff --git a/group11/1178243325/week02/readme.md b/group11/1178243325/week02/readme.md new file mode 100644 index 0000000000..a4f9adc15a --- /dev/null +++ b/group11/1178243325/week02/readme.md @@ -0,0 +1,23 @@ +## 讲课内容: +- 17-03-01:第一周作业讲评 +- 17-03-05:漫谈进程和线程和布置第三周作业 + +## 第二周作业(2-27 至 3-5) +- 实现第一个大作业:读取struts.xml,执行Action +- 5道数据结构习题 + +## 完成情况: +- struts大作业完成 +- 数据结构习题完成 + +## 我的收获: +- TDD +- 操作系统抽象概念 +- 进程在虚拟存储器表示 +- 进程调度 +- 进程同步 +- 线程 + + +![99.jpg](http://upload-images.jianshu.io/upload_images/2031765-d3740acf4d284e93.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/array/ArrayUtil.java b/group11/1178243325/week02/src/main/java/com/sprint/array/ArrayUtil.java similarity index 93% rename from group11/1178243325/DataStructure/src/main/java/com/coderising/array/ArrayUtil.java rename to group11/1178243325/week02/src/main/java/com/sprint/array/ArrayUtil.java index f94d5d01c4..01d7d5f0da 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/array/ArrayUtil.java +++ b/group11/1178243325/week02/src/main/java/com/sprint/array/ArrayUtil.java @@ -1,4 +1,4 @@ -package com.coderising.array; +package com.sprint.array; public class ArrayUtil { @@ -32,7 +32,7 @@ public static void reverseArray(int[] origin){ public static int[] removeZero(int[] oldArray){ if (oldArray == null) { - return null; + return new int[0]; } int zeroCount = 0; @@ -60,7 +60,7 @@ public static int[] removeZero(int[] oldArray){ public static int[] merge(int[] array1, int[] array2){ if (array1 == null && array2 == null) - return null; + return new int[0]; int index1 = 0, index2 = 0; int[] array3 = new int[array1.length + array2.length]; int index = 0; @@ -101,7 +101,7 @@ public static int[] merge(int[] array1, int[] array2){ */ public static int[] grow(int [] oldArray, int size){ if (size <= 0) - return null; + return new int[0]; int[] newArray = new int[oldArray.length + size]; for (int i = 0; i < oldArray.length; i++) { newArray[i] = oldArray[i]; @@ -118,9 +118,9 @@ public static int[] grow(int [] oldArray, int size){ */ public static int[] fibonacci(int max){ if (max < 1) - return null; + return new int[0]; if (max == 1) - return null; + return new int[0]; int[] array = new int[max]; int i = 0; int value = fibonaccis(i+1); @@ -151,7 +151,7 @@ private static int fibonaccis(int n) { */ public static int[] getPrimes(int max){ if (max <= 1) { - return null; + return new int[0]; } int[] array = new int[max]; int index = 0; @@ -177,7 +177,7 @@ public static int[] getPrimes(int max){ */ public static int[] getPerfectNumbers(int max){ if (max <= 0) - return null; + return new int[0]; int[] array = new int[max]; int index = 0; for (int i = 1; i < max; i++) { diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Configuration.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Configuration.java new file mode 100644 index 0000000000..0f10458fc3 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Configuration.java @@ -0,0 +1,86 @@ +package com.sprint.litestruts; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; +public class Configuration { + Map actions = new HashMap<>(); + public Configuration(String fileName) { + InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName); + parseXML(is); + try { + is.close(); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + private void parseXML(InputStream is) { + SAXBuilder builder = new SAXBuilder(); + try { + Document doc = builder.build(is); + Element root = doc.getRootElement(); + for (Element actionElement : root.getChildren("action")) { + String actionName = actionElement.getAttributeValue("name"); + String clzName = actionElement.getAttributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, clzName); + for (Element resultElement : actionElement.getChildren("result")) { + String resultName = resultElement.getAttributeValue("name"); + String viewName = resultElement.getText().trim(); + ac.addViewResult(resultName, viewName); + } + this.actions.put(actionName, ac); + } + } catch (JDOMException e) { + throw new ConfigurationException(e); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + public String getClassName(String actionName) { + ActionConfig ac = this.actions.get(actionName); + if(ac == null) { + return null; + } + return ac.getClassName(); + } + + public String getResultView(String actionName, String resultName) { + ActionConfig ac = this.actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getViewName(resultName); + } + private static class ActionConfig { + String name; + String clzName; + Map viewResult = new HashMap<>(); + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + + public String getClassName() { + return clzName; + } + + public void addViewResult(String name, String viewName) { + viewResult.put(name, viewName); + } + + public String getViewName(String resultName) { + return viewResult.get(resultName); + } + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ConfigurationException.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..25c6784f43 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ConfigurationException.java @@ -0,0 +1,18 @@ +package com.sprint.litestruts; + +import java.io.IOException; +import org.jdom2.JDOMException; +public class ConfigurationException extends RuntimeException { + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/LoginAction.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/LoginAction.java new file mode 100644 index 0000000000..4b4f2b8e38 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/LoginAction.java @@ -0,0 +1,40 @@ +package com.sprint.litestruts; + +/** + * 这是一个展示业务逻辑的类,其中用户名是硬编码 + * @author xingzhaohu + */ + +public class LoginAction { + private String name; + private String password; + private String message; + + public String execute() { + if ("test".equals(name) && "1234".equals(password)) { + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + public void setName(String name) { + this.name = name; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String getMessage() { + return message; + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtil.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..822355655b --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtil.java @@ -0,0 +1,70 @@ +package com.sprint.litestruts; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + return getMethods(clz, "set"); + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz, "get"); + } + + private static List getMethods(Class clz, String startWithName) { + List methods = new ArrayList<>(); + for (Method m : clz.getDeclaredMethods()) { + if (m.getName().startsWith(startWithName)) { + methods.add(m); + } + } + return methods; + } + + public static void setParameters(Object o, Map params) { + List methods = getSetterMethods(o.getClass()); + for (String name : params.keySet()) { + String methodName = "set" + name; + for (Method m : methods) { + if (m.getName().equalsIgnoreCase(methodName)) { + try { + m.invoke(o, params.get(name)); + } catch (IllegalAccessException e) { + throw new ReflectionUtilException(e); + } catch (IllegalArgumentException e) { + throw new ReflectionUtilException(e); + } catch (InvocationTargetException e) { + throw new ReflectionUtilException(e); + } + } + } + } + + } + + public static Map getParameterMap(Object o) { + Map params = new HashMap<>(); + List methods = getGetterMethods(o.getClass()); + for (Method m : methods) { + String methodName = m.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); + try { + Object value = m.invoke(o); + params.put(name, value); + } catch (IllegalAccessException e) { + throw new ReflectionUtilException(e); + } catch (IllegalArgumentException e) { + throw new ReflectionUtilException(e); + } catch (InvocationTargetException e) { + throw new ReflectionUtilException(e); + } + } + return params; + } + +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtilException.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtilException.java new file mode 100644 index 0000000000..65cbfdf322 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtilException.java @@ -0,0 +1,20 @@ +package com.sprint.litestruts; + +import java.lang.reflect.InvocationTargetException; +public class ReflectionUtilException extends RuntimeException { + + public ReflectionUtilException(String msg) { + super(msg); + } + public ReflectionUtilException(IllegalAccessException e) { + super(e); + } + + public ReflectionUtilException(IllegalArgumentException e) { + super(e); + } + + public ReflectionUtilException(InvocationTargetException e) { + super(e); + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Struts.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Struts.java new file mode 100644 index 0000000000..bff4dec33b --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Struts.java @@ -0,0 +1,53 @@ +package com.sprint.litestruts; + +import java.lang.reflect.Method; +import java.util.Map; +public class Struts { + private final static Configuration cfg = new Configuration("struts.xml"); + public static View runAction(String actionName, Map parameters) { + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + String clzName = cfg.getClassName(actionName); + if (clzName == null) { + return null; + } + + try { + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + + ReflectionUtil.setParameters(action, parameters); + + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String)m.invoke(action); + + Map params = ReflectionUtil.getParameterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/View.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/View.java similarity index 59% rename from group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/View.java rename to group11/1178243325/week02/src/main/java/com/sprint/litestruts/View.java index 0194c681f6..fb380de515 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/View.java +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/View.java @@ -1,23 +1,24 @@ -package com.coderising.litestruts; - -import java.util.Map; - -public class View { - private String jsp; - private Map parameters; - - public String getJsp() { - return jsp; - } - public View setJsp(String jsp) { - this.jsp = jsp; - return this; - } - public Map getParameters() { - return parameters; - } - public View setParameters(Map parameters) { - this.parameters = parameters; - return this; - } -} +package com.sprint.litestruts; + +import java.util.Map; +public class View { + private String jsp; + private Map parameters; + + public void setJsp(String jsp) { + this.jsp = jsp; + } + + public String getJsp() { + return jsp; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + public Map getParameters() { + return parameters; + } + +} diff --git a/group11/1178243325/week02/src/main/resources/struts.xml b/group11/1178243325/week02/src/main/resources/struts.xml new file mode 100644 index 0000000000..c82c7d1574 --- /dev/null +++ b/group11/1178243325/week02/src/main/resources/struts.xml @@ -0,0 +1,12 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + + diff --git a/group11/1178243325/week02/src/test/java/com/sprint/array/ArrayUtilTest.java b/group11/1178243325/week02/src/test/java/com/sprint/array/ArrayUtilTest.java new file mode 100644 index 0000000000..9cba21f7cf --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/array/ArrayUtilTest.java @@ -0,0 +1,76 @@ +package com.sprint.array; + +import java.util.Arrays; +import org.junit.Assert; +import org.junit.Test; +public class ArrayUtilTest { + + @Test + public void testReverseArray() { + int[] a = new int[]{7, 9, 30, 3}; + int[] expected = new int[]{3, 30, 9, 7}; + ArrayUtil.reverseArray(a); + Assert.assertArrayEquals(a, expected); + a = new int[]{7, 9, 30, 3, 4}; + expected = new int[]{4, 3, 30, 9, 7}; + ArrayUtil.reverseArray(a); + Assert.assertArrayEquals(a, expected); + } + + @Test + public void testRemoveZero() { + int[] oldArr = new int[]{1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; + int[] expected = new int[]{1,3,4,5,6,6,5,4,7,6,7,5}; + Assert.assertArrayEquals(ArrayUtil.removeZero(oldArr), expected); + oldArr = new int[]{1, 0, 2, 0, 3, 0}; + expected = new int[]{1, 2, 3}; + Assert.assertArrayEquals(ArrayUtil.removeZero(oldArr), expected); + } + + @Test + public void testMerge() { + int[] a1 = {3, 5, 7, 8}; + int[] a2 = {4, 5, 6, 7}; + int[] a3 = {3, 4, 5, 6, 7, 8}; + Assert.assertArrayEquals(ArrayUtil.merge(a1, a2), a3); + } + + @Test + public void testGrow() { + int[] oldArray = new int[]{2, 3, 6}; + int[] expected = new int[]{2, 3, 6, 0, 0, 0}; + Assert.assertArrayEquals(ArrayUtil.grow(oldArray, 3), expected); + } + + @Test + public void testFibonacci() { + int[] expected = new int[]{1, 1, 2, 3, 5, 8, 13}; + Assert.assertArrayEquals(ArrayUtil.fibonacci(15), expected); + expected = new int[0]; + Assert.assertArrayEquals(ArrayUtil.fibonacci(1), expected); + /*GET 新技能: [] == new int[0]*/ + System.out.println(Arrays.toString(expected)); + } + + @Test + public void testGetPrimes() { + int[] expected = new int[]{2,3,5,7,11,13,17,19}; + Assert.assertArrayEquals(ArrayUtil.getPrimes(23), expected); + } + + @Test + public void testGetPerfectNumbers() { + int[] result = new int[]{6}; + int length = ArrayUtil.getPerfectNumbers(7).length; + System.out.println(length); + Assert.assertArrayEquals(ArrayUtil.getPerfectNumbers(7), result); + } + + @Test + public void tetJoin() { + String result = "3-8-9"; + int[] array = {3, 8, 9}; + Assert.assertEquals(ArrayUtil.join(array, "-"), result); + } + +} diff --git a/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ConfigurationTest.java b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..f4b5f91668 --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ConfigurationTest.java @@ -0,0 +1,31 @@ +package com.sprint.litestruts; + +import org.junit.Test; +import org.junit.Assert; +public class ConfigurationTest { + Configuration cfg = new Configuration("struts.xml"); + + @Test + public void testGetClassName() { + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.sprint.litestruts.LoginAction", clzName); + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.sprint.litestruts.LoginAction", clzName); + } + + @Test + public void testGetResultView() { + String jsp = cfg.getResultView("login", "success"); + Assert.assertEquals("/jsp/homepage.jsp", jsp); + + jsp = cfg.getResultView("login", "fail"); + Assert.assertEquals("/jsp/showLogin.jsp", jsp); + + jsp = cfg.getResultView("logout", "success"); + Assert.assertEquals("/jsp/welcome.jsp", jsp); + + jsp = cfg.getResultView("logout", "error"); + Assert.assertEquals("/jsp/error.jsp", jsp); + } + +} diff --git a/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ReflectionUtilTest.java b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..c6fb04bda6 --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ReflectionUtilTest.java @@ -0,0 +1,92 @@ +package com.sprint.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Set; +import java.util.Map; + + +import org.junit.Test; +import org.junit.Assert; +public class ReflectionUtilTest { + + @Test + public void testGetSetterMethod() throws Exception{ + String name = "com.sprint.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + Set acctualNames = new HashSet<>(); + for (Method m : methods) { + acctualNames.add(m.getName()); + } + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testGetGetterMethod() throws Exception { + String name = "com.sprint.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + expectedNames.add("getMessage"); + + Set acctualNames = new HashSet<>(); + for (Method m : methods) { + acctualNames.add(m.getName()); + } + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception { + String name = "com.sprint.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap<>(); + params.put("name", "test"); + params.put("password", "1234"); + + ReflectionUtil.setParameters(o, params); + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + f = clz.getDeclaredField("password"); + f.setAccessible(true); + Assert.assertEquals("1234", f.get(o)); + } + + @Test + public void testGetParameters() throws Exception { + String name = "com.sprint.litestruts.LoginAction"; + Class clz = Class.forName(name); + LoginAction action = (LoginAction)clz.newInstance(); + action.setName("test"); + action.setPassword("123456"); + + Map params = ReflectionUtil.getParameterMap(action); + Assert.assertEquals(3, params.size()); + Assert.assertEquals(null, params.get("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + + } + +} diff --git a/group11/1178243325/week02/src/test/java/com/sprint/litestruts/StrutsTest.java b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/StrutsTest.java new file mode 100644 index 0000000000..d8c68d2807 --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/StrutsTest.java @@ -0,0 +1,32 @@ +package com.sprint.litestruts; + +import java.util.HashMap; +import java.util.Map; +import org.junit.Assert; +import org.junit.Test; +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + String actionName = "login"; + Map params = new HashMap<>(); + params.put("name", "test"); + params.put("password", "1234"); + + View view = Struts.runAction(actionName, params); + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap<>(); + params.put("name", "test"); + params.put("password", "123456"); //密码不一致 + + View view = Struts.runAction(actionName, params); + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group11/1178243325/week03/build.gradle b/group11/1178243325/week03/build.gradle new file mode 100644 index 0000000000..c4da624f95 --- /dev/null +++ b/group11/1178243325/week03/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + testCompile("junit:junit:4.12") +} diff --git a/group11/1178243325/week03/readme.md b/group11/1178243325/week03/readme.md new file mode 100644 index 0000000000..5de5dada98 --- /dev/null +++ b/group11/1178243325/week03/readme.md @@ -0,0 +1,16 @@ +## 讲课内容: +- 17-03-07:答疑(YY) +- 17-03-09:TDD和第二次作业讲解 +- 17-03-12:职场15年 + +## 第三周作业(3-6 至 3-12) +- 实现第二个大作业:多线程下载文件,支持断点续传 +- 5道数据结构习题 + +## 完成情况: +- 多线程完成 +- 待重构 + +## 我的收获: +- TTD大法好 +- 面向对象的思想以及抽象化,更深刻 diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Iterator.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/Iterator.java similarity index 100% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/Iterator.java rename to group11/1178243325/week03/src/main/java/com/sprint/basic/Iterator.java diff --git a/group11/1178243325/week03/src/main/java/com/sprint/basic/LinkedList.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/LinkedList.java new file mode 100644 index 0000000000..ac4128fe80 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/basic/LinkedList.java @@ -0,0 +1,319 @@ +package com.sprint.basic; + +import com.sprint.basic.exception.ConcurrentModificationException; +import java.util.Objects; +public class LinkedList implements List { + + private Node head; + private int size; + public LinkedList() { + head = new Node(null, null); + size = 0; + } + + public void add(Object o){ + add(size, o); + } + + public void add(int index , Object o){ + if (index > size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Node frontNode = getNode(index-1); + Node newNode = new Node(o, frontNode.next); + frontNode.next = newNode; + size++; + + } + + /*getNode getPreNodeByElement getNextNodeByElement的效率低些*/ + private Node getNode(int index) { + Node node = head; + int i = 0; + while(node.next != null && i <= index) { + node = node.next; + i++; + } + return node; + } + + private Node getPreNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i-1); + } + } + } + return null; + } + + private Node getNextNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i+1); + } + } + } + return null; + } + public Object get(int index){ + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + Node node = getNode(index); + return node.data; + } + + public Object remove(int index){ + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Node frontNode = getNode(index-1); + Node oldNode = getNode(index); + frontNode.next = oldNode.next; + size--; + return oldNode.data; + } + + public int size(){ + return size; + } + + public void addFirst(Object o){ + add(0, o); + } + + public void addLast(Object o){ + add(size, o); + } + + public Object removeFirst(){ + return remove(0); + } + + public Object removeLast(){ + return remove(size-1); + } + + public Iterator iterator(){ + return new LinkedListIterator(); + } + + private class LinkedListIterator implements Iterator { + int index; + final int capacity = size; + LinkedListIterator() { + index = 0; + } + @Override + public boolean hasNext() { + if (capacity != size) + throw new ConcurrentModificationException("此对象没有修改同步"); + return index < capacity; + } + + @Override + public Object next() { + if (capacity != size) + throw new ConcurrentModificationException("此对象没有修改同步"); + if (index >= capacity) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + return get(index++); + } + } + + private String outOfBoundsMsg(int index) { + return "index:" + index + ", size:" + size; + } + + private static class Node { + Object data; + Node next; + + Node(Object data, Node next) { + this.data = data; + this.next = next; + } + + void setData(Object data) { + this.data = data; + } + + Object getData() { + return data; + } + + void setNext(Node next) { + this.next = next; + } + + Object getNext() { + return next; + } + } + + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Object[] oldData = new Object[size]; + Node temp = head; + int index = 1; + while(temp.next != null) { + temp = temp.next; + oldData[size - index] = temp.data; + index++; + } + + index = 0; + temp = head; + while(temp.next != null) { + temp = temp.next; + temp.data = oldData[index]; + index++; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + + public void removeFirstHalf(){ + int count = size; + if (count % 2 != 0) { + for (int i = 0; i <= count/2; i++) { + removeFirst(); + } + } else { + for (int i = 0; i < count/2; i++) { + removeFirst(); + } + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + + public void remove(int i, int length){ + if (i < 0 || length < 0) { + return; + } + if (i == 0) { + for (int k = 0; k < length; k++) + removeFirst(); + } else { + while (length > 0) { + remove(i-1); + length--; + } + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + + public int[] getElements(LinkedList list){ + if (list.size() == 0) { + return new int[0]; + } + int[] array = new int[list.size()]; + int index = 0; + for (int i = 0; i < list.size(); i++) { + array[i] = (int)get((int)list.get(i)); + } + return array; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * @param list + */ + public void subtract(LinkedList list){ + if (list.size() == 0) { + return; + } + for (int i = 0; i < list.size(); i++) { + removeElement(list.get(i)); + } + } + + private Object removeElement(Object obj) { + if (obj == null) { + return null; + } + Node preNode = getPreNodeByElement(obj); + Node nextNode = getNextNodeByElement(obj); + if (preNode == null && nextNode == null) + return null; + preNode.next = nextNode; + return obj; + } + + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + + public void removeDuplicateValues(){ + if (size == 0 || size == 1) { + return; + } + + Node p1 = head; + Node p2 = head.next; + + while (p1 != null && p2 != null) { + if (Objects.equals(p1.data, p2.data)) { + p2 = p2.next; + p1.next = p2; + size--; + } else { + p1 = p2; + p2 = p2.next; + } + } + } + + + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + + public void removeRange(int min, int max){ + } + + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + + public LinkedList intersection( LinkedList list){ + + return null; + + } +} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/List.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/List.java similarity index 100% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/List.java rename to group11/1178243325/week03/src/main/java/com/sprint/basic/List.java diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/ConcurrentModificationException.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java similarity index 100% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/ConcurrentModificationException.java rename to group11/1178243325/week03/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/DownloadThread.java b/group11/1178243325/week03/src/main/java/com/sprint/download/DownloadThread.java new file mode 100644 index 0000000000..434b60e7be --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/DownloadThread.java @@ -0,0 +1,36 @@ +package com.sprint.download; + +import com.sprint.download.api.Connection; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; +public class DownloadThread extends Thread { + Connection conn; + int startPos; + int endPos; + CyclicBarrier barrier; + String localFile; + public DownloadThread(Connection conn, int startPos, int endPos, + String localFile, CyclicBarrier barrier) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + + @Override + public void run() { + try { + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + file.seek(startPos); + file.write(data); + file.close(); + conn.close(); + barrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/FileDownloader.java b/group11/1178243325/week03/src/main/java/com/sprint/download/FileDownloader.java new file mode 100644 index 0000000000..9a817aefaf --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/FileDownloader.java @@ -0,0 +1,89 @@ +package com.sprint.download; + +import com.sprint.download.api.Connection; +import com.sprint.download.api.ConnectionManager; +import com.sprint.download.api.DownloadListener; +import java.util.concurrent.CyclicBarrier; +import java.io.RandomAccessFile; +import java.io.IOException; +public class FileDownloader { + private String url; + private String localFile; + + DownloadListener listener; + ConnectionManager cm; + + private static final int DOWNLOAD_THREAD_NUM = 3; + + public FileDownloader(String _url, String localFile) { + this.url = _url; + this.localFile = localFile; + } + + public void execute() { + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM, new Runnable() { + public void run() { + listener.notifyFinished(); + } + }); + + Connection conn = null; + + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + createPlaceHolderFile(this.localFile, length); + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length); + for (int i = 0; i < DOWNLOAD_THREAD_NUM; i++) { + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + thread.start(); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + RandomAccessFile file = new RandomAccessFile(fileName, "rw"); + for (int i = 0; i < contentLen; i++) { + file.write(0); + } + file.close(); + } + + private int[][] allocateDownloadRange(int threadNum, int contentLen) { + int[][] ranges = new int[threadNum][2]; + int eachThreadSize = contentLen / threadNum; + int left = contentLen % threadNum; + for (int i = 0; i < threadNum; i++) { + int startPos = i*eachThreadSize; + int endPos = (i+1) * eachThreadSize - 1; + if (i == (threadNum -1)) { + endPos += left; + } + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + return ranges; + } + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return listener; + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/Connection.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/Connection.java new file mode 100644 index 0000000000..958a0b1ce3 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/Connection.java @@ -0,0 +1,26 @@ +package com.sprint.download.api; + +import java.io.IOException; +public interface Connection { + /** + * 给定开始位置和结束位置,读取数据,返回值是字节 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + + public byte[] read(int startPos, int endPos) throws IOException; + + /** + * 得到数据内容的长度 + * @return + */ + + public int getContentLength(); + + /** + * 关闭连接 + */ + + public void close(); +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionException.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionException.java new file mode 100644 index 0000000000..f9ec627440 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionException.java @@ -0,0 +1,7 @@ +package com.sprint.download.api; + +public class ConnectionException extends Exception { + public ConnectionException(Exception e) { + super(e); + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionManager.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionManager.java new file mode 100644 index 0000000000..f20bbacc87 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionManager.java @@ -0,0 +1,11 @@ +package com.sprint.download.api; + +public interface ConnectionManager { + /** + * 给定一个url, 打开一个连接 + * @param url + * @return + */ + + public Connection open(String url) throws ConnectionException; +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/DownloadListener.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/DownloadListener.java new file mode 100644 index 0000000000..fc95ba8199 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.sprint.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionImpl.java b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..c6c1f32cb4 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionImpl.java @@ -0,0 +1,68 @@ +package com.sprint.download.impl; + +import com.sprint.download.api.Connection; +import com.sprint.download.api.ConnectionException; +import java.util.Arrays; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.HttpURLConnection; + +public class ConnectionImpl implements Connection { + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException { + try { + url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream is = httpConn.getInputStream(); + byte[] buff = new byte[BUFFER_SIZE]; + int totalLen = endPos - startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while (baos.size() < totalLen) { + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff, 0, len); + } + + if (baos.size() > totalLen) { + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + URLConnection con; + try { + con = url.openConnection(); + return con.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionManagerImpl.java b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..7a012808ef --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.sprint.download.impl; + +import com.sprint.download.api.Connection; +import com.sprint.download.api.ConnectionException; +import com.sprint.download.api.ConnectionManager; +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } +} + + diff --git a/group11/1178243325/week03/src/test/java/com/sprint/download/FileDownloaderTest.java b/group11/1178243325/week03/src/test/java/com/sprint/download/FileDownloaderTest.java new file mode 100644 index 0000000000..6e3bccd2dc --- /dev/null +++ b/group11/1178243325/week03/src/test/java/com/sprint/download/FileDownloaderTest.java @@ -0,0 +1,41 @@ +package com.sprint.download; + +import com.sprint.download.api.ConnectionManager; +import com.sprint.download.api.DownloadListener; +import com.sprint.download.impl.ConnectionManagerImpl; + +import org.junit.Assert; +import org.junit.Test; +public class FileDownloaderTest { + boolean downloadFinished = false; + + @Test + public void testDownload() { + String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + FileDownloader downloader = new FileDownloader(url, "/home/sprint/xxx/test.jpg");// 保存地址时我的本地地址 + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = false; + } + }); + + downloader.execute(); + + //等待多线程下载 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + } +} diff --git a/group11/1178243325/week03/src/test/java/com/sprint/download/api/ConnectionTest.java b/group11/1178243325/week03/src/test/java/com/sprint/download/api/ConnectionTest.java new file mode 100644 index 0000000000..4322814936 --- /dev/null +++ b/group11/1178243325/week03/src/test/java/com/sprint/download/api/ConnectionTest.java @@ -0,0 +1,21 @@ +package com.sprint.download.api; + +import com.sprint.download.impl.ConnectionManagerImpl; +import org.junit.Assert; +import org.junit.Test; +public class ConnectionTest { + + @Test + public void testGetContentLength() throws Exception { + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + Assert.assertEquals(35470, conn.getContentLength()); + } + + @Test + public void testRead() throws Exception { + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + + } +} diff --git a/group11/1178243325/week04/readme.md b/group11/1178243325/week04/readme.md new file mode 100644 index 0000000000..2199199aef --- /dev/null +++ b/group11/1178243325/week04/readme.md @@ -0,0 +1,12 @@ +## 讲课内容: +- 17-03-15:第三次作业讲解 +- 17-03-19:Edison分享的职业发展 + +## 第四周作业(3-13 至 3-19) +无,调整进度 + +## 完成情况: +休养生息 + +## 我的收获: +- 职业发展:从新人到老兵 diff --git a/group11/1178243325/week05/readme.md b/group11/1178243325/week05/readme.md new file mode 100644 index 0000000000..d4388e66d7 --- /dev/null +++ b/group11/1178243325/week05/readme.md @@ -0,0 +1,13 @@ +## 讲课内容: +- 17-03-22 :漫谈操作系统之虚拟内存 +- 17-03-26 :概要性介绍class文件结构和字节码的执行过程 + +## 第五周作业(3-20 至 3-26) +无,调整进度 + +## 完成情况: +修养生息 + +## 我的收获: +- 虚拟内存 +- 进一步理解JVM diff --git a/group11/1178243325/week06/build.gradle b/group11/1178243325/week06/build.gradle new file mode 100644 index 0000000000..128f6fda07 --- /dev/null +++ b/group11/1178243325/week06/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + compile("commons-io:commons-io:2.4") + //compile("commons-lang:commons-lang:2.6") + compile("org.apache.commons:commons-lang3:3.4") + testCompile("junit:junit:4.12") +} + diff --git a/group11/1178243325/week06/readme.md b/group11/1178243325/week06/readme.md new file mode 100644 index 0000000000..d89a5c904e --- /dev/null +++ b/group11/1178243325/week06/readme.md @@ -0,0 +1,16 @@ +## 讲课内容: +- 17-03-27:JVM第一周 +- 17-03-29:JVM之classLoader + +## 第六周作业(3-27 至 04-02) +- 完成对一个.class文件的读取和对.class文件开头四个字节的魔数的判断需要实现ClassLoader.java +- 实现LRU算法 +- 一篇文章 + +## 完成情况: +- ClassLoader.java已完 +- LRU已完 +- [文章](http://www.jianshu.com/p/02a8b4ee4596) + +## 我的收获: +使用开源工具读取文件,并利用工作类进行字符转换.LRU算法(双链表操作),但是更重要的抽象化思想. diff --git a/group11/1178243325/week06/src/main/java/com/sprint/basic/LRUPageFrame.java b/group11/1178243325/week06/src/main/java/com/sprint/basic/LRUPageFrame.java new file mode 100644 index 0000000000..0a2febd715 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/basic/LRUPageFrame.java @@ -0,0 +1,117 @@ +package com.sprint.basic; + +public class LRUPageFrame { + + /** + * 用双向链表实现LRU算法 + */ + + private static class Node { + Node prev; + Node next; + int pageNum; + + Node() { + + } + } + + private int capacity; + private int currentSize; + private Node first; + private Node last; + + public LRUPageFrame(int capacity) { + this.currentSize = 0; + this.capacity = capacity; + } + + /** + * + */ + public void access(int pageNum) { + Node node = find(pageNum); + if (node != null) { + moveExistingNodeToHead(node); + } else { + node = new Node(); + node.pageNum = pageNum; + if (currentSize >= capacity) { + removeLast(); + } + addNewNodeToHead(node); + } + } + + private Node find(int pageNum) { + Node node = first; + while (node != null) { + if (node.pageNum == pageNum) { + return node; + } + node = node.next; + } + return null; + } + + private void moveExistingNodeToHead(Node node) { + if (node == first) { + return; + } else if (node == last) { + Node prevNode = node.prev; + prevNode.next = null; + last.prev = null; + last = prevNode; + } else { + Node prevNode = node.prev; + prevNode.next = node.next; + Node nextNode = node.next; + nextNode.prev = prevNode; + } + + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev; + this.currentSize--; + } + + private void addNewNodeToHead(Node node) { + if (isEmpty()) { + node.prev = null; + node.next = null; + first = node; + last = node; + } else { + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + this.currentSize++; + } + + private boolean isEmpty() { + return (first == null) && (last == null); + } + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.pageNum); + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/clz/ClassFile.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..c40c88b183 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/clz/ClassFile.java @@ -0,0 +1,9 @@ +package com.sprint.jvm.clz; + +public class ClassFile { + private final String cafebabe = "cafebabe"; + + public String getCafebabe() { + return cafebabe; + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..445519b3be --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,17 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.util.Util; +import java.util.Arrays; +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[] {codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..1191be47eb --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java @@ -0,0 +1,49 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; +import java.util.List; +import java.util.ArrayList; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +public class ClassFileLoader { + List clzPaths = new ArrayList<>(); + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } + + public void addClassPath(String clzPath) { + if (this.clzPaths.contains(clzPath)) { + return; + } + this.clzPaths.add(clzPath); + } + + private byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar) + ".class"; + for (String path : clzPaths) { + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileParser.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..229e7db360 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileParser.java @@ -0,0 +1,14 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +public class ClassFileParser { + public ClassFile parse(byte[] codes) { + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magicNumber = iter.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) { + return null; + } + return clzFile; + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/util/Util.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/util/Util.java new file mode 100644 index 0000000000..6081635316 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/util/Util.java @@ -0,0 +1,17 @@ +package com.sprint.jvm.util; + +public class Util { + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group11/1178243325/week06/src/test/java/com/sprint/basic/LRUPageFrameTest.java b/group11/1178243325/week06/src/test/java/com/sprint/basic/LRUPageFrameTest.java new file mode 100644 index 0000000000..ac28668dbe --- /dev/null +++ b/group11/1178243325/week06/src/test/java/com/sprint/basic/LRUPageFrameTest.java @@ -0,0 +1,33 @@ +package com.sprint.basic; +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + frame.access(5); + Assert.assertEquals("5,4,0", frame.toString()); + + } + +} diff --git a/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..d3d84b414f --- /dev/null +++ b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,23 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import org.junit.Test; +import org.junit.Assert; +public class ClassFileLoaderTest { + + private static final String FULL_QUALTFIED_CLASS_NAME = "com/sprint/jvm/EmployeeV1"; + + static String path1 = "/home/sprint/java/code/coding2017/group11/1178243325/week06/build/classes/test"; + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.sprint.jvm.loader.EmployeeV1"; + clzFile = loader.loadClass(className); + } + + @Test + public void test() { + Assert.assertEquals("cafebabe", clzFile.getCafebabe()); + } +} diff --git a/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/EmployeeV1.java b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..6b8532842b --- /dev/null +++ b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello, this is class Employee"); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 20); + p.sayHello(); + } +} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/.Struts.java.swp b/group11/1178243325/week07/.readme.md.swp similarity index 77% rename from group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/.Struts.java.swp rename to group11/1178243325/week07/.readme.md.swp index 1f45a5f25e..3d7e4464a8 100644 Binary files a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/.Struts.java.swp and b/group11/1178243325/week07/.readme.md.swp differ diff --git a/group11/1178243325/week07/build.gradle b/group11/1178243325/week07/build.gradle new file mode 100644 index 0000000000..128f6fda07 --- /dev/null +++ b/group11/1178243325/week07/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + compile("commons-io:commons-io:2.4") + //compile("commons-lang:commons-lang:2.6") + compile("org.apache.commons:commons-lang3:3.4") + testCompile("junit:junit:4.12") +} + diff --git a/group11/1178243325/week07/readme.md b/group11/1178243325/week07/readme.md new file mode 100644 index 0000000000..cc9d7c6f3c --- /dev/null +++ b/group11/1178243325/week07/readme.md @@ -0,0 +1,12 @@ +## 讲课内容: +- 17-03-29 :JVM之classLoader + +## 第七周作业(04-03 至 04-09) +- 实现对一个.class文件的常量池读取 +- 实现StackUtil +- [文章](http://www.jianshu.com/p/502c1e5caa97) +## 完成情况: + + +## 我的收获: + diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/AccessFlag.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..e74740aa3e --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.sprint.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flagValue) { + this.flagValue = flagValue; + } + + public boolean isPublicClass() { + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass() { + return (this.flagValue & 0x0010) != 0; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassFile.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..4e5aad16f9 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassFile.java @@ -0,0 +1,71 @@ +package com.sprint.jvm.clz; + +import com.sprint.jvm.constant.ConstantPool; +import com.sprint.jvm.constant.ClassInfo; +public class ClassFile { + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + public int getMinorVersion() { + return minorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ClassIndex getClassIndex() { + return clzIndex; + } + + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public ConstantPool getConstantPool() { + return pool; + } + + public void setConstantPool(ConstantPool pool) { + this.pool = pool; + } + + public void print() { + if (this.accessFlag.isPublicClass()) { + System.out.println("Access flag : public "); + } + System.out.println("Class Name:" + getClassName() ); + System.out.println("Super Class Name:" + getSuperClassName()); + } + + private String getClassName() { + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName() { + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassIndex.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..46e7443d90 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassIndex.java @@ -0,0 +1,22 @@ +package com.sprint.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + + public void setThisClassIndex(int index) { + this.thisClassIndex = index; + } + + public int getSuperClassIndex() { + return superClassIndex; + } + + public void setSuperClassIndex(int index) { + this.superClassIndex = index; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ClassInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..b8da3c656d --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ClassInfo.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public void setUtf8Index(int index) { + this.utf8Index = index; + } + + public int getUtf8Index() { + return utf8Index; + } + + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..a8db82689e --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.sprint.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo() {} + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantPool.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..3a35c22ce0 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantPool.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + private List constantInfos = new ArrayList(); + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + this.constantInfos.add(info); + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/FieldRefInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..c0eb449085 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/FieldRefInfo.java @@ -0,0 +1,52 @@ +package com.sprint.jvm.constant; + +public class FieldRefInfo extends ConstantInfo { + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return getClassName() + ":" + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + ClassInfo classInfo = (ClassInfo)this.getConstantInfo(this.getClassInfoIndex()); + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + return utf8Info.getValue(); + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/MethodRefInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..85bb5c4934 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.sprint.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + return getClassName() + ":" + this.getMethodName() + ":" + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} + diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NameAndTypeInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..492fd6e0db --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,52 @@ +package com.sprint.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo { + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } + + +} + + diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NullConstantInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..f257cea240 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NullConstantInfo.java @@ -0,0 +1,12 @@ +package com.sprint.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + public NullConstantInfo() { + + } + + @Override + public int getType() { + return -1; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/StringInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..73c58a5e71 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.sprint.jvm.constant; + +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.STRING_INFO; + private int index; + + public StringInfo(ConstantPool constantPool) { + super(constantPool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/UTF8Info.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..5516999c0e --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/UTF8Info.java @@ -0,0 +1,35 @@ +package com.sprint.jvm.constant; + +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value + "]"; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..fc5d1b2ac2 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,50 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.util.Util; +import java.util.Arrays; +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1ToInt() { + return Util.byteToInt(new byte[] {codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[] {codes[pos++], codes[pos++]}); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[] {codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[] {codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + } + + public void back(int n) { + this.pos -= n; + } + + +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..f190f54915 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java @@ -0,0 +1,52 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; +import java.util.List; +import java.util.ArrayList; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + public byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar) + ".class"; + for (String path : this.clzPaths) { + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch(IOException e) { + e.printStackTrace(); + return null; + } + } + + public void addClassPath(String path) { + if (this.clzPaths.contains(path)) { + return; + } + this.clzPaths.add(path); + } + + public String getClassPath() { + return StringUtils.join(this.clzPaths, ";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileParser.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..4b77190a04 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileParser.java @@ -0,0 +1,107 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import com.sprint.jvm.clz.AccessFlag; +import com.sprint.jvm.clz.ClassIndex; +import com.sprint.jvm.constant.ClassInfo; +import com.sprint.jvm.constant.ConstantPool; +import com.sprint.jvm.constant.FieldRefInfo; +import com.sprint.jvm.constant.NameAndTypeInfo; +import com.sprint.jvm.constant.NullConstantInfo; +import com.sprint.jvm.constant.MethodRefInfo; +import com.sprint.jvm.constant.StringInfo; +import com.sprint.jvm.constant.UTF8Info; +import java.io.UnsupportedEncodingException; +public class ClassFileParser { + public ClassFile parse(byte[] codes) { + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magicNumber = iter.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) { + return null; + } + clzFile.setMinorVersion(iter.nextU2ToInt()); + System.out.println("minor:" + clzFile.getMinorVersion()); + clzFile.setMajorVersion(iter.nextU2ToInt()); + System.out.println("marjor:" + clzFile.getMajorVersion()); + ConstantPool pool = parseConstantPool(iter); + clzFile.setConstantPool(pool); + + AccessFlag flag = parseAccessFlag(iter); + clzFile.setAccessFlag(flag); + + ClassIndex clzIndex = parseClassIndex(iter); + clzFile.setClassIndex(clzIndex); + return clzFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag flag = new AccessFlag(iter.nextU2ToInt()); + return flag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + int thisClassIndex = iter.nextU2ToInt(); + int superClassIndex = iter.nextU2ToInt(); + + ClassIndex clzIndex = new ClassIndex(); + clzIndex.setThisClassIndex(thisClassIndex); + clzIndex.setSuperClassIndex(superClassIndex); + return clzIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int constPoolCount = iter.nextU2ToInt(); + System.out.println("Constant Pool Count :" + constPoolCount); + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + for (int i = 1; i <= constPoolCount - 1; i++) { + int tag = iter.nextU1ToInt(); + if (tag == 7) { + int utf8Index = iter.nextU2ToInt(); + ClassInfo clzInfo = new ClassInfo(pool); + clzInfo.setUtf8Index(utf8Index); + pool.addConstantInfo(clzInfo); + } else if (tag == 1) { + int len = iter.nextU2ToInt(); + byte[] data = iter.getBytes(len); + String value = null; + try { + value = new String(data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info utf8Str = new UTF8Info(pool); + utf8Str.setLength(len); + utf8Str.setValue(value); + pool.addConstantInfo(utf8Str); + } else if (tag == 8) { + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(info); + } else if (tag == 9) { + FieldRefInfo field = new FieldRefInfo(pool); + field.setClassInfoIndex(iter.nextU2ToInt()); + field.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(field); + } else if (tag == 10) { + MethodRefInfo method = new MethodRefInfo(pool); + method.setClassInfoIndex(iter.nextU2ToInt()); + method.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(method); + } else if (tag == 12) { + NameAndTypeInfo nameType = new NameAndTypeInfo(pool); + nameType.setIndex1(iter.nextU2ToInt()); + nameType.setIndex2(iter.nextU2ToInt()); + pool.addConstantInfo(nameType); + } else { + throw new RuntimeException("the constant pool tag:" + tag + "has no been implemented yet."); + } + } + System.out.println("Finished reading Constant Pool"); + return pool; + } + + +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/util/Util.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/util/Util.java new file mode 100644 index 0000000000..0f5dc89626 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/util/Util.java @@ -0,0 +1,22 @@ +package com.sprint.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes) { + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..5cbc24577e --- /dev/null +++ b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,181 @@ +package com.sprint.jvm.loader; + + +import com.sprint.jvm.clz.ClassFile; +import com.sprint.jvm.clz.ClassIndex; +import com.sprint.jvm.constant.*; +import org.junit.Test; +import org.junit.Assert; +public class ClassFileLoaderTest { + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/sprint/jvm/loader/EmployeeV1"; + static String path1 = "/home/sprint/java/code/coding2017/group11/1178243325/week07/build/classes/test"; + static String path2 = "/home/sprint/xxx"; + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.sprint.jvm.loader.EmployeeV1"; + clzFile = loader.loadClass(className); + clzFile.print(); + } + + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "com.sprint.jvm.loader.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1050, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.sprint.jvm.loader.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClassIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + +} diff --git a/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/EmployeeV1.java b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..6b8532842b --- /dev/null +++ b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello, this is class Employee"); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 20); + p.sayHello(); + } +} diff --git a/group11/1310368322/RemoteSystemsTempFiles/.project b/group11/1310368322/RemoteSystemsTempFiles/.project new file mode 100644 index 0000000000..5447a64fa9 --- /dev/null +++ b/group11/1310368322/RemoteSystemsTempFiles/.project @@ -0,0 +1,12 @@ + + + RemoteSystemsTempFiles + + + + + + + org.eclipse.rse.ui.remoteSystemsTempNature + + diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/AttributeInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..58f2190146 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + + int attrNameIndex; + int attrLen ; + + public AttributeInfo(int attrNameIndex, int attrLen) { + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/CodeAttr.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..e07662a68b --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/CodeAttr.java @@ -0,0 +1,86 @@ +package com.coderising.jvm.attr; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.loader.ByteCodeIterator; + +public class CodeAttr extends AttributeInfo{ + + private int maxStack; + private int maxLocals; + private int codeLen; + private String code; + + public String getCode(){ + return code; + } + + + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + + + public CodeAttr(int attrNameIndex, int attrLen , int maxStack, int maxLocals, int codeLen,String code) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2toInt(); + int attrLen = iter.nextU2toInt(); + int maxStack = iter.nextU2toInt(); + int max_Locals = iter.nextU2toInt(); + int codeLen = iter.nextU4toInt(); + // code + String code = iter.nextUxToHexString(codeLen); + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, max_Locals, max_Locals, code); + + int exceptionTableLen = iter.nextU2toInt(); + + if(exceptionTableLen > 0){ + String exTable = iter.nextUxToHexString(exceptionTableLen); + System.out.println("Encounted exception table, just ignore it"); + } + + int subAttributesCount = iter.nextU2toInt(); + + for(int i = 0; i < subAttributesCount; i++){ + int subAttrNameIndex = iter.nextU2toInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrNameIndex); + if(CodeAttr.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)){ + int subAttrLen = iter.nextU4toInt();// localVariableTable Ե + LocalVariableTable locVarTable = LocalVariableTable.parse(iter, subAttrNameIndex, subAttrLen); + codeAttr.setLocalVariableTable(locVarTable); + }else if(CodeAttr.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)){ + int subAttrLen = iter.nextU4toInt(); + LineNumberTable lineNumTable = LineNumberTable.parse(iter, subAttrNameIndex, subAttrLen); + codeAttr.setLineNumberTable(lineNumTable); + }else if(CodeAttr.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)){ + int subAttrLen = iter.nextU4toInt(); + StackMapTable stackMapTable = StackMapTable.parse(iter); + codeAttr.setStackMapTable(stackMapTable); + }else{ + throw new RuntimeException("need code to process" + subAttrName); + } + } + + return codeAttr; + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LineNumberTable.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..24bcb25572 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LineNumberTable.java @@ -0,0 +1,52 @@ +package com.coderising.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo{ + + List items = new ArrayList();// кűкܶġкŶӦ + + // LineNumberTableһṹñ˿ + private static class LineNumberItem{ + int startPC;// ¼ֽк + int lineNum;// ¼JavaԴк + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LineNumberTable parse(ByteCodeIterator iter, int subAttrNameIndex, int subAttrLen){ + LineNumberTable lineNumTable = new LineNumberTable(subAttrNameIndex, subAttrLen); + int lineNumTableLen = iter.nextU2toInt(); + for(int i = 0; i < lineNumTableLen; i ++){ + int startPC = iter.nextU2toInt(); + int lineNum = iter.nextU2toInt(); + LineNumberItem lineNumItem = new LineNumberItem(); + lineNumItem.setStartPC(startPC); + lineNumItem.setLineNum(lineNum); + lineNumTable.addLineNumberItem(lineNumItem); + } + return lineNumTable; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableItem.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..842e1d0a96 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableItem.java @@ -0,0 +1,41 @@ +package com.coderising.jvm.attr; + +public class LocalVariableItem { + + private int startPC;// ֲڿʼʱֽƫ + private int length; // ֽij + private int nameIndex; // ֲ + private int descIndex; // ֲ + private int index; // ֲջ֡еľֲе slot λ + + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableTable.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..757f28918b --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableTable.java @@ -0,0 +1,41 @@ +package com.coderising.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter, int subAttrName, int subAttrLen){ + + LocalVariableTable locVarTable = new LocalVariableTable(subAttrName, subAttrLen); + int localVarTableLen = iter.nextU2toInt(); + for(int i = 0; i < localVarTableLen; i++){ + int startPC = iter.nextU2toInt(); + int length = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descIndex = iter.nextU2toInt(); + int index = iter.nextU2toInt(); + LocalVariableItem locVarItem = new LocalVariableItem(); + locVarItem.setStartPC(startPC); + locVarItem.setLength(length); + locVarItem.setNameIndex(nameIndex); + locVarItem.setDescIndex(descIndex); + locVarItem.setIndex(index); + locVarTable.addLocalVariableItem(locVarItem); + } + + return locVarTable; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/StackMapTable.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..9df44fb5ca --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/StackMapTable.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.attr; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2toInt(); + int len = iter.nextU4toInt(); + StackMapTable t = new StackMapTable(index,len); + + //StackMapTable̫ӣ ٴ ֻԭʼĴ + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/AccessFlag.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..4e26442ed5 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value){ + this.flagValue = value; + } + + public int getFlagValue(){ + return flagValue; + } + + public void setFlagValue(int flag){ + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassFile.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..4492d2df9e --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,95 @@ +package com.coderising.jvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class ClassFile { + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag;// ڳ֮ + private ClassIndex clzIndex;// ڷʱ־֮, ͽӿ + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + + public AccessFlag getAccessFlag(){ + return accessFlag; + } + + public ClassIndex getClzIndex(){ + return clzIndex; + } + + public void setClassIndex(ClassIndex clzIndex){ + this.clzIndex = clzIndex; + } + + public int getMinorVersion(){ + System.out.println(minorVersion); + return minorVersion; + } + + public void setMinorVersion(int minorVersion){ + this.minorVersion = minorVersion; + } + + public int getMajorVersion(){ + return majorVersion; + } + + public void setMajorVersion(int majorVersion){ + this.majorVersion = majorVersion; + } + + public ConstantPool getConstantPool(){ + return this.pool; + } + public void setConstantPool(ConstantPool pool){ + this.pool = pool; + } + + public void addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + public void print(){ + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("ClassName: " + getClassName()); + System.out.println("SuperClassName: " + getSuperClassName()); + + } + + public void setAccessFlag(AccessFlag accessFlag){ + this.accessFlag = accessFlag; + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassIndex.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..8382ef03f9 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,23 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex(){ + System.out.println(thisClassIndex); + return thisClassIndex; + } + + public void setThisClassIndex(int thisClassIndex){ + this.thisClassIndex = thisClassIndex; + } + + public int getSuperClassIndex(){ + return superClassIndex; + } + + public void setSuperClassIndex(int superClassIndex){ + this.superClassIndex = superClassIndex; + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ClassInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..13fc4101a3 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,33 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo{ + + private int type = ConstantInfo.CLASS_INFO;// ʾóΪ ӿڵķ + private int utf8Index;// CONSTANT_Class_info ͳ ṹе name_index name_index ָһ CONSTANT_Utf8_info ͵ij + + public ClassInfo(ConstantPool pool){ + super(pool); + } + + public int getUtf8Index(){ + return utf8Index; + } + + public void setUtf8Index(int utf8Index){ + this.utf8Index = utf8Index; + } + + @Override + public int getType(){ + return type; + } + + // + public String getClassName(){ + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..e20be200d6 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,34 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool){// Ϊ֮Ҫ + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool(){ + return constantPool; + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index);// õ ConstantInfo ı constantPool е getConstantInfo + // ContantInfo е getConstantInfo ͬ + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantPool.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..82565b7f59 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,31 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + // е Ϣ + private List constantInfos = new ArrayList(); + + public ConstantPool(){ + + } + + public void addConstantInfo(ConstantInfo info){ + this.constantInfos.add(info); + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + + public String getUTF8String(int index){ + System.out.println("index: " + index); + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + + public Object getSize(){ + return constantInfos.size() - 1; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/FieldRefInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..731c35b118 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,62 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex;// ָ Ϣ + private int nameAndTypeIndex;// ֶָ ֺ + + public FieldRefInfo(ConstantPool pool){ + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex(){ + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex){ + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex(){ + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex){ + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return getClassName() + " : " + typeInfo.getName() + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName(){ + ClassInfo classInfo = (ClassInfo)this.getConstantInfo(this.getClassInfoIndex()); + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + return utf8Info.getValue(); + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(nameAndTypeIndex); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(nameAndTypeIndex); + return typeInfo.getTypeInfo(); + } +} + + + + + + + + + diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/MethodRefInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..49d89083fd --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,52 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo{ + + private int type = ConstantInfo.METHOD_INFO; + private int classInfoIndex;// ָ ÷ + private int nameAndTypeIndex;// ָ÷ ƺ͵ + + public MethodRefInfo(ConstantPool pool){ + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex(){ + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex){ + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex(){ + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex){ + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.classInfoIndex); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.nameAndTypeIndex); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.nameAndTypeIndex); + return typeInfo.getTypeInfo(); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NameAndTypeInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..8494e5e76a --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,52 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1;// ָƵ + private int index2;// ָ() + + public NameAndTypeInfo(ConstantPool pool){ + super(pool); + } + + public int getIndex1(){ + return index1; + } + + public void setIndex1(int index1){ + this.index1 = index1; + } + + public int getIndex2(){ + return index2; + } + + public void setIndex2(int index2){ + this.index2 = index2; + } + + @Override + public int getType(){ + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1);// õ ֶ Name + return utf8Info1.getValue(); // ֶ Nameֵ + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo() + ")"; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NullConstantInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..f0be39e410 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo{ + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/StringInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..3ff8e9402b --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + + private int type = ConstantInfo.STRING_INFO; + private int index;// ַָ + + public StringInfo(ConstantPool pool){ + super(pool); + } + + + @Override + public int getType() { + return type; + } + + public int getIndex(){ + return index; + } + + public void setIndex(int index){ + this.index = index; + } + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/UTF8Info.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..6374764b5f --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,40 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool){ + super(pool); + } + + public int getLength(){ + return length; + } + + public void setLength(int length){ + this.length = length; + } + + @Override + public int getType() { + return type; + } + + public String getValue(){ + return value; + } + + public void setValue(String value){ + this.value = value; + } + + @Override + public String toString(){ + return "UTF8Info [type=" + type + ",length" + length + ",value" + value + ")]"; + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/field/Field.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/field/Field.java new file mode 100644 index 0000000000..9e110b1867 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/field/Field.java @@ -0,0 +1,43 @@ +package com.coderising.jvm.field; + +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.loader.ByteCodeIterator; + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private ConstantPool pool; + public int getNameIndex(){ + return nameIndex; + } + public int getDescIndex(){ + return descriptorIndex; + } + public String toString(){ + return pool.getUTF8String(nameIndex) + ":" + pool.getUTF8String(descriptorIndex); + } + public Field(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool pool){ + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + public static Field parse(ConstantPool pool, ByteCodeIterator iter){ + int accessFlag = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descriptorIndex = iter.nextU2toInt(); + int attrLen = iter.nextU2toInt(); + if(attrLen > 0){ + throw new RuntimeException("Field attributes has not been implemented"); + } + Field field = new Field(accessFlag,nameIndex,descriptorIndex,pool); + + return field; + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ByteCodeIterator.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..41516cd506 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,61 @@ +package com.coderising.jvm.loader; + +public class ByteCodeIterator { + + byte[] codes; + int pos;// άλ + + public ByteCodeIterator(byte[] codes){ + this.codes = codes; + } + + public int nextU1toInt(){ + return (codes[pos++] & 0xFF); + } + + public int nextU2toInt(){ + byte [] a = new byte[]{ codes[pos++], codes[pos++]}; + return (a[0]<<8) + a[1]; + } + + public int nextU4toInt(){ + byte [] a = new byte[]{ codes[pos++], codes[pos++], codes[pos++], codes[pos++]}; + return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; + } + + public byte[] getByte(int length){ + byte []a = new byte[length]; + for(int i = 0; i < length; i++){ + a[i] = codes[pos++]; + } + return a; + } + public String nextU4ToHexString(){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < 4; i++){ + int a = codes[pos++] & 0xFF; + String strHex = Integer.toHexString(a); + if(strHex.length() < 2){ + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + public String nextUxToHexString(int len) { + + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < len; i++){ + int a = codes[pos++] & 0xFF; + String strHex = Integer.toHexString(a); + if(strHex.length() < 2){ + strHex = "0" + strHex; + } + buffer.append(strHex); + } + + return buffer.toString(); + + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileLoader.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6e479bbce9 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,69 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.runners.Parameterized.Parameters; + +import com.coderising.jvm.clz.ClassFile; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + int countForClassPath = 0; + int countForReadBinaryCode = 0; + byte [] a = new byte[10000]; + + /* ָ·ȡļ䱣浽һֽУ + * @Parameters ָ· + * @ֽ + */ + public byte[] readBinaryCode(String className) throws IOException{ + DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream(className))); + for(int i = 0; dis.available() != 0; i++){ + a[i] = dis.readByte(); + countForReadBinaryCode++; + } + byte []target = new byte[countForReadBinaryCode]; + System.arraycopy(a, 0, target, 0, countForReadBinaryCode); + dis.close(); + return target; + } + + public void addClassPath(String path){ + clzPaths.add(path); + countForClassPath++; + } + + public String getClassPath(){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < countForClassPath; i++ ){ + if(i==countForClassPath-1){ + buffer.append(clzPaths.get(i)); + }else{ + buffer.append(clzPaths.get(i)+";"); + } + } + return buffer.toString(); + } + + public ClassFile loadClass(String className) throws IOException{ + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } + + + + + + + + + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileParser.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..43e3796ef5 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,169 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; + +import javax.management.RuntimeErrorException; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +/* + * һֽ飬ɶа ClassFile + */ +public class ClassFileParser { + + // غ ClassFile + public ClassFile parse(byte[] codes){ + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magicNumber = iter.nextU4ToHexString(); + if(!magicNumber.equals("cafebabe")){ + return null; + } + clzFile.setMinorVersion(iter.nextU2toInt()); + clzFile.setMajorVersion(iter.nextU2toInt()); + + // ȡ + ConstantPool pool = parseConstantPool(iter); + AccessFlag accessFlag = parseAccessFlag(iter); + ClassIndex clzIndex = parseClassIndex(iter); + clzFile.setAccessFlag(accessFlag); + clzFile.setClassIndex(clzIndex); + clzFile.setConstantPool(pool);// м볣 + + parseInterfaces(iter); + parseFields(clzFile,iter); + parseMethods(clzFile,iter); + + + return clzFile; + } + + + + + private AccessFlag parseAccessFlag(ByteCodeIterator iter){ + int accessFlagValue = iter.nextU2toInt(); + AccessFlag accessFlag = new AccessFlag(accessFlagValue); + accessFlag.setFlagValue(accessFlagValue); + return accessFlag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter){ + int thisClassIndex = iter.nextU2toInt(); + int superClassIndex = iter.nextU2toInt(); + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(superClassIndex); + return classIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter){ + + int constantPoolCount = iter.nextU2toInt(); + System.out.println("ConstantPool Count : " + constantPoolCount); + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + + // ӳϢ + for(int i = 1; i <= constantPoolCount-1; i++){// JVM 涨Ҫ ȥ 1ȥ 1ij + + int tag = iter.nextU1toInt(); + if(tag == 7){ + // ӿڵķ ClassInfo + int utf8Index = iter.nextU2toInt(); + ClassInfo clzInfo= new ClassInfo(pool);// һ ClassInfo + clzInfo.setUtf8Index(utf8Index); + pool.addConstantInfo(clzInfo); + }else if(tag == 1){ + // UTF-8 ַ + int length = iter.nextU2toInt(); + byte data[] = iter.getByte(length); + String value = null; + try { + value = new String(data,"UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + UTF8Info utf8Info = new UTF8Info(pool); + utf8Info.setLength(length); + utf8Info.setValue(value); + pool.addConstantInfo(utf8Info); + }else if(tag == 12){ + // NameAndTypeInfo ֶλ򷽷IJַ + int NameIndex = iter.nextU2toInt(); + int TypeIndex = iter.nextU2toInt(); + NameAndTypeInfo nameAndType = new NameAndTypeInfo(pool); + nameAndType.setIndex1(NameIndex); + nameAndType.setIndex2(TypeIndex); + pool.addConstantInfo(nameAndType); + }else if(tag == 9){ + // FieldRefInfo ֶεķ + int classInfoIndex = iter.nextU2toInt(); + int nameAndTypeIndex = iter.nextU2toInt(); + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(classInfoIndex); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(fieldRefInfo); + }else if(tag == 10){ + // MethodRefInfo зķ + int classInfoIndex = iter.nextU2toInt(); + int nameAndTypeIndex = iter.nextU2toInt(); + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(classInfoIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(methodRefInfo); + }else if(tag == 8){ + int stringIndex = iter.nextU2toInt();// ַָ + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setIndex(stringIndex); + pool.addConstantInfo(stringInfo); + }else{ + throw new RuntimeException("the constant pool tag" + tag + "has not been implemented yet"); + } + + } + return pool; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfacesCount = iter.nextU2toInt(); + System.out.println("interfacesCount: " + interfacesCount); + if(interfacesCount > 0){ + throw new RuntimeException("interfaces has not been implemented"); + } + + } + + private void parseFields(ClassFile clzFile, ByteCodeIterator iter) { + int fieldsCount = iter.nextU2toInt(); + System.out.println("fieldsCount: " + fieldsCount); + for(int i = 0; i < fieldsCount; i++){ + Field f = Field.parse(clzFile.getConstantPool(), iter); + clzFile.addField(f); + } + + } + + private void parseMethods(ClassFile clzFile, ByteCodeIterator iter) { + int methodsCount = iter.nextU2toInt(); + System.out.println("methodsCount: " + methodsCount); + for(int i = 0; i < methodsCount; i++){ + Method m = Method.parse(clzFile, iter); + clzFile.addMethod(m); + } + + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/TestJVM.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/TestJVM.java new file mode 100644 index 0000000000..735e4d1dc2 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/TestJVM.java @@ -0,0 +1,7 @@ +package com.coderising.jvm.loader; + +public class TestJVM { + public static void main(String[] args) { + System.out.println("Hello"); + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/method/Method.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/method/Method.java new file mode 100644 index 0000000000..572880f729 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/method/Method.java @@ -0,0 +1,68 @@ +package com.coderising.jvm.method; + +import com.coderising.jvm.attr.AttributeInfo; +import com.coderising.jvm.attr.CodeAttr; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.loader.ByteCodeIterator; + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + public int getNameIndex() { + return nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public ClassFile getClzFile() { + return clzFile; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + int accessFlag = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descriptor = iter.nextU2toInt(); + int attrCount = iter.nextU2toInt(); + + + Method method = new Method(clzFile,accessFlag,nameIndex,descriptor); + System.out.println("attrCount: " + attrCount); + // methodе + for(int i = 0; i < attrCount; i++){ + int attrNameIndex = iter.nextU2toInt(); + String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex); + System.out.println(attrName); + if(AttributeInfo.CODE.equalsIgnoreCase(attrName)){ + CodeAttr attrCode = CodeAttr.parse(clzFile, iter); + method.setCodeAttr(attrCode); + } + + } + return method; + } +} diff --git a/group11/1310368322/src/Download/DownloadThread.java b/group11/1310368322/src/data_structure/BigHomework/Download/DownloadThread.java similarity index 100% rename from group11/1310368322/src/Download/DownloadThread.java rename to group11/1310368322/src/data_structure/BigHomework/Download/DownloadThread.java diff --git a/group11/1310368322/src/Download/FileDownloader.java b/group11/1310368322/src/data_structure/BigHomework/Download/FileDownloader.java similarity index 100% rename from group11/1310368322/src/Download/FileDownloader.java rename to group11/1310368322/src/data_structure/BigHomework/Download/FileDownloader.java diff --git a/group11/1310368322/src/Download/api/Connection.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/Connection.java similarity index 100% rename from group11/1310368322/src/Download/api/Connection.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/Connection.java diff --git a/group11/1310368322/src/Download/api/ConnectionException.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionException.java similarity index 100% rename from group11/1310368322/src/Download/api/ConnectionException.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionException.java diff --git a/group11/1310368322/src/Download/api/ConnectionManager.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionManager.java similarity index 100% rename from group11/1310368322/src/Download/api/ConnectionManager.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionManager.java diff --git a/group11/1310368322/src/Download/api/DownloadListener.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/DownloadListener.java similarity index 100% rename from group11/1310368322/src/Download/api/DownloadListener.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/DownloadListener.java diff --git a/group11/1310368322/src/Download/impl/ConnectionImpl.java b/group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionImpl.java similarity index 100% rename from group11/1310368322/src/Download/impl/ConnectionImpl.java rename to group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionImpl.java diff --git a/group11/1310368322/src/Download/impl/ConnectionManagerImpl.java b/group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionManagerImpl.java similarity index 100% rename from group11/1310368322/src/Download/impl/ConnectionManagerImpl.java rename to group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionManagerImpl.java diff --git a/group11/1310368322/src/ArrayList.java b/group11/1310368322/src/data_structure/baseDataStructure_1/ArrayList.java similarity index 100% rename from group11/1310368322/src/ArrayList.java rename to group11/1310368322/src/data_structure/baseDataStructure_1/ArrayList.java diff --git a/group11/1310368322/src/LinkedList.java b/group11/1310368322/src/data_structure/baseDataStructure_1/LinkedList.java similarity index 100% rename from group11/1310368322/src/LinkedList.java rename to group11/1310368322/src/data_structure/baseDataStructure_1/LinkedList.java diff --git a/group11/1310368322/src/ArrayUtil.java b/group11/1310368322/src/data_structure/baseDataStructure_2/ArrayUtil.java similarity index 100% rename from group11/1310368322/src/ArrayUtil.java rename to group11/1310368322/src/data_structure/baseDataStructure_2/ArrayUtil.java diff --git a/group11/1310368322/src/data_structure/baseDataStructure_3/LinkedList.java b/group11/1310368322/src/data_structure/baseDataStructure_3/LinkedList.java new file mode 100644 index 0000000000..5ea6a988be --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_3/LinkedList.java @@ -0,0 +1,162 @@ +package DataStructure_3; + +import java.util.Stack; + +import DataStructure_1.LinkedList.Node; + +public class LinkedList { + private Node head; + static int size = 0; + public void add(Object o){ + if(null == head){ + head = new Node(); + head.data = o; + head.next = null; + }else{ + Node p = head; + while(null != p.next){ + p = p.next; + } + Node newNode = new Node(); + newNode.data = o; + p.next = newNode; + newNode.next =null; + } + size++; + } + public int size(){ + return size; + } + public void add(int index,Object o){ + if(index < 0){ + throw new RuntimeException("±겻Ϊ"); + } + if(index == 0){ + addFirst(o); + size++; + return; + } + if(index > size){ + throw new RuntimeException(""); + } + int i = 0; + Node p = head; + Node q = null; + + while(i!=index){ + q = p; + p = p.next; + i++; + } + Node r = new Node(); + r.data = o; + r.next =null; + q.next = r; + r.next = p; + size++; + return; + } + + public Object get(int index){ + int i = 0; + Node p = head; + while(i != index){ + p = p.next; + i++; + } + return p.data; + } + public Object remove(int index){ + if(index < 0){ + throw new RuntimeException("±겻Ϊ"); + } + if(index == 1){ + size--; + return head.data; + } + int i = 0; + Node p = head; + Node q = null; + while(i != index){ + q = p; + p = p.next; + i++; + } + q.next = p.next; + size--; + return p.data; + } + public void addFirst(Object o){ + Node p = new Node(); + p.next = head; + p.data = o; + head = p; + size++; + } + public Object removeFirst(){ + head = head.next; + size--; + return null; + } + public static class Node{ + Object data; + Node next; + } + + /** + * Ѹ + * 3->7->10 úΪ 10->7->3 + */ + public void reverse(){ + if(null == head || null == head.next){ + return; + } + Stack s = new Stack(); + Node curNode = head; + while(curNode != null){ + s.push(curNode); + Node nextNode = curNode.next; + curNode.next = null; // Ͽ + curNode = nextNode; + } + + head = s.pop(); + curNode = head; + while(!s.isEmpty()){ + Node nextNode = s.pop(); + curNode.next = nextNode; + curNode = nextNode; + } + + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + buffer.append("["); + Node node = head; + while(node != null){ + buffer.append(node.data); + if(node.next != null){ + buffer.append(","); + } + node = node.next; + } + buffer.append("]"); + return buffer.toString(); + } + + + + + + + + + + + + + + + +} diff --git a/group11/1310368322/src/data_structure/baseDataStructure_4_LRU/LRUPageFrame.java b/group11/1310368322/src/data_structure/baseDataStructure_4_LRU/LRUPageFrame.java new file mode 100644 index 0000000000..5e860a31d7 --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_4_LRU/LRUPageFrame.java @@ -0,0 +1,143 @@ +package DataStructure_4_LRU; + +import org.junit.runners.Parameterized.Parameters; + +/* + * ˫ʵLRU㷨 + */ +public class LRUPageFrame { + private static class Node{ + Node prev; + Node next; + int pageNum = -1;// ҳ + + Node(){ + + } + } + + private int capacity; + + private Node first;// ͷ + private Node last;// β + boolean tag = false; + + public LRUPageFrame(int capacity){ + this.capacity = capacity; + + for(int i = 0; i < capacity; i++){ + Node curNode = new Node(); + if(null == first){ + last = first = curNode; + }else{ + last.next = curNode; + curNode.prev = last; + last = last.next; + } + last.next = null; + } + } + public void printList(){ + Node curNode = first; + while(curNode != null){ + curNode = curNode.next; + } + } + /* + * ȡж + * @param key + * @return + */ + public void access(int pageNum){ + printList(); + Node index = findLogicPage(pageNum); + modifyPhysicalPage(index,pageNum); + } + + /* + * @param pageNum ʾҪѯ߼ҳ + * @return ҳҵҪѯ߼ҳ棬򷵻ظҳڵã򷵻null + */ + public Node findLogicPage(int pageNum){ + + Node index = null; + Node curNode = first; + while(curNode != null){ + if(curNode.pageNum == pageNum){ + index = curNode; + tag = true; + } + curNode = curNode.next; + } + return index; + } + /* + * @prama index ߼ҳҳĽڵ + */ + public void modifyPhysicalPage(Node index,int pageNum){ + push(pageNum,index); + } + /* + * @param pageNum Ҫ push߼ҳ棬 Ĭջ first, bottom ջ ָջĴС + */ + public void push(int pageNum,Node bottom){ + Node index = checkWhichListNodeNotUsed(); + if(index != null){ + index.pageNum = pageNum; + return; + } + + Node lastNode; + if(null == bottom){ + lastNode = last; + }else{ + lastNode = bottom; + } + Node curNode = lastNode.prev; + while(curNode != null){ + lastNode.pageNum = curNode.pageNum; + lastNode = curNode; + curNode = curNode.prev; + } + lastNode.pageNum = pageNum; + return; + } + + /* + * @return ҳ pageNum ûбʹõĽڵ(ջ)ȫʹã򷵻 null + */ + public Node checkWhichListNodeNotUsed(){ + Node node = first; + Node index = null; + while(node != null){ + if(node.pageNum == -1){ + index = node; + } + node = node.next; + } + return index; + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + + + + + + + + + +} diff --git a/group11/1310368322/src/data_structure/baseDataStructure_5_Stack/StackUtil.java b/group11/1310368322/src/data_structure/baseDataStructure_5_Stack/StackUtil.java new file mode 100644 index 0000000000..782c7d59a6 --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_5_Stack/StackUtil.java @@ -0,0 +1,106 @@ +package DataStructure_5_Stack; + +import java.util.Stack; + +public class StackUtil { + /* + * ջеԪIntegerջջǣ 5,4,3,2,1 ø÷󣬴ջջ׻ 1,2,3,4,5 + * ע⣺ ֻʹ StackĻpush,pop,peek,isEmpty + */ + public static void reverse(Stack s){ + if(s.isEmpty()){ return; } + int length = s.size(); + Object []temp = new Object[length]; + for(int i = 0; i < length; i++){ + temp[i] = s.pop(); + } + for(int i = 0; i < length; i++){ + s.push(temp[i]); + } + return; + } + + /* + * ɾջָԪأע⣺ֻʹStackĻpush,pop,peek,isEmpty + * + */ + public static void remove(Stack s, Object o){ + int length = s.size(); + Object elementTemp; + System.out.println(length); + int count = 0; + Object []temp = new Object[length]; + if(s.isEmpty()){ return; } + for(int i = 0; i < length;i++){ + elementTemp = s.pop(); + if(!o.equals(elementTemp)){ + temp[count++] = elementTemp; + System.out.println(temp[i]); + } + } + + for(int i = count-1; i >= 0; i--){ + s.push(temp[i]); + } + return; + } + + /* + * ջȡlenԪأԭջеԪرֲ + * @param len + * @return + */ + public static Object[] getTop(Stack s , int len){ + if(s.isEmpty() || len > s.size() || len < 0){ + return null; + } + Object []result = new Object[len]; + for(int i = 0; i < len; i++){ + result[i] = s.pop(); + } + return result; + } + + /* + * ַ s ܰЩַ () [] {}, a, b, c ... x, y, z + * ʹöջַ s еDzdzɶԳֵ + * 磺 s = ([e{d}f]),ַеdzɶԳֵģ÷ true + * s = "([b{x]})",ַеŲdzɶԳֵģ÷ false + * @param s + * @return + */ + public static boolean isValidPairs(String s){ + Stack stack = new Stack(); + System.out.println(stack.isEmpty()); + char elementTemp; + boolean tag = false; + char [] a = s.toCharArray(); + for(int i = 0; i < a.length; i++){ + if((!tag) && (a[i] == '(' || a[i] == ')' || a[i] == '[' || a[i] == ']' || a[i] == '{' || a[i] == '}')){ + stack.push(a[i]); + tag = true; + }else{ + if(a[i] == '(' || a[i] == ')' || a[i] == '[' || a[i] == ']' || a[i] == '{' || a[i] == '}'){ + elementTemp = (char) stack.pop(); + switch(elementTemp){ + case '(': if(a[i]==')'){}else{ stack.push(elementTemp); stack.push(a[i]); }; break; + case '[': if(a[i]==']'){}else{ stack.push(elementTemp); stack.push(a[i]); }; break; + case '{': if(a[i]=='}'){}else{ stack.push(elementTemp); stack.push(a[i]); }; break; + + } + } + } + + } + if(stack.isEmpty()){ + return true; + } + return false; + } +} + + + + + + diff --git a/group11/1310368322/src/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java b/group11/1310368322/src/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java new file mode 100644 index 0000000000..c7285dd9a2 --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java @@ -0,0 +1,106 @@ +package dataStructure_6InfixExpr; + +import java.util.Stack; + +public class InfixExpr { + + String expr = null; + + public InfixExpr(String expr){ + this.expr = expr; + } + + public double evaluate(){ + + Stack operatorStack = new Stack(); + Stack operandStack = new Stack(); + + int tag = -1; + for(int i = 0; i < expr.length(); i++){ + if(operatorStack.isEmpty()){ + tag = -1; + } + char c = expr.charAt(i); + if( tag == 1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + System.out.println("i= " + i); + char down = (char) operatorStack.pop(); + System.out.println("down: " + down); + System.out.println("up: " + c); + if(judgePriority(down,c)){ + double operand = (double) operandStack.pop(); + double operanded = (double) operandStack.pop(); + operandStack.push(operator(down,operanded,operand)); + operatorStack.push(c); + }else{ + operatorStack.push(down); + operatorStack.push(c); + } + }else if(tag == -1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + tag = 1; + operatorStack.push(c); + + }else{ + String number = extractNumber(i,expr); + int length = number.length(); + i += length-1; + double operand = Double.parseDouble(number); + operandStack.push(operand); + } + } + + while(!operatorStack.isEmpty()){ + char operator = (char) operatorStack.pop(); + System.out.println(operator); + double operand = (double) operandStack.pop(); + System.out.println(operand); + double operanded = (double) operandStack.pop(); + System.out.println(operanded); + operandStack.push( operator(operator,operanded,operand)); + } + + return (double) operandStack.pop(); + } + + private String extractNumber(int i, String expr2) { + + StringBuffer buffer = new StringBuffer(); + while( (expr.charAt(i) != '+') && (expr.charAt(i) != '-') && (expr.charAt(i) != '*') && (expr.charAt(i) != '/') ){ + buffer.append(expr.charAt(i)); + if(i >= expr2.length()-1){ + break; + } + i++; + } + return buffer.toString(); + } + + private boolean judgePriority(char down, char up) { + boolean tag = false; + + if((up == '+' || up == '-') && (down == '*' || down == '/')){ + tag = true; + }else if( (up == '*') && (down == '/')){ + tag = true; + }else if( (up == '/') && (down == '*')){ + tag = true; + }else if( (up == '+') && (down == '-') ){ + tag = true; + }else if( (up == '-') && (down == '+') ){ + tag = true; + } + return tag; + } + + private double operator(char operator, double operanded, double operand) { + double result = 0; + + switch(operator){ + case '+': result = operanded + operand; break; + case '-': result = operanded - operand; break; + case '*': System.out.println("˷"); result = operanded * operand; break; + case '/': result = operanded / operand; break; + } + + return result; + } +} diff --git a/group11/1310368322/test/Mini_JVM/EmployeeV1.java b/group11/1310368322/test/Mini_JVM/EmployeeV1.java new file mode 100644 index 0000000000..acbc34c9bb --- /dev/null +++ b/group11/1310368322/test/Mini_JVM/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age){ + this.name = name; + this.age = age; + } + + public void setName(String name){ + this.name = name; + } + + public void setAge(int age){ + this.age = age; + } + + public void sayHello(){ + System.out.println("Hello, this is class Employee"); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + } +} diff --git a/group11/1310368322/test/Mini_JVM/TestClassFileLoader.java b/group11/1310368322/test/Mini_JVM/TestClassFileLoader.java new file mode 100644 index 0000000000..d1874a0834 --- /dev/null +++ b/group11/1310368322/test/Mini_JVM/TestClassFileLoader.java @@ -0,0 +1,246 @@ +package com.coderising.jvm.loader; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.List; + +import org.junit.*; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.*; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class TestClassFileLoader { + static String path1 = "D:/ProgramWorld"; + static String path2 = "D:/ProgramWorld/Java"; + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/loader/EmployeeV1"; + static String classPath1 = "D:/ProgramWorld/Java/Practice/LangSi/2017Ⱥ/bin/com/coderising/jvm/loader/EmployeeV1.class"; + static String classPath2 = "D:/TestClass.class"; + static ClassFile clzFile = null; + + + @Test + public void test() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1 + ";" + path2, clzPath); + } + @Test + public void testClassFileLength() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "D:/ProgramWorld/Java/Practice/LangSi/2017Ⱥ/bin/com/coderising/jvm/loader/EmployeeV1.class"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // ע⣺ ֽܺJVM汾йϵԿõൽж + Assert.assertEquals(1058,byteCodes.length); + } + @Test + public void testMagicNumber() throws IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "D:/ProgramWorld/Java/Practice/LangSi/2017Ⱥ/bin/com/coderising/jvm/loader/EmployeeV1.class"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{ + byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3] + }; + System.out.println("ddd"); + String actualValue = this.byteToHexString(codes); + Assert.assertEquals("cafebabe",actualValue); + + } + + private String byteToHexString(byte[] codes){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < codes.length; i++){ + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if(strHex.length() < 2){ + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + //--------------------------------------------- + + + @Test + public void testVersion() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath2); + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(51, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool() throws IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //鼸 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex() throws IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + ClassIndex clzIndex = clzFile.getClzIndex(); + System.out.println("clzIndex="+clzIndex); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + System.out.println(thisClassInfo.getClassName()); + System.out.println(superClassInfo.getClassName()); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + // --------------------- JVM + @Test + public void testReadFields() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + + @Test + public void testMethods() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + + +} diff --git a/group11/1310368322/test/FileDownloaderTest.java b/group11/1310368322/test/data_structure/BigHomework/Download/FileDownloaderTest.java similarity index 100% rename from group11/1310368322/test/FileDownloaderTest.java rename to group11/1310368322/test/data_structure/BigHomework/Download/FileDownloaderTest.java diff --git a/group11/1310368322/test/ArrayUtilTest.java b/group11/1310368322/test/data_structure/baseDataStructure_2/ArrayUtilTest.java similarity index 100% rename from group11/1310368322/test/ArrayUtilTest.java rename to group11/1310368322/test/data_structure/baseDataStructure_2/ArrayUtilTest.java diff --git a/group11/1310368322/test/data_structure/baseDataStructure_3/TestLinkedList.java b/group11/1310368322/test/data_structure/baseDataStructure_3/TestLinkedList.java new file mode 100644 index 0000000000..343f9d6f39 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_3/TestLinkedList.java @@ -0,0 +1,25 @@ +package DataStructure_3; + +import static org.junit.Assert.*; +import org.junit.Assert; +import org.junit.Test; + +public class TestLinkedList { + + @Test + public void test() { + LinkedList L = new LinkedList(); + Assert.assertEquals("[]", L.toString()); + + L.add(1); + L.reverse(); + Assert.assertEquals("[1]", L.toString()); + + L.add(2); + L.add(3); + L.add(4); + L.reverse(); + Assert.assertEquals("[4,3,2,1]",L.toString()); + } + +} diff --git a/group11/1310368322/test/data_structure/baseDataStructure_4_LRU/TestLRUPageFrame.java b/group11/1310368322/test/data_structure/baseDataStructure_4_LRU/TestLRUPageFrame.java new file mode 100644 index 0000000000..227599c187 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_4_LRU/TestLRUPageFrame.java @@ -0,0 +1,31 @@ +package DataStructure_4_LRU; + +import static org.junit.Assert.*; +import org.junit.*; + +import org.junit.Test; + +public class TestLRUPageFrame { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3);// ҳ洢Ϊ3ҳ + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7",frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0",frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1",frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2",frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2",frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3",frame.toString()); + } + +} diff --git a/group11/1310368322/test/data_structure/baseDataStructure_5_Stack/TestStackUtil.java b/group11/1310368322/test/data_structure/baseDataStructure_5_Stack/TestStackUtil.java new file mode 100644 index 0000000000..0b227e9ff6 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_5_Stack/TestStackUtil.java @@ -0,0 +1,77 @@ +package DataStructure_5_Stack; + +import java.util.Stack; + +import org.junit.Assert; + +import org.junit.Test; + +public class TestStackUtil { + + @Test + public void test_reverse_1() { + Stack s = new Stack(); + for(int i = 0; i < 5; i++){ + s.push(i+1); + } + System.out.println(s.toString()); + StackUtil.reverse(s); + System.out.println(s.toString()); + } + + @Test + public void test_reverse_2() { + Stack s = new Stack(); + System.out.println(s.isEmpty()); + System.out.println(s.toString()); + StackUtil.reverse(s); + System.out.println(s.toString()); + } + + @Test + public void testRemove_1(){ + Stack actual = new Stack(); + Stack expected = new Stack(); + for(int i = 0; i < 5; i++){ + actual.push(i+1); + if(i != 2){ expected.push(i+1); } + } + StackUtil.remove(actual, 3); + Assert.assertEquals(expected, actual); + } + @Test + public void testRemove_2(){ + Stack actual = new Stack(); + Stack expected = new Stack(); + StackUtil.remove(actual, 3); + Assert.assertEquals(expected, actual); + } + + @Test + public void testGetTop(){ + Stack s = new Stack(); + for(int i = 0; i < 5; i++){ + s.push(i+1); + } + Object expected[] = {5,4,3}; + Object[] actual = StackUtil.getTop(s, 3); + Assert.assertArrayEquals(expected, actual); + + } + + + @Test + public void testIsValidPairs_1(){ + boolean actual = StackUtil.isValidPairs("([e{d}f])"); + boolean expected = true; + Assert.assertEquals(expected, actual); + } + + @Test + public void testValidPairs_2(){ + boolean actual = StackUtil.isValidPairs("([b{x]})"); + boolean expected = false; + Assert.assertEquals(expected, actual); + } + +} diff --git a/group11/1310368322/test/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java b/group11/1310368322/test/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java new file mode 100644 index 0000000000..c7285dd9a2 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java @@ -0,0 +1,106 @@ +package dataStructure_6InfixExpr; + +import java.util.Stack; + +public class InfixExpr { + + String expr = null; + + public InfixExpr(String expr){ + this.expr = expr; + } + + public double evaluate(){ + + Stack operatorStack = new Stack(); + Stack operandStack = new Stack(); + + int tag = -1; + for(int i = 0; i < expr.length(); i++){ + if(operatorStack.isEmpty()){ + tag = -1; + } + char c = expr.charAt(i); + if( tag == 1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + System.out.println("i= " + i); + char down = (char) operatorStack.pop(); + System.out.println("down: " + down); + System.out.println("up: " + c); + if(judgePriority(down,c)){ + double operand = (double) operandStack.pop(); + double operanded = (double) operandStack.pop(); + operandStack.push(operator(down,operanded,operand)); + operatorStack.push(c); + }else{ + operatorStack.push(down); + operatorStack.push(c); + } + }else if(tag == -1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + tag = 1; + operatorStack.push(c); + + }else{ + String number = extractNumber(i,expr); + int length = number.length(); + i += length-1; + double operand = Double.parseDouble(number); + operandStack.push(operand); + } + } + + while(!operatorStack.isEmpty()){ + char operator = (char) operatorStack.pop(); + System.out.println(operator); + double operand = (double) operandStack.pop(); + System.out.println(operand); + double operanded = (double) operandStack.pop(); + System.out.println(operanded); + operandStack.push( operator(operator,operanded,operand)); + } + + return (double) operandStack.pop(); + } + + private String extractNumber(int i, String expr2) { + + StringBuffer buffer = new StringBuffer(); + while( (expr.charAt(i) != '+') && (expr.charAt(i) != '-') && (expr.charAt(i) != '*') && (expr.charAt(i) != '/') ){ + buffer.append(expr.charAt(i)); + if(i >= expr2.length()-1){ + break; + } + i++; + } + return buffer.toString(); + } + + private boolean judgePriority(char down, char up) { + boolean tag = false; + + if((up == '+' || up == '-') && (down == '*' || down == '/')){ + tag = true; + }else if( (up == '*') && (down == '/')){ + tag = true; + }else if( (up == '/') && (down == '*')){ + tag = true; + }else if( (up == '+') && (down == '-') ){ + tag = true; + }else if( (up == '-') && (down == '+') ){ + tag = true; + } + return tag; + } + + private double operator(char operator, double operanded, double operand) { + double result = 0; + + switch(operator){ + case '+': result = operanded + operand; break; + case '-': result = operanded - operand; break; + case '*': System.out.println("˷"); result = operanded * operand; break; + case '/': result = operanded / operand; break; + } + + return result; + } +} diff --git a/group11/252308879/README.md b/group11/252308879/README.md new file mode 100644 index 0000000000..99f5dc58e0 --- /dev/null +++ b/group11/252308879/README.md @@ -0,0 +1,29 @@ +Coding2017 项目 +=== + +## 简介 + +* 考虑到目前的项目目录比较凌乱,所以整理一下目录。目前还未整理完成。 + +* 该项目主要是个人的日常作业,包含三大部分(后续会更多): + * 前三周的打基础(计算机系统知识) + * 数据结构 + * mini-jvm + +--- + +## 目录 + +[TOC] + +--- + +## 正文 + +* data-structure 项目中主要包含前三周的作业 + * 基本的数据结构 + * 解析struts.xml + * 多线程下载 +* mini-jvm 项目中主要包含解析jvm的作业 + +* 在目前这两个大模块中,都包含了每周的数据结构练习 diff --git a/group11/252308879/data-structure/pom.xml b/group11/252308879/data-structure/pom.xml new file mode 100644 index 0000000000..42eb53c993 --- /dev/null +++ b/group11/252308879/data-structure/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + + + com.pan + 252308879 + 1.0.0-SNAPSHOT + + + data-structure + 1.0.0-SNAPSHOT + jar + + data-structure + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + + + dom4j + dom4j + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + + + org.apache.maven.plugins + maven-source-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/BinaryTreeNode.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/BinaryTreeNode.java similarity index 84% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/BinaryTreeNode.java rename to group11/252308879/data-structure/src/main/java/com/pan/basic/BinaryTreeNode.java index 1cf38aee30..aab398a9b6 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/BinaryTreeNode.java +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/BinaryTreeNode.java @@ -1,33 +1,32 @@ -package com.coding.basic; - -public class BinaryTreeNode { - - private Object data; - private BinaryTreeNode left; - private BinaryTreeNode right; - - public Object getData() { - return data; - } - - public void setData(Object data) { - this.data = data; - } - - public BinaryTreeNode getLeft() { - return left; - } - - public void setLeft(BinaryTreeNode left) { - this.left = left; - } - - public BinaryTreeNode getRight() { - return right; - } - - public void setRight(BinaryTreeNode right) { - this.right = right; - } - -} +package com.pan.basic; + +public class BinaryTreeNode { + + private Object data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public Object getData() { + return data; + } + public void setData(Object data) { + this.data = data; + } + public BinaryTreeNode getLeft() { + return left; + } + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + public BinaryTreeNode getRight() { + return right; + } + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(Object o){ + return null; + } + +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/Iterator.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/Iterator.java new file mode 100644 index 0000000000..70735fa34e --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/Iterator.java @@ -0,0 +1,7 @@ +package com.pan.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/List.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/List.java new file mode 100644 index 0000000000..8ac9cf8e2e --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/List.java @@ -0,0 +1,9 @@ +package com.pan.basic; + +public interface List { + public void add(Object o); + public void add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/Queue.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/Queue.java new file mode 100644 index 0000000000..874d8a5690 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/Queue.java @@ -0,0 +1,19 @@ +package com.pan.basic; + +public class Queue { + + public void enQueue(Object o){ + } + + public Object deQueue(){ + return null; + } + + public boolean isEmpty(){ + return false; + } + + public int size(){ + return -1; + } +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/linklist/LRUPageFrame.java b/group11/252308879/data-structure/src/main/java/com/pan/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..5208e5bc76 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/linklist/LRUPageFrame.java @@ -0,0 +1,133 @@ +package com.pan.linklist; + + +/* + * 用双向链表实现LRU算法 + */ +public class LRUPageFrame { + private static class Node{ + Node prev; + Node next; + int pageNum = -1;// 物理页 + + Node(){ + + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + boolean tag = false; + + public LRUPageFrame(int capacity){ + this.capacity = capacity; + + for(int i = 0; i < capacity; i++){ + Node curNode = new Node(); + if(null == first){ + last = first = curNode; + }else{ + last.next = curNode; + curNode.prev = last; + last = last.next; + } + last.next = null; + } + } + public void printList(){ + Node curNode = first; + while(curNode != null){ + curNode = curNode.next; + } + } + /* + * 获取缓存中对象 + * @param key + * @return + */ + public void access(int pageNum){ + printList(); + Node index = findLogicPage(pageNum); + modifyPhysicalPage(index,pageNum); + } + + /* + * @param pageNum 表示要查询的逻辑页面 + * @return 若在物理页中找到要查询的逻辑页面,则返回该物理页节点的引用,否则返回null + */ + public Node findLogicPage(int pageNum){ + + Node index = null; + Node curNode = first; + while(curNode != null){ + if(curNode.pageNum == pageNum){ + index = curNode; + tag = true; + } + curNode = curNode.next; + } + return index; + } + /* + * @prama index 代表了 有逻辑页的物理页的节点的引用 + */ + public void modifyPhysicalPage(Node index,int pageNum){ + push(pageNum,index); + } + /* + * @param pageNum 要 push的逻辑页面, 默认栈顶是 first, bottom 栈底 指定了栈的大小 + */ + public void push(int pageNum,Node bottom){ + Node index = checkWhichListNodeNotUsed(); + if(index != null){ + index.pageNum = pageNum; + return; + } + + Node lastNode; + if(null == bottom){ + lastNode = last; + }else{ + lastNode = bottom; + } + Node curNode = lastNode.prev; + while(curNode != null){ + lastNode.pageNum = curNode.pageNum; + lastNode = curNode; + curNode = curNode.prev; + } + lastNode.pageNum = pageNum; + return; + } + + /* + * @return 返回物理页中 pageNum 没有被使用的节点的引用(返回栈中最下面的),如果全部都被使用,则返回 null + */ + public Node checkWhichListNodeNotUsed(){ + Node node = first; + Node index = null; + while(node != null){ + if(node.pageNum == -1){ + index = node; + } + node = node.next; + } + return index; + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/stack/StackUtil.java b/group11/252308879/data-structure/src/main/java/com/pan/stack/StackUtil.java new file mode 100644 index 0000000000..74918b1e37 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/stack/StackUtil.java @@ -0,0 +1,141 @@ +package com.pan.stack; + + +import java.util.Stack; + +/** + * Created by QiPan on 2017/4/12. + */ +public class StackUtil { + + public static void bad_reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack<>(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + + s = tmpStack; + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Integer top = s.pop(); + reverse(s); + addToBottom(s,top); + + + } + public static void addToBottom(Stack s, Integer value){ + if(s.isEmpty()){ + s.push(value); + } else{ + Integer top = s.pop(); + addToBottom(s,value); + s.push(top); + } + + } + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + + while(!s.isEmpty()){ + Object value = s.pop(); + if(!value.equals(o)){ + tmpStack.push(value); + } + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + + if(s == null || s.isEmpty() || s.size() stack = new Stack<>(); + for(int i=0;i + 4.0.0 + + + com.pan + 252308879 + 1.0.0-SNAPSHOT + + + mini-jvm + 1.0.0-SNAPSHOT + jar + + mini-jvm + http://maven.apache.org + + + UTF-8 + + + + + com.pan + data-structure + 1.0.0-SNAPSHOT + + + + junit + junit + + + org.apache.commons + commons-lang3 + + + commons-io + commons-io + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + + + org.apache.maven.plugins + maven-source-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/alg/LRUPageFrame.java b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/LRUPageFrame.java new file mode 100644 index 0000000000..d9455d3807 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/LRUPageFrame.java @@ -0,0 +1,133 @@ +package com.pan.alg; + + +/* + * 用双向链表实现LRU算法 + */ +public class LRUPageFrame { + private static class Node{ + Node prev; + Node next; + int pageNum = -1;// 物理页 + + Node(){ + + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + boolean tag = false; + + public LRUPageFrame(int capacity){ + this.capacity = capacity; + + for(int i = 0; i < capacity; i++){ + Node curNode = new Node(); + if(null == first){ + last = first = curNode; + }else{ + last.next = curNode; + curNode.prev = last; + last = last.next; + } + last.next = null; + } + } + public void printList(){ + Node curNode = first; + while(curNode != null){ + curNode = curNode.next; + } + } + /* + * 获取缓存中对象 + * @param key + * @return + */ + public void access(int pageNum){ + printList(); + Node index = findLogicPage(pageNum); + modifyPhysicalPage(index,pageNum); + } + + /* + * @param pageNum 表示要查询的逻辑页面 + * @return 若在物理页中找到要查询的逻辑页面,则返回该物理页节点的引用,否则返回null + */ + public Node findLogicPage(int pageNum){ + + Node index = null; + Node curNode = first; + while(curNode != null){ + if(curNode.pageNum == pageNum){ + index = curNode; + tag = true; + } + curNode = curNode.next; + } + return index; + } + /* + * @prama index 代表了 有逻辑页的物理页的节点的引用 + */ + public void modifyPhysicalPage(Node index,int pageNum){ + push(pageNum,index); + } + /* + * @param pageNum 要 push的逻辑页面, 默认栈顶是 first, bottom 栈底 指定了栈的大小 + */ + public void push(int pageNum,Node bottom){ + Node index = checkWhichListNodeNotUsed(); + if(index != null){ + index.pageNum = pageNum; + return; + } + + Node lastNode; + if(null == bottom){ + lastNode = last; + }else{ + lastNode = bottom; + } + Node curNode = lastNode.prev; + while(curNode != null){ + lastNode.pageNum = curNode.pageNum; + lastNode = curNode; + curNode = curNode.prev; + } + lastNode.pageNum = pageNum; + return; + } + + /* + * @return 返回物理页中 pageNum 没有被使用的节点的引用(返回栈中最下面的),如果全部都被使用,则返回 null + */ + public Node checkWhichListNodeNotUsed(){ + Node node = first; + Node index = null; + while(node != null){ + if(node.pageNum == -1){ + index = node; + } + node = node.next; + } + return index; + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/alg/StackUtil.java b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/StackUtil.java new file mode 100644 index 0000000000..01a7f2da52 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/StackUtil.java @@ -0,0 +1,141 @@ +package com.pan.alg; + + +import java.util.Stack; + +/** + * Created by QiPan on 2017/4/12. + */ +public class StackUtil { + + public static void bad_reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack<>(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + + s = tmpStack; + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Integer top = s.pop(); + reverse(s); + addToBottom(s,top); + + + } + public static void addToBottom(Stack s, Integer value){ + if(s.isEmpty()){ + s.push(value); + } else{ + Integer top = s.pop(); + addToBottom(s,value); + s.push(top); + } + + } + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + + while(!s.isEmpty()){ + Object value = s.pop(); + if(!value.equals(o)){ + tmpStack.push(value); + } + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + + if(s == null || s.isEmpty() || s.size() stack = new Stack<>(); + for(int i=0;i clzPaths = new ArrayList(); + int countForClassPath = 0; + int countForReadBinaryCode = 0; + byte [] a = new byte[10000]; + + /* 从指定路径读取二进制文件流,并将其保存到一个字节数组中,并返回 + * @Parameters 指定路径 + * @字节数组 + */ + public byte[] readBinaryCode(String className) throws IOException{ + DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream(className))); + for(int i = 0; dis.available() != 0; i++){ + a[i] = dis.readByte(); + countForReadBinaryCode++; + } + byte []target = new byte[countForReadBinaryCode]; + System.arraycopy(a, 0, target, 0, countForReadBinaryCode); + dis.close(); + return target; + } + + public void addClassPath(String path){ + clzPaths.add(path); + countForClassPath++; + } + + public String getClassPath(){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < countForClassPath; i++ ){ + if(i==countForClassPath-1){ + buffer.append(clzPaths.get(i)); + }else{ + buffer.append(clzPaths.get(i)+";"); + } + } + return buffer.toString(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/EmployeeV1.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/EmployeeV1.java new file mode 100644 index 0000000000..71f9ff54a4 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.pan.jvm; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/AttributeInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..1a81e8b473 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.pan.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/CodeAttr.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..80a05a9ac0 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/CodeAttr.java @@ -0,0 +1,94 @@ +package com.pan.jvm.attr; + +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + int maxStack = iter.nextU2ToInt(); + int maxLocals = iter.nextU2ToInt(); + int codeLen = iter.nextU4ToInt(); + + String code = iter.nextUxToHexString(codeLen); + + System.out.println("CODE-code: "+code); + + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code); + + int exceptionTableLen = iter.nextU2ToInt(); + + if (exceptionTableLen > 0){ + String exTable = iter.nextUxToHexString(exceptionTableLen); + System.out.println("Encountered exception table, just ignore!"); + } + + // 处理子属性 + int subAttrCount = iter.nextU2ToInt(); + for (int i = 1; i <= subAttrCount; i++) { + int suAttrIndex = iter.nextU2ToInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(suAttrIndex); + + iter.back(2);// 便于在子属性中获取 attrNameIndex + + if (AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)){ + LineNumberTable lineNumberTable = LineNumberTable.parse(iter); + codeAttr.setLineNumberTable(lineNumberTable); + }else if (AttributeInfo.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)){ + LocalVariableTable localVariableTable = LocalVariableTable.parse(iter); + codeAttr.setLocalVariableTable(localVariableTable); + }else if (AttributeInfo.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)){ + StackMapTable stackMapTable = StackMapTable.parse(iter); + codeAttr.setStackMapTable(stackMapTable); + }else { + throw new RuntimeException("Need code to process :" + subAttrName); + } + + } + return codeAttr; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LineNumberTable.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..563e8b19d5 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LineNumberTable.java @@ -0,0 +1,53 @@ +package com.pan.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.pan.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + LineNumberTable lineNumberTable = new LineNumberTable(attrNameIndex, attrLen); + + int attrItemSize = iter.nextU2ToInt(); + for (int i = 1; i <= attrItemSize; i++) { + LineNumberItem lineNumberItem = new LineNumberItem(); + lineNumberItem.setStartPC(iter.nextU2ToInt()); + lineNumberItem.setLineNum(iter.nextU2ToInt()); + + lineNumberTable.addLineNumberItem(lineNumberItem); + } + return lineNumberTable; + } + + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableItem.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..7e202a3931 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package com.pan.jvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableTable.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..74c73baac6 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableTable.java @@ -0,0 +1,42 @@ +package com.pan.jvm.attr; + + +import java.util.ArrayList; +import java.util.List; + +import com.pan.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + + LocalVariableTable localVariableTable = new LocalVariableTable(attrNameIndex, attrLen); + + int attrItemSize = iter.nextU2ToInt(); + for (int i = 1; i <= attrItemSize; i++) { + LocalVariableItem localVariableItem = new LocalVariableItem(); + localVariableItem.setStartPC(iter.nextU2ToInt()); + localVariableItem.setLength(iter.nextU2ToInt()); + localVariableItem.setNameIndex(iter.nextU2ToInt()); + localVariableItem.setDescIndex(iter.nextU2ToInt()); + localVariableItem.setIndex(iter.nextU2ToInt()); + localVariableTable.addLocalVariableItem(localVariableItem); + } + + return localVariableTable; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/StackMapTable.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..8d7c32b4bd --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/StackMapTable.java @@ -0,0 +1,30 @@ +package com.pan.jvm.attr; + + +import com.pan.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/AccessFlag.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..045741bd1e --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.pan.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassFile.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..e632888d89 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassFile.java @@ -0,0 +1,88 @@ +package com.pan.jvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.pan.jvm.constant.ClassInfo; +import com.pan.jvm.constant.ConstantPool; +import com.pan.jvm.field.Field; +import com.pan.jvm.method.Method; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public void addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + + public void print(){ + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + System.out.println("Super Class Name:"+ getSuperClassName()); + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassIndex.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..e09d6f0076 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.pan.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ClassInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..b842755586 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ClassInfo.java @@ -0,0 +1,28 @@ +package com.pan.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public int getUtf8Index() { + return utf8Index; + } + + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info) constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..464e44a79d --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantInfo.java @@ -0,0 +1,31 @@ +package com.pan.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo() { + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantPool.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..c2da2637c5 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package com.pan.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info) this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/FieldRefInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..2aaced31d3 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/FieldRefInfo.java @@ -0,0 +1,58 @@ +package com.pan.jvm.constant; + +public class FieldRefInfo extends ConstantInfo { + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() + " : " + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info) this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/MethodRefInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..a3e6f969b0 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/MethodRefInfo.java @@ -0,0 +1,58 @@ +package com.pan.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + return getClassName() + " : " + this.getMethodName() + " : " + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NameAndTypeInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..30be83ef3a --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,49 @@ +package com.pan.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo { + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } + + public int getType() { + return type; + } + + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info) pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info) pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NullConstantInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..cc6989bef7 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package com.pan.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo() { + + } + + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/StringInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..ad3f397949 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/StringInfo.java @@ -0,0 +1,28 @@ +package com.pan.jvm.constant; + +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.STRING_INFO; + private int index; + + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/UTF8Info.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..502adae968 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/UTF8Info.java @@ -0,0 +1,38 @@ +package com.pan.jvm.constant; + +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value + ")]"; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/field/Field.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/field/Field.java new file mode 100644 index 0000000000..22775d0de7 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/field/Field.java @@ -0,0 +1,47 @@ +package com.pan.jvm.field; + + +import com.pan.jvm.constant.ConstantPool; +import com.pan.jvm.constant.UTF8Info; +import com.pan.jvm.loader.ByteCodeIterator; + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + @Override + public String toString() { + String name = ((UTF8Info) pool.getConstantInfo(this.nameIndex)).getValue(); + String desc = ((UTF8Info) pool.getConstantInfo(this.descriptorIndex)).getValue(); + + return name + ":" + desc; + } + + public static Field parse(ConstantPool pool, ByteCodeIterator iter){ + + int accessFlags = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptorIndex = iter.nextU2ToInt(); + int attrCount = iter.nextU2ToInt(); + System.out.println("Field Attributes Count: " + attrCount); + Field field = new Field(accessFlags, nameIndex, descriptorIndex, pool); + if (attrCount > 0){ + throw new RuntimeException("Attributes Count > 0"); + } + return field; + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ByteCodeIterator.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..24f00ccc5d --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,52 @@ +package com.pan.jvm.loader; + +import java.util.Arrays; + +import com.pan.jvm.util.Util; + +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1toInt() { + return Util.byteToInt(new byte[]{codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++]}); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString((new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]})); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + } + + public void back(int n) { + this.pos -= n; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileLoader.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..fa25990691 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileLoader.java @@ -0,0 +1,104 @@ +package com.pan.jvm.loader; + +import com.pan.jvm.clz.ClassFile; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList<>(); + + public byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar) + ".class"; + for (String path : this.clzPaths) { + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + public void addClassPath(String path) { + if (this.clzPaths.contains(path)) { + return; + } + this.clzPaths.add(path); + } + + + public String getClassPath() { + return StringUtils.join(this.clzPaths, ";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + // ------------------------------backup------------------------ + public String getClassPath_V1() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < this.clzPaths.size(); i++) { + buffer.append(this.clzPaths.get(i)); + if (i < this.clzPaths.size() - 1) { + buffer.append(";"); + } + } + return buffer.toString(); + } + + private byte[] loadClassFile_V1(String clzFileName) { + + BufferedInputStream bis = null; + try { + File f = new File(clzFileName); + bis = new BufferedInputStream(new FileInputStream(f)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length = -1; + while ((length = bis.read(buffer)) != -1) { + bos.write(buffer, 0, length); + } + byte[] codes = bos.toByteArray(); + return codes; + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileParser.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..b2bddb85c2 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileParser.java @@ -0,0 +1,172 @@ +package com.pan.jvm.loader; + +import com.pan.jvm.clz.AccessFlag; +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.clz.ClassIndex; +import com.pan.jvm.constant.*; +import com.pan.jvm.field.Field; +import com.pan.jvm.method.Method; + +import java.io.UnsupportedEncodingException; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + + ByteCodeIterator iterator = new ByteCodeIterator(codes); + String magicNumber = iterator.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) {// 验证是否为Java的.class文件 + return null; + } + ClassFile classFile = new ClassFile(); + classFile.setMinorVersion(iterator.nextU2ToInt()); + classFile.setMajorVersion(iterator.nextU2ToInt()); + + ConstantPool constantPool = parseConstantPool(iterator); + classFile.setConstPool(constantPool); + + AccessFlag flag = parseAccessFlag(iterator); + classFile.setAccessFlag(flag); + + // this clz 和 supper clz + ClassIndex clzIndex = parseClassIndex(iterator); + classFile.setClassIndex(clzIndex); + + // interface + parseInterfaces(iterator); + + // field + parseFields(classFile, iterator); + + // method + parseMethods(classFile, iterator); + + return classFile; + } + + private void parseMethods(ClassFile classFile, ByteCodeIterator iterator) { + int methodsCount = iterator.nextU2ToInt(); + System.out.println("Methods Count: " + methodsCount); + + for (int i = 1; i <= methodsCount; i++) { + Method method = Method.parse(classFile, iterator); + classFile.addMethod(method); + } + } + + + private void parseFields(ClassFile clzFile, ByteCodeIterator iterator) { + int fieldsCount = iterator.nextU2ToInt(); + System.out.println("Field count:" + fieldsCount); + for (int i = 1; i <= fieldsCount; i++) {// 从第一个开始,因为不包含本身 + Field field = Field.parse(clzFile.getConstantPool(), iterator); + clzFile.addField(field); + } + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt()); + return accessFlag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + + int thisClassIndex = iter.nextU2ToInt(); + int supperClassIndex = iter.nextU2ToInt(); + + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(supperClassIndex); + return classIndex; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextU2ToInt(); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + /** + * 解析常量池 + * + * @param iter + * @return + */ + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constPoolCount = iter.nextU2ToInt(); + + System.out.println("Constant Pool Count :" + constPoolCount); + ConstantPool pool = new ConstantPool(); + // 因为常量池中的信息是从 1 开始的,但是数组或者List 下标是从0开始,所以设置第一个为空的常量 + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i <= constPoolCount - 1; i++) { + + // 获取标识符信息 + int tag = iter.nextU1toInt(); + + switch (tag) { + + case 7: //CONSTANT_Class + int utf8Index = iter.nextU2ToInt(); + ClassInfo classInfo = new ClassInfo(pool); + classInfo.setUtf8Index(utf8Index); + + pool.addConstantInfo(classInfo); + break; + case 9: // CONSTANT_Fieldref + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(iter.nextU2ToInt()); + fieldRefInfo.setNameAndTypeIndex(iter.nextU2ToInt()); + + pool.addConstantInfo(fieldRefInfo); + break; + case 10: // CONSTANT_Methodref + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(iter.nextU2ToInt()); + methodRefInfo.setNameAndTypeIndex(iter.nextU2ToInt()); + + pool.addConstantInfo(methodRefInfo); + break; + case 8: + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(info); + break; + case 12: // CONSTANT_NameAndType + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setIndex1(iter.nextU2ToInt()); + nameAndTypeInfo.setIndex2(iter.nextU2ToInt()); + + pool.addConstantInfo(nameAndTypeInfo); + break; + case 1: // CONSTANT_Utf8 + int length = iter.nextU2ToInt(); + byte[] data = iter.getBytes(length); + String value = null; + try { + value = new String(data, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info utf8Str = new UTF8Info(pool); + utf8Str.setLength(length); + utf8Str.setValue(value); + + pool.addConstantInfo(utf8Str); + break; + default: + throw new RuntimeException("the constant pool tag " + tag + " has not been implemented yet."); + + } + } + System.out.println("Finished reading Constant pool "); + return pool; + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/method/Method.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/method/Method.java new file mode 100644 index 0000000000..0fbb0f0946 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/method/Method.java @@ -0,0 +1,71 @@ +package com.pan.jvm.method; + + +import com.pan.jvm.attr.AttributeInfo; +import com.pan.jvm.attr.CodeAttr; +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.loader.ByteCodeIterator; + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + int accessFlags = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptorIndex = iter.nextU2ToInt(); + int attrCount = iter.nextU2ToInt(); + + System.out.println("Method Attributes Count: " + attrCount); + Method method = new Method(clzFile, accessFlags, nameIndex, descriptorIndex); + if (attrCount > 0){ + for (int i = 1; i <= attrCount; i++) { + int attrNameIndex = iter.nextU2ToInt(); + String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex); + iter.back(2); // 回退两个,便于Code 中读取属性 + if (AttributeInfo.CODE.equalsIgnoreCase(attrName)){ + CodeAttr codeAttr = CodeAttr.parse(clzFile, iter); + method.setCodeAttr(codeAttr); + }else { + throw new RuntimeException("Current Has CODE. Not Support Other"); + } + } + } + return method; + + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/util/Util.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/util/Util.java new file mode 100644 index 0000000000..ae130b4183 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/util/Util.java @@ -0,0 +1,23 @@ +package com.pan.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes) { + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/alg/LRUPageFrameTest.java b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/LRUPageFrameTest.java new file mode 100644 index 0000000000..8f6803c11f --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/LRUPageFrameTest.java @@ -0,0 +1,34 @@ +package com.pan.alg; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + frame.access(5); + Assert.assertEquals("5,4,0", frame.toString()); + + } + +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/alg/StackUtilTest.java b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/StackUtilTest.java new file mode 100644 index 0000000000..71671c9b47 --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/StackUtilTest.java @@ -0,0 +1,76 @@ +package com.pan.alg; + +import java.util.Stack; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +public class StackUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddToBottom() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/ClassFileLoaderTest.java b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/ClassFileLoaderTest.java new file mode 100644 index 0000000000..d341553c70 --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/ClassFileLoaderTest.java @@ -0,0 +1,258 @@ +package com.pan.jvm; + +import java.util.List; + +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.clz.ClassIndex; +import com.pan.jvm.constant.*; +import com.pan.jvm.field.Field; +import com.pan.jvm.loader.ClassFileLoader; +import com.pan.jvm.method.Method; +import com.pan.jvm.util.Util; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + + + + +public class ClassFileLoaderTest { + + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/pan/jvm/EmployeeV1"; + + static String path1 = EmployeeV1.class.getClassLoader().getResource("").getPath() + .replace("test-classes", "classes"); + static String path2 = "C:/temp"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.pan.jvm.EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "com.pan.jvm.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1032, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.pan.jvm.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String actualValue = Util.byteToHexString(codes); + + Assert.assertEquals("cafebabe", actualValue); + } + + + /** + * ---------------------------------------------------------------------- + */ + + + @Test + public void testVersion(){ + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + } + + @Test + public void testConstantPool(){ + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + + +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/TestReadCFBB.java b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/TestReadCFBB.java new file mode 100644 index 0000000000..8590e78c09 --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/TestReadCFBB.java @@ -0,0 +1,41 @@ +package com.pan.jvm; + +import com.pan.jvm.loader.ClassFileLoader; +import org.junit.Test; + +import java.io.IOException; + +/** + * 用于测试第一次JVM作业,读取.class作业 和 魔幻数字 + */ +public class TestReadCFBB { + + @Test + public void testClassPath(){ + ClassFileLoader classFileLoader = new ClassFileLoader(); + String path = ClassFileLoader.class.getClassLoader().getResource("").getPath(); + path = path.replace("test-classes", "classes"); + classFileLoader.addClassPath(path); + classFileLoader.addClassPath("d://tmp"); + + String clzPath = classFileLoader.getClassPath(); + System.out.println(clzPath); + } + + + + @Test + public void testReadCFBB() throws IOException { + + ClassFileLoader classFileLoader = new ClassFileLoader(); + String path = ClassFileLoader.class.getClassLoader().getResource("").getPath(); + path = path.replace("test-classes", "classes"); + classFileLoader.addClassPath(path); + byte[] bytes = classFileLoader.readBinaryCode("com.pan.jvm.loader.ClassFileLoader"); + for (byte b : bytes) { + String toHexString = Integer.toHexString(b & 0xFF).toUpperCase(); + System.out.print(toHexString + " "); + } + } + +} diff --git a/group11/252308879/pom.xml b/group11/252308879/pom.xml new file mode 100644 index 0000000000..642387b95a --- /dev/null +++ b/group11/252308879/pom.xml @@ -0,0 +1,140 @@ + + + + + + data-structure + mini-jvm + + + com.pan + 252308879 + pom + 1.0.0-SNAPSHOT + + 4.0.0 + + + UTF-8 + 1.8 + 1.8 + 3.3 + 2.4 + 2.5 + 2.5 + 2.8.2 + 2.3.1 + 2.5 + 2.12.2 + + + + + + junit + junit + 4.12 + test + + + dom4j + dom4j + 1.6.1 + + + org.apache.commons + commons-lang3 + 3.4 + + + commons-io + commons-io + 2.4 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven_compiler_plugin_version} + + ${java_source_version} + ${java_target_version} + ${project.build.sourceEncoding} + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + ${maven_surefire_report_plugin} + + false + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven_source_plugin_version} + + + attach-sources + + jar-no-fork + + + + + true + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven_jar_plugin_version} + + + true + + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven_war_plugin_version} + + + true + + + + + + org.codehaus.mojo + findbugs-maven-plugin + ${findbugs_maven_plugin_version} + + true + target/site + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven_checkstyle_plugin_version} + + + + \ No newline at end of file diff --git a/group11/283091182/mini-jvm-week1-bk/loader/ClassFileLoader.java b/group11/283091182/mini-jvm-week1-bk/loader/ClassFileLoader.java new file mode 100644 index 0000000000..527e2f14d8 --- /dev/null +++ b/group11/283091182/mini-jvm-week1-bk/loader/ClassFileLoader.java @@ -0,0 +1,93 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + File classFile = getClassFileFromPath(className); + + byte[] buffer = new byte[1024]; + try { + FileInputStream fis = new FileInputStream(classFile); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int readLen; + while((readLen = fis.read(buffer))>-1){ + baos.write(buffer, 0, readLen); + } + + return baos.toByteArray(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + + public void addClassPath(String path) { + File clzPath = new File(path); + if(clzPath.exists() && clzPath.isDirectory()){ + this.clzPaths.add(path); + }else{ + System.out.println("Invalid path:"+ path); + } + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + Iterator it = this.clzPaths.iterator(); + while(it.hasNext()){ + if(sb.length()>0){ + sb.append(";"); + } + sb.append(it.next()); + } + return sb.toString(); + } + + public File getClassFileFromPath(String className) { + Iterator it = this.clzPaths.iterator(); + + //replace "." with "\\" in windows + String fullclassPath = className.replaceAll("\\.", (File.separatorChar=='\\')?"\\\\":"/")+".class"; + + while(it.hasNext()){ + File clzFile; + String path = (String)it.next(); + if(path.endsWith(String.valueOf(File.separatorChar))){ + clzFile = new File(path+fullclassPath); + }else{ + clzFile = new File(path+File.separatorChar+fullclassPath); + } + + //Check file before further proceed + if(clzFile.exists()&&clzFile.isFile()){ + return clzFile; + } + } + + throw new RuntimeException("Class not found:"+className); + } + + + +} diff --git a/group11/283091182/mini-jvm-week1-bk/test/ClassFileloaderTest.java b/group11/283091182/mini-jvm-week1-bk/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..21d7e97074 --- /dev/null +++ b/group11/283091182/mini-jvm-week1-bk/test/ClassFileloaderTest.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + static String path1 = "C:\\Users\\Administrator\\mygit\\coding2017\\liuxin\\bin"; + static String path2 = "C:\\temp"; + + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/FieldRefInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..65475e194c --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/MethodRefInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..7f05870020 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/NameAndTypeInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..402f9dec86 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/NullConstantInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/StringInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..f1f8eb4ed4 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/UTF8Info.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..5cac9f04f7 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/loader/ByteCodeIterator.java b/group11/283091182/mini-jvm/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..514d85e08f --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,87 @@ +package com.coderising.jvm.loader; + +public class ByteCodeIterator { + private byte[] bytes; + private int pos = 0; + public ByteCodeIterator(byte[] byteCodes){ + this.bytes = byteCodes; + } + + public boolean hasNext(){ + return this.pos < bytes.length-1; + } + + public byte next(){ + byte b = bytes[pos]; + pos ++; + return b; + } + + public byte[] getBytes(int len){ + if(pos+len>bytes.length){ + throw new RuntimeException("Index out of bounds:"+(pos+len)); + } + byte[] bytes = new byte[len]; + int idx = 0; + while(hasNext() && idx clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + + + + } + + private byte[] loadClassFile(String clzFileName) { + + File f = new File(clzFileName); + + try { + + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + + public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + + this.clzPaths.add(path); + + } + + + + public String getClassPath(){ + return StringUtils.join(this.clzPaths,";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + + // ------------------------------backup------------------------ + public String getClassPath_V1(){ + + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + +} diff --git a/group11/283091182/src/com/coding/basic/ArrayList.java b/group11/283091182/src/com/coderising/array/ArrayList.java similarity index 91% rename from group11/283091182/src/com/coding/basic/ArrayList.java rename to group11/283091182/src/com/coderising/array/ArrayList.java index 402d05c019..18b0dcca6f 100644 --- a/group11/283091182/src/com/coding/basic/ArrayList.java +++ b/group11/283091182/src/com/coderising/array/ArrayList.java @@ -1,7 +1,10 @@ -package com.coding.basic; +package com.coderising.array; import java.util.Arrays; +import com.coding.basic.Iterator; +import com.coding.basic.List; + public class ArrayList implements List { private int size = 0; diff --git a/group11/283091182/src/com/coding/basic/ArrayListTest.java b/group11/283091182/src/com/coderising/array/ArrayListTest.java similarity index 69% rename from group11/283091182/src/com/coding/basic/ArrayListTest.java rename to group11/283091182/src/com/coderising/array/ArrayListTest.java index 7807fa831e..8bdc0515d1 100644 --- a/group11/283091182/src/com/coding/basic/ArrayListTest.java +++ b/group11/283091182/src/com/coderising/array/ArrayListTest.java @@ -1,7 +1,7 @@ /** * */ -package com.coding.basic; +package com.coderising.array; import static org.junit.Assert.*; @@ -51,7 +51,7 @@ public void tearDown() throws Exception { } /** - * Test method for {@link com.coding.basic.ArrayList#add(java.lang.Object)}. + * Test method for {@link com.coderising.array.ArrayList#add(java.lang.Object)}. */ @Test public final void testAddObject() { @@ -65,7 +65,7 @@ public final void testAddObject() { } /** - * Test method for {@link com.coding.basic.ArrayList#add(int, java.lang.Object)}. + * Test method for {@link com.coderising.array.ArrayList#add(int, java.lang.Object)}. */ @Test public final void testAddIntObject() { @@ -78,14 +78,14 @@ public final void testAddIntObject() { assertEquals(3,al.size()); } /** - * Test method for {@link com.coding.basic.ArrayList#add(int, java.lang.Object)}. + * Test method for {@link com.coderising.array.ArrayList#add(int, java.lang.Object)}. */ @Test(expected=IndexOutOfBoundsException.class) public final void testAddIntObjectWithException1() { al.add(-1, "aaa"); } /** - * Test method for {@link com.coding.basic.ArrayList#add(int, java.lang.Object)}. + * Test method for {@link com.coderising.array.ArrayList#add(int, java.lang.Object)}. */ @Test(expected=IndexOutOfBoundsException.class) public final void testAddIntObjectWithException2() { @@ -94,21 +94,21 @@ public final void testAddIntObjectWithException2() { } /** - * Test method for {@link com.coding.basic.ArrayList#get(int)}. + * Test method for {@link com.coderising.array.ArrayList#get(int)}. */ @Test public final void testGet() { fail("Not yet implemented"); // TODO } /** - * Test method for {@link com.coding.basic.ArrayList#get(int)}. + * Test method for {@link com.coderising.array.ArrayList#get(int)}. */ @Test public final void testGetWithException1() { fail("Not yet implemented"); // TODO } /** - * Test method for {@link com.coding.basic.ArrayList#get(int)}. + * Test method for {@link com.coderising.array.ArrayList#get(int)}. */ @Test public final void testGetWithException2() { @@ -116,7 +116,7 @@ public final void testGetWithException2() { } /** - * Test method for {@link com.coding.basic.ArrayList#remove(int)}. + * Test method for {@link com.coderising.array.ArrayList#remove(int)}. */ @Test public final void testRemove() { @@ -124,7 +124,7 @@ public final void testRemove() { } /** - * Test method for {@link com.coding.basic.ArrayList#size()}. + * Test method for {@link com.coderising.array.ArrayList#size()}. */ @Test public final void testSize() { @@ -132,7 +132,7 @@ public final void testSize() { } /** - * Test method for {@link com.coding.basic.ArrayList#iterator()}. + * Test method for {@link com.coderising.array.ArrayList#iterator()}. */ @Test public final void testIterator() { diff --git a/group11/283091182/src/com/coding/basic/Queue.java b/group11/283091182/src/com/coding/basic/Queue.java index 45fea2a118..0f1f068e19 100644 --- a/group11/283091182/src/com/coding/basic/Queue.java +++ b/group11/283091182/src/com/coding/basic/Queue.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coding.basic.linklist.LinkedList; + public class Queue { private LinkedList list = new LinkedList(); diff --git a/group11/283091182/src/com/coding/basic/Stack.java b/group11/283091182/src/com/coding/basic/Stack.java index 915d173b1b..5ff5ce5279 100644 --- a/group11/283091182/src/com/coding/basic/Stack.java +++ b/group11/283091182/src/com/coding/basic/Stack.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coderising.array.ArrayList; + public class Stack { private ArrayList elementData = new ArrayList(); diff --git a/group11/283091182/src/com/coding/basic/linklist/LRUPageFrame.java b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..9f6edbcb66 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,141 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + Node(int pageNum, Node prev, Node next){ + this.pageNum = pageNum; + this.next = next; + this.prev = prev; + } + } + + private int capacity; + + private int size; + + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + System.out.println("CurrentList= "+this.toString()+"; accessing - "+pageNum); + Node target = find(pageNum); + if(target==null){ + createNewNodeAsHead(pageNum); + }else{ + moveExistingNodeToHead(target); + } + + } + + private void removeLast(){ + Node secToLast = last.prev; + last = null; + secToLast.next = null; + last = secToLast; + size--; + } + + private void moveExistingNodeToHead(Node node){ + + Node prev = node.prev; + Node next = node.next; + + if(prev==null){ + //already in the head,do nothing; + return; + } + + if(next==null){ + //currently in the tail + last = prev; + } + + //in the middle + prev.next = next; + if(next!=null){ + next.prev = prev; + } + node.prev = null; + node.next = first; + first = node; + } + + private void createNewNodeAsHead(int value){ + Node node = new Node(value,null,null); + //first node + if(size==0){ + this.first = node; + this.last = node; + this.size ++; + }else{ + //linklist already exists + this.first.prev = node; + node.next = this.first; + this.first = node; + this.size++; + + if(size>capacity){ + removeLast(); + } + } + + } + + private Node find(int value){ + if(size==0){ + return null; + } + Node temp = first; + while(temp!=null){ + if(temp.pageNum==value){ + return temp; + }else{ + temp = temp.next; + } + } + return null; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/283091182/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..4070f1f2b3 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group11/283091182/src/com/coding/basic/LinkedList.java b/group11/283091182/src/com/coding/basic/linklist/LinkedList.java similarity index 92% rename from group11/283091182/src/com/coding/basic/LinkedList.java rename to group11/283091182/src/com/coding/basic/linklist/LinkedList.java index 233c243130..2c5959890a 100644 --- a/group11/283091182/src/com/coding/basic/LinkedList.java +++ b/group11/283091182/src/com/coding/basic/linklist/LinkedList.java @@ -1,4 +1,7 @@ -package com.coding.basic; +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; public class LinkedList implements List { diff --git a/group11/283091182/src/com/coding/basic/stack/Stack.java b/group11/283091182/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..c59be3c1e4 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,50 @@ +package com.coding.basic.stack; + +import com.coderising.array.ArrayList; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + elementData.add(o); + } + + public Object pop(){ + if(elementData.size()==0)throw new RuntimeException("Stack is empty."); + return elementData.remove(elementData.size()-1); + } + + public Object peek(){ + if(elementData.size()==0)throw new RuntimeException("Stack is empty."); + return elementData.get(elementData.size()-1); + } + public boolean isEmpty(){ + return (elementData.size()==0); + } + public int size(){ + return elementData.size(); + } + + @Override + public String toString(){ + return elementData.toString(); + } + + public static void main(String[] args){ + Stack s = new Stack(); + s.push("aaa"); + s.push("bbb"); + s.push("ccc"); + System.out.println(s); + System.out.println(s.isEmpty()); + System.out.println(s.size()); + System.out.println(s.peek()); + System.out.println(s.pop()); + System.out.println(s.pop()); + System.out.println(s.pop()); + System.out.println(s); + System.out.println(s.isEmpty()); + System.out.println(s.size()); + //System.out.println(s.pop()); + } +} diff --git a/group11/283091182/src/com/coding/basic/stack/StackUtil.java b/group11/283091182/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..cd5aa08d06 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,140 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if(s==null || s.isEmpty()){ + return; + }; + Stack temp = new Stack(); + int counter = s.size(); + while(counter>1){ + //Get the peek one + Object o = s.pop(); + for(int i=0;is.size()){ + throw new RuntimeException("Index Out of Bound:"+ len); + } + Object[] objArr = new Object[len]; + Stack tmpStk = new Stack(); + for(int i=0;i totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } @Override diff --git a/group11/542194147/myDataStructure/src/com/coderising/jvm/loader/ClassFileLoader.java b/group11/542194147/myDataStructure/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..f6b93bfb41 --- /dev/null +++ b/group11/542194147/myDataStructure/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,89 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + private static final int BUFFER_SIZE=1024; + + public byte[] readBinaryCode(String className) { + className=className.replace(".","\\")+".class"; + String absolutePath=null; + for(int i=0;ifile.length()){ + return Arrays.copyOf(baos.toByteArray(), (int) file.length()); + } + } catch (IOException e) { + e.printStackTrace(); + }finally{ + try { + fis.close(); + baos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return baos.toByteArray(); + } + + + public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuffer sb=new StringBuffer(); + for(int i=0;i=capacity){//缓存已满删除最后的数据 + removeLastNode(); + } + addNewNodeTOHead(newNode);//把新数据加到缓存头部 + } + } + + private void addNewNodeTOHead(Node node) { + if(first==null&&last==null){ + first=node; + last=node; + node.next=null; + node.prev=null; + }else{ + first.prev=node; + node.prev=null; + node.next=first; + first=node; + } + currentSize++; + } + + private void removeLastNode() { + Node node=last.prev; + node.next=null; + last.prev=null; + last=node; + currentSize--; + } + + private void moveExistingNodeToHead(Node node) { + if(node==first){ + return; + }else if(node==last){ + Node prevNode=node.prev; + last=prevNode; + prevNode.next=null; + }else{ + node.prev.next=node.next; + node.next.prev=node.prev; + } + node.prev=null; + node.next=first; + first.prev=node; + first=node; + } + + + private Node findNode(int data) { + Node node=first; + while(node!=null){ + if(node.pageNum==data){ + return node; + } + node=node.next; + } + return null; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/542194147/myDataStructure/src/com/coding/basic/LRUPageFrameTest.java b/group11/542194147/myDataStructure/src/com/coding/basic/LRUPageFrameTest.java new file mode 100644 index 0000000000..53db234945 --- /dev/null +++ b/group11/542194147/myDataStructure/src/com/coding/basic/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/clz/AccessFlag.java b/group11/996108220/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..faae056835 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group11/996108220/src/com/coderising/jvm/clz/ClassFile.java b/group11/996108220/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..8575f5641a --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,74 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group11/996108220/src/com/coderising/jvm/clz/ClassIndex.java b/group11/996108220/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..f42e45d48f --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex;//u2 + private int superClassIndex;//u2 + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group11/996108220/src/com/coderising/jvm/constant/ClassInfo.java b/group11/996108220/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..d673cae1bd --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ;//u2 + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/ConstantInfo.java b/group11/996108220/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..466b072244 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/ConstantPool.java b/group11/996108220/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..86c0445695 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/FieldRefInfo.java b/group11/996108220/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..07133aa3a1 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex;//u2 + private int nameAndTypeIndex;//u2 + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/MethodRefInfo.java b/group11/996108220/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..ad3723ad0c --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; //u2 + private int nameAndTypeIndex;//u2 + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group11/996108220/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..ee05963d21 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1;//u2 + private int index2;//u2 + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/NullConstantInfo.java b/group11/996108220/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/StringInfo.java b/group11/996108220/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..1f0539dda4 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index;//u2 + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/UTF8Info.java b/group11/996108220/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..c2c4408421 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ;//2 + private String value;//length + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group11/996108220/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..a151decad8 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,51 @@ +package com.coderising.jvm.loader; + +import java.util.Arrays; +import com.coderising.jvm.util.Util; + + + +public class ByteCodeIterator { + byte[] codes; + int cursor=0; + public ByteCodeIterator(byte[] codes) { + this.codes=codes; + } + public ByteCodeIterator(byte[] codes,int cursor) { + this.codes=codes; + this.cursor=cursor; + } + public boolean hasNext() { + return cursor != codes.length; + } + + + public int next() { + + int i = cursor; + if (i >= codes.length) + throw new ArrayIndexOutOfBoundsException(); + cursor = i + 1; + return codes[i]&0xFF; + } + public int nextU2ToInt() { + + return Util.byteToInt(new byte[]{codes[cursor++],codes[cursor++]}); + } + public int nextU4ToInt() { + + return Util.byteToInt(new byte[]{codes[cursor++],codes[cursor++], + codes[cursor++],codes[cursor++]}); + } + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[]{codes[cursor++],codes[cursor++], + codes[cursor++],codes[cursor++]}); + + } + public byte[] getByte(int length) { + int i=cursor; + cursor=cursor+length; + return Arrays.copyOfRange(codes,i, cursor); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/loader/ClassFileLoader.java b/group11/996108220/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..eccf6dc7b0 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,88 @@ +package com.coderising.jvm.loader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import com.coderising.jvm.clz.ClassFile; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + + } + + private byte[] loadClassFile(String fileName) { + ArrayList list=new ArrayList(); + try { + InputStream in=new FileInputStream(fileName.toString()); + int length=-1; + byte[] buffer=new byte[1024]; + while ((length=in.read(buffer))!=-1) { + int size=list.size(); + for (int i = size; i < size+length; i++) { + list.add(buffer[i-size]); + } + } + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + byte[] byteCodes=new byte[list.size()]; + for (int i = 0; i < byteCodes.length; i++) { + byteCodes[i]=list.get(i); + } + + return byteCodes; + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + public void addClassPath(String path) { + clzPaths.add(path); + + } + + + + public String getClassPath(){ + String string=""; + for (int i = 0; i < clzPaths.size(); i++) { + string=i==0?string+clzPaths.get(i):string+";"+clzPaths.get(i); + } + return string; + } + + + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/loader/ClassFileParser.java b/group11/996108220/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..ac55f25e0e --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,111 @@ +package com.coderising.jvm.loader; +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.util.Util; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ByteCodeIterator iter=new ByteCodeIterator(codes); + String magicNumber=iter.nextU4ToHexString(); + if (!magicNumber.equals("cafebabe")) { + return null; + } + ClassFile classFile=new ClassFile(); + classFile.setMinorVersion(iter.nextU2ToInt()); + classFile.setMajorVersion(iter.nextU2ToInt()); + classFile.setConstPool(parseConstantPool(iter)); + classFile.setAccessFlag(parseAccessFlag(iter)); + classFile.setClassIndex(parseClassInfex(iter)); + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + + return new AccessFlag(iter.nextU2ToInt()); + } + + private ClassIndex parseClassInfex(ByteCodeIterator iter) { + ClassIndex classIndex=new ClassIndex(); + classIndex.setThisClassIndex(iter.nextU2ToInt()); + classIndex.setSuperClassIndex(iter.nextU2ToInt()); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int constPoolCount=iter.nextU2ToInt(); + + ConstantPool pool=new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + for (int i = 1; i <= constPoolCount-1; i++) { + int tag=iter.next(); + if (tag==1) { + //UTF8Info + UTF8Info utf8Info=new UTF8Info(pool); + int length=iter.nextU2ToInt(); + utf8Info.setLength(length); + String value=Util.byteToString(iter.getByte(length)); + utf8Info.setValue(value); + pool.addConstantInfo(utf8Info); + } + else if (tag==7) { + //ClassInfo + ClassInfo classInfo=new ClassInfo(pool); + int utf8Index=iter.nextU2ToInt(); + classInfo.setUtf8Index(utf8Index); + pool.addConstantInfo(classInfo); + } + else if (tag==8) { + //StringInfo + StringInfo stringInfo=new StringInfo(pool); + int index=iter.nextU2ToInt(); + stringInfo.setIndex(index); + pool.addConstantInfo(stringInfo); + } + else if (tag==9) { + //FieldRefInfo + FieldRefInfo fieldRefInfo=new FieldRefInfo(pool); + int classInfoIndex=iter.nextU2ToInt(); + int nameAndTypeIndex=iter.nextU2ToInt(); + fieldRefInfo.setClassInfoIndex(classInfoIndex); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(fieldRefInfo); + } + else if (tag==10) { + //MethodRefInfo + MethodRefInfo methodRefInfo=new MethodRefInfo(pool); + int classInfoIndex=iter.nextU2ToInt(); + int nameAndTypeIndex=iter.nextU2ToInt(); + methodRefInfo.setClassInfoIndex(classInfoIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(methodRefInfo); + } + else if (tag==12) { + //NameAndTypeInfo + NameAndTypeInfo nameAndTypeInfo=new NameAndTypeInfo(pool); + int index1=iter.nextU2ToInt(); + int index2=iter.nextU2ToInt(); + nameAndTypeInfo.setIndex1(index1); + nameAndTypeInfo.setIndex2(index2); + pool.addConstantInfo(nameAndTypeInfo); + } + else { + new RuntimeException("缺少tag为"+tag+"的常量"); + } + } + + return pool; + } + + +} diff --git a/group11/996108220/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group11/996108220/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..44d000a19a --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,201 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + static String path1 = "F:\\mycoding2017\\group11\\996108220\\bin"; + static String path2 = "C:\temp"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + //clzFile.print(); + } + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/test/EmployeeV1.java b/group11/996108220/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..9a36573dd3 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/test/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.test; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group11/996108220/src/com/coderising/jvm/util/Util.java b/group11/996108220/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..c9808b1c1c --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,33 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;ielementData.length)this.grow(elementData); - else elementData[size++]=o; + else{ + elementData[size]=o; + size++; + } + } /** * 在index处添加元素,index+1到size-1元素向后移动 diff --git a/group11/996108220/src/com/coding/basic/Stack.java b/group11/996108220/src/com/coding/basic/Stack.java deleted file mode 100644 index ea41c87d1b..0000000000 --- a/group11/996108220/src/com/coding/basic/Stack.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.coding.basic; - -public class Stack { - //用动态数组实现栈 - private ArrayList elementData = new ArrayList(); - - public void push(Object o){ - elementData.add(elementData.size()); - } - - public Object pop(){ - return elementData.remove(elementData.size()-1); - } - - public Object peek(){ - return elementData.get(elementData.size()-1); - } - public boolean isEmpty(){ - return elementData.size()==0?true:false; - } - public int size(){ - return elementData.size(); - } -} diff --git a/group11/996108220/src/com/coding/basic/linklist/LRUPageFrame.java b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..f9ee1e68fa --- /dev/null +++ b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,139 @@ +package com.coding.basic.linklist; + + +/** + * 用双向链表实现LRU算法 + * @author 996108220 + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + public Node(int pageNum2) { + this.pageNum=pageNum2; + this.next=null; + this.prev=null; + } + + } + + private int capacity; + private int size; + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + this.size=0; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + Node node=remove(pageNum); + if (node==null) { + node=new Node(pageNum); + push(node); + } + else { + addTail(node); + } + + + } + + + private void push(Node node) { + if (this.size()==capacity) { + removeFirst(); + } + addTail(node); + } + + private void addTail(Node node) { + if (size==0) { + first=node; + last=node; + } + else { + node.prev=last; + last.next=node; + last=node; + + } + size++; + + } + + private void removeFirst() { + + Node node=this.first; + first=first.next; + node.next=null; + first.prev=null; + size--; + } + + private int size() { + + return size; + } + + private Node remove(int pageNum) { + Node node=first; + while(node!=null){ + if (node.pageNum==pageNum) { + if (node==first) { + first=node.next; + node.next=null; + first.prev=null; + } + else if (node==last) { + last=node.prev; + last.next=null; + node.prev=null; + } + else { + node.prev.next=node.next; + node.next.prev=node.prev; + node.next=null; + node.prev=null; + } + size--; + break; + } + node=node.next; + } + return node; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = last; + while(node != null){ + buffer.append(node.pageNum); + + node = node.prev; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/996108220/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group11/996108220/src/com/coding/basic/stack/Stack.java b/group11/996108220/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..05f380a304 --- /dev/null +++ b/group11/996108220/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,40 @@ +package com.coding.basic.stack; + +import com.coding.basic.ArrayList; + +public class Stack { + //用动态数组实现栈 + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + elementData.add(o); + } + + public Object pop(){ + return elementData.remove(elementData.size()-1); + } + + public Object peek(){ + return elementData.get(elementData.size()-1); + } + public boolean isEmpty(){ + return elementData.size()==0?true:false; + } + public int size(){ + return elementData.size(); + } + public String toString() { + + StringBuffer buffer=new StringBuffer("["); + for (int i = elementData.size()-1; i >=0; i--) { + if (i==0) { + buffer.append(elementData.get(i).toString()+"]"); + } + else { + buffer.append(elementData.get(i).toString()+","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/996108220/src/com/coding/basic/stack/StackUtil.java b/group11/996108220/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..2499f144ea --- /dev/null +++ b/group11/996108220/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,131 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + + reverse(s,s.size()); + } + + private static void reverse(Stack s, int length) { + if (length==1) { + return ; + } + Stack s1=new Stack(); + Object o=s.pop(); + for (int i = 1; i < length; i++) { + s1.push(s.pop()); + } + s.push(o); + for (int i = 1; i < length; i++) { + s.push(s1.pop()); + } + reverse(s, length-1); + + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if (s.size()==0) { + return; + } + Stack s1=new Stack(); + while(s.size()!=0) { + if (!s.peek().equals(o)) { + s1.push(s.pop()); + + } + else { + s.pop(); + break; + } + } + while(s1.size()!=0) { + s.push(s1.pop()); + } + + + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len>s.size()||len<=0) { + return null; + } + Stack s1=new Stack(); + Object[] array=new Object[len]; + for (int i = 0; i < len; i++) { + Object object=s.pop(); + array[i]=object; + s1.push(object); + } + while(s1.size()!=0) { + s.push(s1.pop()); + } + return array; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s){ + Stack stack=new Stack(); + for (int i = 0; i < s.length(); i++) { + switch (s.charAt(i)) { + case '(': + stack.push(s.charAt(i)); + break; + case '[': + stack.push(s.charAt(i)); + break; + case '{': + stack.push(s.charAt(i)); + break; + case ')': + if (stack.size()==0||(!stack.pop().equals('('))) { + return false; + } + break; + case ']': + if (stack.size()==0||(!stack.pop().equals('['))) { + return false; + } + break; + case '}': + if (stack.size()==0||(!stack.pop().equals('{'))) { + return false; + } + break; + default: + break; + } + } + if (stack.size()!=0) { + return false; + } + else { + return true; + } + + } + + +} diff --git a/group11/996108220/src/com/coding/basic/stack/StackUtilTest.java b/group11/996108220/src/com/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..91e3211683 --- /dev/null +++ b/group11/996108220/src/com/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,82 @@ +package com.coding.basic.stack; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class StackUtilTest { + Stack s; + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + } + @Test + public void testToString() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + + Assert.assertEquals("[6,5,4,3,2,1]", s.toString()); + } + + @Test + public void testReverse() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + StackUtil.reverse(s); + //System.out.println(s.size()); + Assert.assertEquals("[1,2,3,4,5,6]", s.toString()); + } + @Test + public void testRemove() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + StackUtil.remove(s, 6); + //System.out.println(s.toString()); + Assert.assertEquals("[5,4,3,2,1]", s.toString()); + } + @Test + public void testGetTop() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + Object[] s1=StackUtil.getTop(s, s.size()); + for (int i = 0; i < s1.length; i++) { + System.out.println(s1[i]); + } + //Assert.assertEquals("[5,6]", s1.toString()); + } + @Test + public void testIsValidPairs() { + String s="([e{df])" ; + Assert.assertEquals(false, StackUtil.isValidPairs(s)); + } + +} diff --git a/group11/group11.md b/group11/group11.md deleted file mode 100644 index 8b13789179..0000000000 --- a/group11/group11.md +++ /dev/null @@ -1 +0,0 @@ -