11cb0ef41Sopenharmony_ci// Copyright 2009 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 31cb0ef41Sopenharmony_ci// modification, are permitted provided that the following conditions are 41cb0ef41Sopenharmony_ci// met: 51cb0ef41Sopenharmony_ci// 61cb0ef41Sopenharmony_ci// * Redistributions of source code must retain the above copyright 71cb0ef41Sopenharmony_ci// notice, this list of conditions and the following disclaimer. 81cb0ef41Sopenharmony_ci// * Redistributions in binary form must reproduce the above 91cb0ef41Sopenharmony_ci// copyright notice, this list of conditions and the following 101cb0ef41Sopenharmony_ci// disclaimer in the documentation and/or other materials provided 111cb0ef41Sopenharmony_ci// with the distribution. 121cb0ef41Sopenharmony_ci// * Neither the name of Google Inc. nor the names of its 131cb0ef41Sopenharmony_ci// contributors may be used to endorse or promote products derived 141cb0ef41Sopenharmony_ci// from this software without specific prior written permission. 151cb0ef41Sopenharmony_ci// 161cb0ef41Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171cb0ef41Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181cb0ef41Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191cb0ef41Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201cb0ef41Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211cb0ef41Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221cb0ef41Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231cb0ef41Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241cb0ef41Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251cb0ef41Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261cb0ef41Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci/** 301cb0ef41Sopenharmony_ci * Creates a CSV lines parser. 311cb0ef41Sopenharmony_ci */ 321cb0ef41Sopenharmony_ciexport class CsvParser { 331cb0ef41Sopenharmony_ci /** 341cb0ef41Sopenharmony_ci * Converts \x00 and \u0000 escape sequences in the given string. 351cb0ef41Sopenharmony_ci * 361cb0ef41Sopenharmony_ci * @param {string} input field. 371cb0ef41Sopenharmony_ci **/ 381cb0ef41Sopenharmony_ci escapeField(string) { 391cb0ef41Sopenharmony_ci let nextPos = string.indexOf("\\"); 401cb0ef41Sopenharmony_ci if (nextPos === -1) return string; 411cb0ef41Sopenharmony_ci let result = [string.substring(0, nextPos)]; 421cb0ef41Sopenharmony_ci // Escape sequences of the form \x00 and \u0000; 431cb0ef41Sopenharmony_ci let pos = 0; 441cb0ef41Sopenharmony_ci while (nextPos !== -1) { 451cb0ef41Sopenharmony_ci const escapeIdentifier = string[nextPos + 1]; 461cb0ef41Sopenharmony_ci pos = nextPos + 2; 471cb0ef41Sopenharmony_ci if (escapeIdentifier === 'n') { 481cb0ef41Sopenharmony_ci result.push('\n'); 491cb0ef41Sopenharmony_ci nextPos = pos; 501cb0ef41Sopenharmony_ci } else if (escapeIdentifier === '\\') { 511cb0ef41Sopenharmony_ci result.push('\\'); 521cb0ef41Sopenharmony_ci nextPos = pos; 531cb0ef41Sopenharmony_ci } else { 541cb0ef41Sopenharmony_ci if (escapeIdentifier === 'x') { 551cb0ef41Sopenharmony_ci // \x00 ascii range escapes consume 2 chars. 561cb0ef41Sopenharmony_ci nextPos = pos + 2; 571cb0ef41Sopenharmony_ci } else { 581cb0ef41Sopenharmony_ci // \u0000 unicode range escapes consume 4 chars. 591cb0ef41Sopenharmony_ci nextPos = pos + 4; 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci // Convert the selected escape sequence to a single character. 621cb0ef41Sopenharmony_ci const escapeChars = string.substring(pos, nextPos); 631cb0ef41Sopenharmony_ci if (escapeChars === '2C') { 641cb0ef41Sopenharmony_ci result.push(','); 651cb0ef41Sopenharmony_ci } else { 661cb0ef41Sopenharmony_ci result.push(String.fromCharCode(parseInt(escapeChars, 16))); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Continue looking for the next escape sequence. 711cb0ef41Sopenharmony_ci pos = nextPos; 721cb0ef41Sopenharmony_ci nextPos = string.indexOf("\\", pos); 731cb0ef41Sopenharmony_ci // If there are no more escape sequences consume the rest of the string. 741cb0ef41Sopenharmony_ci if (nextPos === -1) { 751cb0ef41Sopenharmony_ci result.push(string.substr(pos)); 761cb0ef41Sopenharmony_ci break; 771cb0ef41Sopenharmony_ci } else if (pos !== nextPos) { 781cb0ef41Sopenharmony_ci result.push(string.substring(pos, nextPos)); 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci return result.join(''); 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci /** 851cb0ef41Sopenharmony_ci * Parses a line of CSV-encoded values. Returns an array of fields. 861cb0ef41Sopenharmony_ci * 871cb0ef41Sopenharmony_ci * @param {string} line Input line. 881cb0ef41Sopenharmony_ci */ 891cb0ef41Sopenharmony_ci parseLine(line) { 901cb0ef41Sopenharmony_ci let pos = 0; 911cb0ef41Sopenharmony_ci const endPos = line.length; 921cb0ef41Sopenharmony_ci const fields = []; 931cb0ef41Sopenharmony_ci if (endPos == 0) return fields; 941cb0ef41Sopenharmony_ci let nextPos = 0; 951cb0ef41Sopenharmony_ci while(nextPos !== -1) { 961cb0ef41Sopenharmony_ci nextPos = line.indexOf(',', pos); 971cb0ef41Sopenharmony_ci let field; 981cb0ef41Sopenharmony_ci if (nextPos === -1) { 991cb0ef41Sopenharmony_ci field = line.substr(pos); 1001cb0ef41Sopenharmony_ci } else { 1011cb0ef41Sopenharmony_ci field = line.substring(pos, nextPos); 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci fields.push(this.escapeField(field)); 1041cb0ef41Sopenharmony_ci pos = nextPos + 1; 1051cb0ef41Sopenharmony_ci }; 1061cb0ef41Sopenharmony_ci return fields 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci} 109