diff --git a/include/libnpy/npy.hpp b/include/libnpy/npy.hpp
index 9b6f7fb..24244ca 100644
--- a/include/libnpy/npy.hpp
+++ b/include/libnpy/npy.hpp
@@ -20,16 +20,21 @@
    SOFTWARE.
 */
 
+#ifndef NPY_H
+#define NPY_H
+
 #include <complex>
 #include <fstream>
 #include <string>
 #include <iostream>
 #include <sstream>
 #include <cstdint>
+#include <cstring>
 #include <vector>
 #include <stdexcept>
 #include <algorithm>
 #include <regex>
+#include <unordered_map>
 
 
 namespace npy {
@@ -61,29 +66,28 @@
     big_endian_char : 
     little_endian_char );
 
+/* npy array length */
+typedef unsigned long int ndarray_len_t;
+
 inline void write_magic(std::ostream& ostream, unsigned char v_major=1, unsigned char v_minor=0) {
   ostream.write(magic_string, magic_string_length);
   ostream.put(v_major);
   ostream.put(v_minor);
 }
 
-inline void read_magic(std::istream& istream, unsigned char *v_major, unsigned char *v_minor) {
-  char *buf = new char[magic_string_length+2];
+inline void read_magic(std::istream& istream, unsigned char& v_major, unsigned char& v_minor) {
+  char buf[magic_string_length+2];
   istream.read(buf, magic_string_length+2);
 
   if(!istream) {
-      throw std::runtime_error("io error: failed reading file");
+    throw std::runtime_error("io error: failed reading file");
   }
 
-  for (size_t i=0; i < magic_string_length; i++) {
-    if(buf[i] != magic_string[i]) {
-      throw std::runtime_error("this file do not have a valid npy format.");
-    }
-  }
+  if (0 != std::memcmp(buf, magic_string, magic_string_length))
+    throw std::runtime_error("this file does not have a valid npy format.");
 
-  *v_major = buf[magic_string_length];
-  *v_minor = buf[magic_string_length+1];
-  delete[] buf;
+  v_major = buf[magic_string_length];
+  v_minor = buf[magic_string_length+1];
 }
 
 // typestring magic
@@ -101,25 +105,40 @@
       return std::string(buf);
     }
 
-    Typestring(std::vector<float>& v) :c_endian {host_endian_char}, c_type {'f'}, len {sizeof(float)} {}
-    Typestring(std::vector<double>& v) :c_endian {host_endian_char}, c_type {'f'}, len {sizeof(double)} {}
-    Typestring(std::vector<long double>& v) :c_endian {host_endian_char}, c_type {'f'}, len {sizeof(long double)} {}
+    Typestring(const std::vector<float>& v) 
+      :c_endian {host_endian_char}, c_type {'f'}, len {sizeof(float)} {}
+    Typestring(const std::vector<double>& v) 
+      :c_endian {host_endian_char}, c_type {'f'}, len {sizeof(double)} {}
+    Typestring(const std::vector<long double>& v) 
+      :c_endian {host_endian_char}, c_type {'f'}, len {sizeof(long double)} {}
 
-    Typestring(std::vector<char>& v) :c_endian {no_endian_char}, c_type {'i'}, len {sizeof(char)} {}
-    Typestring(std::vector<short>& v) :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(short)} {}
-    Typestring(std::vector<int>& v) :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(int)} {}
-    Typestring(std::vector<long>& v) :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(long)} {}
-    Typestring(std::vector<long long>& v) :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(long long)} {}
+    Typestring(const std::vector<char>& v) 
+      :c_endian {no_endian_char}, c_type {'i'}, len {sizeof(char)} {}
+    Typestring(const std::vector<short>& v) 
+      :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(short)} {}
+    Typestring(const std::vector<int>& v) 
+      :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(int)} {}
+    Typestring(const std::vector<long>& v)
+      :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(long)} {}
+    Typestring(const std::vector<long long>& v) :c_endian {host_endian_char}, c_type {'i'}, len {sizeof(long long)} {}
 
