bes  Updated for version 3.20.5
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 CSV_Obj::CSV_Obj()
46 {
47  _reader = new CSV_Reader();
48  _header = new CSV_Header();
49  _data = new vector<CSV_Data*>();
50 }
51 
52 CSV_Obj::~CSV_Obj()
53 {
54  if (_reader) {
55  _reader->close();
56  delete _reader;
57  _reader = 0;
58  }
59  if (_header) {
60  delete _header;
61  _header = 0;
62  }
63  if (_data) {
64  CSV_Data *d = 0;
65  vector<CSV_Data*>::iterator i = _data->begin();
66  vector<CSV_Data*>::iterator e = _data->end();
67  while (i != e) {
68  d = (*i);
69  delete d;
70  _data->erase(i);
71  i = _data->begin();
72  e = _data->end();
73  }
74  delete _data;
75  _data = 0;
76  }
77 }
78 
79 bool CSV_Obj::open(const string& filepath)
80 {
81  return _reader->open(filepath);
82 }
83 
84 void CSV_Obj::load()
85 {
86  vector<string> txtLine;
87  bool OnHeader = true;
88  _reader->reset();
89  while (!_reader->eof()) {
90  _reader->get(txtLine);
91 
92  if (OnHeader) {
93  if (_header->populate(&txtLine)) {
94  for (unsigned int i = 0; i < txtLine.size(); i++) {
95  _data->push_back(new CSV_Data());
96  }
97  }
98  OnHeader = false;
99  }
100  else if (!txtLine.empty()) {
101  int index = 0;
102  vector<CSV_Data *>::iterator it = _data->begin();
103  vector<CSV_Data *>::iterator et = _data->end();
104  for (; it != et; it++) {
105  CSV_Data *d = (*it);
106  string token = txtLine.at(index);
107  CSV_Utils::slim(token);
108  CSV_Field *f = _header->getField(index);
109  if (!f) {
110  ostringstream err;
111  err << " Attempting to add value " << token << " to field " << index << ", field does not exist";
112  throw BESInternalError(err.str(), __FILE__, __LINE__);
113  }
114  d->insert(f, &token);
115  index++;
116  }
117  }
118  txtLine.clear();
119  }
120 }
121 
122 void CSV_Obj::getFieldList(vector<string> &list)
123 {
124  _header->getFieldList(list);
125 }
126 
127 string CSV_Obj::getFieldType(const string& fieldName)
128 {
129  return _header->getFieldType(fieldName);
130 }
131 
132 int CSV_Obj::getRecordCount()
133 {
134  CSV_Data* alphaField = _data->at(0);
135  string type = alphaField->getType();
136 
137  if (type.compare(string(STRING)) == 0) {
138  return ((vector<string>*) alphaField->getData())->size();
139  }
140  else if (type.compare(string(FLOAT32)) == 0) {
141  return ((vector<float>*) alphaField->getData())->size();
142  }
143  else if (type.compare(string(FLOAT64)) == 0) {
144  return ((vector<double>*) alphaField->getData())->size();
145  }
146  else if (type.compare(string(INT16)) == 0) {
147  return ((vector<short>*) alphaField->getData())->size();
148  }
149  else if (type.compare(string(INT32)) == 0) {
150  return ((vector<int>*) alphaField->getData())->size();
151  }
152  else {
153  return -1;
154  }
155 }
156 
157 void *
158 CSV_Obj::getFieldData(const string& field)
159 {
160  void *ret = 0;
161  CSV_Field *f = _header->getField(field);
162  if (f) {
163  int index = f->getIndex();
164  CSV_Data *d = _data->at(index);
165  if (d) {
166  ret = d->getData();
167  }
168  else {
169  string err = (string) "Unable to get data for field " + field;
170  throw BESInternalError(err, __FILE__, __LINE__);
171  }
172  }
173  else {
174  string err = (string) "Unable to get data for field " + field + ", no such field exists";
175  throw BESInternalError(err, __FILE__, __LINE__);
176  }
177  return ret;
178 }
179 
180 vector<string> CSV_Obj::getRecord(const int rowNum)
181 {
182  vector<string> record;
183  void* fieldData;
184  string type;
185 
186  int maxRows = getRecordCount();
187  if (rowNum > maxRows) {
188  ostringstream err;
189  err << "Attempting to retrieve row " << rowNum << " of " << maxRows;
190  throw BESInternalError(err.str(), __FILE__, __LINE__);
191  }
192 
193  vector<string> fieldList;
194  getFieldList(fieldList);
195  vector<string>::iterator it = fieldList.begin();
196  vector<string>::iterator et = fieldList.end();
197  for (; it != et; it++) {
198  string fieldName = (*it);
199  ostringstream oss;
200  fieldData = getFieldData(fieldName);
201  CSV_Field *f = _header->getField(fieldName);
202  if (!f) {
203  ostringstream err;
204  err << "Unable to retrieve data for field " << fieldName << " on row " << rowNum;
205  throw BESInternalError(err.str(), __FILE__, __LINE__);
206  }
207  type = f->getType();
208 
209  if (type.compare(string(STRING)) == 0) {
210  record.push_back(((vector<string>*) fieldData)->at(rowNum));
211  }
212  else if (type.compare(string(FLOAT32)) == 0) {
213  oss << ((vector<float>*) fieldData)->at(rowNum);
214  record.push_back(oss.str());
215  }
216  else if (type.compare(string(FLOAT64)) == 0) {
217  oss << ((vector<double>*) fieldData)->at(rowNum);
218  record.push_back(oss.str());
219  }
220  else if (type.compare(string(INT16)) == 0) {
221  oss << ((vector<short>*) fieldData)->at(rowNum);
222  record.push_back(oss.str());
223  }
224  else if (type.compare(string(INT32)) == 0) {
225  oss << ((vector<int>*) fieldData)->at(rowNum);
226  record.push_back(oss.str());
227  }
228  }
229 
230  return record;
231 }
232 
233 void CSV_Obj::dump(ostream &strm) const
234 {
235  strm << BESIndent::LMarg << "CSV_Obj::dump - (" << (void *) this << ")" << endl;
236  BESIndent::Indent();
237  if (_reader) {
238  strm << BESIndent::LMarg << "reader:" << endl;
239  BESIndent::Indent();
240  _reader->dump(strm);
241  BESIndent::UnIndent();
242  }
243  if (_header) {
244  strm << BESIndent::LMarg << "header:" << endl;
245  BESIndent::Indent();
246  _header->dump(strm);
247  BESIndent::UnIndent();
248  }
249  if (_data) {
250  strm << BESIndent::LMarg << "data:" << endl;
251  }
252  BESIndent::UnIndent();
253 }
254 
CSV_Field
Definition: CSV_Field.h:44
CSV_Header::dump
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
Definition: CSV_Header.cc:161
CSV_Obj::dump
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
Definition: CSV_Obj.cc:233
CSV_Data
Definition: CSV_Data.h:51
BESInternalError
exception thrown if inernal error encountered
Definition: BESInternalError.h:43
CSV_Utils::slim
static void slim(string &str)
Strips leading and trailing double quotes from string.
Definition: CSV_Utils.cc:87
CSV_Header
Definition: CSV_Header.h:48
CSV_Reader
Definition: CSV_Reader.h:48
CSV_Reader::dump
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
Definition: CSV_Reader.cc:108