-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDictionary.ts
152 lines (129 loc) · 6.62 KB
/
Dictionary.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright (c) 2016 - now David Sehnal, licensed under MIT License, See LICENSE file for more info.
*/
namespace CIFTools.Binary {
"use strict";
export class File implements CIFTools.File {
dataBlocks: DataBlock[];
toJSON() {
return this.dataBlocks.map(b => b.toJSON());
}
constructor(data: EncodedFile) {
this.dataBlocks = data.dataBlocks.map(b => new DataBlock(b));
}
}
export class DataBlock implements CIFTools.DataBlock {
private categoryMap: Map<string, Category>;
private categoryList: Category[];
header: string;
additionalData: { [name: string]: any } = {}
get categories() { return this.categoryList; }
getCategory(name: string) { return this.categoryMap.get(name); }
toJSON() {
return {
id: this.header,
categories: this.categoryList.map(c => c.toJSON()),
additionalData: this.additionalData
};
}
constructor(data: EncodedDataBlock) {
this.header = data.header;
this.categoryList = data.categories.map(c => new Category(c));
this.categoryMap = new Map<string, Category>();
for (let c of this.categoryList) {
this.categoryMap.set(c.name, c);
}
}
}
export class Category implements CIFTools.Category {
private encodedColumns: Map<string, EncodedColumn>;
private columnNameList: string[];
name: string;
columnCount: number;
rowCount: number;
get columnNames() { return this.columnNameList; }
getColumn(name: string): CIFTools.Column {
let w = this.encodedColumns.get(name);
if (w) return wrapColumn(w);
return CIFTools.UndefinedColumn;
}
toJSON() {
let rows: any[] = [];
let columns = this.columnNameList.map(name => ({ name, column: this.getColumn(name) }));
for (let i = 0; i < this.rowCount; i++) {
let item: any = {};
for (let c of columns) {
let d = c.column.getValuePresence(i);
if (d === ValuePresence.Present) item[c.name] = c.column.getString(i);
else if (d === ValuePresence.NotSpecified) item[c.name] = '.';
else item[c.name] = '?';
}
rows[i] = item;
}
return { name: this.name, columns: this.columnNames, rows };
}
constructor(data: EncodedCategory) {
this.name = data.name;
this.columnCount = data.columns.length;
this.rowCount = data.rowCount;
this.columnNameList = [];
this.encodedColumns = new Map<string, EncodedColumn>();
for (let c of data.columns) {
this.encodedColumns.set(c.name, c);
this.columnNameList.push(c.name);
}
}
}
function wrapColumn(column: EncodedColumn): Column {
if (!column.data.data) return CIFTools.UndefinedColumn;
let data = decode(column.data);
let mask: Uint8Array | undefined = void 0;
if (column.mask) mask = decode(column.mask);
if (data.buffer && data.byteLength && data.BYTES_PER_ELEMENT) {
return mask ? new MaskedNumericColumn(data, mask) : new NumericColumn(data);
}
return mask ? new MaskedStringColumn(data, mask) : new StringColumn(data);
}
import fastParseInt = CIFTools.Utils.FastNumberParsers.parseInt
import fastParseFloat = CIFTools.Utils.FastNumberParsers.parseFloat
class NumericColumn implements Column {
isDefined = true;
getString(row: number): string { return `${this.data[row]}`; }
getInteger(row: number): number { return this.data[row] | 0; }
getFloat(row: number): number { return 1.0 * this.data[row]; }
stringEquals(row: number, value: string) { return this.data[row] === fastParseFloat(value, 0, value.length); }
areValuesEqual(rowA: number, rowB: number) { return this.data[rowA] === this.data[rowB]; }
getValuePresence(row: number) { return ValuePresence.Present; }
constructor(private data: any) { }
}
class MaskedNumericColumn implements Column {
isDefined = true;
getString(row: number): string | null { return this.mask[row] === ValuePresence.Present ? `${this.data[row]}` : null; }
getInteger(row: number): number { return this.mask[row] === ValuePresence.Present ? this.data[row] : 0; }
getFloat(row: number): number { return this.mask[row] === ValuePresence.Present ? this.data[row] : 0; }
stringEquals(row: number, value: string) { return this.mask[row] === ValuePresence.Present ? this.data[row] === fastParseFloat(value, 0, value.length) : value === null || value === void 0; }
areValuesEqual(rowA: number, rowB: number) { return this.data[rowA] === this.data[rowB]; }
getValuePresence(row: number): ValuePresence { return this.mask[row]; }
constructor(private data: any, private mask: Uint8Array) { }
}
class StringColumn implements Column {
isDefined = true;
getString(row: number): string | null { return this.data[row]; }
getInteger(row: number): number { let v = this.data[row]; return fastParseInt(v, 0, v.length); }
getFloat(row: number): number { let v = this.data[row]; return fastParseFloat(v, 0, v.length); }
stringEquals(row: number, value: string) { return this.data[row] === value; }
areValuesEqual(rowA: number, rowB: number) { return this.data[rowA] === this.data[rowB]; }
getValuePresence(row: number) { return ValuePresence.Present; }
constructor(private data: string[]) { }
}
class MaskedStringColumn implements Column {
isDefined = true;
getString(row: number): string | null { return this.mask[row] === ValuePresence.Present ? this.data[row] : null; }
getInteger(row: number): number { if (this.mask[row] !== ValuePresence.Present) return 0; let v = this.data[row]; return fastParseInt(v || '', 0, (v || '').length); }
getFloat(row: number): number { if (this.mask[row] !== ValuePresence.Present) return 0; let v = this.data[row]; return fastParseFloat(v || '', 0, (v || '').length); }
stringEquals(row: number, value: string) { return this.data[row] === value; }
areValuesEqual(rowA: number, rowB: number) { return this.data[rowA] === this.data[rowB]; }
getValuePresence(row: number): ValuePresence { return this.mask[row]; }
constructor(private data: any, private mask: Uint8Array) { }
}
}