-    Typestring(std::vector<unsigned char>& v) :c_endian {no_endian_char}, c_type {'u'}, len {sizeof(unsigned char)} {}
-    Typestring(std::vector<unsigned short>& v) :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned short)} {}
-    Typestring(std::vector<unsigned int>& v) :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned int)} {}
-    Typestring(std::vector<unsigned long>& v) :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned long)} {}
-    Typestring(std::vector<unsigned long long>& v) :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned long long)} {}
+    Typestring(const std::vector<unsigned char>& v)
+      :c_endian {no_endian_char}, c_type {'u'}, len {sizeof(unsigned char)} {}
+    Typestring(const std::vector<unsigned short>& v)
+      :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned short)} {}
+    Typestring(const std::vector<unsigned int>& v)
+      :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned int)} {}
+    Typestring(const std::vector<unsigned long>& v)
+      :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned long)} {}
+    Typestring(const std::vector<unsigned long long>& v)
+      :c_endian {host_endian_char}, c_type {'u'}, len {sizeof(unsigned long long)} {}
 
-    Typestring(std::vector<std::complex<float>>& v) :c_endian {host_endian_char}, c_type {'c'}, len {sizeof(std::complex<float>)} {}
-    Typestring(std::vector<std::complex<double>>& v) :c_endian {host_endian_char}, c_type {'c'}, len {sizeof(std::complex<double>)} {}
-    Typestring(std::vector<std::complex<long double>>& v) :c_endian {host_endian_char}, c_type {'c'}, len {sizeof(std::complex<long double>)} {}
+    Typestring(const std::vector<std::complex<float>>& v)
+      :c_endian {host_endian_char}, c_type {'c'}, len {sizeof(std::complex<float>)} {}
+    Typestring(const std::vector<std::complex<double>>& v)
+      :c_endian {host_endian_char}, c_type {'c'}, len {sizeof(std::complex<double>)} {}
+    Typestring(const std::vector<std::complex<long double>>& v)
+      :c_endian {host_endian_char}, c_type {'c'}, len {sizeof(std::complex<long double>)} {}
 };
 
 inline void parse_typestring( std::string typestring){
@@ -133,39 +152,174 @@
   }
 }
 
