• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / loaders.gl / 20352515932

18 Dec 2025 09:56PM UTC coverage: 35.115% (-28.4%) from 63.485%
20352515932

push

github

web-flow
feat(loader-utils): Export is-type helpers (#3258)

1188 of 1998 branches covered (59.46%)

Branch coverage included in aggregate %.

147 of 211 new or added lines in 13 files covered. (69.67%)

30011 existing lines in 424 files now uncovered.

37457 of 108056 relevant lines covered (34.66%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.9
/modules/netcdf/src/netcdfjs/netcdf-reader.ts
1
import {IOBuffer} from '../iobuffer/iobuffer';
1✔
2
import type {
1✔
3
  NetCDFHeader,
1✔
4
  NetCDFDimension,
1✔
5
  NetCDFRecordDimension,
1✔
6
  NetCDFAttribute,
1✔
7
  NetCDFVariable
1✔
8
} from './netcdf-types';
1✔
9
import {readNetCDFHeader} from './read-header';
1✔
10
import {readRecord, readNonRecord} from './read-data';
1✔
11

1✔
12
/**
1✔
13
 * Reads a NetCDF v3.x file
1✔
14
 * https://www.unidata.ucar.edu/software/netcdf/docs/file_format_specifications.html
1✔
15
 * @param {ArrayBuffer} data - ArrayBuffer or any Typed Array (including Node.js' Buffer from v4) with the data
1✔
16
 * @constructor
1✔
17
 */
1✔
18
export class NetCDFReader {
1✔
19
  public header: NetCDFHeader;
1!
UNCOV
20
  public buffer: IOBuffer;
×
21

1✔
22
  constructor(data) {
1✔
UNCOV
23
    const buffer = new IOBuffer(data);
×
UNCOV
24
    buffer.setBigEndian();
×
UNCOV
25

×
UNCOV
26
    // Validate that it's a NetCDF file
×
UNCOV
27
    const magic = buffer.readChars(3);
×
UNCOV
28
    if (magic !== 'CDF') {
×
UNCOV
29
      throw new Error(`NetCDF: file should start with 'CDF', found ${magic}`);
×
UNCOV
30
    }
×
UNCOV
31

×
UNCOV
32
    // Check the NetCDF format
×
UNCOV
33
    const version = buffer.readByte();
×
UNCOV
34
    if (version > 2) {
×
35
      throw new Error(`NetCDF: unsupported version ${version}`);
×
36
    }
×
UNCOV
37

×
UNCOV
38
    // Read the header
×
UNCOV
39
    this.header = readNetCDFHeader(buffer, version);
×
UNCOV
40
    this.buffer = buffer;
×
UNCOV
41
  }
×
42

1✔
43
  /**
1✔
44
   * @return {string} - Version for the NetCDF format
1✔
45
   */
1✔
46
  get version() {
1✔
UNCOV
47
    if (this.header.version === 1) {
×
UNCOV
48
      return 'classic format';
×
UNCOV
49
    }
×
UNCOV
50
    return '64-bit offset format';
×
UNCOV
51
  }
×
52

1✔
53
  /**
1✔
54
   * Get metadata for the record dimension
1✔
55
   */
1✔
56
  get recordDimension(): NetCDFRecordDimension {
1✔
UNCOV
57
    return this.header.recordDimension;
×
UNCOV
58
  }
×
59

1✔
60
  /**
1✔
61
   * Get list of dimensions (each with `name` and `size`)
1✔
62
   */
1✔
63
  get dimensions(): NetCDFDimension[] {
1✔
UNCOV
64
    return this.header.dimensions;
×
UNCOV
65
  }
×
66

1✔
67
  /**
1✔
68
   * Get list of global attributes with:
1✔
69
   *  * `name`: String with the name of the attribute
1✔
70
   *  * `type`: String with the type of the attribute
1✔
71
   *  * `value`: A number or string with the value of the attribute
1✔
72
   */
1✔
73
  get attributes(): NetCDFAttribute[] {
1✔
UNCOV
74
    return this.header.attributes;
×
UNCOV
75
  }
×
76

1✔
77
  /**
1✔
78
   * Get list of variables
1✔
79
   */
1✔
80
  get variables(): NetCDFVariable[] {
1✔
UNCOV
81
    return this.header.variables;
×
UNCOV
82
  }
×
83

1✔
84
  /**
1✔
85
   * Check if an attribute exists
1✔
86
   * @param attributeName - Name of the attribute to find
1✔
87
   * @return
1✔
88
   */
1✔
89
  attributeExists(attributeName: string): boolean {
1✔
UNCOV
90
    const attribute = this.attributes.find((val) => val.name === attributeName);
×
UNCOV
91
    return attribute !== undefined;
×
UNCOV
92
  }
×
93

1✔
94
  /**
1✔
95
   * Returns the value of an attribute
1✔
96
   * @param attributeName
1✔
97
   * @return Value of the attributeName or null
1✔
98
   */
1✔
99
  getAttribute(attributeName: string): string | null {
1✔
100
    const attribute = this.attributes.find((val) => val.name === attributeName);
×
101
    if (attribute) return attribute.value;
×
102
    return null;
×
103
  }
×
104

1✔
105
  /**
1✔
106
   * Check if a dataVariable exists
1✔
107
   * @param variableName - Name of the variable to find
1✔
108
   * @return
1✔
109
   */
1✔
110
  dataVariableExists(variableName: string): boolean {
1✔
UNCOV
111
    const variable = this.header.variables.find(function (val) {
×
UNCOV
112
      return val.name === variableName;
×
UNCOV
113
    });
×
UNCOV
114
    return variable !== undefined;
×
UNCOV
115
  }
×
116

1✔
117
  /**
1✔
118
   * Returns the value of a variable as a string
1✔
119
   * @param variableName
1✔
120
   * @return Value of the variable as a string or null
1✔
121
   */
1✔
122
  getDataVariableAsString(variableName: string): string | null {
1✔
UNCOV
123
    const variable = this.getDataVariable(variableName);
×
UNCOV
124
    if (variable) return variable.join('');
×
125
    return null;
×
UNCOV
126
  }
×
127

1✔
128
  /**
1✔
129
   * Retrieves the data for a given variable
1✔
130
   * @param variableName - Name of the variable to search or variable object
1✔
131
   * @return List with the variable values
1✔
132
   */
1✔
133
  getDataVariable(variableName: string | object): any[] {
1✔
UNCOV
134
    let variable;
×
UNCOV
135
    if (typeof variableName === 'string') {
×
UNCOV
136
      // search the variable
×
UNCOV
137
      variable = this.header.variables.find(function (val) {
×
UNCOV
138
        return val.name === variableName;
×
UNCOV
139
      });
×
UNCOV
140
    } else {
×
UNCOV
141
      variable = variableName;
×
UNCOV
142
    }
×
UNCOV
143

×
UNCOV
144
    // throws if variable not found
×
UNCOV
145
    if (variable === undefined) {
×
UNCOV
146
      let errorOutput;
×
UNCOV
147
      if (typeof variableName === 'string') {
×
UNCOV
148
        errorOutput = variableName;
×
UNCOV
149
      } else if (typeof variableName === 'object') {
×
150
        errorOutput = JSON.stringify(variableName);
×
151
      }
×
UNCOV
152
      throw new Error(`NetCDF: variable not found: ${errorOutput}`);
×
UNCOV
153
    }
×
UNCOV
154

×
UNCOV
155
    // go to the offset position
×
UNCOV
156
    this.buffer.seek(variable.offset);
×
UNCOV
157

×
UNCOV
158
    if (variable.record) {
×
UNCOV
159
      // record variable case
×
UNCOV
160
      return readRecord(this.buffer, variable, this.header.recordDimension);
×
UNCOV
161
    }
×
UNCOV
162
    // non-record variable case
×
UNCOV
163
    return readNonRecord(this.buffer, variable);
×
UNCOV
164
  }
×
165

1✔
166
  toString(): string {
1✔
167
    const result: string[] = [];
×
168

×
169
    result.push('DIMENSIONS');
×
170
    for (const dimension of this.dimensions) {
×
171
      result.push(`  ${dimension.name.padEnd(30)} = size: ${dimension.size}`);
×
172
    }
×
173

×
174
    result.push('');
×
175
    result.push('GLOBAL ATTRIBUTES');
×
176
    for (const attribute of this.attributes) {
×
177
      result.push(`  ${attribute.name.padEnd(30)} = ${attribute.value}`);
×
178
    }
×
179

×
180
    const variables = JSON.parse(JSON.stringify(this.variables));
×
181
    result.push('');
×
182
    result.push('VARIABLES:');
×
183
    for (const variable of variables) {
×
184
      variable.value = this.getDataVariable(variable);
×
185
      let stringify = JSON.stringify(variable.value);
×
186
      if (stringify.length > 50) stringify = stringify.substring(0, 50);
×
187
      if (!isNaN(variable.value.length)) {
×
188
        stringify += ` (length: ${variable.value.length})`;
×
189
      }
×
190
      result.push(`  ${variable.name.padEnd(30)} = ${stringify}`);
×
191
    }
×
192
    return result.join('\n');
×
193
  }
×
194
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc