@loaders.gl/shapefile 3.1.7 → 3.2.0-alpha.2

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.
Files changed (58) hide show
  1. package/dist/dbf-worker.js +60 -22
  2. package/dist/dist.min.js +23 -10
  3. package/dist/es5/dbf-loader.js +1 -1
  4. package/dist/es5/dbf-loader.js.map +1 -1
  5. package/dist/es5/lib/parsers/parse-dbf.js +69 -53
  6. package/dist/es5/lib/parsers/parse-dbf.js.map +1 -1
  7. package/dist/es5/lib/parsers/parse-shapefile.js.map +1 -1
  8. package/dist/es5/lib/parsers/parse-shp-geometry.js +2 -1
  9. package/dist/es5/lib/parsers/parse-shp-geometry.js.map +1 -1
  10. package/dist/es5/lib/parsers/parse-shp.js +10 -2
  11. package/dist/es5/lib/parsers/parse-shp.js.map +1 -1
  12. package/dist/es5/lib/parsers/types.js +2 -0
  13. package/dist/es5/lib/parsers/types.js.map +1 -0
  14. package/dist/es5/lib/streaming/binary-chunk-reader.js.map +1 -1
  15. package/dist/es5/shapefile-loader.js +1 -1
  16. package/dist/es5/shapefile-loader.js.map +1 -1
  17. package/dist/es5/shp-loader.js +1 -1
  18. package/dist/es5/shp-loader.js.map +1 -1
  19. package/dist/esm/dbf-loader.js +1 -1
  20. package/dist/esm/dbf-loader.js.map +1 -1
  21. package/dist/esm/lib/parsers/parse-dbf.js +20 -9
  22. package/dist/esm/lib/parsers/parse-dbf.js.map +1 -1
  23. package/dist/esm/lib/parsers/parse-shapefile.js.map +1 -1
  24. package/dist/esm/lib/parsers/parse-shp-geometry.js +1 -1
  25. package/dist/esm/lib/parsers/parse-shp-geometry.js.map +1 -1
  26. package/dist/esm/lib/parsers/parse-shp.js +10 -2
  27. package/dist/esm/lib/parsers/parse-shp.js.map +1 -1
  28. package/dist/esm/lib/parsers/types.js +2 -0
  29. package/dist/esm/lib/parsers/types.js.map +1 -0
  30. package/dist/esm/lib/streaming/binary-chunk-reader.js.map +1 -1
  31. package/dist/esm/shapefile-loader.js +1 -1
  32. package/dist/esm/shapefile-loader.js.map +1 -1
  33. package/dist/esm/shp-loader.js +1 -1
  34. package/dist/esm/shp-loader.js.map +1 -1
  35. package/dist/lib/parsers/parse-dbf.d.ts +4 -18
  36. package/dist/lib/parsers/parse-dbf.d.ts.map +1 -1
  37. package/dist/lib/parsers/parse-dbf.js +15 -8
  38. package/dist/lib/parsers/parse-shapefile.d.ts +3 -8
  39. package/dist/lib/parsers/parse-shapefile.d.ts.map +1 -1
  40. package/dist/lib/parsers/parse-shapefile.js +0 -4
  41. package/dist/lib/parsers/parse-shp-geometry.d.ts +2 -3
  42. package/dist/lib/parsers/parse-shp-geometry.d.ts.map +1 -1
  43. package/dist/lib/parsers/parse-shp-geometry.js +1 -1
  44. package/dist/lib/parsers/parse-shp.d.ts.map +1 -1
  45. package/dist/lib/parsers/parse-shp.js +10 -2
  46. package/dist/lib/parsers/types.d.ts +63 -0
  47. package/dist/lib/parsers/types.d.ts.map +1 -0
  48. package/dist/lib/parsers/types.js +2 -0
  49. package/dist/lib/streaming/binary-chunk-reader.d.ts +5 -3
  50. package/dist/lib/streaming/binary-chunk-reader.d.ts.map +1 -1
  51. package/dist/shp-worker.js +55 -18
  52. package/package.json +5 -5
  53. package/src/lib/parsers/parse-dbf.ts +37 -58
  54. package/src/lib/parsers/parse-shapefile.ts +3 -6
  55. package/src/lib/parsers/parse-shp-geometry.ts +3 -2
  56. package/src/lib/parsers/parse-shp.ts +24 -10
  57. package/src/lib/parsers/types.ts +74 -0
  58. package/src/lib/streaming/binary-chunk-reader.ts +5 -1
@@ -549,13 +549,21 @@
549
549
  }
550
550
  };
