| 154 | } |
| 155 | |
| 156 | NumpyHeader parseHeader(ReadBuffer &buf) |
| 157 | { |
| 158 | /// Check magic bytes |
| 159 | const char * magic_string = "\x93NUMPY"; |
| 160 | assertString(magic_string, buf); |
| 161 | |
| 162 | /// Read npy version. |
| 163 | UInt8 version_major = 0; |
| 164 | UInt8 version_minor = 0; |
| 165 | readBinary(version_major, buf); |
| 166 | readBinary(version_minor, buf); |
| 167 | |
| 168 | /// Read header length. |
| 169 | UInt32 header_length = 0; |
| 170 | /// In v1 header length is 2 bytes, in v2 - 4 bytes. |
| 171 | if (version_major == 1) |
| 172 | { |
| 173 | UInt16 header_length_u16 = 0; |
| 174 | readBinaryLittleEndian(header_length_u16, buf); |
| 175 | header_length = header_length_u16; |
| 176 | } |
| 177 | else |
| 178 | { |
| 179 | readBinaryLittleEndian(header_length, buf); |
| 180 | } |
| 181 | |
| 182 | /// Remember current count of read bytes to skip remaining |
| 183 | /// bytes in header when we find all required fields. |
| 184 | size_t header_start = buf.count(); |
| 185 | |
| 186 | /// Start parsing header. |
| 187 | String shape; |
| 188 | String descr; |
| 189 | |
| 190 | assertChar('{', buf); |
| 191 | skipWhitespaceIfAny(buf); |
| 192 | bool first = true; |
| 193 | while (!checkChar('}', buf)) |
| 194 | { |
| 195 | /// Skip delimiter between key-value pairs. |
| 196 | if (!first) |
| 197 | { |
| 198 | skipWhitespaceIfAny(buf); |
| 199 | } |
| 200 | else |
| 201 | { |
| 202 | first = false; |
| 203 | } |
| 204 | |
| 205 | /// Read map key. |
| 206 | String key; |
| 207 | readQuotedString(key, buf); |
| 208 | assertChar(':', buf); |
| 209 | skipWhitespaceIfAny(buf); |
| 210 | /// Read map value. |
| 211 | String value; |
| 212 | readQuotedField(value, buf); |
| 213 | assertChar(',', buf); |
no test coverage detected