Skip to content

Commit

Permalink
add error handling (removes compile warnings)
Browse files Browse the repository at this point in the history
  • Loading branch information
temporaer committed Apr 17, 2013
1 parent 58b7ca8 commit add0e5b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
43 changes: 30 additions & 13 deletions cnpy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,19 @@ template<> std::vector<char>& cnpy::operator+=(std::vector<char>& lhs, const std

template<> std::vector<char>& cnpy::operator+=(std::vector<char>& lhs, const char* rhs) {
//write in little endian
char len = strlen(rhs);
for(char byte = 0; byte < len; byte++) {
size_t len = strlen(rhs);
lhs.reserve(len);
for(size_t byte = 0; byte < len; byte++) {
lhs.push_back(rhs[byte]);
}
return lhs;
}

void cnpy::parse_npy_header(FILE* fp, unsigned int& word_size, unsigned int*& shape, unsigned int& ndims) {
char buffer[256];
fread(buffer,sizeof(char),11,fp);
size_t res = fread(buffer,sizeof(char),11,fp);
if(res != 11)
throw std::runtime_error("parse_npy_header: failed fread");
std::string header = fgets(buffer,256,fp);
assert(header[header.size()-1] == '\n');

Expand All @@ -76,7 +79,7 @@ void cnpy::parse_npy_header(FILE* fp, unsigned int& word_size, unsigned int*& sh
if(str_shape[str_shape.size()-1] == ',') ndims = 1;
else ndims = std::count(str_shape.begin(),str_shape.end(),',')+1;
shape = new unsigned int[ndims];
for(int i = 0;i < ndims;i++) {
for(unsigned int i = 0;i < ndims;i++) {
loc1 = str_shape.find(",");
shape[i] = atoi(str_shape.substr(0,loc1).c_str());
str_shape = str_shape.substr(loc1+1);
Expand All @@ -89,7 +92,7 @@ void cnpy::parse_npy_header(FILE* fp, unsigned int& word_size, unsigned int*& sh
bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
assert(littleEndian);

char type = header[loc1+1];
//char type = header[loc1+1];
//assert(type == map_type(T));

std::string str_ws = header.substr(loc1+2);
Expand All @@ -101,7 +104,9 @@ void cnpy::parse_zip_footer(FILE* fp, unsigned short& nrecs, unsigned int& globa
{
std::vector<char> footer(22);
fseek(fp,-22,SEEK_END);
fread(&footer[0],sizeof(char),22,fp);
size_t res = fread(&footer[0],sizeof(char),22,fp);
if(res != 22)
throw std::runtime_error("parse_zip_footer: failed fread");

unsigned short disk_no, disk_start, nrecs_on_disk, comment_len;
disk_no = *(unsigned short*) &footer[4];
Expand All @@ -123,13 +128,15 @@ cnpy::NpyArray load_the_npy_file(FILE* fp) {
unsigned int ndims, word_size;
cnpy::parse_npy_header(fp,word_size,shape,ndims);
unsigned long long size = 1; //long long so no overflow when multiplying by word_size
for(int i = 0;i < ndims;i++) size *= shape[i];
for(unsigned int i = 0;i < ndims;i++) size *= shape[i];

cnpy::NpyArray arr;
arr.word_size = word_size;
arr.shape = std::vector<unsigned int>(shape,shape+ndims);
arr.data = new char[size*word_size];
int nread = fread(arr.data,word_size,size,fp);
size_t nread = fread(arr.data,word_size,size,fp);
if(nread != size)
throw std::runtime_error("load_the_npy_file: failed fread");
return arr;
}

Expand All @@ -143,15 +150,19 @@ cnpy::npz_t cnpy::npz_load(std::string fname) {

while(1) {
std::vector<char> local_header(30);
fread(&local_header[0],sizeof(char),30,fp);
size_t headerres = fread(&local_header[0],sizeof(char),30,fp);
if(headerres != 30)
throw std::runtime_error("npz_load: failed fread");

//if we've reached the global header, stop reading
if(local_header[2] != 0x03 || local_header[3] != 0x04) break;

//read in the variable name
unsigned short name_len = *(unsigned short*) &local_header[26];
std::string varname(name_len,' ');
fread(&varname[0],sizeof(char),name_len,fp);
size_t vname_res = fread(&varname[0],sizeof(char),name_len,fp);
if(vname_res != name_len)
throw std::runtime_error("npz_load: failed fread");

//erase the lagging .npy
varname.erase(varname.end()-4,varname.end());
Expand All @@ -160,7 +171,9 @@ cnpy::npz_t cnpy::npz_load(std::string fname) {
unsigned short extra_field_len = *(unsigned short*) &local_header[28];
if(extra_field_len > 0) {
std::vector<char> buff(extra_field_len);
fread(&buff[0],sizeof(char),extra_field_len,fp);
size_t efield_res = fread(&buff[0],sizeof(char),extra_field_len,fp);
if(efield_res != extra_field_len)
throw std::runtime_error("npz_load: failed fread");
}

arrays[varname] = load_the_npy_file(fp);
Expand All @@ -180,15 +193,19 @@ cnpy::NpyArray cnpy::npz_load(std::string fname, std::string varname) {

while(1) {
std::vector<char> local_header(30);
fread(&local_header[0],sizeof(char),30,fp);
size_t header_res = fread(&local_header[0],sizeof(char),30,fp);
if(header_res != 30)
throw std::runtime_error("npz_load: failed fread");

//if we've reached the global header, stop reading
if(local_header[2] != 0x03 || local_header[3] != 0x04) break;

//read in the variable name
unsigned short name_len = *(unsigned short*) &local_header[26];
std::string vname(name_len,' ');
fread(&vname[0],sizeof(char),name_len,fp);
size_t vname_res = fread(&vname[0],sizeof(char),name_len,fp);
if(vname_res != name_len)
throw std::runtime_error("npz_load: failed fread");
vname.erase(vname.end()-4,vname.end()); //erase the lagging .npy

//read in the extra field
Expand Down
6 changes: 5 additions & 1 deletion cnpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define LIBCNPY_H_

#include<string>
#include<stdexcept>
#include<sstream>
#include<vector>
#include<cstdio>
Expand Down Expand Up @@ -131,7 +132,10 @@ namespace cnpy {
parse_zip_footer(fp,nrecs,global_header_size,global_header_offset);
fseek(fp,global_header_offset,SEEK_SET);
global_header.resize(global_header_size);
fread(&global_header[0],sizeof(char),global_header_size,fp);
size_t res = fread(&global_header[0],sizeof(char),global_header_size,fp);
if(res != global_header_size){
throw std::runtime_error("npz_save: header read error while adding to existing zip");
}
fseek(fp,global_header_offset,SEEK_SET);
}
else {
Expand Down

0 comments on commit add0e5b

Please sign in to comment.