551
551
  function parseDBF(arrayBuffer, options = {}) {
552
- const loaderOptions = options.dbf || {};
553
- const { encoding } = loaderOptions;
552
+ const { encoding = "latin1" } = options.dbf || {};
554
553
  const dbfParser = new DBFParser({ encoding });
555
554
  dbfParser.write(arrayBuffer);
556
555
  dbfParser.end();
557
556
  const { data, schema } = dbfParser.result;
558
- switch (options.tables && options.tables.format) {
557
+ const shape = options?.tables?.format || options?.dbf?.shape;
558
+ switch (shape) {
559
+ case "object-row-table": {
560
+ const table = {
561
+ shape: "object-row-table",
562
+ schema,
563
+ data
564
+ };
565
+ return table;
566
+ }
559
567
  case "table":
560
568
  return { schema, rows: data };
561
569
  case "rows":
@@ -564,8 +572,7 @@
564
572
  }
565
573
  }
566
574
  async function* parseDBFInBatches(asyncIterator, options = {}) {
567
- const loaderOptions = options.dbf || {};
568
- const { encoding } = loaderOptions;
575
+ const { encoding = "latin1" } = options.dbf || {};
569
576
  const parser = new DBFParser({ encoding });
570
577
  let headerReturned = false;
571
578
  for await (const arrayBuffer of asyncIterator) {
@@ -592,7 +599,7 @@
592
599
  case 3:
593
600
  return state;
594
601
  case 0:
595
- const dataView = binaryReader.getDataView(DBF_HEADER_SIZE, "DBF header");
602
+ const dataView = binaryReader.getDataView(DBF_HEADER_SIZE);
596
603
  if (!dataView) {
597
604
  return state;
598
605
  }
@@ -605,7 +612,7 @@
605
612
  state = 1;
606
613
  break;
607
614
  case 1:
608
- const fieldDescriptorView = binaryReader.getDataView(result.dbfHeader.headerLength - DBF_HEADER_SIZE, "DBF field descriptors");
615
+ const fieldDescriptorView = binaryReader.getDataView(result.dbfHeader.headerLength - DBF_HEADER_SIZE);
609
616
  if (!fieldDescriptorView) {
610
617
  return state;
611
618
  }
@@ -732,7 +739,7 @@
732
739
  }
733
740
 
734
741
  // src/dbf-loader.ts
735
- var VERSION = true ? "3.1.7" : "latest";
742
+ var VERSION = true ? "3.2.0-alpha.2" : "latest";
736
743
  var DBFWorkerLoader = {
737
744
  name: "DBF",
738
745
  id: "dbf",
@@ -791,16 +798,33 @@
791
798
  }
792
799
 
793
800
  // ../worker-utils/src/lib/worker-farm/worker-body.ts
801
+ function getParentPort() {
802
+ let parentPort;
803
+ try {
804
+ eval("globalThis.parentPort = require('worker_threads').parentPort");
805
+ parentPort = globalThis.parentPort;
806
+ } catch {
807
+ }
808
+ return parentPort;
809
+ }
794
810
  var onMessageWrapperMap = new Map();
795
811
  var WorkerBody = class {
812
+ static inWorkerThread() {
813
+ return typeof self !== "undefined" || Boolean(getParentPort());
814
+ }
796
815
  static set onmessage(onMessage) {
797
- self.onmessage = (message) => {
798
- if (!isKnownMessage(message)) {
799
- return;
800
- }
801
- const { type, payload } = message.data;
816
+ function handleMessage(message) {
817
+ const parentPort3 = getParentPort();
818
+ const { type, payload } = parentPort3 ? message : message.data;
802
819
  onMessage(type, payload);
803
- };
820
+ }
821
+ const parentPort2 = getParentPort();
822
+ if (parentPort2) {
823
+ parentPort2.on("message", handleMessage);
824
+ parentPort2.on("exit", () => console.debug("Node worker closing"));
825
+ } else {
826
+ globalThis.onmessage = handleMessage;
827
+ }
804
828
  }
805
829
  static addEventListener(onMessage) {
806
830
  let onMessageWrapper = onMessageWrapperMap.get(onMessage);
@@ -809,22 +833,36 @@
809
833
  if (!isKnownMessage(message)) {
810
834
  return;
811
835
  }
812
- const { type, payload } = message.data;
836
+ const parentPort3 = getParentPort();
837
+ const { type, payload } = parentPort3 ? message : message.data;
813
838
  onMessage(type, payload);
814
839
  };
815
840
  }
816
- self.addEventListener("message", onMessageWrapper);
841
+ const parentPort2 = getParentPort();
842
+ if (parentPort2) {
843
+ console.error("not implemented");
844
+ } else {
845
+ globalThis.addEventListener("message", onMessageWrapper);
846
+ }
817
847
  }
818
848
  static removeEventListener(onMessage) {
819
849
  const onMessageWrapper = onMessageWrapperMap.get(onMessage);
820
850
  onMessageWrapperMap.delete(onMessage);
821
- self.removeEventListener("message", onMessageWrapper);
851
+ const parentPort2 = getParentPort();
852
+ if (parentPort2) {
853
+ console.error("not implemented");
854
+ } else {
855
+ globalThis.removeEventListener("message", onMessageWrapper);
856
+ }
822
857
  }
823
858
  static postMessage(type, payload) {
824
- if (self) {
825
- const data = { source: "loaders.gl", type, payload };
826
- const transferList = getTransferList(payload);
827
- self.postMessage(data, transferList);
859
+ const data = { source: "loaders.gl", type, payload };
860
+ const transferList = getTransferList(payload);
861
+ const parentPort2 = getParentPort();
862
+ if (parentPort2) {
863
+ parentPort2.postMessage(data, transferList);
864
+ } else {
865
+ globalThis.postMessage(data, transferList);
828
866
  }
829
867
  }
830
868
  };
@@ -836,7 +874,7 @@
836
874
  // ../loader-utils/src/lib/worker-loader-utils/create-loader-worker.ts
837
875
  var requestId = 0;
838
876
  function createLoaderWorker(loader) {
839
- if (typeof self === "undefined") {
877
+ if (!WorkerBody.inWorkerThread()) {
840
878
  return;
841
879
  }
842
880
  WorkerBody.onmessage = async (type, payload) => {
package/dist/dist.min.js CHANGED
@@ -155,7 +155,7 @@
155
155
 
156
156
  // src/lib/parsers/parse-shp-geometry.ts
157
157
  function parseRecord(view, options) {
158
- const { _maxDimensions } = options?.shp || {};
158
+ const { _maxDimensions = 4 } = options?.shp || {};
159
159
  let offset = 0;
160
160
  const type = view.getInt32(offset, LITTLE_ENDIAN2);
161
161
  offset += Int32Array.BYTES_PER_ELEMENT;
@@ -390,7 +390,7 @@
390
390
  binaryReader.rewind(SHP_RECORD_HEADER_SIZE);
391
391
  return state;
392
392
  }
393
- const invalidRecord = recordHeader.byteLength < 4 || recordHeader.type !== result.header.type || recordHeader.recordNumber !== result.currentIndex;
393
+ const invalidRecord = recordHeader.byteLength < 4 || recordHeader.type !== result.header?.type || recordHeader.recordNumber !== result.currentIndex;
394
394
  if (invalidRecord) {
395
395
  binaryReader.rewind(SHP_RECORD_HEADER_SIZE - 4);
396
396
  } else {
@@ -440,7 +440,13 @@
440
440
  this.binaryReader = new BinaryChunkReader({ maxRewindBytes: SHP_RECORD_HEADER_SIZE });
441
441
  this.state = STATE.EXPECTING_HEADER;
442
442
  this.result = {
443
- geometries: []
443
+ geometries: [],
444
+ progress: {
445
+ bytesTotal: NaN,
446
+ bytesUsed: NaN,
447
+ rows: NaN
448
+ },
449
+ currentIndex: NaN
444
450
  };
445
451
  this.options = options;
446
452
  }
@@ -7087,13 +7093,21 @@
7087
7093
 
7088
7094
  // src/lib/parsers/parse-dbf.ts
7089
7095
  function parseDBF(arrayBuffer, options = {}) {
7090
- const loaderOptions = options.dbf || {};
7091
- const { encoding } = loaderOptions;
7096
+ const { encoding = "latin1" } = options.dbf || {};
7092
7097
  const dbfParser = new DBFParser({ encoding });
7093
7098
  dbfParser.write(arrayBuffer);
7094
7099
  dbfParser.end();
7095
7100
  const { data, schema } = dbfParser.result;
7096
- switch (options.tables && options.tables.format) {
7101
+ const shape = options?.tables?.format || options?.dbf?.shape;
7102
+ switch (shape) {
7103
+ case "object-row-table": {
7104
+ const table = {
7105
+ shape: "object-row-table",
7106
+ schema,
7107
+ data
7108
+ };
7109
+ return table;
7110
+ }
7097
7111
  case "table":
7098
7112
  return { schema, rows: data };
7099
7113
  case "rows":
@@ -7102,8 +7116,7 @@
7102
7116
  }
7103
7117
  }
7104
7118
  async function* parseDBFInBatches(asyncIterator, options = {}) {
7105
- const loaderOptions = options.dbf || {};
7106
- const { encoding } = loaderOptions;
7119
+ const { encoding = "latin1" } = options.dbf || {};
7107
7120
  const parser = new DBFParser({ encoding });
7108
7121
  let headerReturned = false;
7109
7122
  for await (const arrayBuffer of asyncIterator) {
@@ -7130,7 +7143,7 @@
7130
7143
  case 3:
7131
7144
  return state;
7132
7145
  case 0:
7133
- const dataView = binaryReader.getDataView(DBF_HEADER_SIZE, "DBF header");
7146
+ const dataView = binaryReader.getDataView(DBF_HEADER_SIZE);
7134
7147
  if (!dataView) {
7135
7148
  return state;
7136
7149
  }
@@ -7143,7 +7156,7 @@
7143
7156
  state = 1;
7144
7157
  break;
7145
7158
  case 1:
7146
- const fieldDescriptorView = binaryReader.getDataView(result.dbfHeader.headerLength - DBF_HEADER_SIZE, "DBF field descriptors");
7159
+ const fieldDescriptorView = binaryReader.getDataView(result.dbfHeader.headerLength - DBF_HEADER_SIZE);
7147
7160
  if (!fieldDescriptorView) {
7148
7161
  return state;
7149
7162
  }
@@ -19,7 +19,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
19
19
 
20
20
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
21
21
 
22
- var VERSION = typeof "3.1.7" !== 'undefined' ? "3.1.7" : 'latest';
22
+ var VERSION = typeof "3.2.0-alpha.2" !== 'undefined' ? "3.2.0-alpha.2" : 'latest';
23
23
  var DBFWorkerLoader = {
24
24
  name: 'DBF',
25
25
  id: 'dbf',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/dbf-loader.ts"],"names":["VERSION","DBFWorkerLoader","name","id","module","version","worker","category","extensions","mimeTypes","options","dbf","encoding","DBFLoader","parse","arrayBuffer","parseSync","parseDBF","parseInBatches","parseDBFInBatches"],"mappings":";;;;;;;;;;;;;;;AACA;;;;;;AAIA,IAAMA,OAAO,GAAG,mBAAuB,WAAvB,aAAmD,QAAnE;AAKO,IAAMC,eAAuB,GAAG;AACrCC,EAAAA,IAAI,EAAE,KAD+B;AAErCC,EAAAA,EAAE,EAAE,KAFiC;AAGrCC,EAAAA,MAAM,EAAE,WAH6B;AAIrCC,EAAAA,OAAO,EAAEL,OAJ4B;AAKrCM,EAAAA,MAAM,EAAE,IAL6B;AAMrCC,EAAAA,QAAQ,EAAE,OAN2B;AAOrCC,EAAAA,UAAU,EAAE,CAAC,KAAD,CAPyB;AAQrCC,EAAAA,SAAS,EAAE,CAAC,mBAAD,CAR0B;AASrCC,EAAAA,OAAO,EAAE;AACPC,IAAAA,GAAG,EAAE;AACHC,MAAAA,QAAQ,EAAE;AADP;AADE;AAT4B,CAAhC;;;AAiBA,IAAMC,SAA2B,mCACnCZ,eADmC;AAEtCa,EAAAA,KAAK;AAAA,2EAAE,iBAAOC,WAAP,EAAoBL,OAApB;AAAA;AAAA;AAAA;AAAA;AAAA,+CAAgC,wBAASK,WAAT,EAAsBL,OAAtB,CAAhC;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAAF;;AAAA;AAAA;AAAA;;AAAA;AAAA,KAFiC;AAGtCM,EAAAA,SAAS,EAAEC,kBAH2B;AAItCC,EAAAA,cAAc,EAAEC;AAJsB,EAAjC","sourcesContent":["import type {Loader, LoaderWithParser} from '@loaders.gl/loader-utils';\nimport {parseDBF, parseDBFInBatches} from './lib/parsers/parse-dbf';\n\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\n\n/**\n * DBFLoader - DBF files are used to contain non-geometry columns in Shapefiles\n */\nexport const DBFWorkerLoader: Loader = {\n name: 'DBF',\n id: 'dbf',\n module: 'shapefile',\n version: VERSION,\n worker: true,\n category: 'table',\n extensions: ['dbf'],\n mimeTypes: ['application/x-dbf'],\n options: {\n dbf: {\n encoding: 'latin1'\n }\n }\n};\n\n/** DBF file loader */\nexport const DBFLoader: LoaderWithParser = {\n ...DBFWorkerLoader,\n parse: async (arrayBuffer, options) => parseDBF(arrayBuffer, options),\n parseSync: parseDBF,\n parseInBatches: parseDBFInBatches\n};\n"],"file":"dbf-loader.js"}
1
+ {"version":3,"sources":["../../src/dbf-loader.ts"],"names":["VERSION","DBFWorkerLoader","name","id","module","version","worker","category","extensions","mimeTypes","options","dbf","encoding","DBFLoader","parse","arrayBuffer","parseSync","parseDBF","parseInBatches","parseDBFInBatches"],"mappings":";;;;;;;;;;;;;;;AACA;;;;;;AAIA,IAAMA,OAAO,GAAG,2BAAuB,WAAvB,qBAAmD,QAAnE;AAKO,IAAMC,eAAuB,GAAG;AACrCC,EAAAA,IAAI,EAAE,KAD+B;AAErCC,EAAAA,EAAE,EAAE,KAFiC;AAGrCC,EAAAA,MAAM,EAAE,WAH6B;AAIrCC,EAAAA,OAAO,EAAEL,OAJ4B;AAKrCM,EAAAA,MAAM,EAAE,IAL6B;AAMrCC,EAAAA,QAAQ,EAAE,OAN2B;AAOrCC,EAAAA,UAAU,EAAE,CAAC,KAAD,CAPyB;AAQrCC,EAAAA,SAAS,EAAE,CAAC,mBAAD,CAR0B;AASrCC,EAAAA,OAAO,EAAE;AACPC,IAAAA,GAAG,EAAE;AACHC,MAAAA,QAAQ,EAAE;AADP;AADE;AAT4B,CAAhC;;;AAiBA,IAAMC,SAA2B,mCACnCZ,eADmC;AAEtCa,EAAAA,KAAK;AAAA,2EAAE,iBAAOC,WAAP,EAAoBL,OAApB;AAAA;AAAA;AAAA;AAAA;AAAA,+CAAgC,wBAASK,WAAT,EAAsBL,OAAtB,CAAhC;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAAF;;AAAA;AAAA;AAAA;;AAAA;AAAA,KAFiC;AAGtCM,EAAAA,SAAS,EAAEC,kBAH2B;AAItCC,EAAAA,cAAc,EAAEC;AAJsB,EAAjC","sourcesContent":["import type {Loader, LoaderWithParser} from '@loaders.gl/loader-utils';\nimport {parseDBF, parseDBFInBatches} from './lib/parsers/parse-dbf';\n\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\n\n/**\n * DBFLoader - DBF files are used to contain non-geometry columns in Shapefiles\n */\nexport const DBFWorkerLoader: Loader = {\n name: 'DBF',\n id: 'dbf',\n module: 'shapefile',\n version: VERSION,\n worker: true,\n category: 'table',\n extensions: ['dbf'],\n mimeTypes: ['application/x-dbf'],\n options: {\n dbf: {\n encoding: 'latin1'\n }\n }\n};\n\n/** DBF file loader */\nexport const DBFLoader: LoaderWithParser = {\n ...DBFWorkerLoader,\n parse: async (arrayBuffer, options) => parseDBF(arrayBuffer, options),\n parseSync: parseDBF,\n parseInBatches: parseDBFInBatches\n};\n"],"file":"dbf-loader.js"}
@@ -78,9 +78,14 @@ var DBFParser = function () {
78
78
  }();
79
79
 
80
80
  function parseDBF(arrayBuffer) {
81
+ var _options$tables, _options$dbf;
82
+
81
83
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
82
- var loaderOptions = options.dbf || {};
83
- var encoding = loaderOptions.encoding;
84
+
85
+ var _ref = options.dbf || {},
86
+ _ref$encoding = _ref.encoding,
87
+ encoding = _ref$encoding === void 0 ? 'latin1' : _ref$encoding;
88
+
84
89
  var dbfParser = new DBFParser({
85
90
  encoding: encoding
86
91
  });
@@ -89,8 +94,19 @@ function parseDBF(arrayBuffer) {
89
94
  var _dbfParser$result = dbfParser.result,
90
95
  data = _dbfParser$result.data,
91
96
  schema = _dbfParser$result.schema;
97
+ var shape = (options === null || options === void 0 ? void 0 : (_options$tables = options.tables) === null || _options$tables === void 0 ? void 0 : _options$tables.format) || (options === null || options === void 0 ? void 0 : (_options$dbf = options.dbf) === null || _options$dbf === void 0 ? void 0 : _options$dbf.shape);
98
+
99
+ switch (shape) {
100
+ case 'object-row-table':
101
+ {
102
+ var table = {
103
+ shape: 'object-row-table',
104
+ schema: schema,
105
+ data: data
106
+ };
107
+ return table;
108
+ }
92
109
 
93
- switch (options.tables && options.tables.format) {
94
110
  case 'table':
95
111
  return {
96
112
  schema: schema,
@@ -110,7 +126,8 @@ function parseDBFInBatches(_x) {
110
126
  function _parseDBFInBatches() {
111
127
  _parseDBFInBatches = (0, _wrapAsyncGenerator2.default)(_regenerator.default.mark(function _callee(asyncIterator) {
112
128
  var options,
113
- loaderOptions,
129
+ _ref2,
130
+ _ref2$encoding,
114
131
  encoding,
115
132
  parser,
116
133
  headerReturned,
@@ -128,32 +145,31 @@ function _parseDBFInBatches() {
128
145
  switch (_context.prev = _context.next) {
129
146
  case 0:
130
147
  options = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
131
- loaderOptions = options.dbf || {};
132
- encoding = loaderOptions.encoding;
148
+ _ref2 = options.dbf || {}, _ref2$encoding = _ref2.encoding, encoding = _ref2$encoding === void 0 ? 'latin1' : _ref2$encoding;
133
149
  parser = new DBFParser({
134
150
  encoding: encoding
135
151
  });
136
152
  headerReturned = false;
137
153
  _iteratorNormalCompletion = true;
138
154
  _didIteratorError = false;
139
- _context.prev = 7;
155
+ _context.prev = 6;
140
156
  _iterator = (0, _asyncIterator2.default)(asyncIterator);
141
157
 
142
- case 9:
143
- _context.next = 11;
158
+ case 8:
159
+ _context.next = 10;
144
160
  return (0, _awaitAsyncGenerator2.default)(_iterator.next());
145
161
 
146
- case 11:
162
+ case 10:
147
163
  _step = _context.sent;
148
164
  _iteratorNormalCompletion = _step.done;
149
- _context.next = 15;
165
+ _context.next = 14;
150
166
  return (0, _awaitAsyncGenerator2.default)(_step.value);
151
167
 
152
- case 15:
168
+ case 14:
153
169
  _value = _context.sent;
154
170
 
155
171
  if (_iteratorNormalCompletion) {
156
- _context.next = 30;
172
+ _context.next = 29;
157
173
  break;
158
174
  }
159
175
 
@@ -161,86 +177,86 @@ function _parseDBFInBatches() {
161
177
  parser.write(arrayBuffer);
162
178
 
163
179
  if (!(!headerReturned && parser.result.dbfHeader)) {
164
- _context.next = 23;
180
+ _context.next = 22;
165
181
  break;
166
182
  }
167
183
 
168
184
  headerReturned = true;
169
- _context.next = 23;
185
+ _context.next = 22;
170
186
  return parser.result.dbfHeader;
171
187
 
172
- case 23:
188
+ case 22:
173
189
  if (!(parser.result.data.length > 0)) {
174
- _context.next = 27;
190
+ _context.next = 26;
175
191
  break;
176
192
  }
177
193
 
178
- _context.next = 26;
194
+ _context.next = 25;
179
195
  return parser.result.data;
180
196
 
181
- case 26:
197
+ case 25:
182
198
  parser.result.data = [];
183
199
 
184
- case 27:
200
+ case 26:
185
201
  _iteratorNormalCompletion = true;
186
- _context.next = 9;
202
+ _context.next = 8;
187
203
  break;
188
204
 
189
- case 30:
190
- _context.next = 36;
205
+ case 29:
206
+ _context.next = 35;
191
207
  break;
192
208
 
193
- case 32:
194
- _context.prev = 32;
195
- _context.t0 = _context["catch"](7);
209
+ case 31:
210
+ _context.prev = 31;
211
+ _context.t0 = _context["catch"](6);
196
212
  _didIteratorError = true;
197
213
  _iteratorError = _context.t0;
198
214
 
199
- case 36:
215
+ case 35:
216
+ _context.prev = 35;
200
217
  _context.prev = 36;
201
- _context.prev = 37;
202
218
 
203
219
  if (!(!_iteratorNormalCompletion && _iterator.return != null)) {
204
- _context.next = 41;
220
+ _context.next = 40;
205
221
  break;
206
222
  }
207
223
 
208
- _context.next = 41;
224
+ _context.next = 40;
209
225
  return (0, _awaitAsyncGenerator2.default)(_iterator.return());
210
226
 
211
- case 41:
212
- _context.prev = 41;
227
+ case 40:
228
+ _context.prev = 40;
213
229
 
214
230
  if (!_didIteratorError) {
215
- _context.next = 44;
231
+ _context.next = 43;
216
232
  break;
217
233
  }
218
234
 
219
235
  throw _iteratorError;
220
236
 
237
+ case 43:
238
+ return _context.finish(40);
239
+
221
240
  case 44:
222
- return _context.finish(41);
241
+ return _context.finish(35);
223
242
 
224
243
  case 45:
225
- return _context.finish(36);
226
-
227
- case 46:
228
244
  parser.end();
229
245
 
230
246
  if (!(parser.result.data.length > 0)) {
231
- _context.next = 50;
247
+ _context.next = 49;
232
248
  break;
233
249
  }
234
250
 
235
- _context.next = 50;
251
+ _context.next = 49;
236
252
  return parser.result.data;
237
253
 
238
- case 50:
254
+ case 49:
239
255
  case "end":
240
256
  return _context.stop();
241
257
  }
242
258
  }
243
- }, _callee, null, [[7, 32, 36, 46], [37,, 41, 45]]);
259
+ }, _callee, null, [[6, 31, 35, 45], [36,, 40, 44]]);
244
260
  }));
245
261
  return _parseDBFInBatches.apply(this, arguments);
246
262
  }
@@ -254,7 +270,7 @@ function parseState(state, result, binaryReader, textDecoder) {
254
270
  return state;
255
271
 
256
272
  case STATE.START:
257
- var dataView = binaryReader.getDataView(DBF_HEADER_SIZE, 'DBF header');
273
+ var dataView = binaryReader.getDataView(DBF_HEADER_SIZE);
258
274
 
259
275
  if (!dataView) {
260
276
  return state;
@@ -270,7 +286,7 @@ function parseState(state, result, binaryReader, textDecoder) {
270
286
  break;
271
287
 
272
288
  case STATE.FIELD_DESCRIPTORS:
273
- var fieldDescriptorView = binaryReader.getDataView(result.dbfHeader.headerLength - DBF_HEADER_SIZE, 'DBF field descriptors');
289
+ var fieldDescriptorView = binaryReader.getDataView(result.dbfHeader.headerLength - DBF_HEADER_SIZE);
274
290
 
275
291
  if (!fieldDescriptorView) {
276
292
  return state;
@@ -285,11 +301,11 @@ function parseState(state, result, binaryReader, textDecoder) {
285
301
  break;
286
302
 
287
303
  case STATE.FIELD_PROPERTIES:
288
- var _ref = (result === null || result === void 0 ? void 0 : result.dbfHeader) || {},
289
- _ref$recordLength = _ref.recordLength,
290
- recordLength = _ref$recordLength === void 0 ? 0 : _ref$recordLength,
291
- _ref$nRecords = _ref.nRecords,
292
- nRecords = _ref$nRecords === void 0 ? 0 : _ref$nRecords;
304
+ var _ref3 = (result === null || result === void 0 ? void 0 : result.dbfHeader) || {},
305
+ _ref3$recordLength = _ref3.recordLength,
306
+ recordLength = _ref3$recordLength === void 0 ? 0 : _ref3$recordLength,
307
+ _ref3$nRecords = _ref3.nRecords,
308
+ nRecords = _ref3$nRecords === void 0 ? 0 : _ref3$nRecords;
293
309
 
294
310
  while (result.data.length < nRecords) {
295
311
  var recordView = binaryReader.getDataView(recordLength - 1);
@@ -419,11 +435,11 @@ function parseCharacter(text) {
419
435
  return text.trim() || null;
420
436
  }
421
437
 
422
- function makeField(_ref2) {
423
- var name = _ref2.name,
424
- dataType = _ref2.dataType,
425
- fieldLength = _ref2.fieldLength,
426
- decimal = _ref2.decimal;
438
+ function makeField(_ref4) {
439
+ var name = _ref4.name,
440
+ dataType = _ref4.dataType,
441
+ fieldLength = _ref4.fieldLength,
442
+ decimal = _ref4.decimal;
427
443
 
428
444
  switch (dataType) {
429
445
  case 'B':
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/parsers/parse-dbf.ts"],"names":["LITTLE_ENDIAN","DBF_HEADER_SIZE","STATE","DBFParser","options","BinaryChunkReader","START","data","textDecoder","TextDecoder","encoding","arrayBuffer","binaryReader","write","state","parseState","result","end","END","ERROR","error","parseDBF","loaderOptions","dbf","dbfParser","schema","tables","format","rows","parseDBFInBatches","asyncIterator","parser","headerReturned","dbfHeader","length","dataView","getDataView","parseDBFHeader","progress","bytesUsed","rowsTotal","nRecords","FIELD_DESCRIPTORS","fieldDescriptorView","headerLength","dbfFields","parseFieldDescriptors","Schema","map","dbfField","makeField","FIELD_PROPERTIES","skip","recordLength","recordView","row","parseRow","push","message","headerView","year","getUint8","month","day","getUint32","getUint16","languageDriver","view","nFields","byteLength","fields","offset","i","name","decode","Uint8Array","buffer","byteOffset","replace","dataType","String","fromCharCode","fieldLength","decimal","out","field","text","parseField","parseNumber","parseCharacter","parseDate","parseBoolean","Error","str","Date","UTC","slice","parseInt","value","test","number","parseFloat","isNaN","trim","Field","Float64","Utf8","TimestampMillisecond","Bool"],"mappings":"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","sourcesContent":["import {Schema, Field, Bool, Utf8, Float64, TimestampMillisecond} from '@loaders.gl/schema';\nimport BinaryChunkReader from '../streaming/binary-chunk-reader';\n\ntype DBFRowsOutput = object[];\n\ninterface DBFTableOutput {\n schema?: Schema;\n rows: DBFRowsOutput;\n}\n\ntype DBFHeader = {\n // Last updated date\n year: number;\n month: number;\n day: number;\n // Number of records in data file\n nRecords: number;\n // Length of header in bytes\n headerLength: number;\n // Length of each record\n recordLength: number;\n // Not sure if this is usually set\n languageDriver: number;\n};\n\ntype DBFField = {\n name: string;\n dataType: string;\n fieldLength: number;\n decimal: number;\n};\n\ntype DBFResult = {\n data: {[key: string]: any}[];\n schema?: Schema;\n error?: string;\n dbfHeader?: DBFHeader;\n dbfFields?: DBFField[];\n progress?: {\n bytesUsed: number;\n rowsTotal: number;\n rows: number;\n };\n};\n\nconst LITTLE_ENDIAN = true;\nconst DBF_HEADER_SIZE = 32;\n\nenum STATE {\n START = 0, // Expecting header\n FIELD_DESCRIPTORS = 1,\n FIELD_PROPERTIES = 2,\n END = 3,\n ERROR = 4\n}\n\nclass DBFParser {\n binaryReader = new BinaryChunkReader();\n textDecoder: TextDecoder;\n state = STATE.START;\n result: DBFResult = {\n data: []\n };\n\n constructor(options: {encoding: string}) {\n this.textDecoder = new TextDecoder(options.encoding);\n }\n\n /**\n * @param arrayBuffer\n */\n write(arrayBuffer: ArrayBuffer): void {\n this.binaryReader.write(arrayBuffer);\n this.state = parseState(this.state, this.result, this.binaryReader, this.textDecoder);\n // this.result.progress.bytesUsed = this.binaryReader.bytesUsed();\n\n // important events:\n // - schema available\n // - first rows available\n // - all rows available\n }\n\n end(): void {\n this.binaryReader.end();\n this.state = parseState(this.state, this.result, this.binaryReader, this.textDecoder);\n // this.result.progress.bytesUsed = this.binaryReader.bytesUsed();\n if (this.state !== STATE.END) {\n this.state = STATE.ERROR;\n this.result.error = 'DBF incomplete file';\n }\n }\n}\n\n/**\n * @param arrayBuffer\n * @param options\n * @returns DBFTable or rows\n */\nexport function parseDBF(\n arrayBuffer: ArrayBuffer,\n options: any = {}\n): DBFRowsOutput | DBFTableOutput {\n const loaderOptions = options.dbf || {};\n const {encoding} = loaderOptions;\n\n const dbfParser = new DBFParser({encoding});\n dbfParser.write(arrayBuffer);\n dbfParser.end();\n\n const {data, schema} = dbfParser.result;\n switch (options.tables && options.tables.format) {\n case 'table':\n // TODO - parse columns\n return {schema, rows: data};\n\n case 'rows':\n default:\n return data;\n }\n}\n/**\n * @param asyncIterator\n * @param options\n */\nexport async function* parseDBFInBatches(\n asyncIterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>,\n options: any = {}\n): AsyncIterable<DBFHeader | DBFRowsOutput | DBFTableOutput> {\n const loaderOptions = options.dbf || {};\n const {encoding} = loaderOptions;\n\n const parser = new DBFParser({encoding});\n let headerReturned = false;\n for await (const arrayBuffer of asyncIterator) {\n parser.write(arrayBuffer);\n if (!headerReturned && parser.result.dbfHeader) {\n headerReturned = true;\n yield parser.result.dbfHeader;\n }\n\n if (parser.result.data.length > 0) {\n yield parser.result.data;\n parser.result.data = [];\n }\n }\n parser.end();\n if (parser.result.data.length > 0) {\n yield parser.result.data;\n }\n}\n/**\n * https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm\n * @param state\n * @param result\n * @param binaryReader\n * @param textDecoder\n * @returns\n */\n/* eslint-disable complexity, max-depth */\nfunction parseState(\n state: STATE,\n result: DBFResult,\n binaryReader: {[key: string]: any},\n textDecoder: TextDecoder\n): STATE {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n switch (state) {\n case STATE.ERROR:\n case STATE.END:\n return state;\n\n case STATE.START:\n // Parse initial file header\n const dataView = binaryReader.getDataView(DBF_HEADER_SIZE, 'DBF header');\n if (!dataView) {\n return state;\n }\n result.dbfHeader = parseDBFHeader(dataView);\n result.progress = {\n bytesUsed: 0,\n rowsTotal: result.dbfHeader.nRecords,\n rows: 0\n };\n state = STATE.FIELD_DESCRIPTORS;\n break;\n\n case STATE.FIELD_DESCRIPTORS:\n // Parse DBF field descriptors (schema)\n const fieldDescriptorView = binaryReader.getDataView(\n // @ts-ignore\n result.dbfHeader.headerLength - DBF_HEADER_SIZE,\n 'DBF field descriptors'\n );\n if (!fieldDescriptorView) {\n return state;\n }\n\n result.dbfFields = parseFieldDescriptors(fieldDescriptorView, textDecoder);\n result.schema = new Schema(result.dbfFields.map((dbfField) => makeField(dbfField)));\n\n state = STATE.FIELD_PROPERTIES;\n\n // TODO(kyle) Not exactly sure why start offset needs to be headerLength + 1?\n // parsedbf uses ((fields.length + 1) << 5) + 2;\n binaryReader.skip(1);\n break;\n\n case STATE.FIELD_PROPERTIES:\n const {recordLength = 0, nRecords = 0} = result?.dbfHeader || {};\n while (result.data.length < nRecords) {\n const recordView = binaryReader.getDataView(recordLength - 1);\n if (!recordView) {\n return state;\n }\n // Note: Avoid actually reading the last byte, which may not be present\n binaryReader.skip(1);\n\n // @ts-ignore\n const row = parseRow(recordView, result.dbfFields, textDecoder);\n result.data.push(row);\n // @ts-ignore\n result.progress.rows = result.data.length;\n }\n state = STATE.END;\n break;\n\n default:\n state = STATE.ERROR;\n result.error = `illegal parser state ${state}`;\n return state;\n }\n } catch (error) {\n state = STATE.ERROR;\n result.error = `DBF parsing failed: ${(error as Error).message}`;\n return state;\n }\n }\n}\n\n/**\n * @param headerView\n */\nfunction parseDBFHeader(headerView: DataView): DBFHeader {\n return {\n // Last updated date\n year: headerView.getUint8(1) + 1900,\n month: headerView.getUint8(2),\n day: headerView.getUint8(3),\n // Number of records in data file\n nRecords: headerView.getUint32(4, LITTLE_ENDIAN),\n // Length of header in bytes\n headerLength: headerView.getUint16(8, LITTLE_ENDIAN),\n // Length of each record\n recordLength: headerView.getUint16(10, LITTLE_ENDIAN),\n // Not sure if this is usually set\n languageDriver: headerView.getUint8(29)\n };\n}\n\n/**\n * @param view\n */\nfunction parseFieldDescriptors(view: DataView, textDecoder: TextDecoder): DBFField[] {\n // NOTE: this might overestimate the number of fields if the \"Database\n // Container\" container exists and is included in the headerLength\n const nFields = (view.byteLength - 1) / 32;\n const fields: DBFField[] = [];\n let offset = 0;\n for (let i = 0; i < nFields; i++) {\n const name = textDecoder\n .decode(new Uint8Array(view.buffer, view.byteOffset + offset, 11))\n // eslint-disable-next-line no-control-regex\n .replace(/\\u0000/g, '');\n\n fields.push({\n name,\n dataType: String.fromCharCode(view.getUint8(offset + 11)),\n fieldLength: view.getUint8(offset + 16),\n decimal: view.getUint8(offset + 17)\n });\n offset += 32;\n }\n return fields;\n}\n\n/*\n * @param {BinaryChunkReader} binaryReader\nfunction parseRows(binaryReader, fields, nRecords, recordLength, textDecoder) {\n const rows = [];\n for (let i = 0; i < nRecords; i++) {\n const recordView = binaryReader.getDataView(recordLength - 1);\n binaryReader.skip(1);\n // @ts-ignore\n rows.push(parseRow(recordView, fields, textDecoder));\n }\n return rows;\n}\n */\n\n/**\n *\n * @param view\n * @param fields\n * @param textDecoder\n * @returns\n */\nfunction parseRow(\n view: DataView,\n fields: DBFField[],\n textDecoder: TextDecoder\n): {[key: string]: any} {\n const out = {};\n let offset = 0;\n for (const field of fields) {\n const text = textDecoder.decode(\n new Uint8Array(view.buffer, view.byteOffset + offset, field.fieldLength)\n );\n out[field.name] = parseField(text, field.dataType);\n offset += field.fieldLength;\n }\n\n return out;\n}\n\n/**\n * Should NaN be coerced to null?\n * @param text\n * @param dataType\n * @returns Field depends on a type of the data\n */\nfunction parseField(text: string, dataType: string): string | number | boolean | null {\n switch (dataType) {\n case 'B':\n return parseNumber(text);\n case 'C':\n return parseCharacter(text);\n case 'F':\n return parseNumber(text);\n case 'N':\n return parseNumber(text);\n case 'O':\n return parseNumber(text);\n case 'D':\n return parseDate(text);\n case 'L':\n return parseBoolean(text);\n default:\n throw new Error('Unsupported data type');\n }\n}\n\n/**\n * Parse YYYYMMDD to date in milliseconds\n * @param str YYYYMMDD\n * @returns new Date as a number\n */\nfunction parseDate(str: any): number {\n return Date.UTC(str.slice(0, 4), parseInt(str.slice(4, 6), 10) - 1, str.slice(6, 8));\n}\n\n/**\n * Read boolean value\n * any of Y, y, T, t coerce to true\n * any of N, n, F, f coerce to false\n * otherwise null\n * @param value\n * @returns boolean | null\n */\nfunction parseBoolean(value: string): boolean | null {\n return /^[nf]$/i.test(value) ? false : /^[yt]$/i.test(value) ? true : null;\n}\n\n/**\n * Return null instead of NaN\n * @param text\n * @returns number | null\n */\nfunction parseNumber(text: string): number | null {\n const number = parseFloat(text);\n return isNaN(number) ? null : number;\n}\n\n/**\n *\n * @param text\n * @returns string | null\n */\nfunction parseCharacter(text: string): string | null {\n return text.trim() || null;\n}\n\n/**\n * Create a standard Arrow-style `Field` from field descriptor.\n * TODO - use `fieldLength` and `decimal` to generate smaller types?\n * @param param0\n * @returns Field\n */\n// eslint-disable\nfunction makeField({name, dataType, fieldLength, decimal}): Field {\n switch (dataType) {\n case 'B':\n return new Field(name, new Float64(), true);\n case 'C':\n return new Field(name, new Utf8(), true);\n case 'F':\n return new Field(name, new Float64(), true);\n case 'N':\n return new Field(name, new Float64(), true);\n case 'O':\n return new Field(name, new Float64(), true);\n case 'D':\n return new Field(name, new TimestampMillisecond(), true);\n case 'L':\n return new Field(name, new Bool(), true);\n default:\n throw new Error('Unsupported data type');\n }\n}\n"],"file":"parse-dbf.js"}
1
+ {"version":3,"sources":["../../../../src/lib/parsers/parse-dbf.ts"],"names":["LITTLE_ENDIAN","DBF_HEADER_SIZE","STATE","DBFParser","options","BinaryChunkReader","START","data","textDecoder","TextDecoder","encoding","arrayBuffer","binaryReader","write","state","parseState","result","end","END","ERROR","error","parseDBF","dbf","dbfParser","schema","shape","tables","format","table","rows","parseDBFInBatches","asyncIterator","parser","headerReturned","dbfHeader","length","dataView","getDataView","parseDBFHeader","progress","bytesUsed","rowsTotal","nRecords","FIELD_DESCRIPTORS","fieldDescriptorView","headerLength","dbfFields","parseFieldDescriptors","Schema","map","dbfField","makeField","FIELD_PROPERTIES","skip","recordLength","recordView","row","parseRow","push","message","headerView","year","getUint8","month","day","getUint32","getUint16","languageDriver","view","nFields","byteLength","fields","offset","i","name","decode","Uint8Array","buffer","byteOffset","replace","dataType","String","fromCharCode","fieldLength","decimal","out","field","text","parseField","parseNumber","parseCharacter","parseDate","parseBoolean","Error","str","Date","UTC","slice","parseInt","value","test","number","parseFloat","isNaN","trim","Field","Float64","Utf8","TimestampMillisecond","Bool"],"mappings":"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","sourcesContent":["import {\n Schema,\n Field,\n Bool,\n Utf8,\n Float64,\n TimestampMillisecond,\n ObjectRowTable\n} from '@loaders.gl/schema';\nimport BinaryChunkReader from '../streaming/binary-chunk-reader';\nimport {\n DBFLoaderOptions,\n DBFResult,\n DBFTableOutput,\n DBFHeader,\n DBFRowsOutput,\n DBFField\n} from './types';\n\nconst LITTLE_ENDIAN = true;\nconst DBF_HEADER_SIZE = 32;\n\nenum STATE {\n START = 0, // Expecting header\n FIELD_DESCRIPTORS = 1,\n FIELD_PROPERTIES = 2,\n END = 3,\n ERROR = 4\n}\n\nclass DBFParser {\n binaryReader = new BinaryChunkReader();\n textDecoder: TextDecoder;\n state = STATE.START;\n result: DBFResult = {\n data: []\n };\n\n constructor(options: {encoding: string}) {\n this.textDecoder = new TextDecoder(options.encoding);\n }\n\n /**\n * @param arrayBuffer\n */\n write(arrayBuffer: ArrayBuffer): void {\n this.binaryReader.write(arrayBuffer);\n this.state = parseState(this.state, this.result, this.binaryReader, this.textDecoder);\n // this.result.progress.bytesUsed = this.binaryReader.bytesUsed();\n\n // important events:\n // - schema available\n // - first rows available\n // - all rows available\n }\n\n end(): void {\n this.binaryReader.end();\n this.state = parseState(this.state, this.result, this.binaryReader, this.textDecoder);\n // this.result.progress.bytesUsed = this.binaryReader.bytesUsed();\n if (this.state !== STATE.END) {\n this.state = STATE.ERROR;\n this.result.error = 'DBF incomplete file';\n }\n }\n}\n\n/**\n * @param arrayBuffer\n * @param options\n * @returns DBFTable or rows\n */\nexport function parseDBF(\n arrayBuffer: ArrayBuffer,\n options: DBFLoaderOptions = {}\n): DBFRowsOutput | DBFTableOutput | ObjectRowTable {\n const {encoding = 'latin1'} = options.dbf || {};\n\n const dbfParser = new DBFParser({encoding});\n dbfParser.write(arrayBuffer);\n dbfParser.end();\n\n const {data, schema} = dbfParser.result;\n const shape = options?.tables?.format || options?.dbf?.shape;\n switch (shape) {\n case 'object-row-table': {\n const table: ObjectRowTable = {\n shape: 'object-row-table',\n schema,\n data\n };\n return table;\n }\n case 'table':\n return {schema, rows: data};\n case 'rows':\n default:\n return data;\n }\n}\n/**\n * @param asyncIterator\n * @param options\n */\nexport async function* parseDBFInBatches(\n asyncIterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>,\n options: DBFLoaderOptions = {}\n): AsyncIterable<DBFHeader | DBFRowsOutput | DBFTableOutput> {\n const {encoding = 'latin1'} = options.dbf || {};\n\n const parser = new DBFParser({encoding});\n let headerReturned = false;\n for await (const arrayBuffer of asyncIterator) {\n parser.write(arrayBuffer);\n if (!headerReturned && parser.result.dbfHeader) {\n headerReturned = true;\n yield parser.result.dbfHeader;\n }\n\n if (parser.result.data.length > 0) {\n yield parser.result.data;\n parser.result.data = [];\n }\n }\n parser.end();\n if (parser.result.data.length > 0) {\n yield parser.result.data;\n }\n}\n/**\n * https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm\n * @param state\n * @param result\n * @param binaryReader\n * @param textDecoder\n * @returns\n */\n/* eslint-disable complexity, max-depth */\nfunction parseState(\n state: STATE,\n result: DBFResult,\n binaryReader: BinaryChunkReader,\n textDecoder: TextDecoder\n): STATE {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n switch (state) {\n case STATE.ERROR:\n case STATE.END:\n return state;\n\n case STATE.START:\n // Parse initial file header\n // DBF Header\n const dataView = binaryReader.getDataView(DBF_HEADER_SIZE);\n if (!dataView) {\n return state;\n }\n result.dbfHeader = parseDBFHeader(dataView);\n result.progress = {\n bytesUsed: 0,\n rowsTotal: result.dbfHeader.nRecords,\n rows: 0\n };\n state = STATE.FIELD_DESCRIPTORS;\n break;\n\n case STATE.FIELD_DESCRIPTORS:\n // Parse DBF field descriptors (schema)\n const fieldDescriptorView = binaryReader.getDataView(\n // @ts-ignore\n result.dbfHeader.headerLength - DBF_HEADER_SIZE\n );\n if (!fieldDescriptorView) {\n return state;\n }\n\n result.dbfFields = parseFieldDescriptors(fieldDescriptorView, textDecoder);\n result.schema = new Schema(result.dbfFields.map((dbfField) => makeField(dbfField)));\n\n state = STATE.FIELD_PROPERTIES;\n\n // TODO(kyle) Not exactly sure why start offset needs to be headerLength + 1?\n // parsedbf uses ((fields.length + 1) << 5) + 2;\n binaryReader.skip(1);\n break;\n\n case STATE.FIELD_PROPERTIES:\n const {recordLength = 0, nRecords = 0} = result?.dbfHeader || {};\n while (result.data.length < nRecords) {\n const recordView = binaryReader.getDataView(recordLength - 1);\n if (!recordView) {\n return state;\n }\n // Note: Avoid actually reading the last byte, which may not be present\n binaryReader.skip(1);\n\n // @ts-ignore\n const row = parseRow(recordView, result.dbfFields, textDecoder);\n result.data.push(row);\n // @ts-ignore\n result.progress.rows = result.data.length;\n }\n state = STATE.END;\n break;\n\n default:\n state = STATE.ERROR;\n result.error = `illegal parser state ${state}`;\n return state;\n }\n } catch (error) {\n state = STATE.ERROR;\n result.error = `DBF parsing failed: ${(error as Error).message}`;\n return state;\n }\n }\n}\n\n/**\n * @param headerView\n */\nfunction parseDBFHeader(headerView: DataView): DBFHeader {\n return {\n // Last updated date\n year: headerView.getUint8(1) + 1900,\n month: headerView.getUint8(2),\n day: headerView.getUint8(3),\n // Number of records in data file\n nRecords: headerView.getUint32(4, LITTLE_ENDIAN),\n // Length of header in bytes\n headerLength: headerView.getUint16(8, LITTLE_ENDIAN),\n // Length of each record\n recordLength: headerView.getUint16(10, LITTLE_ENDIAN),\n // Not sure if this is usually set\n languageDriver: headerView.getUint8(29)\n };\n}\n\n/**\n * @param view\n */\nfunction parseFieldDescriptors(view: DataView, textDecoder: TextDecoder): DBFField[] {\n // NOTE: this might overestimate the number of fields if the \"Database\n // Container\" container exists and is included in the headerLength\n const nFields = (view.byteLength - 1) / 32;\n const fields: DBFField[] = [];\n let offset = 0;\n for (let i = 0; i < nFields; i++) {\n const name = textDecoder\n .decode(new Uint8Array(view.buffer, view.byteOffset + offset, 11))\n // eslint-disable-next-line no-control-regex\n .replace(/\\u0000/g, '');\n\n fields.push({\n name,\n dataType: String.fromCharCode(view.getUint8(offset + 11)),\n fieldLength: view.getUint8(offset + 16),\n decimal: view.getUint8(offset + 17)\n });\n offset += 32;\n }\n return fields;\n}\n\n/*\n * @param {BinaryChunkReader} binaryReader\nfunction parseRows(binaryReader, fields, nRecords, recordLength, textDecoder) {\n const rows = [];\n for (let i = 0; i < nRecords; i++) {\n const recordView = binaryReader.getDataView(recordLength - 1);\n binaryReader.skip(1);\n // @ts-ignore\n rows.push(parseRow(recordView, fields, textDecoder));\n }\n return rows;\n}\n */\n\n/**\n *\n * @param view\n * @param fields\n * @param textDecoder\n * @returns\n */\nfunction parseRow(\n view: DataView,\n fields: DBFField[],\n textDecoder: TextDecoder\n): {[key: string]: any} {\n const out = {};\n let offset = 0;\n for (const field of fields) {\n const text = textDecoder.decode(\n new Uint8Array(view.buffer, view.byteOffset + offset, field.fieldLength)\n );\n out[field.name] = parseField(text, field.dataType);\n offset += field.fieldLength;\n }\n\n return out;\n}\n\n/**\n * Should NaN be coerced to null?\n * @param text\n * @param dataType\n * @returns Field depends on a type of the data\n */\nfunction parseField(text: string, dataType: string): string | number | boolean | null {\n switch (dataType) {\n case 'B':\n return parseNumber(text);\n case 'C':\n return parseCharacter(text);\n case 'F':\n return parseNumber(text);\n case 'N':\n return parseNumber(text);\n case 'O':\n return parseNumber(text);\n case 'D':\n return parseDate(text);\n case 'L':\n return parseBoolean(text);\n default:\n throw new Error('Unsupported data type');\n }\n}\n\n/**\n * Parse YYYYMMDD to date in milliseconds\n * @param str YYYYMMDD\n * @returns new Date as a number\n */\nfunction parseDate(str: any): number {\n return Date.UTC(str.slice(0, 4), parseInt(str.slice(4, 6), 10) - 1, str.slice(6, 8));\n}\n\n/**\n * Read boolean value\n * any of Y, y, T, t coerce to true\n * any of N, n, F, f coerce to false\n * otherwise null\n * @param value\n * @returns boolean | null\n */\nfunction parseBoolean(value: string): boolean | null {\n return /^[nf]$/i.test(value) ? false : /^[yt]$/i.test(value) ? true : null;\n}\n\n/**\n * Return null instead of NaN\n * @param text\n * @returns number | null\n */\nfunction parseNumber(text: string): number | null {\n const number = parseFloat(text);\n return isNaN(number) ? null : number;\n}\n\n/**\n *\n * @param text\n * @returns string | null\n */\nfunction parseCharacter(text: string): string | null {\n return text.trim() || null;\n}\n\n/**\n * Create a standard Arrow-style `Field` from field descriptor.\n * TODO - use `fieldLength` and `decimal` to generate smaller types?\n * @param param0\n * @returns Field\n */\n// eslint-disable\nfunction makeField({name, dataType, fieldLength, decimal}: DBFField): Field {\n switch (dataType) {\n case 'B':\n return new Field(name, new Float64(), true);\n case 'C':\n return new Field(name, new Utf8(), true);\n case 'F':\n return new Field(name, new Float64(), true);\n case 'N':\n return new Field(name, new Float64(), true);\n case 'O':\n return new Field(name, new Float64(), true);\n case 'D':\n return new Field(name, new TimestampMillisecond(), true);\n case 'L':\n return new Field(name, new Bool(), true);\n default:\n throw new Error('Unsupported data type');\n }\n}\n"],"file":"parse-dbf.js"}