123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632 |
- import { _decorator } from "cc";
- const { ccclass, property } = _decorator;
- var CELL_DELIMITERS = [",", ";", "\t", "|", "^"];
- var LINE_DELIMITERS = ["\r\n", "\r", "\n"];
- var getter = function (index: any) {
- return ("d[" + index + "]");
- };
- var getterCast = function(value: any, index: any, cast: any, d: any) {
- if (cast instanceof Array) {
- if (cast[index] === "number") {
- return Number(d[index]);
- } else if (cast[index] === "boolean") {
- return d[index] === "true" || d[index] === "t" || d[index] === "1";
- } else {
- return d[index];
- }
- } else {
- if (!isNaN(Number(value))) {
- return Number(d[index]);
- } else if (value == "false" || value == "true" || value == "t" || value == "f") {
- return d[index] === "true" || d[index] === "t" || d[index] === "1";
- } else {
- return d[index];
- }
- }
- };
- var CSV = {
- //
- /* =========================================
- * Constants ===============================
- * ========================================= */
- STANDARD_DECODE_OPTS: {
- skip: 0,
- limit: false,
- header: false,
- cast: false,
- comment: ""
- },
- STANDARD_ENCODE_OPTS: {
- delimiter: CELL_DELIMITERS[0],
- newline: LINE_DELIMITERS[0],
- skip: 0,
- limit: false,
- header: false
- },
- quoteMark: '"',
- doubleQuoteMark: '""',
- quoteRegex: /"/g,
- /* =========================================
- * Utility Functions =======================
- * ========================================= */
- assign: function () {
- var args = Array.prototype.slice.call(arguments);
- var base = args[0];
- var rest = args.slice(1);
- for (var i = 0, len = rest.length; i < len; i++) {
- for (var attr in rest[i]) {
- base[attr] = rest[i][attr];
- }
- }
- return base;
- },
- map: function (collection: any, fn: Function) {
- var results = [];
- for (var i = 0, len = collection.length; i < len; i++) {
- results[i] = fn(collection[i], i);
- }
- return results;
- },
- getType: function (obj: any) {
- return Object.prototype.toString.call(obj).slice(8, -1);
- },
- getLimit: function (limit: any, len: any) {
- return limit === false ? len : limit;
- },
- buildObjectConstructor: function(fields: any, sample: any, cast: any) {
- return function(d: any) {
- var object: any = new Object();
- var setter = function(attr: any, value: any) {
- return object[attr] = value;
- };
- if (cast) {
- fields.forEach(function(attr: any, idx: number) {
- setter(attr, getterCast(sample[idx], idx, cast, d));
- });
- } else {
- fields.forEach(function(attr: any, idx: number) {
- setter(attr, getterCast(sample[idx], idx, null, d));
- });
- }
- // body.push("return object;");
- // body.join(";\n");
- return object;
- };
- },
- buildArrayConstructor: function(fields: any, sample: any, cast: any) {
- return function(d: any) {
- var row = new Array(sample.length);
- var setter = function(idx: any, value: any) {
- return row[idx] = value;
- };
- if (cast) {
- fields.forEach(function(attr: any, idx: number) {
- setter(attr, getterCast(sample[idx], idx, cast, d));
- });
- } else {
- fields.forEach(function(attr: any, idx: number) {
- setter(attr, getterCast(sample[idx], idx, null, d));
- });
- }
- return row;
- };
- },
- frequency: function (coll: any, needle: any, limit: any) {
- if (limit === void 0) limit = false;
- var count = 0;
- var lastIndex = 0;
- var maxIndex = this.getLimit(limit, coll.length);
- while (lastIndex < maxIndex) {
- lastIndex = coll.indexOf(needle, lastIndex);
- if (lastIndex === -1) break;
- lastIndex += 1;
- count++;
- }
- return count;
- },
- mostFrequent: function (coll: any, needles: any, limit: any) {
- var max = 0;
- var detected;
- for (var cur = needles.length - 1; cur >= 0; cur--) {
- if (this.frequency(coll, needles[cur], limit) > max) {
- detected = needles[cur];
- }
- }
- return detected || needles[0];
- },
- unsafeParse: function (text: any, opts: any, fn: any) {
- var lines = text.split(opts.newline);
- if (opts.skip > 0) {
- lines.splice(opts.skip);
- }
- var fields;
- var constructor;
- function cells(lines: any) {
- var line = lines.shift();
- if (line.indexOf('"') >= 0) {// 含引号
- // 找到这行完整的数据, 找到对称的双引号
- var lastIndex = 0;
- var findIndex = 0;
- var count = 0;
- while (lines.length > 0) {
- lastIndex = line.indexOf('"', findIndex);
- if (lastIndex === -1 && count % 2 === 0) break;
- if (lastIndex !== -1) {
- findIndex = lastIndex + 1;
- count++;
- } else {
- line = line + opts.newline + lines.shift();
- }
- }
- var list = [];
- var item;
- var quoteCount = 0;
- var start = 0;
- var end = 0;
- var length = line.length;
- for (var key in line) {
- if (!line.hasOwnProperty(key)) {
- continue;
- }
- let numKey = parseInt(key);
- var value = line[key];
- if (numKey === 0 && value === '"') {
- quoteCount++;
- start = 1;
- }
- if (value === '"') {
- quoteCount++;
- if (line[numKey - 1] === opts.delimiter && start === numKey) {
- start++;
- }
- }
- if (value === '"' && quoteCount % 2 === 0) {
- if (line[numKey + 1] === opts.delimiter || numKey + 1 === length) {
- end = numKey;
- item = line.substring(start, end);
- list.push(item);
- start = end + 2;
- end = start;
- }
- }
- if (value === opts.delimiter && quoteCount % 2 === 0) {
- end = numKey;
- if (end > start) {
- item = line.substring(start, end);
- list.push(item);
- start = end + 1;
- end = start;
- } else if (end === start) {
- list.push("");
- start = end + 1;
- end = start;
- }
- }
- }
- end = length;
- if (end >= start) {
- item = line.substring(start, end);
- list.push(item);
- }
- return list;
- } else {
- return line.split(opts.delimiter);
- }
- }
- if (opts.header) {
- if (opts.header === true) {
- opts.comment = cells(lines); // 第一行是注释
- opts.cast = cells(lines); // 第二行是数据类型
- fields = cells(lines);
- } else if (this.getType(opts.header) === "Array") {
- fields = opts.header;
- }
- constructor = this.buildObjectConstructor(fields, lines[0].split(opts.delimiter), opts.cast);
- } else {
- constructor = this.buildArrayConstructor(fields, lines[0].split(opts.delimiter), opts.cast);
- }
- while (lines.length > 0) {
- var row = cells(lines);
- if (row.length > 1) {
- fn(constructor(row), fields[0]);
- }
- }
- return true;
- },
- safeParse: function (text: any, opts: any, fn: Function) {
- var delimiter = opts.delimiter;
- var newline = opts.newline;
- var lines = text.split(newline);
- if (opts.skip > 0) {
- lines.splice(opts.skip);
- }
- return true;
- },
- encodeCells: function (line: any, delimiter: any, newline: any) {
- var row = line.slice(0);
- for (var i = 0, len = row.length; i < len; i++) {
- if (row[i].indexOf(this.quoteMark) !== -1) {
- row[i] = row[i].replace(this.quoteRegex, this.doubleQuoteMark);
- }
- if (row[i].indexOf(delimiter) !== -1 || row[i].indexOf(newline) !== -1) {
- row[i] = this.quoteMark + row[i] + this.quoteMark;
- }
- }
- return row.join(delimiter);
- },
- encodeArrays: function(coll: any, opts: any, fn: Function) {
- var delimiter = opts.delimiter;
- var newline = opts.newline;
- if (opts.header && this.getType(opts.header) === "Array") {
- fn(this.encodeCells(opts.header, delimiter, newline));
- }
- for (var cur = 0, lim = this.getLimit(opts.limit, coll.length); cur < lim; cur++) {
- fn(this.encodeCells(coll[cur], delimiter, newline));
- }
- return true;
- },
- encodeObjects: function (coll: any, opts: any, fn:Function) {
- var delimiter = opts.delimiter;
- var newline = opts.newline;
- var header;
- var row;
- header = [];
- row = [];
- for (var key in coll[0]) {
- header.push(key);
- row.push(coll[0][key]);
- }
- if (opts.header === true) {
- fn(this.encodeCells(header, delimiter, newline));
- } else if (this.getType(opts.header) === "Array") {
- fn(this.encodeCells(opts.header, delimiter, newline));
- }
- //@ts-ignore
- fn(this.encodeCells(row, delimiter));
- for (var cur = 1, lim = this.getLimit(opts.limit, coll.length); cur < lim; cur++) {
- row = [];
- for (var key$1 = 0, len = header.length; key$1 < len; key$1++) {
- row.push(coll[cur][header[key$1]]);
- }
- fn(this.encodeCells(row, delimiter, newline));
- }
- return true;
- },
- parse: function (text: any, opts: any, fn: Function) {
- var rows: any;
- if (this.getType(opts) === "Function") {
- fn = opts;
- opts = {};
- } else if (this.getType(fn) !== "Function") {
- rows = [];
- fn = rows.push.bind(rows);
- } else {
- rows = [];
- }
- //@ts-ignore
- opts = this.assign({}, this.STANDARD_DECODE_OPTS, opts);
- //@ts-ignore
- this.opts = opts;
- if (!opts.delimiter || !opts.newline) {
- var limit = Math.min(48, Math.floor(text.length / 20), text.length);
- opts.delimiter = opts.delimiter || this.mostFrequent(text, CELL_DELIMITERS, limit);
- opts.newline = opts.newline || this.mostFrequent(text, LINE_DELIMITERS, limit);
- }
- // modify by jl 由表自行控制不要含有双引号.提高解析效率
- return this.unsafeParse(text, opts, fn) &&
- (rows.length > 0 ? rows : true);
- },
- encode: function (coll: any, opts: any, fn: Function) {
- var lines: any;
- if (this.getType(opts) === "Function") {
- fn = opts;
- opts = {};
- } else if (this.getType(fn) !== "Function") {
- lines = [];
- fn = lines.push.bind(lines);
- }
- //@ts-ignore
- opts = this.assign({}, this.STANDARD_ENCODE_OPTS, opts);
- if (opts.skip > 0) {
- coll = coll.slice(opts.skip);
- }
- return (this.getType(coll[0]) === "Array" ? this.encodeArrays : this.encodeObjects)(coll, opts, fn) &&
- (lines.length > 0 ? lines.join(opts.newline) : true);
- }
- };
- @ccclass("CSVManager")
- export class CSVManager {
- /* class member could be defined like this */
- static _instance: CSVManager;
- static get instance () {
- if (this._instance) {
- return this._instance;
- }
- this._instance = new CSVManager();
- return this._instance;
- }
- private _csvTables:any = {};
- private _csvTableForArr:any = {};
- private _tableCast:any = {};
- private _tableComment:any = {};
- addTable (tableName:string, tableContent:string, force?:boolean) {
- if (this._csvTables[tableName] && !force) {
- return;
- }
- let tableData: any = {};
- let tableArr: any[] = [];
- let opts = { header: true };
- CSV.parse(tableContent, opts, function (row: any, keyName: string) {
- tableData[row[keyName]] = row;
- tableArr.push(row);
- });
- this._tableCast[tableName] = (CSV as any).opts.cast;
- this._tableComment[tableName] = (CSV as any).opts.comment;
- this._csvTables[tableName] = tableData;
- this._csvTableForArr[tableName] = tableArr;
- //this.csvTables[tableName].initFromText(tableContent);
- }
- /**
- * 根据表名获取表的所有内容
- * @param {string} tableName 表名
- * @returns {object} 表内容
- */
- getTableArr (tableName:string) {
- return this._csvTableForArr[tableName];
- }
- /**
- * 根据表名获取表的所有内容
- * @param {string} tableName 表名
- * @returns {object} 表内容
- */
- getTable (tableName:string) {
- return this._csvTables[tableName];
- }
- /**
- * 查询一条表内容
- * @param {string} tableName 表名
- * @param {string} key 列名
- * @param {any} value 值
- * @returns {Object} 一条表内容
- */
- queryOne (tableName:string, key:string, value:any) {
- var table = this.getTable(tableName);
- if (!table) {
- return null;
- }
- if (key) {
- for (var tbItem in table) {
- if (!table.hasOwnProperty(tbItem)) {
- continue;
- }
- if (table[tbItem][key] === value) {
- return table[tbItem];
- }
- }
- } else {
- return table[value];
- }
- }
- /**
- * 根据ID查询一条表内容
- * @param {string}tableName 表名
- * @param {string}ID
- * @returns {Object} 一条表内容
- */
- queryByID (tableName:string, ID:string) {
- //@ts-ignore
- return this.queryOne(tableName, null, ID);
- }
- /**
- * 查询key和value对应的所有行内容
- * @param {string} tableName 表名
- * @param {string} key 列名
- * @param {any} value 值
- * @returns {Object}
- */
- queryAll (tableName:string, key:string, value:any) {
- var table = this.getTable(tableName);
- if (!table || !key) {
- return null;
- }
- var ret: any = {};
- for (var tbItem in table) {
- if (!table.hasOwnProperty(tbItem)) {
- continue;
- }
- if (table[tbItem][key] === value) {
- ret[tbItem] = table[tbItem];
- }
- }
- return ret;
- }
- /**
- * 选出指定表里所有 key 的值在 values 数组中的数据,返回 Object,key 为 ID
- * @param {string} tableName 表名
- * @param {string} key 列名
- * @param {Array}values 数值
- * @returns
- */
- queryIn (tableName:string, key:string, values:Array<any>) {
- var table = this.getTable(tableName);
- if (!table || !key) {
- return null;
- }
- var ret: any = {};
- var keys = Object.keys(table);
- var length = keys.length;
- for (var i = 0; i < length; i++) {
- var item = table[keys[i]];
- if (values.indexOf(item[key]) > -1) {
- ret[keys[i]] = item;
- }
- }
- return ret;
- }
- /**
- * 选出符合条件的数据。condition key 为表格的key,value 为值的数组。返回的object,key 为数据在表格的ID,value为具体数据
- * @param {string} tableName 表名
- * @param {any} condition 筛选条件
- * @returns
- */
- queryByCondition (tableName:string, condition: any) {
- if (condition.constructor !== Object) {
- return null;
- }
- var table = this.getTable(tableName);
- if (!table) {
- return null;
- }
- var ret: any = {};
- var tableKeys = Object.keys(table);
- var tableKeysLength = tableKeys.length;
- var keys = Object.keys(condition);
- var keysLength = keys.length;
- for (var i = 0; i < tableKeysLength; i++) {
- var item = table[tableKeys[i]];
- var fit = true;
- for (var j = 0; j < keysLength; j++) {
- var key = keys[j];
- fit = fit && (condition[key] === item[key]) && !ret[tableKeys[i]];
- }
- if (fit) {
- ret[tableKeys[i]] = item;
- }
- }
- return ret;
- }
- queryOneByCondition (tableName:string, condition: any) {
- if (condition.constructor !== Object) {
- return null;
- }
- var table = this.getTable(tableName);
- if (!table) {
- return null;
- }
-
- var keys = Object.keys(condition);
- var keysLength = keys.length;
- for (let keyName in table) {
- var item = table[keyName];
- var fit = true;
- for (var j = 0; j < keysLength; j++) {
- var key = keys[j];
- fit = fit && (condition[key] === item[key]);
- }
- if (fit) {
- return item;
- }
- }
- return null;
- }
- }
|