Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | 18x 18x 18x 18x 18x 18x 18x 18x | 'use strict'; const utils = require('./utils'); const types = require('./types'); // Grammar constants const ZERO = 0; const NC_DIMENSION = 10; const NC_VARIABLE = 11; const NC_ATTRIBUTE = 12; /** * Read the header of the file * @ignore * @param {IOBuffer} buffer - Buffer for the file data * @param {number} version - Version of the file * @return {object} - Object with the fields: * * `recordDimension`: Number with the length of record dimension * * `dimensions`: List of dimensions * * `globalAttributes`: List of global attributes * * `variables`: List of variables */ function header(buffer, version) { // Length of record dimension // sum of the varSize's of all the record variables. var header = { recordDimension: { length: buffer.readUint32() } }; // Version header.version = version; // List of dimensions var dimList = dimensionsList(buffer); header.recordDimension.id = dimList.recordId; // id of the unlimited dimension header.recordDimension.name = dimList.recordName; // name of the unlimited dimension header.dimensions = dimList.dimensions; // List of global attributes header.globalAttributes = attributesList(buffer); // List of variables var variables = variablesList(buffer, dimList.recordId, version); header.variables = variables.variables; header.recordDimension.recordStep = variables.recordStep; return header; } const NC_UNLIMITED = 0; /** * List of dimensions * @ignore * @param {IOBuffer} buffer - Buffer for the file data * @return {object} - Ojbect containing the following properties: * * `dimensions` that is an array of dimension object: * * `name`: String with the name of the dimension * * `size`: Number with the size of the dimension dimensions: dimensions * * `recordId`: the id of the dimension that has unlimited size or undefined, * * `recordName`: name of the dimension that has unlimited size */ function dimensionsList(buffer) { var recordId, recordName; const dimList = buffer.readUint32(); if (dimList === ZERO) { utils.notNetcdf((buffer.readUint32() !== ZERO), 'wrong empty tag for list of dimensions'); return []; } else { utils.notNetcdf((dimList !== NC_DIMENSION), 'wrong tag for list of dimensions'); // Length of dimensions const dimensionSize = buffer.readUint32(); var dimensions = new Array(dimensionSize); for (var dim = 0; dim < dimensionSize; dim++) { // Read name var name = utils.readName(buffer); // Read dimension size const size = buffer.readUint32(); I if (size === NC_UNLIMITED) { // in netcdf 3 one field can be of size unlimmited recordId = dim; recordName = name; } dimensions[dim] = { name: name, size: size }; } } return { dimensions: dimensions, recordId: recordId, recordName: recordName }; } /** * List of attributes * @ignore * @param {IOBuffer} buffer - Buffer for the file data * @return {Array<object>} - List of attributes with: * * `name`: String with the name of the attribute * * `type`: String with the type of the attribute * * `value`: A number or string with the value of the attribute */ function attributesList(buffer) { const gAttList = buffer.readUint32(); if (gAttList === ZERO) { utils.notNetcdf((buffer.readUint32() !== ZERO), 'wrong empty tag for list of attributes'); return []; } else { utils.notNetcdf((gAttList !== NC_ATTRIBUTE), 'wrong tag for list of attributes'); // Length of attributes const attributeSize = buffer.readUint32(); var attributes = new Array(attributeSize); for (var gAtt = 0; gAtt < attributeSize; gAtt++) { // Read name var name = utils.readName(buffer); // Read type var type = buffer.readUint32(); utils.notNetcdf(((type < 1) || (type > 6)), `non valid type ${type}`); // Read attribute var size = buffer.readUint32(); var value = types.readType(buffer, type, size); // Apply padding utils.padding(buffer); attributes[gAtt] = { name: name, type: types.num2str(type), value: value }; } } return attributes; } /** * List of variables * @ignore * @param {IOBuffer} buffer - Buffer for the file data * @param {number} recordId - Id of the unlimited dimension (also called record dimension) * This value may be undefined if there is no unlimited dimension * @param {number} version - Version of the file * @return {object} - Number of recordStep and list of variables with: * * `name`: String with the name of the variable * * `dimensions`: Array with the dimension IDs of the variable * * `attributes`: Array with the attributes of the variable * * `type`: String with the type of the variable * * `size`: Number with the size of the variable * * `offset`: Number with the offset where of the variable begins * * `record`: True if is a record variable, false otherwise (unlimited size) */ function variablesList(buffer, recordId, version) { const varList = buffer.readUint32(); var recordStep = 0; if (varList === ZERO) { utils.notNetcdf((buffer.readUint32() !== ZERO), 'wrong empty tag for list of variables'); return []; } else { utils.notNetcdf((varList !== NC_VARIABLE), 'wrong tag for list of variables'); // Length of variables const variableSize = buffer.readUint32(); var variables = new Array(variableSize); for (var v = 0; v < variableSize; v++) { // Read name var name = utils.readName(buffer); // Read dimensionality of the variable const dimensionality = buffer.readUint32(); // Index into the list of dimensions var dimensionsIds = new Array(dimensionality); for (var dim = 0; dim < dimensionality; dim++) { dimensionsIds[dim] = buffer.readUint32(); } // Read variables size var attributes = attributesList(buffer); // Read type var type = buffer.readUint32(); utils.notNetcdf(((type < 1) && (type > 6)), `non valid type ${type}`); // Read variable size // The 32-bit varSize field is not large enough to contain the size of variables that require // more than 2^32 - 4 bytes, so 2^32 - 1 is used in the varSize field for such variables. const varSize = buffer.readUint32(); // Read offset var offset = buffer.readUint32(); I if (version === 2) { utils.notNetcdf((offset > 0), 'offsets larger than 4GB not supported'); offset = buffer.readUint32(); } let record = false; // Count amount of record variables I if ((typeof recordId !== 'undefined') && (dimensionsIds[0] === recordId)) { recordStep += varSize; record = true; } variables[v] = { name: name, dimensions: dimensionsIds, attributes, type: types.num2str(type), size: varSize, offset, record }; } } return { variables: variables, recordStep: recordStep }; } module.exports = header; |