├── CCNx
├── lib
│ ├── ccn.jar
│ └── bcprov-jdk16-143.jar
├── src
│ ├── org
│ │ └── json
│ │ │ ├── zip
│ │ │ ├── README
│ │ │ ├── None.java
│ │ │ ├── BitReader.java
│ │ │ ├── BitWriter.java
│ │ │ ├── PostMortem.java
│ │ │ ├── Keep.java
│ │ │ ├── BitOutputStream.java
│ │ │ ├── BitInputStream.java
│ │ │ ├── MapKeep.java
│ │ │ ├── JSONzip.java
│ │ │ ├── Decompressor.java
│ │ │ ├── Huff.java
│ │ │ └── TrieKeep.java
│ │ │ ├── JSONString.java
│ │ │ ├── JSONException.java
│ │ │ ├── README
│ │ │ ├── HTTPTokener.java
│ │ │ ├── Property.java
│ │ │ ├── JSONStringer.java
│ │ │ ├── CookieList.java
│ │ │ ├── HTTP.java
│ │ │ ├── Cookie.java
│ │ │ ├── CDL.java
│ │ │ ├── JSONWriter.java
│ │ │ ├── XMLTokener.java
│ │ │ ├── Kim.java
│ │ │ └── JSONTokener.java
│ ├── ContentProps.java
│ └── ClientManager.java
├── tools
│ ├── ClientManager
│ └── compile.sh
├── config.properties
└── README
├── .gitmodules
├── CITATION
├── POX
├── __init__.py
├── startup.py
├── README
├── CCNxPlugin.py
└── forwarding.py
└── README
/CCNx/lib/ccn.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUDelftNAS/SDN-NDNFlow/HEAD/CCNx/lib/ccn.jar
--------------------------------------------------------------------------------
/CCNx/lib/bcprov-jdk16-143.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUDelftNAS/SDN-NDNFlow/HEAD/CCNx/lib/bcprov-jdk16-143.jar
--------------------------------------------------------------------------------
/CCNx/src/org/json/zip/README:
--------------------------------------------------------------------------------
1 | FOR EVALUATION PURPOSES ONLY. THIS PACKAGE HAS NOT BEEN TESTED ADEQUATELY FOR
2 | PRODUCTION USE.
3 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "POX/pox"]
2 | path = POX/pox
3 | url = git://github.com/noxrepo/pox.git
4 | [submodule "CCNx/ccnx"]
5 | path = CCNx/ccnx
6 | url = git://github.com/ProjectCCNx/ccnx.git
7 |
--------------------------------------------------------------------------------
/CITATION:
--------------------------------------------------------------------------------
1 | When using NDNFlow please refer to the accompanying article:
2 | Niels L. M. van Adrichem and Fernando A. Kuipers, NDNFlow: Software-Defined Named Data Networking, IEEE Conference on Network Softwarization (IEEE NetSoft), London, UK, April 13-17, 2015
3 | http://www.nas.ewi.tudelft.nl/people/Fernando/papers/NDNflow.pdf
4 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/zip/None.java:
--------------------------------------------------------------------------------
1 | package org.json.zip;
2 |
3 | /**
4 | * None is an interface that makes the constant none (short for
5 | * negative one or long for -1) available to any class that implements it.
6 | * The none value is used to stand for an integer that is not an integer,
7 | * such as the negative result of a search.
8 | */
9 | public interface None {
10 | /**
11 | * Negative One.
12 | */
13 | public static final int none = -1;
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/JSONString.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 | /**
3 | * The JSONString interface allows a toJSONString()
4 | * method so that a class can change the behavior of
5 | * JSONObject.toString(), JSONArray.toString(),
6 | * and JSONWriter.value(Object). The
7 | * toJSONString method will be used instead of the default behavior
8 | * of using the Object's toString() method and quoting the result.
9 | */
10 | public interface JSONString {
11 | /**
12 | * The toJSONString method allows a class to produce its own JSON
13 | * serialization.
14 | *
15 | * @return A strictly syntactically correct JSON text.
16 | */
17 | public String toJSONString();
18 | }
19 |
--------------------------------------------------------------------------------
/POX/__init__.py:
--------------------------------------------------------------------------------
1 | # #Copyright (C) 2015, Delft University of Technology, Faculty of Electrical Engineering, Mathematics and Computer Science, Network Architectures and Services, Niels van Adrichem
2 | #
3 | # This file is part of NDNFlow.
4 | #
5 | # NDNFlow is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # NDNFlow is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with NDNFlow. If not, see
35 | * A JSONStringer instance provides a value method for appending
36 | * values to the
37 | * text, and a key
38 | * method for adding keys before values in objects. There are array
39 | * and endArray methods that make and bound array values, and
40 | * object and endObject methods which make and bound
41 | * object values. All of these methods return the JSONWriter instance,
42 | * permitting cascade style. For example,
43 | * myString = new JSONStringer()
44 | * .object()
45 | * .key("JSON")
46 | * .value("Hello, World!")
47 | * .endObject()
48 | * .toString(); which produces the string
49 | * {"JSON":"Hello, World!"}
50 | *
51 | * The first method called must be array or object.
52 | * There are no methods for adding commas or colons. JSONStringer adds them for
53 | * you. Objects and arrays can be nested up to 20 levels deep.
54 | *
55 | * This can sometimes be easier than using a JSONObject to build a string.
56 | * @author JSON.org
57 | * @version 2008-09-18
58 | */
59 | public class JSONStringer extends JSONWriter {
60 | /**
61 | * Make a fresh JSONStringer. It can be used to build one JSON text.
62 | */
63 | public JSONStringer() {
64 | super(new StringWriter());
65 | }
66 |
67 | /**
68 | * Return the JSON text. This method is used to obtain the product of the
69 | * JSONStringer instance. It will return null if there was a
70 | * problem in the construction of the JSON text (such as the calls to
71 | * array were not properly balanced with calls to
72 | * endArray).
73 | * @return The JSON text.
74 | */
75 | public String toString() {
76 | return this.mode == 'd' ? this.writer.toString() : null;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/CookieList.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 |
3 | /*
4 | Copyright (c) 2002 JSON.org
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | The Software shall be used for Good, not Evil.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 | */
26 |
27 | import java.util.Iterator;
28 |
29 | /**
30 | * Convert a web browser cookie list string to a JSONObject and back.
31 | * @author JSON.org
32 | * @version 2010-12-24
33 | */
34 | public class CookieList {
35 |
36 | /**
37 | * Convert a cookie list into a JSONObject. A cookie list is a sequence
38 | * of name/value pairs. The names are separated from the values by '='.
39 | * The pairs are separated by ';'. The names and the values
40 | * will be unescaped, possibly converting '+' and '%' sequences.
41 | *
42 | * To add a cookie to a cooklist,
43 | * cookielistJSONObject.put(cookieJSONObject.getString("name"),
44 | * cookieJSONObject.getString("value"));
45 | * @param string A cookie list string
46 | * @return A JSONObject
47 | * @throws JSONException
48 | */
49 | public static JSONObject toJSONObject(String string) throws JSONException {
50 | JSONObject jo = new JSONObject();
51 | JSONTokener x = new JSONTokener(string);
52 | while (x.more()) {
53 | String name = Cookie.unescape(x.nextTo('='));
54 | x.next('=');
55 | jo.put(name, Cookie.unescape(x.nextTo(';')));
56 | x.next();
57 | }
58 | return jo;
59 | }
60 |
61 |
62 | /**
63 | * Convert a JSONObject into a cookie list. A cookie list is a sequence
64 | * of name/value pairs. The names are separated from the values by '='.
65 | * The pairs are separated by ';'. The characters '%', '+', '=', and ';'
66 | * in the names and values are replaced by "%hh".
67 | * @param jo A JSONObject
68 | * @return A cookie list string
69 | * @throws JSONException
70 | */
71 | public static String toString(JSONObject jo) throws JSONException {
72 | boolean b = false;
73 | Iterator keys = jo.keys();
74 | String string;
75 | StringBuffer sb = new StringBuffer();
76 | while (keys.hasNext()) {
77 | string = keys.next().toString();
78 | if (!jo.isNull(string)) {
79 | if (b) {
80 | sb.append(';');
81 | }
82 | sb.append(Cookie.escape(string));
83 | sb.append("=");
84 | sb.append(Cookie.escape(jo.getString(string)));
85 | b = true;
86 | }
87 | }
88 | return sb.toString();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/CCNx/README:
--------------------------------------------------------------------------------
1 | # #Copyright (C) 2015, Delft University of Technology, Faculty of Electrical Engineering, Mathematics and Computer Science, Network Architectures and Services, Niels van Adrichem
2 | #
3 | # This file is part of NDNFlow.
4 | #
5 | # NDNFlow is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # NDNFlow is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with NDNFlow. If not, see
{
43 | * Method: "POST" (for example),
44 | * "Request-URI": "/" (for example),
45 | * "HTTP-Version": "HTTP/1.1" (for example)
46 | * }
47 | * A response header will contain
48 | * {
49 | * "HTTP-Version": "HTTP/1.1" (for example),
50 | * "Status-Code": "200" (for example),
51 | * "Reason-Phrase": "OK" (for example)
52 | * }
53 | * In addition, the other parameters in the header will be captured, using
54 | * the HTTP field names as JSON names, so that 55 | * Date: Sun, 26 May 2002 18:06:04 GMT 56 | * Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s 57 | * Cache-Control: no-cache58 | * become 59 | *
{...
60 | * Date: "Sun, 26 May 2002 18:06:04 GMT",
61 | * Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
62 | * "Cache-Control": "no-cache",
63 | * ...}
64 | * It does no further checking or conversion. It does not parse dates.
65 | * It does not do '%' transforms on URLs.
66 | * @param string An HTTP header string.
67 | * @return A JSONObject containing the elements and attributes
68 | * of the XML string.
69 | * @throws JSONException
70 | */
71 | public static JSONObject toJSONObject(String string) throws JSONException {
72 | JSONObject jo = new JSONObject();
73 | HTTPTokener x = new HTTPTokener(string);
74 | String token;
75 |
76 | token = x.nextToken();
77 | if (token.toUpperCase().startsWith("HTTP")) {
78 |
79 | // Response
80 |
81 | jo.put("HTTP-Version", token);
82 | jo.put("Status-Code", x.nextToken());
83 | jo.put("Reason-Phrase", x.nextTo('\0'));
84 | x.next();
85 |
86 | } else {
87 |
88 | // Request
89 |
90 | jo.put("Method", token);
91 | jo.put("Request-URI", x.nextToken());
92 | jo.put("HTTP-Version", x.nextToken());
93 | }
94 |
95 | // Fields
96 |
97 | while (x.more()) {
98 | String name = x.nextTo(':');
99 | x.next(':');
100 | jo.put(name, x.nextTo('\0'));
101 | x.next();
102 | }
103 | return jo;
104 | }
105 |
106 |
107 | /**
108 | * Convert a JSONObject into an HTTP header. A request header must contain
109 | * {
110 | * Method: "POST" (for example),
111 | * "Request-URI": "/" (for example),
112 | * "HTTP-Version": "HTTP/1.1" (for example)
113 | * }
114 | * A response header must contain
115 | * {
116 | * "HTTP-Version": "HTTP/1.1" (for example),
117 | * "Status-Code": "200" (for example),
118 | * "Reason-Phrase": "OK" (for example)
119 | * }
120 | * Any other members of the JSONObject will be output as HTTP fields.
121 | * The result will end with two CRLF pairs.
122 | * @param jo A JSONObject
123 | * @return An HTTP header string.
124 | * @throws JSONException if the object does not contain enough
125 | * information.
126 | */
127 | public static String toString(JSONObject jo) throws JSONException {
128 | Iterator keys = jo.keys();
129 | String string;
130 | StringBuffer sb = new StringBuffer();
131 | if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
132 | sb.append(jo.getString("HTTP-Version"));
133 | sb.append(' ');
134 | sb.append(jo.getString("Status-Code"));
135 | sb.append(' ');
136 | sb.append(jo.getString("Reason-Phrase"));
137 | } else if (jo.has("Method") && jo.has("Request-URI")) {
138 | sb.append(jo.getString("Method"));
139 | sb.append(' ');
140 | sb.append('"');
141 | sb.append(jo.getString("Request-URI"));
142 | sb.append('"');
143 | sb.append(' ');
144 | sb.append(jo.getString("HTTP-Version"));
145 | } else {
146 | throw new JSONException("Not enough material for an HTTP header.");
147 | }
148 | sb.append(CRLF);
149 | while (keys.hasNext()) {
150 | string = keys.next().toString();
151 | if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) &&
152 | !"Reason-Phrase".equals(string) && !"Method".equals(string) &&
153 | !"Request-URI".equals(string) && !jo.isNull(string)) {
154 | sb.append(string);
155 | sb.append(": ");
156 | sb.append(jo.getString(string));
157 | sb.append(CRLF);
158 | }
159 | }
160 | sb.append(CRLF);
161 | return sb.toString();
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/Cookie.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 |
3 | /*
4 | Copyright (c) 2002 JSON.org
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | The Software shall be used for Good, not Evil.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 | */
26 |
27 | /**
28 | * Convert a web browser cookie specification to a JSONObject and back.
29 | * JSON and Cookies are both notations for name/value pairs.
30 | * @author JSON.org
31 | * @version 2010-12-24
32 | */
33 | public class Cookie {
34 |
35 | /**
36 | * Produce a copy of a string in which the characters '+', '%', '=', ';'
37 | * and control characters are replaced with "%hh". This is a gentle form
38 | * of URL encoding, attempting to cause as little distortion to the
39 | * string as possible. The characters '=' and ';' are meta characters in
40 | * cookies. By convention, they are escaped using the URL-encoding. This is
41 | * only a convention, not a standard. Often, cookies are expected to have
42 | * encoded values. We encode '=' and ';' because we must. We encode '%' and
43 | * '+' because they are meta characters in URL encoding.
44 | * @param string The source string.
45 | * @return The escaped result.
46 | */
47 | public static String escape(String string) {
48 | char c;
49 | String s = string.trim();
50 | StringBuffer sb = new StringBuffer();
51 | int length = s.length();
52 | for (int i = 0; i < length; i += 1) {
53 | c = s.charAt(i);
54 | if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
55 | sb.append('%');
56 | sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
57 | sb.append(Character.forDigit((char)(c & 0x0f), 16));
58 | } else {
59 | sb.append(c);
60 | }
61 | }
62 | return sb.toString();
63 | }
64 |
65 |
66 | /**
67 | * Convert a cookie specification string into a JSONObject. The string
68 | * will contain a name value pair separated by '='. The name and the value
69 | * will be unescaped, possibly converting '+' and '%' sequences. The
70 | * cookie properties may follow, separated by ';', also represented as
71 | * name=value (except the secure property, which does not have a value).
72 | * The name will be stored under the key "name", and the value will be
73 | * stored under the key "value". This method does not do checking or
74 | * validation of the parameters. It only converts the cookie string into
75 | * a JSONObject.
76 | * @param string The cookie specification string.
77 | * @return A JSONObject containing "name", "value", and possibly other
78 | * members.
79 | * @throws JSONException
80 | */
81 | public static JSONObject toJSONObject(String string) throws JSONException {
82 | String name;
83 | JSONObject jo = new JSONObject();
84 | Object value;
85 | JSONTokener x = new JSONTokener(string);
86 | jo.put("name", x.nextTo('='));
87 | x.next('=');
88 | jo.put("value", x.nextTo(';'));
89 | x.next();
90 | while (x.more()) {
91 | name = unescape(x.nextTo("=;"));
92 | if (x.next() != '=') {
93 | if (name.equals("secure")) {
94 | value = Boolean.TRUE;
95 | } else {
96 | throw x.syntaxError("Missing '=' in cookie parameter.");
97 | }
98 | } else {
99 | value = unescape(x.nextTo(';'));
100 | x.next();
101 | }
102 | jo.put(name, value);
103 | }
104 | return jo;
105 | }
106 |
107 |
108 | /**
109 | * Convert a JSONObject into a cookie specification string. The JSONObject
110 | * must contain "name" and "value" members.
111 | * If the JSONObject contains "expires", "domain", "path", or "secure"
112 | * members, they will be appended to the cookie specification string.
113 | * All other members are ignored.
114 | * @param jo A JSONObject
115 | * @return A cookie specification string
116 | * @throws JSONException
117 | */
118 | public static String toString(JSONObject jo) throws JSONException {
119 | StringBuffer sb = new StringBuffer();
120 |
121 | sb.append(escape(jo.getString("name")));
122 | sb.append("=");
123 | sb.append(escape(jo.getString("value")));
124 | if (jo.has("expires")) {
125 | sb.append(";expires=");
126 | sb.append(jo.getString("expires"));
127 | }
128 | if (jo.has("domain")) {
129 | sb.append(";domain=");
130 | sb.append(escape(jo.getString("domain")));
131 | }
132 | if (jo.has("path")) {
133 | sb.append(";path=");
134 | sb.append(escape(jo.getString("path")));
135 | }
136 | if (jo.optBoolean("secure")) {
137 | sb.append(";secure");
138 | }
139 | return sb.toString();
140 | }
141 |
142 | /**
143 | * Convert %hh sequences to single characters, and
144 | * convert plus to space.
145 | * @param string A string that may contain
146 | * + (plus) and
147 | * %hh sequences.
148 | * @return The unescaped string.
149 | */
150 | public static String unescape(String string) {
151 | int length = string.length();
152 | StringBuffer sb = new StringBuffer();
153 | for (int i = 0; i < length; ++i) {
154 | char c = string.charAt(i);
155 | if (c == '+') {
156 | c = ' ';
157 | } else if (c == '%' && i + 2 < length) {
158 | int d = JSONTokener.dehexchar(string.charAt(i + 1));
159 | int e = JSONTokener.dehexchar(string.charAt(i + 2));
160 | if (d >= 0 && e >= 0) {
161 | c = (char)(d * 16 + e);
162 | i += 2;
163 | }
164 | }
165 | sb.append(c);
166 | }
167 | return sb.toString();
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/CCNx/src/ClientManager.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | # #Copyright (C) 2015, Delft University of Technology, Faculty of Electrical Engineering, Mathematics and Computer Science, Network Architectures and Services, Niels van Adrichem
5 | #
6 | # This file is part of NDNFlow.
7 | #
8 | # NDNFlow is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # NDNFlow is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU General Public License
19 | # along with NDNFlow. If not, see 33 | * Each row of text represents a row in a table or a data record. Each row 34 | * ends with a NEWLINE character. Each row contains one or more values. 35 | * Values are separated by commas. A value can contain any character except 36 | * for comma, unless is is wrapped in single quotes or double quotes. 37 | *
38 | * The first row usually contains the names of the columns. 39 | *
40 | * A comma delimited list can be converted into a JSONArray of JSONObjects. 41 | * The names for the elements in the JSONObjects can be taken from the names 42 | * in the first row. 43 | * @author JSON.org 44 | * @version 2012-11-13 45 | */ 46 | public class CDL { 47 | 48 | /** 49 | * Get the next value. The value can be wrapped in quotes. The value can 50 | * be empty. 51 | * @param x A JSONTokener of the source text. 52 | * @return The value string, or null if empty. 53 | * @throws JSONException if the quoted string is badly formed. 54 | */ 55 | private static String getValue(JSONTokener x) throws JSONException { 56 | char c; 57 | char q; 58 | StringBuffer sb; 59 | do { 60 | c = x.next(); 61 | } while (c == ' ' || c == '\t'); 62 | switch (c) { 63 | case 0: 64 | return null; 65 | case '"': 66 | case '\'': 67 | q = c; 68 | sb = new StringBuffer(); 69 | for (;;) { 70 | c = x.next(); 71 | if (c == q) { 72 | break; 73 | } 74 | if (c == 0 || c == '\n' || c == '\r') { 75 | throw x.syntaxError("Missing close quote '" + q + "'."); 76 | } 77 | sb.append(c); 78 | } 79 | return sb.toString(); 80 | case ',': 81 | x.back(); 82 | return ""; 83 | default: 84 | x.back(); 85 | return x.nextTo(','); 86 | } 87 | } 88 | 89 | /** 90 | * Produce a JSONArray of strings from a row of comma delimited values. 91 | * @param x A JSONTokener of the source text. 92 | * @return A JSONArray of strings. 93 | * @throws JSONException 94 | */ 95 | public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { 96 | JSONArray ja = new JSONArray(); 97 | for (;;) { 98 | String value = getValue(x); 99 | char c = x.next(); 100 | if (value == null || 101 | (ja.length() == 0 && value.length() == 0 && c != ',')) { 102 | return null; 103 | } 104 | ja.put(value); 105 | for (;;) { 106 | if (c == ',') { 107 | break; 108 | } 109 | if (c != ' ') { 110 | if (c == '\n' || c == '\r' || c == 0) { 111 | return ja; 112 | } 113 | throw x.syntaxError("Bad character '" + c + "' (" + 114 | (int)c + ")."); 115 | } 116 | c = x.next(); 117 | } 118 | } 119 | } 120 | 121 | /** 122 | * Produce a JSONObject from a row of comma delimited text, using a 123 | * parallel JSONArray of strings to provides the names of the elements. 124 | * @param names A JSONArray of names. This is commonly obtained from the 125 | * first row of a comma delimited text file using the rowToJSONArray 126 | * method. 127 | * @param x A JSONTokener of the source text. 128 | * @return A JSONObject combining the names and values. 129 | * @throws JSONException 130 | */ 131 | public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) 132 | throws JSONException { 133 | JSONArray ja = rowToJSONArray(x); 134 | return ja != null ? ja.toJSONObject(names) : null; 135 | } 136 | 137 | /** 138 | * Produce a comma delimited text row from a JSONArray. Values containing 139 | * the comma character will be quoted. Troublesome characters may be 140 | * removed. 141 | * @param ja A JSONArray of strings. 142 | * @return A string ending in NEWLINE. 143 | */ 144 | public static String rowToString(JSONArray ja) { 145 | StringBuffer sb = new StringBuffer(); 146 | for (int i = 0; i < ja.length(); i += 1) { 147 | if (i > 0) { 148 | sb.append(','); 149 | } 150 | Object object = ja.opt(i); 151 | if (object != null) { 152 | String string = object.toString(); 153 | if (string.length() > 0 && (string.indexOf(',') >= 0 || 154 | string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 || 155 | string.indexOf(0) >= 0 || string.charAt(0) == '"')) { 156 | sb.append('"'); 157 | int length = string.length(); 158 | for (int j = 0; j < length; j += 1) { 159 | char c = string.charAt(j); 160 | if (c >= ' ' && c != '"') { 161 | sb.append(c); 162 | } 163 | } 164 | sb.append('"'); 165 | } else { 166 | sb.append(string); 167 | } 168 | } 169 | } 170 | sb.append('\n'); 171 | return sb.toString(); 172 | } 173 | 174 | /** 175 | * Produce a JSONArray of JSONObjects from a comma delimited text string, 176 | * using the first row as a source of names. 177 | * @param string The comma delimited text. 178 | * @return A JSONArray of JSONObjects. 179 | * @throws JSONException 180 | */ 181 | public static JSONArray toJSONArray(String string) throws JSONException { 182 | return toJSONArray(new JSONTokener(string)); 183 | } 184 | 185 | /** 186 | * Produce a JSONArray of JSONObjects from a comma delimited text string, 187 | * using the first row as a source of names. 188 | * @param x The JSONTokener containing the comma delimited text. 189 | * @return A JSONArray of JSONObjects. 190 | * @throws JSONException 191 | */ 192 | public static JSONArray toJSONArray(JSONTokener x) throws JSONException { 193 | return toJSONArray(rowToJSONArray(x), x); 194 | } 195 | 196 | /** 197 | * Produce a JSONArray of JSONObjects from a comma delimited text string 198 | * using a supplied JSONArray as the source of element names. 199 | * @param names A JSONArray of strings. 200 | * @param string The comma delimited text. 201 | * @return A JSONArray of JSONObjects. 202 | * @throws JSONException 203 | */ 204 | public static JSONArray toJSONArray(JSONArray names, String string) 205 | throws JSONException { 206 | return toJSONArray(names, new JSONTokener(string)); 207 | } 208 | 209 | /** 210 | * Produce a JSONArray of JSONObjects from a comma delimited text string 211 | * using a supplied JSONArray as the source of element names. 212 | * @param names A JSONArray of strings. 213 | * @param x A JSONTokener of the source text. 214 | * @return A JSONArray of JSONObjects. 215 | * @throws JSONException 216 | */ 217 | public static JSONArray toJSONArray(JSONArray names, JSONTokener x) 218 | throws JSONException { 219 | if (names == null || names.length() == 0) { 220 | return null; 221 | } 222 | JSONArray ja = new JSONArray(); 223 | for (;;) { 224 | JSONObject jo = rowToJSONObject(names, x); 225 | if (jo == null) { 226 | break; 227 | } 228 | ja.put(jo); 229 | } 230 | if (ja.length() == 0) { 231 | return null; 232 | } 233 | return ja; 234 | } 235 | 236 | 237 | /** 238 | * Produce a comma delimited text from a JSONArray of JSONObjects. The 239 | * first row will be a list of names obtained by inspecting the first 240 | * JSONObject. 241 | * @param ja A JSONArray of JSONObjects. 242 | * @return A comma delimited text. 243 | * @throws JSONException 244 | */ 245 | public static String toString(JSONArray ja) throws JSONException { 246 | JSONObject jo = ja.optJSONObject(0); 247 | if (jo != null) { 248 | JSONArray names = jo.names(); 249 | if (names != null) { 250 | return rowToString(names) + toString(names, ja); 251 | } 252 | } 253 | return null; 254 | } 255 | 256 | /** 257 | * Produce a comma delimited text from a JSONArray of JSONObjects using 258 | * a provided list of names. The list of names is not included in the 259 | * output. 260 | * @param names A JSONArray of strings. 261 | * @param ja A JSONArray of JSONObjects. 262 | * @return A comma delimited text. 263 | * @throws JSONException 264 | */ 265 | public static String toString(JSONArray names, JSONArray ja) 266 | throws JSONException { 267 | if (names == null || names.length() == 0) { 268 | return null; 269 | } 270 | StringBuffer sb = new StringBuffer(); 271 | for (int i = 0; i < ja.length(); i += 1) { 272 | JSONObject jo = ja.optJSONObject(i); 273 | if (jo != null) { 274 | sb.append(rowToString(jo.toJSONArray(names))); 275 | } 276 | } 277 | return sb.toString(); 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /CCNx/src/org/json/JSONWriter.java: -------------------------------------------------------------------------------- 1 | package org.json; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | /* 7 | Copyright (c) 2006 JSON.org 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | The Software shall be used for Good, not Evil. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | */ 29 | 30 | /** 31 | * JSONWriter provides a quick and convenient way of producing JSON text. 32 | * The texts produced strictly conform to JSON syntax rules. No whitespace is 33 | * added, so the results are ready for transmission or storage. Each instance of 34 | * JSONWriter can produce one JSON text. 35 | *
36 | * A JSONWriter instance provides a value method for appending
37 | * values to the
38 | * text, and a key
39 | * method for adding keys before values in objects. There are array
40 | * and endArray methods that make and bound array values, and
41 | * object and endObject methods which make and bound
42 | * object values. All of these methods return the JSONWriter instance,
43 | * permitting a cascade style. For example,
44 | * new JSONWriter(myWriter)
45 | * .object()
46 | * .key("JSON")
47 | * .value("Hello, World!")
48 | * .endObject(); which writes
49 | * {"JSON":"Hello, World!"}
50 | *
51 | * The first method called must be array or object.
52 | * There are no methods for adding commas or colons. JSONWriter adds them for
53 | * you. Objects and arrays can be nested up to 20 levels deep.
54 | *
55 | * This can sometimes be easier than using a JSONObject to build a string.
56 | * @author JSON.org
57 | * @version 2011-11-24
58 | */
59 | public class JSONWriter {
60 | private static final int maxdepth = 200;
61 |
62 | /**
63 | * The comma flag determines if a comma should be output before the next
64 | * value.
65 | */
66 | private boolean comma;
67 |
68 | /**
69 | * The current mode. Values:
70 | * 'a' (array),
71 | * 'd' (done),
72 | * 'i' (initial),
73 | * 'k' (key),
74 | * 'o' (object).
75 | */
76 | protected char mode;
77 |
78 | /**
79 | * The object/array stack.
80 | */
81 | private final JSONObject stack[];
82 |
83 | /**
84 | * The stack top index. A value of 0 indicates that the stack is empty.
85 | */
86 | private int top;
87 |
88 | /**
89 | * The writer that will receive the output.
90 | */
91 | protected Writer writer;
92 |
93 | /**
94 | * Make a fresh JSONWriter. It can be used to build one JSON text.
95 | */
96 | public JSONWriter(Writer w) {
97 | this.comma = false;
98 | this.mode = 'i';
99 | this.stack = new JSONObject[maxdepth];
100 | this.top = 0;
101 | this.writer = w;
102 | }
103 |
104 | /**
105 | * Append a value.
106 | * @param string A string value.
107 | * @return this
108 | * @throws JSONException If the value is out of sequence.
109 | */
110 | private JSONWriter append(String string) throws JSONException {
111 | if (string == null) {
112 | throw new JSONException("Null pointer");
113 | }
114 | if (this.mode == 'o' || this.mode == 'a') {
115 | try {
116 | if (this.comma && this.mode == 'a') {
117 | this.writer.write(',');
118 | }
119 | this.writer.write(string);
120 | } catch (IOException e) {
121 | throw new JSONException(e);
122 | }
123 | if (this.mode == 'o') {
124 | this.mode = 'k';
125 | }
126 | this.comma = true;
127 | return this;
128 | }
129 | throw new JSONException("Value out of sequence.");
130 | }
131 |
132 | /**
133 | * Begin appending a new array. All values until the balancing
134 | * endArray will be appended to this array. The
135 | * endArray method must be called to mark the array's end.
136 | * @return this
137 | * @throws JSONException If the nesting is too deep, or if the object is
138 | * started in the wrong place (for example as a key or after the end of the
139 | * outermost array or object).
140 | */
141 | public JSONWriter array() throws JSONException {
142 | if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
143 | this.push(null);
144 | this.append("[");
145 | this.comma = false;
146 | return this;
147 | }
148 | throw new JSONException("Misplaced array.");
149 | }
150 |
151 | /**
152 | * End something.
153 | * @param mode Mode
154 | * @param c Closing character
155 | * @return this
156 | * @throws JSONException If unbalanced.
157 | */
158 | private JSONWriter end(char mode, char c) throws JSONException {
159 | if (this.mode != mode) {
160 | throw new JSONException(mode == 'a'
161 | ? "Misplaced endArray."
162 | : "Misplaced endObject.");
163 | }
164 | this.pop(mode);
165 | try {
166 | this.writer.write(c);
167 | } catch (IOException e) {
168 | throw new JSONException(e);
169 | }
170 | this.comma = true;
171 | return this;
172 | }
173 |
174 | /**
175 | * End an array. This method most be called to balance calls to
176 | * array.
177 | * @return this
178 | * @throws JSONException If incorrectly nested.
179 | */
180 | public JSONWriter endArray() throws JSONException {
181 | return this.end('a', ']');
182 | }
183 |
184 | /**
185 | * End an object. This method most be called to balance calls to
186 | * object.
187 | * @return this
188 | * @throws JSONException If incorrectly nested.
189 | */
190 | public JSONWriter endObject() throws JSONException {
191 | return this.end('k', '}');
192 | }
193 |
194 | /**
195 | * Append a key. The key will be associated with the next value. In an
196 | * object, every value must be preceded by a key.
197 | * @param string A key string.
198 | * @return this
199 | * @throws JSONException If the key is out of place. For example, keys
200 | * do not belong in arrays or if the key is null.
201 | */
202 | public JSONWriter key(String string) throws JSONException {
203 | if (string == null) {
204 | throw new JSONException("Null key.");
205 | }
206 | if (this.mode == 'k') {
207 | try {
208 | this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
209 | if (this.comma) {
210 | this.writer.write(',');
211 | }
212 | this.writer.write(JSONObject.quote(string));
213 | this.writer.write(':');
214 | this.comma = false;
215 | this.mode = 'o';
216 | return this;
217 | } catch (IOException e) {
218 | throw new JSONException(e);
219 | }
220 | }
221 | throw new JSONException("Misplaced key.");
222 | }
223 |
224 |
225 | /**
226 | * Begin appending a new object. All keys and values until the balancing
227 | * endObject will be appended to this object. The
228 | * endObject method must be called to mark the object's end.
229 | * @return this
230 | * @throws JSONException If the nesting is too deep, or if the object is
231 | * started in the wrong place (for example as a key or after the end of the
232 | * outermost array or object).
233 | */
234 | public JSONWriter object() throws JSONException {
235 | if (this.mode == 'i') {
236 | this.mode = 'o';
237 | }
238 | if (this.mode == 'o' || this.mode == 'a') {
239 | this.append("{");
240 | this.push(new JSONObject());
241 | this.comma = false;
242 | return this;
243 | }
244 | throw new JSONException("Misplaced object.");
245 |
246 | }
247 |
248 |
249 | /**
250 | * Pop an array or object scope.
251 | * @param c The scope to close.
252 | * @throws JSONException If nesting is wrong.
253 | */
254 | private void pop(char c) throws JSONException {
255 | if (this.top <= 0) {
256 | throw new JSONException("Nesting error.");
257 | }
258 | char m = this.stack[this.top - 1] == null ? 'a' : 'k';
259 | if (m != c) {
260 | throw new JSONException("Nesting error.");
261 | }
262 | this.top -= 1;
263 | this.mode = this.top == 0
264 | ? 'd'
265 | : this.stack[this.top - 1] == null
266 | ? 'a'
267 | : 'k';
268 | }
269 |
270 | /**
271 | * Push an array or object scope.
272 | * @param c The scope to open.
273 | * @throws JSONException If nesting is too deep.
274 | */
275 | private void push(JSONObject jo) throws JSONException {
276 | if (this.top >= maxdepth) {
277 | throw new JSONException("Nesting too deep.");
278 | }
279 | this.stack[this.top] = jo;
280 | this.mode = jo == null ? 'a' : 'k';
281 | this.top += 1;
282 | }
283 |
284 |
285 | /**
286 | * Append either the value true or the value
287 | * false.
288 | * @param b A boolean.
289 | * @return this
290 | * @throws JSONException
291 | */
292 | public JSONWriter value(boolean b) throws JSONException {
293 | return this.append(b ? "true" : "false");
294 | }
295 |
296 | /**
297 | * Append a double value.
298 | * @param d A double.
299 | * @return this
300 | * @throws JSONException If the number is not finite.
301 | */
302 | public JSONWriter value(double d) throws JSONException {
303 | return this.value(new Double(d));
304 | }
305 |
306 | /**
307 | * Append a long value.
308 | * @param l A long.
309 | * @return this
310 | * @throws JSONException
311 | */
312 | public JSONWriter value(long l) throws JSONException {
313 | return this.append(Long.toString(l));
314 | }
315 |
316 |
317 | /**
318 | * Append an object value.
319 | * @param object The object to append. It can be null, or a Boolean, Number,
320 | * String, JSONObject, or JSONArray, or an object that implements JSONString.
321 | * @return this
322 | * @throws JSONException If the value is out of sequence.
323 | */
324 | public JSONWriter value(Object object) throws JSONException {
325 | return this.append(JSONObject.valueToString(object));
326 | }
327 | }
328 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/XMLTokener.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 |
3 | /*
4 | Copyright (c) 2002 JSON.org
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | The Software shall be used for Good, not Evil.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 | */
26 |
27 | /**
28 | * The XMLTokener extends the JSONTokener to provide additional methods
29 | * for the parsing of XML texts.
30 | * @author JSON.org
31 | * @version 2012-11-13
32 | */
33 | public class XMLTokener extends JSONTokener {
34 |
35 |
36 | /** The table of entity values. It initially contains Character values for
37 | * amp, apos, gt, lt, quot.
38 | */
39 | public static final java.util.HashMap entity;
40 |
41 | static {
42 | entity = new java.util.HashMap(8);
43 | entity.put("amp", XML.AMP);
44 | entity.put("apos", XML.APOS);
45 | entity.put("gt", XML.GT);
46 | entity.put("lt", XML.LT);
47 | entity.put("quot", XML.QUOT);
48 | }
49 |
50 | /**
51 | * Construct an XMLTokener from a string.
52 | * @param s A source string.
53 | */
54 | public XMLTokener(String s) {
55 | super(s);
56 | }
57 |
58 | /**
59 | * Get the text in the CDATA block.
60 | * @return The string up to the ]]>.
61 | * @throws JSONException If the ]]> is not found.
62 | */
63 | public String nextCDATA() throws JSONException {
64 | char c;
65 | int i;
66 | StringBuffer sb = new StringBuffer();
67 | for (;;) {
68 | c = next();
69 | if (end()) {
70 | throw syntaxError("Unclosed CDATA");
71 | }
72 | sb.append(c);
73 | i = sb.length() - 3;
74 | if (i >= 0 && sb.charAt(i) == ']' &&
75 | sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {
76 | sb.setLength(i);
77 | return sb.toString();
78 | }
79 | }
80 | }
81 |
82 |
83 | /**
84 | * Get the next XML outer token, trimming whitespace. There are two kinds
85 | * of tokens: the '<' character which begins a markup tag, and the content
86 | * text between markup tags.
87 | *
88 | * @return A string, or a '<' Character, or null if there is no more
89 | * source text.
90 | * @throws JSONException
91 | */
92 | public Object nextContent() throws JSONException {
93 | char c;
94 | StringBuffer sb;
95 | do {
96 | c = next();
97 | } while (Character.isWhitespace(c));
98 | if (c == 0) {
99 | return null;
100 | }
101 | if (c == '<') {
102 | return XML.LT;
103 | }
104 | sb = new StringBuffer();
105 | for (;;) {
106 | if (c == '<' || c == 0) {
107 | back();
108 | return sb.toString().trim();
109 | }
110 | if (c == '&') {
111 | sb.append(nextEntity(c));
112 | } else {
113 | sb.append(c);
114 | }
115 | c = next();
116 | }
117 | }
118 |
119 |
120 | /**
121 | * Return the next entity. These entities are translated to Characters:
122 | * & ' > < ".
123 | * @param ampersand An ampersand character.
124 | * @return A Character or an entity String if the entity is not recognized.
125 | * @throws JSONException If missing ';' in XML entity.
126 | */
127 | public Object nextEntity(char ampersand) throws JSONException {
128 | StringBuffer sb = new StringBuffer();
129 | for (;;) {
130 | char c = next();
131 | if (Character.isLetterOrDigit(c) || c == '#') {
132 | sb.append(Character.toLowerCase(c));
133 | } else if (c == ';') {
134 | break;
135 | } else {
136 | throw syntaxError("Missing ';' in XML entity: &" + sb);
137 | }
138 | }
139 | String string = sb.toString();
140 | Object object = entity.get(string);
141 | return object != null ? object : ampersand + string + ";";
142 | }
143 |
144 |
145 | /**
146 | * Returns the next XML meta token. This is used for skipping over
147 | * and ...?> structures.
148 | * @return Syntax characters (< > / = ! ?) are returned as
149 | * Character, and strings and names are returned as Boolean. We don't care
150 | * what the values actually are.
151 | * @throws JSONException If a string is not properly closed or if the XML
152 | * is badly structured.
153 | */
154 | public Object nextMeta() throws JSONException {
155 | char c;
156 | char q;
157 | do {
158 | c = next();
159 | } while (Character.isWhitespace(c));
160 | switch (c) {
161 | case 0:
162 | throw syntaxError("Misshaped meta tag");
163 | case '<':
164 | return XML.LT;
165 | case '>':
166 | return XML.GT;
167 | case '/':
168 | return XML.SLASH;
169 | case '=':
170 | return XML.EQ;
171 | case '!':
172 | return XML.BANG;
173 | case '?':
174 | return XML.QUEST;
175 | case '"':
176 | case '\'':
177 | q = c;
178 | for (;;) {
179 | c = next();
180 | if (c == 0) {
181 | throw syntaxError("Unterminated string");
182 | }
183 | if (c == q) {
184 | return Boolean.TRUE;
185 | }
186 | }
187 | default:
188 | for (;;) {
189 | c = next();
190 | if (Character.isWhitespace(c)) {
191 | return Boolean.TRUE;
192 | }
193 | switch (c) {
194 | case 0:
195 | case '<':
196 | case '>':
197 | case '/':
198 | case '=':
199 | case '!':
200 | case '?':
201 | case '"':
202 | case '\'':
203 | back();
204 | return Boolean.TRUE;
205 | }
206 | }
207 | }
208 | }
209 |
210 |
211 | /**
212 | * Get the next XML Token. These tokens are found inside of angle
213 | * brackets. It may be one of these characters: / > = ! ? or it
214 | * may be a string wrapped in single quotes or double quotes, or it may be a
215 | * name.
216 | * @return a String or a Character.
217 | * @throws JSONException If the XML is not well formed.
218 | */
219 | public Object nextToken() throws JSONException {
220 | char c;
221 | char q;
222 | StringBuffer sb;
223 | do {
224 | c = next();
225 | } while (Character.isWhitespace(c));
226 | switch (c) {
227 | case 0:
228 | throw syntaxError("Misshaped element");
229 | case '<':
230 | throw syntaxError("Misplaced '<'");
231 | case '>':
232 | return XML.GT;
233 | case '/':
234 | return XML.SLASH;
235 | case '=':
236 | return XML.EQ;
237 | case '!':
238 | return XML.BANG;
239 | case '?':
240 | return XML.QUEST;
241 |
242 | // Quoted string
243 |
244 | case '"':
245 | case '\'':
246 | q = c;
247 | sb = new StringBuffer();
248 | for (;;) {
249 | c = next();
250 | if (c == 0) {
251 | throw syntaxError("Unterminated string");
252 | }
253 | if (c == q) {
254 | return sb.toString();
255 | }
256 | if (c == '&') {
257 | sb.append(nextEntity(c));
258 | } else {
259 | sb.append(c);
260 | }
261 | }
262 | default:
263 |
264 | // Name
265 |
266 | sb = new StringBuffer();
267 | for (;;) {
268 | sb.append(c);
269 | c = next();
270 | if (Character.isWhitespace(c)) {
271 | return sb.toString();
272 | }
273 | switch (c) {
274 | case 0:
275 | return sb.toString();
276 | case '>':
277 | case '/':
278 | case '=':
279 | case '!':
280 | case '?':
281 | case '[':
282 | case ']':
283 | back();
284 | return sb.toString();
285 | case '<':
286 | case '"':
287 | case '\'':
288 | throw syntaxError("Bad character in a name");
289 | }
290 | }
291 | }
292 | }
293 |
294 |
295 | /**
296 | * Skip characters until past the requested string.
297 | * If it is not found, we are left at the end of the source with a result of false.
298 | * @param to A string to skip past.
299 | * @throws JSONException
300 | */
301 | public boolean skipPast(String to) throws JSONException {
302 | boolean b;
303 | char c;
304 | int i;
305 | int j;
306 | int offset = 0;
307 | int length = to.length();
308 | char[] circle = new char[length];
309 |
310 | /*
311 | * First fill the circle buffer with as many characters as are in the
312 | * to string. If we reach an early end, bail.
313 | */
314 |
315 | for (i = 0; i < length; i += 1) {
316 | c = next();
317 | if (c == 0) {
318 | return false;
319 | }
320 | circle[i] = c;
321 | }
322 |
323 | /* We will loop, possibly for all of the remaining characters. */
324 |
325 | for (;;) {
326 | j = offset;
327 | b = true;
328 |
329 | /* Compare the circle buffer with the to string. */
330 |
331 | for (i = 0; i < length; i += 1) {
332 | if (circle[j] != to.charAt(i)) {
333 | b = false;
334 | break;
335 | }
336 | j += 1;
337 | if (j >= length) {
338 | j -= length;
339 | }
340 | }
341 |
342 | /* If we exit the loop with b intact, then victory is ours. */
343 |
344 | if (b) {
345 | return true;
346 | }
347 |
348 | /* Get the next character. If there isn't one, then defeat is ours. */
349 |
350 | c = next();
351 | if (c == 0) {
352 | return false;
353 | }
354 | /*
355 | * Shove the character in the circle buffer and advance the
356 | * circle offset. The offset is mod n.
357 | */
358 | circle[offset] = c;
359 | offset += 1;
360 | if (offset >= length) {
361 | offset -= length;
362 | }
363 | }
364 | }
365 | }
366 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/zip/Huff.java:
--------------------------------------------------------------------------------
1 | package org.json.zip;
2 |
3 | import org.json.JSONException;
4 |
5 | /*
6 | Copyright (c) 2013 JSON.org
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | The Software shall be used for Good, not Evil.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 | */
28 |
29 | /**
30 | * JSONzip is a compression scheme for JSON text.
31 | * @author JSON.org
32 | * @version 2013-04-18
33 | */
34 |
35 | /**
36 | * A Huffman encoder/decoder. It operates over a domain of integers, which may
37 | * map to characters or other symbols. Symbols that are used frequently are
38 | * given shorter codes than symbols that are used infrequently. This usually
39 | * produces shorter messages.
40 | *
41 | * Initially, all of the symbols are given the same weight. The weight of a
42 | * symbol is incremented by the tick method. The generate method is used to
43 | * generate the encoding table. The table must be generated before encoding or
44 | * decoding. You may regenerate the table with the latest weights at any time.
45 | */
46 | public class Huff implements None, PostMortem {
47 |
48 | /**
49 | * The number of symbols known to the encoder.
50 | */
51 | private final int domain;
52 |
53 | /**
54 | * An array that maps symbol values to symbols.
55 | */
56 | private final Symbol[] symbols;
57 |
58 | /**
59 | * The root of the decoding table, and the terminal of the encoding table.
60 | */
61 | private Symbol table;
62 |
63 | /**
64 | * Have any weights changed since the table was last generated?
65 | */
66 | private boolean upToDate = false;
67 |
68 | /**
69 | * The number of bits in the last symbol. This is used in tracing.
70 | */
71 | private int width;
72 |
73 | private static class Symbol implements PostMortem {
74 | public Symbol back;
75 | public Symbol next;
76 | public Symbol zero;
77 | public Symbol one;
78 | public final int integer;
79 | public long weight;
80 |
81 | /**
82 | * Make a symbol representing a character or other value.
83 | *
84 | * @param integer
85 | * The symbol's number
86 | */
87 | public Symbol(int integer) {
88 | this.integer = integer;
89 | this.weight = 0;
90 | this.next = null;
91 | this.back = null;
92 | this.one = null;
93 | this.zero = null;
94 | }
95 |
96 | public boolean postMortem(PostMortem pm) {
97 | boolean result = true;
98 | Symbol that = (Symbol) pm;
99 |
100 | if (this.integer != that.integer || this.weight != that.weight) {
101 | return false;
102 | }
103 | if ((this.back != null) != (that.back != null)) {
104 | return false;
105 | }
106 | Symbol zero = this.zero;
107 | Symbol one = this.one;
108 | if (zero == null) {
109 | if (that.zero != null) {
110 | return false;
111 | }
112 | } else {
113 | result = zero.postMortem(that.zero);
114 | }
115 | if (one == null) {
116 | if (that.one != null) {
117 | return false;
118 | }
119 | } else {
120 | result = one.postMortem(that.one);
121 | }
122 | return result;
123 | }
124 |
125 | }
126 |
127 | /**
128 | * Construct a Huffman encoder/decoder.
129 | *
130 | * @param domain
131 | * The number of values known to the object.
132 | */
133 | public Huff(int domain) {
134 | this.domain = domain;
135 | int length = domain * 2 - 1;
136 | this.symbols = new Symbol[length];
137 |
138 | // Make the leaf symbols.
139 |
140 | for (int i = 0; i < domain; i += 1) {
141 | symbols[i] = new Symbol(i);
142 | }
143 |
144 | // SMake the links.
145 |
146 | for (int i = domain; i < length; i += 1) {
147 | symbols[i] = new Symbol(none);
148 | }
149 | }
150 |
151 | /**
152 | * Generate the encoding/decoding table. The table determines the bit
153 | * sequences used by the read and write methods.
154 | *
155 | * @return this
156 | */
157 | public void generate() {
158 | if (!this.upToDate) {
159 |
160 | // Phase One: Sort the symbols by weight into a linked list.
161 |
162 | Symbol head = this.symbols[0];
163 | Symbol next;
164 | Symbol previous = head;
165 | Symbol symbol;
166 |
167 | this.table = null;
168 | head.next = null;
169 | for (int i = 1; i < this.domain; i += 1) {
170 | symbol = symbols[i];
171 |
172 | // If this symbol weights less than the head, then it becomes the new head.
173 |
174 | if (symbol.weight < head.weight) {
175 | symbol.next = head;
176 | head = symbol;
177 | } else {
178 |
179 | // To save time, we will start the search from the previous symbol instead
180 | // of the head unless the current symbol weights less than the previous symbol.
181 |
182 | if (symbol.weight < previous.weight) {
183 | previous = head;
184 | }
185 |
186 | // Find a connected pair (previous and next) where the symbol weighs the same
187 | // or more than previous but less than the next. Link the symbol between them.
188 |
189 | while (true) {
190 | next = previous.next;
191 | if (next == null || symbol.weight < next.weight) {
192 | break;
193 | }
194 | previous = next;
195 | }
196 | symbol.next = next;
197 | previous.next = symbol;
198 | previous = symbol;
199 | }
200 | }
201 |
202 | // Phase Two: Make new symbols from the two lightest symbols until only one
203 | // symbol remains. The final symbol becomes the root of the table binary tree.
204 |
205 | int avail = this.domain;
206 | Symbol first;
207 | Symbol second;
208 | previous = head;
209 | while (true) {
210 | first = head;
211 | second = first.next;
212 | head = second.next;
213 | symbol = this.symbols[avail];
214 | avail += 1;
215 | symbol.weight = first.weight + second.weight;
216 | symbol.zero = first;
217 | symbol.one = second;
218 | symbol.back = null;
219 | first.back = symbol;
220 | second.back = symbol;
221 | if (head == null) {
222 | break;
223 | }
224 |
225 | // Insert the new symbol back into the sorted list.
226 |
227 | if (symbol.weight < head.weight) {
228 | symbol.next = head;
229 | head = symbol;
230 | previous = head;
231 | } else {
232 | while (true) {
233 | next = previous.next;
234 | if (next == null || symbol.weight < next.weight) {
235 | break;
236 | }
237 | previous = next;
238 | }
239 | symbol.next = next;
240 | previous.next = symbol;
241 | previous = symbol;
242 | }
243 |
244 | }
245 |
246 | // The last remaining symbol is the root of the table.
247 |
248 | this.table = symbol;
249 | this.upToDate = true;
250 | }
251 | }
252 |
253 | private boolean postMortem(int integer) {
254 | int[] bits = new int[this.domain];
255 | Symbol symbol = this.symbols[integer];
256 | if (symbol.integer != integer) {
257 | return false;
258 | }
259 | int i = 0;
260 | while (true) {
261 | Symbol back = symbol.back;
262 | if (back == null) {
263 | break;
264 | }
265 | if (back.zero == symbol) {
266 | bits[i] = 0;
267 | } else if (back.one == symbol) {
268 | bits[i] = 1;
269 | } else {
270 | return false;
271 | }
272 | i += 1;
273 | symbol = back;
274 | }
275 | if (symbol != this.table) {
276 | return false;
277 | }
278 | this.width = 0;
279 | symbol = this.table;
280 | while (symbol.integer == none) {
281 | i -= 1;
282 | symbol = bits[i] != 0 ? symbol.one : symbol.zero;
283 | }
284 | return symbol.integer == integer && i == 0;
285 | }
286 |
287 | /**
288 | * Compare two Huffman tables.
289 | */
290 | public boolean postMortem(PostMortem pm) {
291 |
292 | // Go through every integer in the domain, generating its bit sequence, and
293 | // then proving that that bit sequence produces the same integer.
294 |
295 | for (int integer = 0; integer < this.domain; integer += 1) {
296 | if (!postMortem(integer)) {
297 | JSONzip.log("\nBad huff ");
298 | JSONzip.logchar(integer, integer);
299 | return false;
300 | }
301 | }
302 | return this.table.postMortem(((Huff) pm).table);
303 | }
304 |
305 | /**
306 | * Read bits until a symbol can be identified. The weight of the read
307 | * symbol will be incremented.
308 | *
309 | * @param bitreader
310 | * The source of bits.
311 | * @return The integer value of the symbol.
312 | * @throws JSONException
313 | */
314 | public int read(BitReader bitreader) throws JSONException {
315 | try {
316 | this.width = 0;
317 | Symbol symbol = this.table;
318 | while (symbol.integer == none) {
319 | this.width += 1;
320 | symbol = bitreader.bit() ? symbol.one : symbol.zero;
321 | }
322 | tick(symbol.integer);
323 | if (JSONzip.probe) {
324 | JSONzip.logchar(symbol.integer, this.width);
325 | }
326 | return symbol.integer;
327 | } catch (Throwable e) {
328 | throw new JSONException(e);
329 | }
330 | }
331 |
332 | /**
333 | * Increase by 1 the weight associated with a value.
334 | *
335 | * @param value
336 | * The number of the symbol to tick
337 | * @return this
338 | */
339 | public void tick(int value) {
340 | this.symbols[value].weight += 1;
341 | this.upToDate = false;
342 | }
343 |
344 | /**
345 | * Increase by 1 the weight associated with a range of values.
346 | *
347 | * @param from
348 | * The first symbol to tick
349 | * @param to
350 | * The last symbol to tick
351 | * @return this
352 | */
353 | public void tick(int from, int to) {
354 | for (int value = from; value <= to; value += 1) {
355 | tick(value);
356 | }
357 | }
358 |
359 | /**
360 | * Recur from a symbol back, emitting bits. We recur before emitting to
361 | * make the bits come out in the right order.
362 | *
363 | * @param symbol
364 | * The symbol to write.
365 | * @param bitwriter
366 | * The bitwriter to write it to.
367 | * @throws JSONException
368 | */
369 | private void write(Symbol symbol, BitWriter bitwriter)
370 | throws JSONException {
371 | try {
372 | Symbol back = symbol.back;
373 | if (back != null) {
374 | this.width += 1;
375 | write(back, bitwriter);
376 | if (back.zero == symbol) {
377 | bitwriter.zero();
378 | } else {
379 | bitwriter.one();
380 | }
381 | }
382 | } catch (Throwable e) {
383 | throw new JSONException(e);
384 | }
385 | }
386 |
387 | /**
388 | * Write the bits corresponding to a symbol. The weight of the symbol will
389 | * be incremented.
390 | *
391 | * @param value
392 | * The number of the symbol to write
393 | * @param bitwriter
394 | * The destination of the bits.
395 | * @return this
396 | * @throws JSONException
397 | */
398 | public void write(int value, BitWriter bitwriter) throws JSONException {
399 | this.width = 0;
400 | write(this.symbols[value], bitwriter);
401 | tick(value);
402 | if (JSONzip.probe) {
403 | JSONzip.logchar(value, this.width);
404 | }
405 | }
406 | }
407 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/zip/TrieKeep.java:
--------------------------------------------------------------------------------
1 | package org.json.zip;
2 |
3 | import org.json.Kim;
4 |
5 | /*
6 | Copyright (c) 2013 JSON.org
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | The Software shall be used for Good, not Evil.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 | */
28 |
29 | /**
30 | * A TrieKeep is a Keep that implements a Trie.
31 | */
32 | class TrieKeep extends Keep {
33 |
34 | /**
35 | * The trie is made of nodes.
36 | */
37 | class Node implements PostMortem {
38 | private int integer;
39 | private Node[] next;
40 |
41 | /**
42 | * Each non-leaf node contains links to up to 256 next nodes. Each node
43 | * has an integer value.
44 | */
45 | public Node() {
46 | this.integer = none;
47 | this.next = null;
48 | }
49 |
50 | /**
51 | * Get one of a node's 256 links. If it is a leaf node, it returns
52 | * null.
53 | *
54 | * @param cell
55 | * A integer between 0 and 255.
56 | * @return
57 | */
58 | public Node get(int cell) {
59 | return this.next == null ? null : this.next[cell];
60 | }
61 |
62 | /**
63 | * Get one of a node's 256 links. If it is a leap node, it returns
64 | * null. The argument is treated as an unsigned integer.
65 | *
66 | * @param cell
67 | * A byte.
68 | * @return
69 | */
70 | public Node get(byte cell) {
71 | return get(((int) cell) & 0xFF);
72 | }
73 |
74 | /**
75 | * Compare two nodes. Their lengths must be equal. Their links must
76 | * also compare.
77 | */
78 | public boolean postMortem(PostMortem pm) {
79 | Node that = (Node) pm;
80 | if (that == null) {
81 | JSONzip.log("\nMisalign");
82 | return false;
83 | }
84 | if (this.integer != that.integer) {
85 | JSONzip.log("\nInteger " + this.integer + " <> " +
86 | that.integer);
87 | return false;
88 | }
89 | if (this.next == null) {
90 | if (that.next == null) {
91 | return true;
92 | }
93 | JSONzip.log("\nNext is null " + this.integer);
94 | return false;
95 | }
96 | for (int i = 0; i < 256; i += 1) {
97 | Node node = this.next[i];
98 | if (node != null) {
99 | if (!node.postMortem(that.next[i])) {
100 | return false;
101 | }
102 | } else if (that.next[i] != null) {
103 | JSONzip.log("\nMisalign " + i);
104 | return false;
105 | }
106 | }
107 | return true;
108 | }
109 |
110 | /**
111 | * Set a node's link to another node.
112 | *
113 | * @param cell
114 | * An integer between 0 and 255.
115 | * @param node
116 | * The new value for the cell.
117 | */
118 | public void set(int cell, Node node) {
119 | if (this.next == null) {
120 | this.next = new Node[256];
121 | }
122 | if (JSONzip.probe) {
123 | if (node == null || this.next[cell] != null) {
124 | JSONzip.log("\nUnexpected set.\n");
125 | }
126 | }
127 | this.next[cell] = node;
128 | }
129 |
130 | /**
131 | * Set a node's link to another node.
132 | *
133 | * @param cell
134 | * A byte.
135 | * @param node
136 | * The new value for the cell.
137 | */
138 | public void set(byte cell, Node node) {
139 | set(((int) cell) & 0xFF, node);
140 | }
141 |
142 | /**
143 | * Get one of a node's 256 links. It will not return null. If there is
144 | * no link, then a link is manufactured.
145 | *
146 | * @param cell
147 | * A integer between 0 and 255.
148 | * @return
149 | */
150 | public Node vet(int cell) {
151 | Node node = get(cell);
152 | if (node == null) {
153 | node = new Node();
154 | set(cell, node);
155 | }
156 | return node;
157 | }
158 |
159 | /**
160 | * Get one of a node's 256 links. It will not return null. If there is
161 | * no link, then a link is manufactured.
162 | *
163 | * @param cell
164 | * A byte.
165 | * @return
166 | */
167 | public Node vet(byte cell) {
168 | return vet(((int) cell) & 0xFF);
169 | }
170 | }
171 |
172 | private int[] froms;
173 | private int[] thrus;
174 | private Node root;
175 | private Kim[] kims;
176 |
177 | /**
178 | * Create a new Keep of kims.
179 | *
180 | * @param bits
181 | * The log2 of the capacity of the Keep. For example, if bits is
182 | * 12, then the keep's capacity will be 4096.
183 | */
184 | public TrieKeep(int bits) {
185 | super(bits);
186 | this.froms = new int[this.capacity];
187 | this.thrus = new int[this.capacity];
188 | this.kims = new Kim[this.capacity];
189 | this.root = new Node();
190 | }
191 |
192 | /**
193 | * Get the kim associated with an integer.
194 | *
195 | * @param integer
196 | * @return
197 | */
198 | public Kim kim(int integer) {
199 | Kim kim = this.kims[integer];
200 | int from = this.froms[integer];
201 | int thru = this.thrus[integer];
202 | if (from != 0 || thru != kim.length) {
203 | kim = new Kim(kim, from, thru);
204 | this.froms[integer] = 0;
205 | this.thrus[integer] = kim.length;
206 | this.kims[integer] = kim;
207 | }
208 | return kim;
209 | }
210 |
211 | /**
212 | * Get the length of the Kim associated with an integer. This is sometimes
213 | * much faster than get(integer).length.
214 | *
215 | * @param integer
216 | * @return
217 | */
218 | public int length(int integer) {
219 | return this.thrus[integer] - this.froms[integer];
220 | }
221 |
222 | /**
223 | * Find the integer value associated with this key, or nothing if this key
224 | * is not in the keep.
225 | *
226 | * @param key
227 | * An object.
228 | * @return An integer
229 | */
230 | public int match(Kim kim, int from, int thru) {
231 | Node node = this.root;
232 | int best = none;
233 | for (int at = from; at < thru; at += 1) {
234 | node = node.get(kim.get(at));
235 | if (node == null) {
236 | break;
237 | }
238 | if (node.integer != none) {
239 | best = node.integer;
240 | }
241 | from += 1;
242 | }
243 | return best;
244 | }
245 |
246 | public boolean postMortem(PostMortem pm) {
247 | boolean result = true;
248 | TrieKeep that = (TrieKeep) pm;
249 | if (this.length != that.length) {
250 | JSONzip.log("\nLength " + this.length + " <> " + that.length);
251 | return false;
252 | }
253 | if (this.capacity != that.capacity) {
254 | JSONzip.log("\nCapacity " + this.capacity + " <> " +
255 | that.capacity);
256 | return false;
257 | }
258 | for (int i = 0; i < this.length; i += 1) {
259 | Kim thiskim = this.kim(i);
260 | Kim thatkim = that.kim(i);
261 | if (!thiskim.equals(thatkim)) {
262 | JSONzip.log("\n[" + i + "] " + thiskim + " <> " + thatkim);
263 | result = false;
264 | }
265 | }
266 | return result && this.root.postMortem(that.root);
267 | }
268 |
269 | public void registerMany(Kim kim) {
270 | int length = kim.length;
271 | int limit = this.capacity - this.length;
272 | if (limit > JSONzip.substringLimit) {
273 | limit = JSONzip.substringLimit;
274 | }
275 | int until = length - (JSONzip.minSubstringLength - 1);
276 | for (int from = 0; from < until; from += 1) {
277 | int len = length - from;
278 | if (len > JSONzip.maxSubstringLength) {
279 | len = JSONzip.maxSubstringLength;
280 | }
281 | len += from;
282 | Node node = this.root;
283 | for (int at = from; at < len; at += 1) {
284 | Node next = node.vet(kim.get(at));
285 | if (next.integer == none
286 | && at - from >= (JSONzip.minSubstringLength - 1)) {
287 | next.integer = this.length;
288 | this.uses[this.length] = 1;
289 | this.kims[this.length] = kim;
290 | this.froms[this.length] = from;
291 | this.thrus[this.length] = at + 1;
292 | if (JSONzip.probe) {
293 | try {
294 | JSONzip.log("<<" + this.length + " "
295 | + new Kim(kim, from, at + 1) + ">> ");
296 | } catch (Throwable ignore) {
297 | }
298 | }
299 | this.length += 1;
300 | limit -= 1;
301 | if (limit <= 0) {
302 | return;
303 | }
304 | }
305 | node = next;
306 | }
307 | }
308 | }
309 |
310 | public void registerOne(Kim kim) {
311 | int integer = registerOne(kim, 0, kim.length);
312 | if (integer != none) {
313 | this.kims[integer] = kim;
314 | }
315 | }
316 |
317 | public int registerOne(Kim kim, int from, int thru) {
318 | if (this.length < this.capacity) {
319 | Node node = this.root;
320 | for (int at = from; at < thru; at += 1) {
321 | node = node.vet(kim.get(at));
322 | }
323 | if (node.integer == none) {
324 | int integer = this.length;
325 | node.integer = integer;
326 | this.uses[integer] = 1;
327 | this.kims[integer] = kim;
328 | this.froms[integer] = from;
329 | this.thrus[integer] = thru;
330 | if (JSONzip.probe) {
331 | try {
332 | JSONzip.log("<<" + integer + " " + new Kim(kim, from, thru) + ">> ");
333 | } catch (Throwable ignore) {
334 | }
335 | }
336 | this.length += 1;
337 | return integer;
338 | }
339 | }
340 | return none;
341 | }
342 |
343 | /**
344 | * Reserve space in the keep, compacting if necessary. A keep may contain
345 | * at most -capacity- elements. The keep contents can be reduced by
346 | * deleting all elements with low use counts, rebuilding the trie with the
347 | * survivors.
348 | */
349 | public void reserve() {
350 | if (this.capacity - this.length < JSONzip.substringLimit) {
351 | int from = 0;
352 | int to = 0;
353 | this.root = new Node();
354 | while (from < this.capacity) {
355 | if (this.uses[from] > 1) {
356 | Kim kim = this.kims[from];
357 | int thru = this.thrus[from];
358 | Node node = this.root;
359 | for (int at = this.froms[from]; at < thru; at += 1) {
360 | Node next = node.vet(kim.get(at));
361 | node = next;
362 | }
363 | node.integer = to;
364 | this.uses[to] = age(this.uses[from]);
365 | this.froms[to] = this.froms[from];
366 | this.thrus[to] = thru;
367 | this.kims[to] = kim;
368 | to += 1;
369 | }
370 | from += 1;
371 | }
372 |
373 | // It is possible, but highly unlikely, that too many items survive.
374 | // If that happens, clear the keep.
375 |
376 | if (this.capacity - to < JSONzip.substringLimit) {
377 | this.power = 0;
378 | this.root = new Node();
379 | to = 0;
380 | }
381 | this.length = to;
382 | while (to < this.capacity) {
383 | this.uses[to] = 0;
384 | this.kims[to] = null;
385 | this.froms[to] = 0;
386 | this.thrus[to] = 0;
387 | to += 1;
388 |
389 | }
390 | }
391 | }
392 |
393 | public Object value(int integer) {
394 | return kim(integer);
395 | }
396 | }
397 |
--------------------------------------------------------------------------------
/CCNx/src/org/json/Kim.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 |
3 |
4 | /*
5 | Copyright (c) 2013 JSON.org
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | The Software shall be used for Good, not Evil.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 | */
27 |
28 | /**
29 | * Kim makes immutable eight bit Unicode strings. If the MSB of a byte is set,
30 | * then the next byte is a continuation byte. The last byte of a character
31 | * never has the MSB reset. Every byte that is not the last byte has the MSB
32 | * set. Kim stands for "Keep it minimal". A Unicode character is never longer
33 | * than 3 bytes. Every byte contributes 7 bits to the character. ASCII is
34 | * unmodified.
35 | *
36 | * Kim UTF-8
37 | * one byte U+007F U+007F
38 | * two bytes U+3FFF U+07FF
39 | * three bytes U+10FFF U+FFFF
40 | * four bytes U+10FFFF
41 | *
42 | * Characters in the ranges U+0800..U+3FFF and U+10000..U+10FFFF will be one
43 | * byte smaller when encoded in Kim compared to UTF-8.
44 | *
45 | * Kim is beneficial when using scripts such as Old South Arabian, Aramaic,
46 | * Avestan, Balinese, Batak, Bopomofo, Buginese, Buhid, Carian, Cherokee,
47 | * Coptic, Cyrillic, Deseret, Egyptian Hieroglyphs, Ethiopic, Georgian,
48 | * Glagolitic, Gothic, Hangul Jamo, Hanunoo, Hiragana, Kanbun, Kaithi,
49 | * Kannada, Katakana, Kharoshthi, Khmer, Lao, Lepcha, Limbu, Lycian, Lydian,
50 | * Malayalam, Mandaic, Meroitic, Miao, Mongolian, Myanmar, New Tai Lue,
51 | * Ol Chiki, Old Turkic, Oriya, Osmanya, Pahlavi, Parthian, Phags-Pa,
52 | * Phoenician, Samaritan, Sharada, Sinhala, Sora Sompeng, Tagalog, Tagbanwa,
53 | * Takri, Tai Le, Tai Tham, Tamil, Telugu, Thai, Tibetan, Tifinagh, UCAS.
54 | *
55 | * A kim object can be constructed from an ordinary UTF-16 string, or from a
56 | * byte array. A kim object can produce a UTF-16 string.
57 | *
58 | * As with UTF-8, it is possible to detect character boundaries within a byte
59 | * sequence. UTF-8 is one of the world's great inventions. While Kim is more
60 | * efficient, it is not clear that it is worth the expense of transition.
61 | *
62 | * @version 2013-04-18
63 | */
64 | public class Kim {
65 |
66 | /**
67 | * The byte array containing the kim's content.
68 | */
69 | private byte[] bytes = null;
70 |
71 | /**
72 | * The kim's hashcode, conforming to Java's hashcode conventions.
73 | */
74 | private int hashcode = 0;
75 |
76 | /**
77 | * The number of bytes in the kim. The number of bytes can be as much as
78 | * three times the number of characters.
79 | */
80 | public int length = 0;
81 |
82 | /**
83 | * The memoization of toString().
84 | */
85 | private String string = null;
86 |
87 | /**
88 | * Make a kim from a portion of a byte array.
89 | *
90 | * @param bytes
91 | * A byte array.
92 | * @param from
93 | * The index of the first byte.
94 | * @param thru
95 | * The index of the last byte plus one.
96 | */
97 | public Kim(byte[] bytes, int from, int thru) {
98 |
99 | // As the bytes are copied into the new kim, a hashcode is computed using a
100 | // modified Fletcher code.
101 |
102 | int sum = 1;
103 | int value;
104 | this.hashcode = 0;
105 | this.length = thru - from;
106 | if (this.length > 0) {
107 | this.bytes = new byte[this.length];
108 | for (int at = 0; at < this.length; at += 1) {
109 | value = (int) bytes[at + from] & 0xFF;
110 | sum += value;
111 | this.hashcode += sum;
112 | this.bytes[at] = (byte) value;
113 | }
114 | this.hashcode += sum << 16;
115 | }
116 | }
117 |
118 | /**
119 | * Make a kim from a byte array.
120 | *
121 | * @param bytes
122 | * The byte array.
123 | * @param length
124 | * The number of bytes.
125 | */
126 | public Kim(byte[] bytes, int length) {
127 | this(bytes, 0, length);
128 | }
129 |
130 | /**
131 | * Make a new kim from a substring of an existing kim. The coordinates are
132 | * in byte units, not character units.
133 | *
134 | * @param kim
135 | * The source of bytes.
136 | * @param from
137 | * The point at which to take bytes.
138 | * @param thru
139 | * The point at which to stop taking bytes.
140 | * @return the substring
141 | */
142 | public Kim(Kim kim, int from, int thru) {
143 | this(kim.bytes, from, thru);
144 | }
145 |
146 | /**
147 | * Make a kim from a string.
148 | *
149 | * @param string
150 | * The string.
151 | * @throws JSONException
152 | * if surrogate pair mismatch.
153 | */
154 | public Kim(String string) throws JSONException {
155 | int stringLength = string.length();
156 | this.hashcode = 0;
157 | this.length = 0;
158 |
159 | // First pass: Determine the length of the kim, allowing for the UTF-16
160 | // to UTF-32 conversion, and then the UTF-32 to Kim conversion.
161 |
162 | if (stringLength > 0) {
163 | for (int i = 0; i < stringLength; i += 1) {
164 | int c = string.charAt(i);
165 | if (c <= 0x7F) {
166 | this.length += 1;
167 | } else if (c <= 0x3FFF) {
168 | this.length += 2;
169 | } else {
170 | if (c >= 0xD800 && c <= 0xDFFF) {
171 | i += 1;
172 | int d = string.charAt(i);
173 | if (c > 0xDBFF || d < 0xDC00 || d > 0xDFFF) {
174 | throw new JSONException("Bad UTF16");
175 | }
176 | }
177 | this.length += 3;
178 | }
179 | }
180 |
181 | // Second pass: Allocate a byte array and fill that array with the conversion
182 | // while computing the hashcode.
183 |
184 | this.bytes = new byte[length];
185 | int at = 0;
186 | int b;
187 | int sum = 1;
188 | for (int i = 0; i < stringLength; i += 1) {
189 | int character = string.charAt(i);
190 | if (character <= 0x7F) {
191 | bytes[at] = (byte) character;
192 | sum += character;
193 | this.hashcode += sum;
194 | at += 1;
195 | } else if (character <= 0x3FFF) {
196 | b = 0x80 | (character >>> 7);
197 | bytes[at] = (byte) b;
198 | sum += b;
199 | this.hashcode += sum;
200 | at += 1;
201 | b = character & 0x7F;
202 | bytes[at] = (byte) b;
203 | sum += b;
204 | this.hashcode += sum;
205 | at += 1;
206 | } else {
207 | if (character >= 0xD800 && character <= 0xDBFF) {
208 | i += 1;
209 | character = (((character & 0x3FF) << 10) | (string
210 | .charAt(i) & 0x3FF)) + 65536;
211 | }
212 | b = 0x80 | (character >>> 14);
213 | bytes[at] = (byte) b;
214 | sum += b;
215 | this.hashcode += sum;
216 | at += 1;
217 | b = 0x80 | ((character >>> 7) & 0xFF);
218 | bytes[at] = (byte) b;
219 | sum += b;
220 | this.hashcode += sum;
221 | at += 1;
222 | b = character & 0x7F;
223 | bytes[at] = (byte) b;
224 | sum += b;
225 | this.hashcode += sum;
226 | at += 1;
227 | }
228 | }
229 | this.hashcode += sum << 16;
230 | }
231 | }
232 |
233 | /**
234 | * Returns the character at the specified index. The index refers to byte
235 | * values and ranges from 0 to length - 1. The index of the next character
236 | * is at index + Kim.characterSize(kim.characterAt(index)).
237 | *
238 | * @param at
239 | * the index of the char value. The first character is at 0.
240 | * @returns a Unicode character between 0 and 0x10FFFF.
241 | * @throws JSONException
242 | * if at does not point to a valid character.
243 | */
244 | public int characterAt(int at) throws JSONException {
245 | int c = get(at);
246 | if ((c & 0x80) == 0) {
247 | return c;
248 | }
249 | int character;
250 | int c1 = get(at + 1);
251 | if ((c1 & 0x80) == 0) {
252 | character = ((c & 0x7F) << 7) | c1;
253 | if (character > 0x7F) {
254 | return character;
255 | }
256 | } else {
257 | int c2 = get(at + 2);
258 | character = ((c & 0x7F) << 14) | ((c1 & 0x7F) << 7) | c2;
259 | if ((c2 & 0x80) == 0 && character > 0x3FFF && character <= 0x10FFFF
260 | && (character < 0xD800 || character > 0xDFFF)) {
261 | return character;
262 | }
263 | }
264 | throw new JSONException("Bad character at " + at);
265 | }
266 |
267 | /**
268 | * Returns the number of bytes needed to contain the character in Kim
269 | * format.
270 | *
271 | * @param character
272 | * a Unicode character between 0 and 0x10FFFF.
273 | * @return 1, 2, or 3
274 | * @throws JSONException
275 | * if the character is not representable in a kim.
276 | */
277 | public static int characterSize(int character) throws JSONException {
278 | if (character < 0 || character > 0x10FFFF) {
279 | throw new JSONException("Bad character " + character);
280 | }
281 | return character <= 0x7F ? 1 : character <= 0x3FFF ? 2 : 3;
282 | }
283 |
284 | /**
285 | * Copy the contents of this kim to a byte array.
286 | *
287 | * @param bytes
288 | * A byte array of sufficient size.
289 | * @param at
290 | * The position within the byte array to take the byes.
291 | * @return The position immediately after the copy.
292 | */
293 | public int copy(byte[] bytes, int at) {
294 | System.arraycopy(this.bytes, 0, bytes, at, this.length);
295 | return at + this.length;
296 | }
297 |
298 | /**
299 | * Two kim objects containing exactly the same bytes in the same order are
300 | * equal to each other.
301 | *
302 | * @param obj
303 | * the other kim with which to compare.
304 | * @returns true if this and obj are both kim objects containing identical
305 | * byte sequences.
306 | */
307 | public boolean equals(Object obj) {
308 | if (!(obj instanceof Kim)) {
309 | return false;
310 | }
311 | Kim that = (Kim) obj;
312 | if (this == that) {
313 | return true;
314 | }
315 | if (this.hashcode != that.hashcode) {
316 | return false;
317 | }
318 | return java.util.Arrays.equals(this.bytes, that.bytes);
319 | }
320 |
321 | /**
322 | * Get a byte from a kim.
323 | * @param at
324 | * The position of the byte. The first byte is at 0.
325 | * @return The byte.
326 | * @throws JSONException
327 | * if there is no byte at that position.
328 | */
329 | public int get(int at) throws JSONException {
330 | if (at < 0 || at > this.length) {
331 | throw new JSONException("Bad character at " + at);
332 | }
333 | return ((int) this.bytes[at]) & 0xFF;
334 | }
335 |
336 | /**
337 | * Returns a hash code value for the kim.
338 | */
339 | public int hashCode() {
340 | return this.hashcode;
341 | }
342 |
343 | /**
344 | * Produce a UTF-16 String from this kim. The number of codepoints in the
345 | * string will not be greater than the number of bytes in the kim, although
346 | * it could be less.
347 | *
348 | * @return The string. A kim memoizes its string representation.
349 | * @throws JSONException
350 | * if the kim is not valid.
351 | */
352 | public String toString() throws JSONException {
353 | if (this.string == null) {
354 | int c;
355 | int length = 0;
356 | char chars[] = new char[this.length];
357 | for (int at = 0; at < this.length; at += characterSize(c)) {
358 | c = this.characterAt(at);
359 | if (c < 0x10000) {
360 | chars[length] = (char) c;
361 | length += 1;
362 | } else {
363 | chars[length] = (char) (0xD800 | ((c - 0x10000) >>> 10));
364 | length += 1;
365 | chars[length] = (char) (0xDC00 | (c & 0x03FF));
366 | length += 1;
367 | }
368 | }
369 | this.string = new String(chars, 0, length);
370 | }
371 | return this.string;
372 | }
373 | }
374 |
--------------------------------------------------------------------------------
/POX/forwarding.py:
--------------------------------------------------------------------------------
1 | # #Copyright (C) 2015, Delft University of Technology, Faculty of Electrical Engineering, Mathematics and Computer Science, Network Architectures and Services, Niels van Adrichem
2 | #
3 | # This file is part of NDNFlow.
4 | #
5 | # NDNFlow is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # NDNFlow is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with NDNFlow. If not, see " (double quote) or
247 | * ' (single quote).
248 | * @return A String.
249 | * @throws JSONException Unterminated string.
250 | */
251 | public String nextString(char quote) throws JSONException {
252 | char c;
253 | StringBuffer sb = new StringBuffer();
254 | for (;;) {
255 | c = this.next();
256 | switch (c) {
257 | case 0:
258 | case '\n':
259 | case '\r':
260 | throw this.syntaxError("Unterminated string");
261 | case '\\':
262 | c = this.next();
263 | switch (c) {
264 | case 'b':
265 | sb.append('\b');
266 | break;
267 | case 't':
268 | sb.append('\t');
269 | break;
270 | case 'n':
271 | sb.append('\n');
272 | break;
273 | case 'f':
274 | sb.append('\f');
275 | break;
276 | case 'r':
277 | sb.append('\r');
278 | break;
279 | case 'u':
280 | sb.append((char)Integer.parseInt(this.next(4), 16));
281 | break;
282 | case '"':
283 | case '\'':
284 | case '\\':
285 | case '/':
286 | sb.append(c);
287 | break;
288 | default:
289 | throw this.syntaxError("Illegal escape.");
290 | }
291 | break;
292 | default:
293 | if (c == quote) {
294 | return sb.toString();
295 | }
296 | sb.append(c);
297 | }
298 | }
299 | }
300 |
301 |
302 | /**
303 | * Get the text up but not including the specified character or the
304 | * end of line, whichever comes first.
305 | * @param delimiter A delimiter character.
306 | * @return A string.
307 | */
308 | public String nextTo(char delimiter) throws JSONException {
309 | StringBuffer sb = new StringBuffer();
310 | for (;;) {
311 | char c = this.next();
312 | if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
313 | if (c != 0) {
314 | this.back();
315 | }
316 | return sb.toString().trim();
317 | }
318 | sb.append(c);
319 | }
320 | }
321 |
322 |
323 | /**
324 | * Get the text up but not including one of the specified delimiter
325 | * characters or the end of line, whichever comes first.
326 | * @param delimiters A set of delimiter characters.
327 | * @return A string, trimmed.
328 | */
329 | public String nextTo(String delimiters) throws JSONException {
330 | char c;
331 | StringBuffer sb = new StringBuffer();
332 | for (;;) {
333 | c = this.next();
334 | if (delimiters.indexOf(c) >= 0 || c == 0 ||
335 | c == '\n' || c == '\r') {
336 | if (c != 0) {
337 | this.back();
338 | }
339 | return sb.toString().trim();
340 | }
341 | sb.append(c);
342 | }
343 | }
344 |
345 |
346 | /**
347 | * Get the next value. The value can be a Boolean, Double, Integer,
348 | * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
349 | * @throws JSONException If syntax error.
350 | *
351 | * @return An object.
352 | */
353 | public Object nextValue() throws JSONException {
354 | char c = this.nextClean();
355 | String string;
356 |
357 | switch (c) {
358 | case '"':
359 | case '\'':
360 | return this.nextString(c);
361 | case '{':
362 | this.back();
363 | return new JSONObject(this);
364 | case '[':
365 | this.back();
366 | return new JSONArray(this);
367 | }
368 |
369 | /*
370 | * Handle unquoted text. This could be the values true, false, or
371 | * null, or it can be a number. An implementation (such as this one)
372 | * is allowed to also accept non-standard forms.
373 | *
374 | * Accumulate characters until we reach the end of the text or a
375 | * formatting character.
376 | */
377 |
378 | StringBuffer sb = new StringBuffer();
379 | while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
380 | sb.append(c);
381 | c = this.next();
382 | }
383 | this.back();
384 |
385 | string = sb.toString().trim();
386 | if ("".equals(string)) {
387 | throw this.syntaxError("Missing value");
388 | }
389 | return JSONObject.stringToValue(string);
390 | }
391 |
392 |
393 | /**
394 | * Skip characters until the next character is the requested character.
395 | * If the requested character is not found, no characters are skipped.
396 | * @param to A character to skip to.
397 | * @return The requested character, or zero if the requested character
398 | * is not found.
399 | */
400 | public char skipTo(char to) throws JSONException {
401 | char c;
402 | try {
403 | long startIndex = this.index;
404 | long startCharacter = this.character;
405 | long startLine = this.line;
406 | this.reader.mark(1000000);
407 | do {
408 | c = this.next();
409 | if (c == 0) {
410 | this.reader.reset();
411 | this.index = startIndex;
412 | this.character = startCharacter;
413 | this.line = startLine;
414 | return c;
415 | }
416 | } while (c != to);
417 | } catch (IOException exc) {
418 | throw new JSONException(exc);
419 | }
420 |
421 | this.back();
422 | return c;
423 | }
424 |
425 |
426 | /**
427 | * Make a JSONException to signal a syntax error.
428 | *
429 | * @param message The error message.
430 | * @return A JSONException object, suitable for throwing
431 | */
432 | public JSONException syntaxError(String message) {
433 | return new JSONException(message + this.toString());
434 | }
435 |
436 |
437 | /**
438 | * Make a printable string of this JSONTokener.
439 | *
440 | * @return " at {index} [character {character} line {line}]"
441 | */
442 | public String toString() {
443 | return " at " + this.index + " [character " + this.character + " line " +
444 | this.line + "]";
445 | }
446 | }
447 |
--------------------------------------------------------------------------------