plist 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010-2011- Nathan Rajlich
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
package/lib/plist.js CHANGED
@@ -1,177 +1,214 @@
1
- var sax = require('sax');
2
- var fs = require('fs');
3
- var util = require('util');
1
+ ;(function (exports, sax) {
2
+ //Checks if running in a non-browser environment
3
+ var inNode = typeof window === 'undefined' ? true : false;
4
4
 
5
- function Parser() {
5
+ function Parser() {
6
6
  sax.SAXParser.call(this, false, { lowercasetags: true, trim: false });
7
- }
7
+ }
8
8
 
9
- util.inherits(Parser, sax.SAXParser);
9
+ var inherits = null;
10
+ if (inNode) {
11
+ var fs = require('fs');
12
+ inherits = require('util').inherits; //use node provided function
13
+ } else { //use in browser
14
+ if ("create" in Object) {
15
+ inherits = function(ctor, superCtor) {
16
+ ctor.super_ = superCtor;
17
+ ctor.prototype = Object.create(superCtor.prototype, {
18
+ constructor: {
19
+ value: ctor,
20
+ enumerable: false,
21
+ writable: true,
22
+ configurable: true
23
+ }
24
+ });
25
+ };
26
+ } else {
27
+ var klass = function() {};
28
+ inherits = function(ctor, superCtor) {
29
+ klass.prototype = superCtor.prototype;
30
+ ctor.prototype = new klass;
31
+ ctor.prototype['constructor'] = ctor;
32
+ }
33
+ }
34
+ }
35
+ inherits(Parser, sax.SAXParser); //inherit from sax (browser-style or node-style)
10
36
 
11
- Parser.prototype.getInteger = function (string) {
37
+ Parser.prototype.getInteger = function (string) {
12
38
  this.value = parseInt(string, 10);
13
- }
14
- Parser.prototype.getString = function (string) {
39
+ }
40
+ Parser.prototype.getReal = function (string) {
41
+ this.value = parseFloat(string);
42
+ }
43
+ Parser.prototype.getString = function (string) {
15
44
  this.value += string;
16
- }
17
- Parser.prototype.getData = function(string) {
45
+ }
46
+ Parser.prototype.getData = function(string) {
18
47
  // todo: parse base64 encoded data
19
48
  this.value += string;
20
- }
21
- Parser.prototype.getDate = function (string) {
49
+ }
50
+ Parser.prototype.getDate = function (string) {
22
51
  this.value = new Date(string);
23
- }
52
+ }
24
53
 
25
- Parser.prototype.addToDict = function (value) {
54
+ Parser.prototype.addToDict = function (value) {
26
55
  this.dict[this.key] = value;
27
- }
28
- Parser.prototype.addToArray = function (value) {
56
+ }
57
+ Parser.prototype.addToArray = function (value) {
29
58
  this.array.push(value);
30
- }
59
+ }
31
60
 
32
- Parser.prototype.onopentag = function (tag) {
61
+ Parser.prototype.onopentag = function (tag) {
33
62
  switch (tag.name) {
34
- case 'dict':
63
+ case 'dict':
35
64
  this.stack.push(this.context);
36
65
  this.context = {
37
- value: function() {
38
- return this.dict;
39
- },
40
- dict: {},
41
- setKey: function(key) {
42
- this.key = key;
43
- },
44
- setValue: function(value) {
45
- this.dict[this.key] = value;
46
- }
66
+ value: function() {
67
+ return this.dict;
68
+ },
69
+ dict: {},
70
+ setKey: function(key) {
71
+ this.key = key;
72
+ },
73
+ setValue: function(value) {
74
+ this.dict[this.key] = value;
75
+ }
47
76
  }
48
77
  break;
49
- case 'plist':
50
- case 'array':
78
+ case 'plist':
79
+ case 'array':
51
80
  this.stack.push(this.context);
52
81
  this.context = {
53
- value: function() {
54
- return this.array;
55
- },
56
- array: [],
57
- setKey: function(key) {
58
- console.log('unexpected <key> element in array');
59
- },
60
- setValue: function(value) {
61
- this.array.push(value);
62
- }
82
+ value: function() {
83
+ return this.array;
84
+ },
85
+ array: [],
86
+ setKey: function(key) {
87
+ console.log('unexpected <key> element in array');
88
+ },
89
+ setValue: function(value) {
90
+ this.array.push(value);
91
+ }
63
92
  }
64
93
  break;
65
- case 'key':
94
+ case 'key':
66
95
  this.ontext = function (text) {
67
- this.context.setKey(text);
96
+ this.context.setKey(text);
68
97
  }
69
98
  break;
70
- case 'integer':
99
+ case 'integer':
71
100
  this.ontext = this.getInteger;
72
101
  break;
73
- case 'string':
102
+ case 'real':
103
+ this.ontext = this.getReal;
104
+ break;
105
+ case 'string':
74
106
  this.value = '';
75
107
  this.ontext = this.getString;
76
108
  this.oncdata = this.getString;
77
109
  break;
78
- case 'data':
110
+ case 'data':
79
111
  this.value = '';
80
112
  this.ontext = this.getData;
81
113
  this.oncdata = this.getData;
82
114
  break;
83
- case 'true':
115
+ case 'true':
84
116
  this.value = true;
85
117
  break;
86
- case 'false':
118
+ case 'false':
87
119
  this.value = false;
88
120
  break;
89
- case 'date':
121
+ case 'date':
90
122
  this.ontext = this.getDate;
91
123
  break;
92
- default:
124
+ default:
93
125
  console.log('ignored tag', tag.name);
94
126
  break;
95
127
  }
96
- }
97
- Parser.prototype.onclosetag = function (tag) {
128
+ }
129
+ Parser.prototype.onclosetag = function (tag) {
98
130
  var value;
99
131
  switch (tag) {
100
- case 'dict':
101
- case 'array':
102
- case 'plist':
132
+ case 'dict':
133
+ case 'array':
134
+ case 'plist':
103
135
  var value = this.context.value();
104
136
  this.context = this.stack.pop();
105
137
  this.context.setValue(value);
106
138
  break;
107
- case 'true':
108
- case 'false':
109
- case 'string':
110
- case 'integer':
111
- case 'date':
112
- case 'data':
139
+ case 'true':
140
+ case 'false':
141
+ case 'string':
142
+ case 'integer':
143
+ case 'real':
144
+ case 'date':
145
+ case 'data':
113
146
  this.context.setValue(this.value);
114
147
  break;
115
- case 'key':
148
+ case 'key':
116
149
  break;
117
- default:
150
+ default:
118
151
  console.log('closing', tag, 'tag ignored');
119
152
  }
120
153
  this.oncdata = this.ontext = this.checkWhitespace;
121
- }
122
- Parser.prototype.checkWhitespace = function (data) {
154
+ }
155
+ Parser.prototype.checkWhitespace = function (data) {
123
156
  if (!data.match(/^[ \t\r\n]*$/)) {
124
- console.log('unexpected non-whitespace data', data);
157
+ console.log('unexpected non-whitespace data', data);
125
158
  }
126
- }
127
- Parser.prototype.oncomment = function (comment) {
128
- }
129
- Parser.prototype.onerror = function (error) {
159
+ }
160
+ Parser.prototype.oncomment = function (comment) {
161
+ }
162
+ Parser.prototype.onerror = function (error) {
130
163
  console.log('sax parser error:', error);
131
164
  throw error;
132
- }
165
+ }
133
166
 
134
- Parser.prototype.parseFile = function (xmlfile, callback) {
167
+ if (inNode) Parser.prototype.parseFile = function (xmlfile, callback) { //browsers aren't capable of opening files, instead use AJAX
135
168
  var parser = this;
136
169
  parser.stack = [ ];
137
170
  parser.context = {
138
- callback: callback,
139
- value: function() {},
140
- setKey: function(key) {},
141
- setValue: function(value) {
142
- callback(null, value);
143
- },
171
+ callback: callback,
172
+ value: function() {},
173
+ setKey: function(key) {},
174
+ setValue: function(value) {
175
+ callback(null, value);
176
+ },
144
177
  }
145
178
  var rs = fs.createReadStream(xmlfile, {
146
179
  encoding: 'utf8'
147
180
  });
148
181
  rs.on('data', function(data) { parser.write(data); });
149
182
  rs.on('end', function() { parser.close(); });
150
- }
183
+ }
151
184
 
152
- Parser.prototype.parseString = function (xml, callback) {
185
+ Parser.prototype.parseString = function (xml, callback) {
153
186
  var parser = this;
154
187
  parser.stack = [ ];
155
188
  parser.context = {
156
- callback: callback,
157
- value: function() {},
158
- setKey: function(key) {},
159
- setValue: function(value) {
160
- this.callback(null, value);
161
- },
189
+ callback: callback,
190
+ value: function() {},
191
+ setKey: function(key) {},
192
+ setValue: function(value) {
193
+ this.callback(null, value);
194
+ },
162
195
  };
163
196
  parser.write(xml);
164
197
  parser.close();
165
- }
198
+ }
166
199
 
167
- exports.Parser = Parser;
200
+ exports.Parser = Parser;
168
201
 
169
- exports.parseString = function (xml, callback) {
202
+ exports.parseString = function (xml, callback) {
170
203
  var parser = new Parser();
171
204
  parser.parseString(xml, callback);
172
- }
205
+ }
173
206
 
174
- exports.parseFile = function (filename, callback) {
207
+ if (inNode) exports.parseFile = function (filename, callback) { //Do not expose no created method
175
208
  var parser = new Parser();
176
209
  parser.parseFile(filename, callback);
177
- }
210
+ }
211
+ })(typeof exports === 'undefined' ? plist = {} : exports, typeof window === "undefined" ? require('sax') : sax)
212
+ //the above line checks for exports (defined in node) and uses it, or creates a global variable and exports to that.
213
+ //also, if in node, require sax node-style, in browser the developer must use a <script> tag to import sax
214
+ // TODO: Implement detection of 'sax' in the Browser environment
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "plist",
3
3
  "description": "Mac OS X Plist parser for NodeJS. Convert a Plist file or string into a native JS object",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "author": "Nathan Rajlich <nathan@tootallnate.net>",
