diff --git a/include/npy.hpp b/include/npy.hpp index 3898e87..2c215fa 100644 --- a/include/npy.hpp +++ b/include/npy.hpp @@ -503,6 +503,78 @@ inline npy_data read_npy(std::istream &in) { return data; } +template +inline npy_data read_npy_partial(std::istream &in,shape_t shape_requested,std::size_t byte_offset) { + std::string header_s = read_header(in); + + // parse header + const header_t header = parse_header(header_s); + + // check if the typestring matches the given one + const dtype_t dtype = dtype_map.at(std::type_index(typeid(Scalar))); + + if (header.dtype.tie() != dtype.tie()) { + throw std::runtime_error("formatting error: typestrings not matching"); + } + + // compute the data size based on the shape the user requested + const auto requested_size=static_cast(comp_size(shape_requested)); + + npy_data data; + + data.shape = shape_requested; + data.fortran_order = header.fortran_order; + + data.data.resize(requested_size); + + // read the data + if (byte_offset>0){ + in.seekg(byte_offset,std::ios::beg); + } + in.read(reinterpret_cast(data.data.data()), sizeof(Scalar) * requested_size); + if (!in){ + std::cerr<<"ERROR: partial read failed!"< +inline void read_npy_into(std::istream &in, npy_data &data) { + std::string header_s = read_header(in); + + // parse header + header_t header = parse_header(header_s); + + // check if the typestring matches the given one + const dtype_t dtype = dtype_map.at(std::type_index(typeid(Scalar))); + + if (header.dtype.tie() != dtype.tie()) { + throw std::runtime_error("formatting error: typestrings not matching"); + } + + // compute the data size based on the shape + auto size = static_cast(comp_size(header.shape)); + + data.shape = header.shape; + data.fortran_order = header.fortran_order; + + // This will now do nothing + if (data.data.size() != size) { + data.data.resize(size); + } + + // read the data + in.read(reinterpret_cast(data.data.data()), sizeof(Scalar) * size); + return; +} + + +inline shape_t read_npy_shape(std::istream& in) { + std::string header_s = read_header(in); + header_t header = parse_header(header_s); + return header.shape; +} + template inline npy_data read_npy(const std::string &filename) { std::ifstream stream(filename, std::ifstream::binary); @@ -513,6 +585,35 @@ inline npy_data read_npy(const std::string &filename) { return read_npy(stream); } +template +inline npy_data read_npy_partial(const std::string &filename,shape_t shape,std::size_t byte_offset) { + std::ifstream stream(filename, std::ifstream::binary); + if (!stream) { + throw std::runtime_error("io error: failed to open a file."); + } + + return read_npy_partial(stream, shape, byte_offset); +} + +inline shape_t read_npy_shape(const std::string &filename) { + std::ifstream stream(filename, std::ifstream::binary); + if (!stream) { + throw std::runtime_error("io error: failed to open a file."); + } + + return read_npy_shape(stream); +} + +template +inline void read_npy_into(const std::string &filename, npy_data &data) { + std::ifstream stream(filename, std::ifstream::binary); + if (!stream) { + throw std::runtime_error("io error: failed to open a file."); + } + read_npy_into(stream, data); + return; +} + template inline void write_npy(std::ostream &out, const npy_data &data) { // static_assert(has_typestring::value, "scalar type not