blob: 1d28a815979436e72d4a6464f9de32478626537c [file] [log] [blame]
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07001/*
2 * @author: ucla-cs
Jeff Thompson745026e2012-10-13 12:49:20 -07003 * See COPYING for copyright and distribution information.
Jeff Thompson4e8b7702012-10-21 23:42:27 -07004 * This class represents a Name as an array of components where each is a byte array.
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07005 */
6
7
Jeff Thompsonf3bd3592012-09-29 23:25:30 -07008var Name = function Name(_components){
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07009
Jeff Thompson86aea882012-09-29 17:32:48 -070010 if( typeof _components == 'string') {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070011
Jeff Thompson86aea882012-09-29 17:32:48 -070012 if(LOG>3)console.log('Content Name String '+_components);
Jeff Thompsonf3bd3592012-09-29 23:25:30 -070013 this.components = Name.makeBlob(Name.createNameArray(_components));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070014 }
Jeff Thompson86aea882012-09-29 17:32:48 -070015 else if(typeof _components === 'object' && _components instanceof Array ){
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070016
Jeff Thompson86aea882012-09-29 17:32:48 -070017 if(LOG>4)console.log('Content Name Array '+_components);
Jeff Thompsonf3bd3592012-09-29 23:25:30 -070018 this.components = Name.makeBlob(_components);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070019
20 }
Jeff Thompson86aea882012-09-29 17:32:48 -070021 else if(_components==null){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070022 this.components =[];
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070023 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070024 else{
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070025
26 if(LOG>1)console.log("NO CONTENT NAME GIVEN");
27
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070028 }
29};
30
Jeff Thompson0d3f2032012-11-04 12:55:27 -080031Name.prototype.getName = function() {
32 return this.to_uri();
Meki Cherkaoui8f173612012-06-06 01:05:40 -070033};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070034
Jeff Thompsonf3bd3592012-09-29 23:25:30 -070035Name.makeBlob=function(name){
Meki Cherkaoui8f173612012-06-06 01:05:40 -070036
37 var blobArrays = new Array(name.length);
38
39 for(var i=0;i<name.length;i++){
40 if(typeof name[i] == 'string')
41 blobArrays[i]= DataUtils.toNumbersFromString( name[i] );
42 else if(typeof name[i] == 'object')
43 blobArrays[i]= name[i] ;
44 else
45 if(LOG>4)console.log('NAME COMPONENT INVALID');
46 }
47
48 return blobArrays;
49};
50
Jeff Thompson0d3f2032012-11-04 12:55:27 -080051Name.createNameArray = function(name) {
52 name = name.trim();
53 if (name.length <= 0)
54 return [];
55
56 var iColon = name.indexOf(':');
57 if (iColon >= 0) {
58 // Make sure the colon came before a '/'.
59 var iFirstSlash = name.indexOf('/');
60 if (iFirstSlash < 0 || iColon < iFirstSlash)
61 // Omit the leading protocol such as ccnx:
62 name = name.substr(iColon + 1, name.length - iColon - 1).trim();
Jeff Thompson4e8b7702012-10-21 23:42:27 -070063 }
Jeff Thompson0d3f2032012-11-04 12:55:27 -080064
65 if (name[0] == '/') {
66 if (name.length >= 2 && name[1] == '/') {
67 // Strip the authority following "//".
68 var iAfterAuthority = name.indexOf('/', 2);
69 if (iAfterAuthority < 0)
70 // Unusual case: there was only an authority.
71 return [];
72 else
73 name = name.substr(iAfterAuthority + 1, name.length - iAfterAuthority - 1).trim();
74 }
75 else
76 name = name.substr(1, name.length - 1).trim();
77 }
78
79 var array = name.split('/');
Jeff Thompson9b411002012-10-21 17:35:16 -070080
81 // Unescape the components.
Jeff Thompson4e8b7702012-10-21 23:42:27 -070082 for (var i = 0; i < array.length; ++i) {
Jeff Thompson0d3f2032012-11-04 12:55:27 -080083 var component = unescape(array[i].trim());
Jeff Thompson4e8b7702012-10-21 23:42:27 -070084
85 if (component.match(/[^.]/) == null) {
Jeff Thompson0d3f2032012-11-04 12:55:27 -080086 // Special case for component of only periods.
87 if (component.length <= 2) {
88 // Zero, one or two periods is illegal. Ignore this componenent to be
89 // consistent with the C implmentation.
90 // This also gets rid of a trailing '/'.
91 array = array.slice(0, i).concat(array.slice(i + 1, array.length));
92 --i;
93 }
Jeff Thompson4e8b7702012-10-21 23:42:27 -070094 else
Jeff Thompson0d3f2032012-11-04 12:55:27 -080095 // Remove 3 periods.
Jeff Thompson4e8b7702012-10-21 23:42:27 -070096 array[i] = component.substr(3, component.length - 3);
97 }
98 else
99 array[i] = component;
100 }
Jeff Thompson9b411002012-10-21 17:35:16 -0700101
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700102 return array;
103}
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700104
105
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700106Name.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700107 decoder.readStartElement(this.getElementLabel());
108
109
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700110 this.components = new Array(); //new ArrayList<byte []>();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700111
112 while (decoder.peekStartElement(CCNProtocolDTags.Component)) {
113 this.add(decoder.readBinaryElement(CCNProtocolDTags.Component));
114 }
115
116 decoder.readEndElement();
117};
118
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700119Name.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700120
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700121 if( this.components ==null )
Jeff Thompson34a2ec02012-09-29 21:47:05 -0700122 throw new Error("CANNOT ENCODE EMPTY CONTENT NAME");
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700123
124 encoder.writeStartElement(this.getElementLabel());
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700125 var count = this.components.length;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700126 for (var i=0; i < count; i++) {
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700127 encoder.writeElement(CCNProtocolDTags.Component, this.components[i]);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700128 }
129 encoder.writeEndElement();
130};
131
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700132Name.prototype.getElementLabel = function(){
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700133 return CCNProtocolDTags.Name;
134};
135
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700136Name.prototype.add = function(param){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700137 return this.components.push(param);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700138};
139
Jeff Thompson4e8b7702012-10-21 23:42:27 -0700140// Return the escaped name string according to "CCNx URI Scheme". Does not include "ccnx:".
141Name.prototype.to_uri = function() {
142 var result = "";
143
144 for(var i = 0; i < this.components.length; ++i)
145 result += "/"+ Name.toEscapedString(this.components[i]);
146
147 return result;
148};
149
150/**
151 * Return component as an escaped string according to "CCNx URI Scheme".
152 * We can't use encodeURIComponent because that doesn't encode all the characters we want to.
153 */
154Name.toEscapedString = function(component) {
155 var result = "";
156 var gotNonDot = false;
157 for (var i = 0; i < component.length; ++i) {
158 if (component[i] != 0x2e) {
159 gotNonDot = true;
160 break;
161 }
162 }
163 if (!gotNonDot) {
164 // Special case for component of zero or more periods. Add 3 periods.
165 result = "...";
166 for (var i = 0; i < component.length; ++i)
167 result += ".";
168 }
169 else {
170 for (var i = 0; i < component.length; ++i) {
171 var value = component[i];
172 // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
173 if (value >= 0x30 && value <= 0x39 || value >= 0x41 && value <= 0x5a ||
174 value >= 0x61 && value <= 0x7a || value == 0x2b || value == 0x2d ||
175 value == 0x2e || value == 0x5f)
176 result += String.fromCharCode(value);
177 else
178 result += "%" + (value < 16 ? "0" : "") + value.toString(16).toUpperCase();
179 }
180 }
181 return result;
182};