6
6
  "contributors": [ "Hans Huebner <hans.huebner@gmail.com>" ],
7
7
  "repository": {
@@ -0,0 +1,38 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>duration</key>
6
+ <real>5555.0495000000001</real>
7
+ <key>loadedTimeRanges</key>
8
+ <array>
9
+ <dict>
10
+ <key>duration</key>
11
+ <real>5555.0495000000001</real>
12
+ <key>start</key>
13
+ <real>0.0</real>
14
+ </dict>
15
+ </array>
16
+ <key>playbackBufferEmpty</key>
17
+ <true/>
18
+ <key>playbackBufferFull</key>
19
+ <false/>
20
+ <key>playbackLikelyToKeepUp</key>
21
+ <true/>
22
+ <key>position</key>
23
+ <real>4.6269989039999997</real>
24
+ <key>rate</key>
25
+ <real>1</real>
26
+ <key>readyToPlay</key>
27
+ <true/>
28
+ <key>seekableTimeRanges</key>
29
+ <array>
30
+ <dict>
31
+ <key>duration</key>
32
+ <real>5555.0495000000001</real>
33
+ <key>start</key>
34
+ <real>0.0</real>
35
+ </dict>
36
+ </array>
37
+ </dict>
38
+ </plist>
package/tests/test.js CHANGED
@@ -37,3 +37,22 @@ plist.parseFile(file2, function(err, dicts) {
37
37
  assert.equal(dict['PopupMenu'][2]['Key'], "\n \n #import &lt;Cocoa/Cocoa.h&gt;\n\n#import &lt;MacRuby/MacRuby.h&gt;\n\nint main(int argc, char *argv[])\n{\n return macruby_main(\"rb_main.rb\", argc, argv);\n}\n\n");
38
38
 
39
39
  });
40
+
41
+
42
+ // Third test...
43
+ var file3 = path.join(__dirname, "airplay.xml");
44
+ var startTime3 = new Date();
45
+
46
+ plist.parseFile(file3, function(err, dicts) {
47
+ if (err) {
48
+ throw err;
49
+ }
50
+
51
+ var endTime = new Date();
52
+ console.log('Parsed "' + file3 + '" in ' + (endTime - startTime3) + 'ms');
53
+
54
+ var dict = dicts[0];
55
+ assert.equal(dict['duration'], 5555.0495000000001);
56
+ assert.equal(dict['position'], 4.6269989039999997);
57
+
58
+ });