]> git.treefish.org Git - phys/latlib.git/blob - datread.cpp
41d3724930f34ebc4b63cfc75a26a87b7cf42fde
[phys/latlib.git] / datread.cpp
1 #include "datread.h"
2
3 #define HEADER_READOK   0
4 #define HEADER_READERR  1
5 #define HEADER_READLAST 2
6
7 datread::datread (const unsigned int& _blocksize, ostream *_log) : blocksize(_blocksize), log(_log)
8 {
9   inbuffer = NULL;
10 }
11
12 int datread::openFile (const string& filename)
13
14   infile.open(filename.c_str(), std::ios::binary);
15
16   if ( ! infile.is_open() ) return -1;
17   
18   if( filename.substr(filename.size()-4) == ".dat" ) {
19     format = Format::DAT;
20   }
21   else if( filename.substr(filename.size()-4) == "edat" ) {
22     format = Format::EDAT;
23   }
24   else if( filename.substr(filename.size()-4) == "sdat" ) {
25     format = Format::SDAT;
26     getline(infile, parastring);
27   }
28
29   if (inbuffer != NULL)
30     delete inbuffer;
31   
32   inbuffer = new boost::iostreams::filtering_istreambuf;
33   inbuffer->push( boost::iostreams::bzip2_decompressor() );
34   inbuffer->push(infile);
35
36   return 0;
37 }
38
39 datread::~datread ()
40 {
41   if (inbuffer != NULL)
42     delete inbuffer;
43 }
44
45 int datread::readDataToMem (char *tmpData, long unsigned int dataSize)
46 {
47   int readturn = -1;
48
49   if ( dataSize == 0 ) return 0;
50
51   try { readturn = boost::iostreams::read(*inbuffer, tmpData, dataSize); }
52   catch(boost::iostreams::bzip2_error& error) { 
53     if(log) *log << "DATREAD: Caught bzip2 exception with error code: " << error.error() << endl << flush;
54     infile.close();
55   } 
56   catch (std::exception const& ex) {
57     if(log) *log << "DATREAD: Caught exception: " << ex.what() << endl << flush;
58     infile.close();
59   }
60   catch( ... ) {
61     if(log) *log << "DATREAD: Caught unknown exception while reading." << endl << flush;
62     infile.close();
63   }
64
65   return readturn;
66 }
67
68 int datread::readHeader ()
69 {
70   long unsigned int headersize;
71   
72   if( readDataToMem((char *)&headersize, sizeof(long unsigned int)) == sizeof(long unsigned int) && infile.is_open() ) {
73     if ( headersize == 0 )
74       return HEADER_READLAST;
75
76     pair<unsigned long, void *> newHeader;
77
78     if( readDataToMem((char *)&newHeader.first, sizeof(unsigned long)) == sizeof(unsigned long) && infile.is_open() ) {
79       newHeader.second = malloc(headersize);
80
81       if( readDataToMem((char *)newHeader.second, headersize) == headersize && infile.is_open() ) {
82         headerStore.push_back(newHeader);
83         return HEADER_READOK;
84       }
85       else {
86         if(log) *log << "DATREAD: Could not read heade-data! Closing dat-file." << endl << flush;
87         infile.close();
88         return HEADER_READERR;
89       }
90     }
91     else {
92       if(log) *log << "DATREAD: Could not read headerid-hash! Closing dat-file." << endl << flush;
93       infile.close();
94       return HEADER_READERR;
95     }
96   }
97   else {
98     if(log) *log << "DATREAD: Could not read header size. Closing dat-file." << endl << flush;
99     infile.close();
100     return HEADER_READERR;
101   }
102 }
103
104 void datread::deleteHeaderStore ()
105 {
106   while ( headerStore.size() > 0 ) {
107     free(headerStore.back().second);
108     headerStore.pop_back();
109   }
110 }
111
112 bool datread::readAllHeaders ()
113 {
114   int readHeaderStatus;
115
116   deleteHeaderStore();
117   
118   do {
119     readHeaderStatus = readHeader();
120   }
121   while ( readHeaderStatus == HEADER_READOK );
122
123   if ( readHeaderStatus == HEADER_READLAST ) return true;
124   else if ( readHeaderStatus == HEADER_READERR ) return false;
125 }
126
127 int datread::readFullBlock (char *tmpData)
128 {
129   if ( ! infile.is_open() )
130     return -4;
131     
132   /* try to read header */
133   if ( format == Format::EDAT || format == Format::SDAT )
134     if ( ! readAllHeaders() ) {
135       infile.close();
136       return -1;
137     }
138       
139   /* read data */
140   if ( readDataToMem(tmpData, blocksize) != blocksize ) {
141     if(log) *log << "DATREAD: Could not read full datablock. Closing dat-file." << endl << flush;
142     infile.close();
143     return -2;
144   }
145     
146   if ( ! infile.is_open() )
147     return -3;
148
149   return 0;
150 }
151
152 void * datread::getHeader (const string& headerid) {
153   for (vector< pair<unsigned long, void *> >::iterator headerStoreIt = headerStore.begin(); headerStoreIt != headerStore.end(); ++headerStoreIt)
154     if ( headerStoreIt->first == hash(headerid) )
155       return headerStoreIt->second;
156   
157   return NULL;
158 }
159
160 bool datread::fisopen ()
161 {
162   return infile.is_open();
163 }
164
165 unsigned long datread::hash(const string& str)
166 {
167   unsigned long hash = 5381;
168
169   for(string::const_iterator it=str.begin();it!=str.end();it++) 
170     hash = ((hash << 5) + hash) + *it; /* hash * 33 + character */
171
172   return hash;
173 }
174
175 string datread::getParaString ()
176 {
177   return parastring;
178 }
179
180 void datread::closeFile ()
181 {
182   if ( infile.is_open() )
183     infile.close();
184 }