summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/CSVProcessor.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/CSVProcessor.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/CSVProcessor.js344
1 files changed, 344 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/CSVProcessor.js b/frontend/delta/js/Clipperz/CSVProcessor.js
new file mode 100644
index 0000000..1288ed7
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/CSVProcessor.js
@@ -0,0 +1,344 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25
26
27Clipperz.CSVProcessor = function(args) {
28 args = args || {};
29
30 // this._status = undefined;
31 // this._error_input= undefined;
32 // this._string = undefined;
33 // this._fields = undefined;
34
35 this._quoteChar = args['quoteChar'] ||"\042";
36 this._eol = args['eol'] ||"";
37 this._escapeChar = args['escapeChar'] ||"\042";
38 this._separatorChar = args['separatorChar'] ||",";
39 this._binary = args['binary'] ||false;
40 this._alwaysQuote = args['alwaysQuote'] ||false;
41
42 return this;
43}
44
45//=============================================================================
46
47Clipperz.CSVProcessor.prototype = MochiKit.Base.update(null, {
48
49 //-------------------------------------------------------------------------
50
51 'quoteChar': function() {
52 return this._quoteChar;
53 },
54
55 //-------------------------------------------------------------------------
56
57 'eol': function() {
58 return this._eol;
59 },
60
61 //-------------------------------------------------------------------------
62
63 'escapeChar': function() {
64 return this._escapeChar;
65 },
66
67 //-------------------------------------------------------------------------
68
69 'separatorChar': function() {
70 return this._separatorChar;
71 },
72
73 'setSeparatorChar': function(aValue) {
74 this._separatorChar = aValue;
75 },
76
77 //-------------------------------------------------------------------------
78
79 'binary': function() {
80 return this._binary;
81 },
82
83 //-------------------------------------------------------------------------
84
85 'alwaysQuote': function() {
86 return this._alwaysQuote;
87 },
88
89 //-------------------------------------------------------------------------
90/*
91 'parse': function(aValue) {
92 var result;
93 var lines;
94 var parameter;
95
96//Clipperz.logDebug(">>> CSVProcessor.parse");
97 result = [];
98
99 lines = aValue.replace(/\r?\n/g, "\n").replace(/^\n* /g, "").replace(/\n$/g, "");;
100 parameter = {
101 line: lines
102 }
103
104 do {
105 var fields;
106
107 fields = this.parseLine(parameter);
108
109 if (fields != null) {
110 result.push(fields);
111 }
112
113 parameter.line = parameter.line.replace(/^\n* /g, "").replace(/\n$/g, "");
114
115//Clipperz.logDebug("line: '" + parameter.line + "'");
116 } while (parameter.line != "");
117//Clipperz.logDebug("--- CSVProcessor.parse - result: " + Clipperz.Base.serializeJSON(result));
118//Clipperz.logDebug("<<< CSVProcessor.parse");
119
120 return result;
121 },
122*/
123 //-------------------------------------------------------------------------
124
125 'deferredParse_core': function(aContext) {
126 var deferredResult;
127
128 if (aContext.line == "") {
129 deferredResult = MochiKit.Async.succeed(aContext.result);
130 } else {
131 var fields;
132
133 fields = this.parseLine(aContext);
134 if (fields != null) {
135 aContext.result.push(fields);
136 }
137
138 aContext.line = aContext.line.replace(/^\n*/g, "").replace(/\n$/g, "");
139
140 deferredResult = new Clipperz.Async.Deferred("CVSProcessor.deferredParse_core");
141 // deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'importProcessorProgressUpdate', {status:'processing', size:aContext.size, progress:(aContext.size - aContext.line.length)});
142 deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'importProcessorProgressUpdate', {status:'processing', size:aContext.size, progress:(aContext.size - aContext.line.length)});
143 deferredResult.addCallback(MochiKit.Async.wait, 0.2);
144 deferredResult.addMethod(this, 'deferredParse_core')
145 deferredResult.callback(aContext);
146 }
147
148 return deferredResult;
149 },
150
151 //.........................................................................
152
153 'deferredParse': function(aValue) {
154 var deferredResult;
155 var lines;
156 var context;
157
158 lines = aValue.replace(/\r?\n/g, "\n").replace(/^\n*/g, "").replace(/\n$/g, "");
159
160 context = {
161 line: lines,
162 size: lines.length,
163 result: []
164 }
165
166 deferredResult = new Clipperz.Async.Deferred("CSVProcessor.deferredParse");
167 deferredResult.addMethod(this, 'deferredParse_core');
168 deferredResult.callback(context);
169
170 return deferredResult;
171 },
172
173 //-------------------------------------------------------------------------
174
175 'parseLine': function(aParameter) {
176 var result;
177 var palatable;
178 var line;
179 var processedField;
180
181 result = [];
182
183 do {
184 processedField = this.parseField(aParameter);
185 if (processedField != null) {
186 result.push(processedField)
187 };
188 } while (processedField != null);
189
190 return result;
191 },
192
193 //-------------------------------------------------------------------------
194
195 'parseField': function(aParameter) {
196 var result;
197
198 var inQuotes;
199 var validRegExp;
200 var singleQuoteBeginRegexp;
201 var escapedQuoteBeginRegexp;
202 var singleQuoteCommaEndRegexp;
203 var singleQuoteNewLineEndRegexp;
204 var commaBeginRegexp;
205 var newlineRegexp;
206
207
208 singleQuoteBeginRegexp = new RegExp("^" + '\\' + this.quoteChar());
209 escapedQuoteBeginRegexp = new RegExp("^" + '\\' + this.escapeChar() + '\\' + this.quoteChar());
210 singleQuoteCommaEndRegexp= new RegExp("^" + '\\' + this.quoteChar() + '\\' + this.separatorChar());
211 singleQuoteNewLineEndRegexp= new RegExp("^" + '\\' + this.quoteChar() + "\n");
212 commaBeginRegexp = new RegExp("^" + '\\' + this.separatorChar());
213 newlineRegexp = new RegExp("^\n");
214
215 inQuotes = false;
216
217//Clipperz.logDebug("#################################### '" + aParameter.line + "'");
218 if (aParameter.line == "") {
219 if (aParameter.isThereAnEmptyFinalField == true) {
220 aParameter.isThereAnEmptyFinalField = false;
221 result = "";
222 } else {
223 result = null;
224 }
225 } else {
226 if (this.binary()) {
227 validRegexp = /^./;
228 // validRegexp = /^[^\\]/;
229 } else {
230 validRegexp = /^[\t\040-\176]/;
231 }
232
233 try {
234 var done;
235
236 done = false;
237 result = "";
238
239 while (!done) {
240 if (aParameter.line.length < 1) {
241//Clipperz.logDebug("---> 1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
242 if (inQuotes == true) {
243//Clipperz.logDebug("---> 1.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
244 throw new Error("CSV Parsing error; end of string, missing closing double-quote...");
245 } else {
246//Clipperz.logDebug("---> 1.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
247 done = true;
248 }
249 } else if (escapedQuoteBeginRegexp.test(aParameter.line)) {
250//Clipperz.logDebug("---> 2.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
251 result += this.quoteChar();
252 aParameter.line = aParameter.line.substr(2, aParameter.line.length - 1);
253//Clipperz.logDebug("<--- 2.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
254 } else if (singleQuoteBeginRegexp.test(aParameter.line)) {
255//Clipperz.logDebug("---> 3: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
256 if (inQuotes == true) {
257 if (aParameter.line.length == 1) {
258//Clipperz.logDebug("---> 3.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
259 aParameter.line = '';
260 done = true;
261 } else if (singleQuoteCommaEndRegexp.test(aParameter.line)) {
262//Clipperz.logDebug("---> 3.3: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
263 aParameter.line = aParameter.line.substr(2, aParameter.line.length - 1);
264 done = true;
265//Clipperz.logDebug("<--- 3.3: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
266 } else if (singleQuoteNewLineEndRegexp.test(aParameter.line)) {
267 aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
268 done = true;
269 } else {
270 throw new Error("CSV Parsing error; double-quote, followed by undesirable character (bad character sequence)... " + aParameter.line);
271 }
272 } else {
273//Clipperz.logDebug("---> 4: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
274 if (result == "") {
275//Clipperz.logDebug("---> 4.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
276 inQuotes = true;
277 aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
278//Clipperz.logDebug("<--- 4.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
279 } else {
280 throw new Error("CSV Parsing error; double-quote, outside of double-quotes (bad character sequence)...");
281 }
282 }
283 } else if (commaBeginRegexp.test(aParameter.line)) {
284//Clipperz.logDebug("---> 5: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
285 if (inQuotes) {
286//Clipperz.logDebug("---> 5.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
287 result += aParameter.line.substr(0 ,1);
288 aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
289//Clipperz.logDebug("<--- 5.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
290 } else {
291//Clipperz.logDebug("---> 5.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
292 aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
293 if (newlineRegexp.test(aParameter.line) || aParameter.line == "") {
294//Clipperz.logDebug("######");
295 aParameter.isThereAnEmptyFinalField = true;
296 };
297 done = true;
298//Clipperz.logDebug("<--- 5.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
299 }
300 } else if (validRegexp.test(aParameter.line)) {
301//Clipperz.logDebug("---> 6: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
302 result += aParameter.line.substr(0, 1);
303 aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
304//Clipperz.logDebug("<--- 6: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
305 } else if (newlineRegexp.test(aParameter.line)) {
306 if (inQuotes == true) {
307 result += aParameter.line.substr(0 ,1);
308 aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
309 } else {
310 if (result == "") {
311 if (aParameter.isThereAnEmptyFinalField == true) {
312 aParameter.isThereAnEmptyFinalField = false;
313 } else {
314 result = null;
315 }
316 }
317
318 done = true;
319 }
320 } else {
321 throw new Error("CSV Parsing error; an undesirable character... '" + aParameter.line.substr(0,1) + "'");
322 }
323 }
324 } catch(exception) {
325 Clipperz.logError(exception.message);
326 // result = null;
327 throw exception;
328 }
329 }
330
331//if (result != null) {
332 //Clipperz.logDebug("<=== result: '" + result.replace(/\n/g, "\\n") + "'");
333//} else {
334 //Clipperz.logDebug("<=== result: NULL");
335//}
336
337 return result;
338 },
339
340 //-------------------------------------------------------------------------
341 __syntaxFix__: "syntax fix"
342});
343
344