MCPcopy Create free account
hub / github.com/LadybugDB/ladybug / parseHeader

Method parseHeader

src/processor/operator/persistent/reader/npy/npy_reader.cpp:102–153  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

100}
101
102void NpyReader::parseHeader() {
103 // The first 6 bytes are a magic string: exactly \x93NUMPY
104 char* magicString = (char*)mmapRegion;
105 const char* expectedMagicString = "\x93NUMPY";
106 if (memcmp(magicString, expectedMagicString, 6) != 0) {
107 throw CopyException("Invalid NPY file");
108 }
109
110 // The next 1 byte is an unsigned byte: the major version number of the file
111 // format, e.g. x01.
112 char* majorVersion = magicString + 6;
113 if (*majorVersion != 1) {
114 throw CopyException("Unsupported NPY file version.");
115 }
116 // The next 1 byte is an unsigned byte: the minor version number of the file
117 // format, e.g. x00. Note: the version of the file format is not tied to the
118 // version of the numpy package.
119 char* minorVersion = majorVersion + 1;
120 if (*minorVersion != 0) {
121 throw CopyException("Unsupported NPY file version.");
122 }
123 // The next 2 bytes form a little-endian unsigned short int: the length of
124 // the header data HEADER_LEN.
125 auto headerLength = *(unsigned short int*)(minorVersion + 1);
126 if (!isLittleEndian()) {
127 headerLength = ((headerLength & 0xff00) >> 8) | ((headerLength & 0x00ff) << 8);
128 }
129
130 // The next HEADER_LEN bytes form the header data describing the array's
131 // format. It is an ASCII string which contains a Python literal expression
132 // of a dictionary. It is terminated by a newline ('n') and padded with
133 // spaces ('x20') to make the total length of the magic string + 4 +
134 // HEADER_LEN be evenly divisible by 16 for alignment purposes.
135 auto metaInfoLength = strlen(expectedMagicString) + 4;
136 char* header = (char*)mmapRegion + metaInfoLength;
137 auto headerEnd = std::find(header, header + headerLength, '}');
138
139 std::string headerString(header, headerEnd + 1);
140 std::unordered_map<std::string, std::string> headerMap =
141 pyparse::parse_dict(headerString, {"descr", "fortran_order", "shape"});
142 auto isFortranOrder = pyparse::parse_bool(headerMap["fortran_order"]);
143 if (isFortranOrder) {
144 throw CopyException("Fortran-order NPY files are not currently supported.");
145 }
146 auto descr = pyparse::parse_str(headerMap["descr"]);
147 parseType(descr);
148 auto shapeV = pyparse::parse_tuple(headerMap["shape"]);
149 for (auto const& item : shapeV) {
150 shape.emplace_back(std::stoul(item));
151 }
152 dataOffset = metaInfoLength + headerLength;
153}
154
155void NpyReader::parseType(std::string descr) {
156 if (descr[0] == '<' || descr[0] == '>') {

Callers

nothing calls this directly

Calls 2

isLittleEndianFunction · 0.85
emplace_backMethod · 0.80

Tested by

no test coverage detected