bes  Updated for version 3.20.6
CSV_Obj.cc
1 // CSV_Obj.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Stephan Zednik <zednik@ucar.edu> and Patrick West <pwest@ucar.edu>
8 // and Jose Garcia <jgarcia@ucar.edu>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact University Corporation for Atmospheric Research at
25 // 3080 Center Green Drive, Boulder, CO 80301
26 
27 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
28 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
29 //
30 // Authors:
31 // zednik Stephan Zednik <zednik@ucar.edu>
32 // pwest Patrick West <pwest@ucar.edu>
33 // jgarcia Jose Garcia <jgarcia@ucar.edu>
34 
35 #include <iostream>
36 #include <sstream>
37 #include <iomanip>
38 
39 #include "CSV_Obj.h"
40 #include "CSV_Utils.h"
41 
42 #include <BESInternalError.h>
43 #include <BESNotFoundError.h>
44 
45 using std::string;
46 using std::ostream;
47 using std::endl;
48 using std::vector;
49 using std::ostringstream;
50 
51 CSV_Obj::CSV_Obj()
52 {
53  _reader = new CSV_Reader();
54  _header = new CSV_Header();
55  _data = new vector<CSV_Data*>();
56 }
57 
58 CSV_Obj::~CSV_Obj()
59 {
60  if (_reader) {
61  _reader->close();
62  delete _reader;
63  _reader = 0;
64  }
65  if (_header) {
66  delete _header;
67  _header = 0;
68  }
69  if (_data) {
70  CSV_Data *d = 0;
71  vector<CSV_Data*>::iterator i = _data->begin();
72  vector<CSV_Data*>::iterator e = _data->end();
73  while (i != e) {
74  d = (*i);
75  delete d;
76  _data->erase(i);
77  i = _data->begin();
78  e = _data->end();
79  }
80  delete _data;
81  _data = 0;
82  }
83 }
84 
85 bool CSV_Obj::open(const string& filepath)
86 {
87  return _reader->open(filepath);
88 }
89 
90 void CSV_Obj::load()
91 {
92  vector<string> txtLine;
93  bool OnHeader = true;
94  _reader->reset();
95  while (!_reader->eof()) {
96  _reader->get(txtLine);
97 
98  if (OnHeader) {
99  if (_header->populate(&txtLine)) {
100  for (unsigned int i = 0; i < txtLine.size(); i++) {
101  _data->push_back(new CSV_Data());
102  }
103  }
104  OnHeader = false;
105  }
106  else if (!txtLine.empty()) {
107  int index = 0;
108  vector<CSV_Data *>::iterator it = _data->begin();
109  vector<CSV_Data *>::iterator et = _data->end();
110  for (; it != et; it++) {
111  CSV_Data *d = (*it);
112  string token = txtLine.at(index);
113  CSV_Utils::slim(token);
114  CSV_Field *f = _header->getField(index);
115  if (!f) {
116  ostringstream err;
117  err << " Attempting to add value " << token << " to field " << index << ", field does not exist";
118  throw BESInternalError(err.str(), __FILE__, __LINE__);
119  }
120  d->insert(f, &token);
121  index++;
122  }
123  }
124  txtLine.clear();
125  }
126 }
127 
128 void CSV_Obj::getFieldList(vector<string> &list)
129 {
130  _header->getFieldList(list);
131 }
132 
133 string CSV_Obj::getFieldType(const string& fieldName)
134 {
135  return _header->getFieldType(fieldName);
136 }
137 
138 int CSV_Obj::getRecordCount()
139 {
140  CSV_Data* alphaField = _data->at(0);
141  string type = alphaField->getType();
142 
143  if (type.compare(string(STRING)) == 0) {
144  return ((vector<string>*) alphaField->getData())->size();
145  }
146  else if (type.compare(string(FLOAT32)) == 0) {
147  return ((vector<float>*) alphaField->getData())->size();
148  }
149  else if (type.compare(string(FLOAT64)) == 0) {
150  return ((vector<double>*) alphaField->getData())->size();
151  }
152  else if (type.compare(string(INT16)) == 0) {
153  return ((vector<short>*) alphaField->getData())->size();
154  }
155  else if (type.compare(string(INT32)) == 0) {
156  return ((vector<int>*) alphaField->getData())->size();
157  }
158  else {
159  return -1;
160  }
161 }
162 
163 void *
164 CSV_Obj::getFieldData(const string& field)
165 {
166  void *ret = 0;
167  CSV_Field *f = _header->getField(field);
168  if (f) {
169  int index = f->getIndex();
170  CSV_Data *d = _data->at(index);
171  if (d) {
172  ret = d->getData();
173  }
174  else {
175  string err = (string) "Unable to get data for field " + field;
176  throw BESInternalError(err, __FILE__, __LINE__);
177  }
178  }
179  else {
180  string err = (string) "Unable to get data for field " + field + ", no such field exists";
181  throw BESInternalError(err, __FILE__, __LINE__);
182  }
183  return ret;
184 }
185 
186 vector<string> CSV_Obj::getRecord(const int rowNum)
187 {
188  vector<string> record;
189  void* fieldData;
190  string type;
191 
192  int maxRows = getRecordCount();
193  if (rowNum > maxRows) {
194  ostringstream err;
195  err << "Attempting to retrieve row " << rowNum << " of " << maxRows;
196  throw BESInternalError(err.str(), __FILE__, __LINE__);
197  }
198 
199  vector<string> fieldList;
200  getFieldList(fieldList);
201  vector<string>::iterator it = fieldList.begin();
202  vector<string>::iterator et = fieldList.end();
203  for (; it != et; it++) {
204  string fieldName = (*it);
205  ostringstream oss;
206  fieldData = getFieldData(fieldName);
207  CSV_Field *f = _header->getField(fieldName);
208  if (!f) {
209  ostringstream err;
210  err << "Unable to retrieve data for field " << fieldName << " on row " << rowNum;
211  throw BESInternalError(err.str(), __FILE__, __LINE__);
212  }
213  type = f->getType();
214 
215  if (type.compare(string(STRING)) == 0) {
216  record.push_back(((vector<string>*) fieldData)->at(rowNum));
217  }
218  else if (type.compare(string(FLOAT32)) == 0) {
219  oss << ((vector<float>*) fieldData)->at(rowNum);
220  record.push_back(oss.str());
221  }
222  else if (type.compare(string(FLOAT64)) == 0) {
223  oss << ((vector<double>*) fieldData)->at(rowNum);
224  record.push_back(oss.str());
225  }
226  else if (type.compare(string(INT16)) == 0) {
227  oss << ((vector<short>*) fieldData)->at(rowNum);
228  record.push_back(oss.str());
229  }
230  else if (type.compare(string(INT32)) == 0) {
231  oss << ((vector<int>*) fieldData)->at(rowNum);
232  record.push_back(oss.str());
233  }
234  }
235 
236  return record;
237 }
238 
239 void CSV_Obj::dump(ostream &strm) const
240 {
241  strm << BESIndent::LMarg << "CSV_Obj::dump - (" << (void *) this << ")" << endl;
242  BESIndent::Indent();
243  if (_reader) {
244  strm << BESIndent::LMarg << "reader:" << endl;
245  BESIndent::Indent();
246  _reader->dump(strm);
247  BESIndent::UnIndent();
248  }
249  if (_header) {
250  strm << BESIndent::LMarg << "header:" << endl;
251  BESIndent::Indent();
252  _header->dump(strm);
253  BESIndent::UnIndent();
254  }
255  if (_data) {
256  strm << BESIndent::LMarg << "data:" << endl;
257  }
258  BESIndent::UnIndent();
259 }
260 
CSV_Field
Definition: CSV_Field.h:42
CSV_Utils::slim
static void slim(std::string &str)
Strips leading and trailing double quotes from string.
Definition: CSV_Utils.cc:91
CSV_Data
Definition: CSV_Data.h:49
CSV_Header::dump
virtual void dump(std::ostream &strm) const
dump the contents of this object to the specified ostream
Definition: CSV_Header.cc:168
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
CSV_Header
Definition: CSV_Header.h:46
CSV_Reader
Definition: CSV_Reader.h:46
CSV_Obj::dump
virtual void dump(std::ostream &strm) const
dump the contents of this object to the specified ostream
Definition: CSV_Obj.cc:239
CSV_Reader::dump
virtual void dump(std::ostream &strm) const
dump the contents of this object to the specified ostream
Definition: CSV_Reader.cc:115