-/* Helpers for the improvised parser */
-inline std::string unwrap_s(std::string s, char delim_front, char delim_back) {
-  if ((s.back() == delim_back) && (s.front() == delim_front))
-    return s.substr(1, s.length()-2);
-  else
-    throw std::runtime_error("unable to unwrap");
+namespace pyparse {
+
+/**
+  Removes leading and trailing whitespaces
+  */
+inline std::string trim(const std::string& str) {
+  const std::string whitespace = " \t";
+  auto begin = str.find_first_not_of(whitespace);
+
+  if (begin == std::string::npos)
+    return "";
+
+  auto end = str.find_last_not_of(whitespace);
+
+  return str.substr(begin, end-begin+1);
 }
 
-inline std::string get_value_from_map(std::string mapstr) {
+
+inline std::string get_value_from_map(const std::string& mapstr) {
   size_t sep_pos = mapstr.find_first_of(":");
   if (sep_pos == std::string::npos)
     return "";
 
-  return mapstr.substr(sep_pos+1);
+  std::string tmp = mapstr.substr(sep_pos+1);
+  return trim(tmp);
 }
 
-inline void pop_char(std::string& s, char c) {
-  if (s.back() == c)
-    s.pop_back();
+/**
+   Parses the string representation of a Python dict
+
+   The keys need to be known and may not appear anywhere else in the data.
+ */
+inline std::unordered_map<std::string, std::string> parse_dict(std::string in, std::vector<std::string>& keys) {
+
+  std::unordered_map<std::string, std::string> map;
+
+  if (keys.size() == 0)
+    return map;
+
+  in = trim(in);
+
+  // unwrap dictionary
+  if ((in.front() == '{') && (in.back() == '}'))
+    in = in.substr(1, in.length()-2);
+  else
+    throw std::runtime_error("Not a Python dictionary.");
+
+  std::vector<std::pair<size_t, std::string>> positions;
+
+  for (auto const& value : keys) {
+    size_t pos = in.find( "'" + value + "'" );
+
+    if (pos == std::string::npos)
+      throw std::runtime_error("Missing '"+value+"' key.");
+
+    std::pair<size_t, std::string> position_pair { pos, value };
+    positions.push_back(position_pair);
+  }
+
+  // sort by position in dict
+  std::sort(positions.begin(), positions.end() );
+
+  for(size_t i = 0; i < positions.size(); ++i) {
+    std::string raw_value;
+    size_t begin { positions[i].first };
+    size_t end { std::string::npos };
+
+    std::string key = positions[i].second;
+
+    if ( i+1 < positions.size() )
+      end = positions[i+1].first;
+
+    raw_value = in.substr(begin, end-begin);
+
+    raw_value = trim(raw_value);
+
+    if (raw_value.back() == ',')
+      raw_value.pop_back();
+
+    map[key] = get_value_from_map(raw_value);
+  }
+
+  return map;
 }
 
-inline void ParseHeader(std::string header, std::string& descr, bool *fortran_order, std::vector<unsigned long>& shape) {
+/**
+  Parses the string representation of a Python boolean
+  */
+inline bool parse_bool(const std::string& in) {
+  if (in == "True")
+    return true;
+  if (in == "False")
+    return false;
+
+  throw std::runtime_error("Invalid python boolan.");
+}
+
+/**
+  Parses the string representation of a Python str
+  */
+inline std::string parse_str(const std::string& in) {
+  if ((in.front() == '\'') && (in.back() == '\''))
+    return in.substr(1, in.length()-2);
+
+  throw std::runtime_error("Invalid python string.");
+}
+
+/**
+  Parses the string represenatation of a Python tuple into a vector of its items
+ */
+inline std::vector<std::string> parse_tuple(std::string in) {
+  std::vector<std::string> v;
+  const char seperator = ',';
+
+  in = trim(in);
+
+  if ((in.front() == '(') && (in.back() == ')'))
+    in = in.substr(1, in.length()-2);
+  else
+    throw std::runtime_error("Invalid Python tuple.");
+
+  std::istringstream iss(in);
+
+  for (std::string token; std::getline(iss, token, seperator);) {
+      v.push_back(token);
+  }
+
+  return v;
+}
+
+template <typename T>
+inline std::string write_tuple(const std::vector<T>& v) {
+  if (v.size() == 0)
+    return "";
+
+  std::ostringstream ss;
+
+  if (v.size() == 1) {
+    ss << "(" << v.front() << ",)";
+  } else {
+    const std::string delimiter = ", ";
+    // v.size() > 1
+    ss << "(";
+    std::copy(v.begin(), v.end()-1, std::ostream_iterator<T>(ss, delimiter.c_str()));
+    ss << v.back();
+    ss << ")";
+  }
+
+  return ss.str();
+}
+
+inline std::string write_boolean(bool b) {
+  if(b)
+    return "True";
+  else
+    return "False";
+}
+
+} // namespace pyparse
+
+
+inline void parse_header(std::string header, std::string& descr, bool& fortran_order, std::vector<ndarray_len_t>& shape) {
   /*
      The first 6 bytes are a magic string: exactly "x93NUMPY".
-
      The next 1 byte is an unsigned byte: the major version number of the file format, e.g. x01.
-
      The next 1 byte is an unsigned byte: the minor version number of the file format, e.g. x00. Note: the version of the file format is not tied to the version of the numpy package.
-
      The next 2 bytes form a little-endian unsigned short int: the length of the header data HEADER_LEN.
-
      The next HEADER_LEN bytes form the header data describing the array's format. It is an ASCII string which contains a Python literal expression of a dictionary. It is terminated by a newline ('n') and padded with spaces ('x20') to make the total length of the magic string + 4 + HEADER_LEN be evenly divisible by 16 for alignment purposes.
-
      The dictionary contains three keys:
 
      "descr" : dtype.descr
@@ -182,128 +336,61 @@
     throw std::runtime_error("invalid header");
   header.pop_back();
 
-  // remove all whitespaces
-  header.erase(std::remove(header.begin(), header.end(), ' '), header.end());
+  // parse the dictionary
+  std::vector<std::string> keys { "descr", "fortran_order", "shape" };
+  auto dict_map = npy::pyparse::parse_dict(header, keys);
 
-  // unwrap dictionary
-  header = unwrap_s(header, '{', '}');
+  if (dict_map.size() == 0)
+    throw std::runtime_error("invalid dictionary in header");
 
-  // find the positions of the 3 dictionary keys
-  size_t keypos_descr = header.find("'descr'");
-  size_t keypos_fortran = header.find("'fortran_order'");
-  size_t keypos_shape = header.find("'shape'");
+  std::string descr_s = dict_map["descr"];
+  std::string fortran_s = dict_map["fortran_order"];
+  std::string shape_s = dict_map["shape"];
 
-  // make sure all the keys are present
-  if (keypos_descr == std::string::npos)
-    throw std::runtime_error("missing 'descr' key");
-  if (keypos_fortran == std::string::npos)
-    throw std::runtime_error("missing 'fortran_order' key");
-  if (keypos_shape == std::string::npos)
-    throw std::runtime_error("missing 'shape' key");
-
-  // Make sure the keys are in order.
-  // Note that this violates the standard, which states that readers *must* not 
-  // depend on the correct order here.
-  // TODO: fix
-  if (keypos_descr >= keypos_fortran || keypos_fortran >= keypos_shape)
-    throw std::runtime_error("header keys in wrong order");
-
-  // get the 3 key-value pairs
-  std::string keyvalue_descr;
-  keyvalue_descr = header.substr(keypos_descr, keypos_fortran - keypos_descr);
-  pop_char(keyvalue_descr, ',');
-
-  std::string keyvalue_fortran;
-  keyvalue_fortran = header.substr(keypos_fortran, keypos_shape - keypos_fortran);
-  pop_char(keyvalue_fortran, ',');
-
-  std::string keyvalue_shape;
-  keyvalue_shape = header.substr(keypos_shape, std::string::npos);
-  pop_char(keyvalue_shape, ',');
-
-  // get the values (right side of `:')
-  std::string descr_s = get_value_from_map(keyvalue_descr);
-  std::string fortran_s = get_value_from_map(keyvalue_fortran);
-  std::string shape_s = get_value_from_map(keyvalue_shape);
-
+  // TODO: extract info from typestring
   parse_typestring(descr_s);
-  descr = unwrap_s(descr_s, '\'', '\'');
+  // remove 
+  descr = npy::pyparse::parse_str(descr_s);
 
   // convert literal Python bool to C++ bool
-  if (fortran_s == "True")
-    *fortran_order = true;
-  else if (fortran_s == "False")
-    *fortran_order = false;
-  else
-    throw std::runtime_error("invalid fortran_order value");
+  fortran_order = npy::pyparse::parse_bool(fortran_s);
 
-  // parse the shape Python tuple ( x, y, z,)
+  // parse the shape tuple
+  auto shape_v = npy::pyparse::parse_tuple(shape_s);
+  if (shape_v.size() == 0)
+    throw std::runtime_error("invalid shape tuple in header");
 
-  // first clear the vector
-  shape.clear();
-  shape_s = unwrap_s(shape_s, '(', ')');
-
-  // a tokenizer would be nice... 
-  size_t pos = 0;
-  size_t pos_next;
-  for(;;) {
-    pos_next = shape_s.find_first_of(',', pos);
-    std::string dim_s;
-    if (pos_next != std::string::npos)
-      dim_s = shape_s.substr(pos, pos_next - pos);
-    else
-      dim_s = shape_s.substr(pos);
-    pop_char(dim_s, ',');
-    if (dim_s.length() == 0) {
-      if (pos_next != std::string::npos)
-        throw std::runtime_error("invalid shape");
-    }else{
-      std::stringstream ss;
-      ss << dim_s;
-      unsigned long tmp;
-      ss >> tmp;
-      shape.push_back(tmp);
-    }
-    if (pos_next != std::string::npos)
-      pos = ++pos_next;
-    else
-      break;
+  for ( auto item : shape_v ) {
+    std::stringstream stream(item);
+    unsigned long value;
+    stream >> value;
+    ndarray_len_t dim = static_cast<ndarray_len_t>(value);
+    shape.push_back(dim);
   }
 }
 
-inline void WriteHeader(std::ostream& out, const std::string& descr, bool fortran_order, unsigned int n_dims, const unsigned long shape[])
+
+inline std::string write_header_dict(const std::string& descr, bool fortran_order, const std::vector<ndarray_len_t>& shape) {
+    std::string s_fortran_order = npy::pyparse::write_boolean(fortran_order);
+    std::string shape_s = npy::pyparse::write_tuple(shape);
+
+    return "{'descr': '" + descr + "', 'fortran_order': " + s_fortran_order + ", 'shape': " + shape_s + ", }";
+}
+
+inline void write_header(std::ostream& out, const std::string& descr, bool fortran_order, const std::vector<ndarray_len_t>& shape_v)
 {
-    std::ostringstream ss_header;
-    std::string s_fortran_order;
-    if (fortran_order)
-      s_fortran_order = "True";
-    else
-      s_fortran_order = "False";
+    std::string header_dict = write_header_dict(descr, fortran_order, shape_v);
 
-    std::ostringstream ss_shape;
-    ss_shape << "(";
-    for (unsigned int n=0; n < n_dims; n++){
-      ss_shape << shape[n] << ", ";
-    }
-    ss_shape << ")";
-
-    ss_header << "{'descr': '" << descr << "', 'fortran_order': " << s_fortran_order << ", 'shape': " << ss_shape.str() << " }";
-
-    size_t header_len_pre = ss_header.str().length() + 1;
-    size_t metadata_len = magic_string_length + 2 + 2 + header_len_pre;
+    size_t length = magic_string_length + 2 + 2 + header_dict.length() + 1;
 
     unsigned char version[2] = {1, 0};
-    if (metadata_len >= 255*255) {
-      metadata_len = magic_string_length + 2 + 4 + header_len_pre;
+    if (length >= 255*255) {
+      length = magic_string_length + 2 + 4 + header_dict.length() + 1;
       version[0] = 2;
       version[1] = 0;
     }
-    size_t padding_len = 16 - metadata_len % 16;
+    size_t padding_len = 16 - length % 16;
     std::string padding (padding_len, ' ');
-    ss_header << padding;
-    ss_header << '\n';
-
-    std::string header = ss_header.str();
 
     // write magic
     write_magic(out, version[0], version[1]);
@@ -311,14 +398,14 @@
     // write header length
     if (version[0] == 1 && version[1] == 0) {
       char header_len_le16[2];
-      uint16_t header_len = header.length();
+      uint16_t header_len = header_dict.length() + padding.length() + 1;
 
       header_len_le16[0] = (header_len >> 0) & 0xff;
       header_len_le16[1] = (header_len >> 8) & 0xff;
       out.write(reinterpret_cast<char *>(header_len_le16), 2);
     }else{
       char header_len_le32[4];
-      uint32_t header_len = header.length();
+      uint32_t header_len = header_dict.length() + padding.length() + 1;
 
       header_len_le32[0] = (header_len >> 0) & 0xff;
       header_len_le32[1] = (header_len >> 8) & 0xff;
@@ -327,96 +414,89 @@
       out.write(reinterpret_cast<char *>(header_len_le32), 4);
     }
 
-    out << header;
+    out << header_dict << padding << '\n';
 }
 
-inline std::string read_header_1_0(std::istream& istream) {
-    // read header length and convert from little endian
-    char header_len_le16[2];
-    istream.read(header_len_le16, 2);
+inline std::string read_header(std::istream& istream) {
+    // check magic bytes an version number
+    unsigned char v_major, v_minor;
+    read_magic(istream, v_major, v_minor);
 
-    uint16_t header_length = (header_len_le16[0] << 0) | (header_len_le16[1] << 8);
+    uint32_t header_length;
+    if(v_major == 1 && v_minor == 0){
 
-    if((magic_string_length + 2 + 2 + header_length) % 16 != 0) {
+      char header_len_le16[2];
+      istream.read(header_len_le16, 2);
+      header_length = (header_len_le16[0] << 0) | (header_len_le16[1] << 8);
+
+      if((magic_string_length + 2 + 2 + header_length) % 16 != 0) {
+          // TODO: display warning
+      }
+    }else if(v_major == 2 && v_minor == 0) {
+      char header_len_le32[4];
+      istream.read(header_len_le32, 4);
+
+      header_length = (header_len_le32[0] <<  0) | (header_len_le32[1] <<  8)
+                    | (header_len_le32[2] << 16) | (header_len_le32[3] <<  24);
+
+      if((magic_string_length + 2 + 4 + header_length) % 16 != 0) {
         // TODO: display warning
+      }
+    }else{
+       throw std::runtime_error("unsupported file format version");
     }
 
-    char *buf = new char[header_length];
-    istream.read(buf, header_length);
-    std::string header (buf, header_length);
-    delete[] buf;
+    auto buf_v = std::vector<char>();
+    buf_v.reserve(header_length);
+    istream.read(buf_v.data(), header_length);
+    std::string header(buf_v.data(), header_length);
 
     return header;
 }
 
-inline std::string read_header_2_0(std::istream& istream) {
-    // read header length and convert from little endian
-    char header_len_le32[4];
-    istream.read(header_len_le32, 4);
+inline ndarray_len_t comp_size(const std::vector<ndarray_len_t>& shape) {
+    ndarray_len_t size = 1;
+    for (ndarray_len_t i : shape )
+      size *= i;
 
-    uint32_t header_length = (header_len_le32[0] <<  0) | (header_len_le32[1] <<  8)
-                           | (header_len_le32[2] << 16) | (header_len_le32[3] <<  24);
-
-    if((magic_string_length + 2 + 4 + header_length) % 16 != 0) {
-      // TODO: display warning
-    }
-
-    char *buf = new char[header_length];
-    istream.read(buf, header_length);
-    std::string header (buf, header_length);
-    delete[] buf;
-
-    return header;
+    return size;
 }
 
 template<typename Scalar>
-void SaveArrayAsNumpy( const std::string& filename, bool fortran_order, unsigned int n_dims, const unsigned long shape[], const std::vector<Scalar>& data)
+inline void SaveArrayAsNumpy( const std::string& filename, bool fortran_order, unsigned int n_dims, const unsigned long shape[], const std::vector<Scalar>& data)
 {
-    Typestring typestring_o {data};
+    Typestring typestring_o(data);
     std::string typestring = typestring_o.str();
 
     std::ofstream stream( filename, std::ofstream::binary);
     if(!stream) {
         throw std::runtime_error("io error: failed to open a file.");
     }
-    WriteHeader(stream, typestring, fortran_order, n_dims, shape);
 
-    size_t size = 1;
-    for (unsigned int i=0; i<n_dims; ++i)
-      size *= shape[i];
-    stream.write(reinterpret_cast<const char*>(&data[0]), sizeof(Scalar) * size);
+    std::vector<ndarray_len_t> shape_v(shape, shape+n_dims);
+    write_header(stream, typestring, fortran_order, shape_v);
+
+    auto size = static_cast<size_t>(comp_size(shape_v));
+
+    stream.write(reinterpret_cast<const char*>(data.data()), sizeof(Scalar) * size);
 }
 
 
-/**
-
- */
 template<typename Scalar>
-void LoadArrayFromNumpy(const std::string& filename, std::vector<unsigned long>& shape, std::vector<Scalar>& data)
+inline void LoadArrayFromNumpy(const std::string& filename, std::vector<unsigned long>& shape, std::vector<Scalar>& data)
 {
     std::ifstream stream(filename, std::ifstream::binary);
     if(!stream) {
         throw std::runtime_error("io error: failed to open a file.");
     }
-    // check magic bytes an version number
-    unsigned char v_major, v_minor;
-    read_magic(stream, &v_major, &v_minor);
 
-    std::string header;
-
-    if(v_major == 1 && v_minor == 0){
-      header = read_header_1_0(stream);
-    }else if(v_major == 2 && v_minor == 0) {
-      header = read_header_2_0(stream);
-    }else{
-       throw std::runtime_error("unsupported file format version");
-    }
+    std::string header = read_header(stream);
 
     // parse header
     bool fortran_order;
     std::string typestr;
 
-    ParseHeader(header, typestr, &fortran_order, shape);
+    parse_header(header, typestr, fortran_order, shape);
 
     // check if the typestring matches the given one
     Typestring typestring_o {data};
@@ -425,15 +505,15 @@
       throw std::runtime_error("formatting error: typestrings not matching");
     }
 
+
     // compute the data size based on the shape
-    size_t total_size = 1;
-    for(size_t i=0; i<shape.size(); ++i) {
-        total_size *= shape[i];
-    }
-    data.resize(total_size);
+    auto size = static_cast<size_t>(comp_size(shape));
+    data.resize(size);
 
     // read the data
-    stream.read(reinterpret_cast<char*>(&data[0]), sizeof(Scalar)*total_size);
+    stream.read(reinterpret_cast<char*>(data.data()), sizeof(Scalar)*size);
 }
 
 } // namespace npy
+
+#endif // NPY_H
