DataCSV.cpp
Go to the documentation of this file.
1 /*
2 MIT LICENSE
3 
4 Copyright (c) 2014-2020 Inertial Sense, Inc. - http://inertialsense.com
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
7 
8 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include <ctime>
14 #include <time.h>
15 #include <string>
16 #include <sstream>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <iomanip>
20 #include <iostream>
21 #include <fstream>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stddef.h>
25 #include <inttypes.h>
26 #include <math.h>
27 #include "DataCSV.h"
28 #include "ISLogger.h"
29 #include "data_sets.h"
30 #include "ISDataMappings.h"
31 #include "ISUtilities.h"
32 #include "ISConstants.h"
33 
34 #ifdef USE_IS_INTERNAL
35 # include "../../libs/IS_internal.h"
36 #endif
37 
38 
39 int cDataCSV::WriteHeaderToFile(FILE* pFile, uint32_t id)
40 {
41  // Verify file pointer
42  if (pFile == NULL || id >= DID_COUNT)
43  {
44  return 0;
45  }
46  //map_lookup_name_t::const_iterator offsetMap = cISDataMappings::GetMap().find(id);
47  const map_name_to_info_t* offsetMap = cISDataMappings::GetMapInfo(id);
48  //if (offsetMap == cISDataMappings::GetMap().end())
49  if (offsetMap == NULLPTR)
50  {
51  return 0;
52  }
53  string header("_ID_");
54  for (map_name_to_info_t::const_iterator offset = offsetMap->begin(); offset != offsetMap->end(); offset++)
55  {
56  header += ",";
57  header += offset->first;
58  }
59  header += "\n";
60  fputs(header.c_str(), pFile);
61  return (int)header.length();
62 }
63 
64 
65 int cDataCSV::ReadHeaderFromFile(FILE* pFile, uint32_t id, vector<data_info_t>& columnHeaders)
66 {
67 #if PLATFORM_IS_EMBEDDED
68 
69  return 0;
70 
71 #else
72 
73  (void)id;
74 
75  char line[8192];
76  line[0] = '\0';
77  if (fgets(line, _ARRAY_BYTE_COUNT(line), pFile) == NULL || ferror(pFile) != 0)
78  {
79  return 0;
80  }
81  const map_name_to_info_t* offsetMap = cISDataMappings::GetMapInfo(id);
82  stringstream stream(line);
83  string columnHeader;
84  columnHeaders.clear();
85  while (stream.good())
86  {
87  getline(stream, columnHeader, ',');
88  while (columnHeader.length() > 0 && (columnHeader[columnHeader.size() - 1] == '\r' || columnHeader[columnHeader.size() - 1] == '\n'))
89  {
90  columnHeader.resize(columnHeader.size() - 1);
91  }
92  if (columnHeader.length() == 0)
93  {
94  columnHeader = "UNKNOWN";
95  }
96  if (columnHeader == "_ID_")
97  {
98  columnHeaders.push_back({ 0xFFFFFFFF, 0xFFFFFFFF, DataTypeInt64, "_ID_" });
99  }
100  else
101  {
102  map_name_to_info_t::const_iterator offset = offsetMap->find(columnHeader);
103  if (offset == offsetMap->end())
104  {
105  columnHeaders.push_back({ 0xFFFFFFFF, 0xFFFFFFFF, DataTypeBinary, columnHeader });
106  }
107  else
108  {
109  columnHeaders.push_back(offset->second);
110  }
111  }
112  }
113  return (int)strnlen(line, _ARRAY_BYTE_COUNT(line));
114 #endif
115 }
116 
117 int cDataCSV::WriteDataToFile(uint64_t orderId, FILE* pFile, const p_data_hdr_t& dataHdr, const uint8_t* dataBuf)
118 {
119  // Verify file pointer
120  if (pFile == NULL || cISDataMappings::GetSize(dataHdr.id) == 0)
121  {
122  return 0;
123  }
124  string s;
125  if (!DataToStringCSV(dataHdr, dataBuf, s))
126  {
127  return 0;
128  }
129  char tmp[64];
130  SNPRINTF(tmp, 64, "%llu", (long long unsigned int)orderId);
131  fputs(tmp, pFile);
132  fputc(',', pFile);
133  fputs(s.c_str(), pFile);
134 
135  // return the data string length plus comma plus order id string
136  return (int)s.length() + 1 + (int)strnlen(tmp, sizeof(tmp));
137 }
138 
139 bool cDataCSV::StringCSVToData(string& s, p_data_hdr_t& hdr, uint8_t* buf, uint32_t bufSize, const vector<data_info_t>& columnHeaders)
140 {
141  const map_name_to_info_t* offsetMap = cISDataMappings::GetMapInfo(hdr.id);
142  if (offsetMap == NULLPTR || hdr.offset != 0 || hdr.size == 0 || bufSize < hdr.size)
143  {
144  return false;
145  }
146  while (s.length() > 0 && (s[s.size() - 1] == '\r' || s[s.size() - 1] == '\n'))
147  {
148  s.resize(s.size() - 1);
149  }
150  // for parsing logic, last comma will allow last field to parse properly
151  s += ",";
152  string columnData;
153  string::const_iterator start = s.begin();
154  uint32_t index = 0;
155  hdr.offset = 0;
156  hdr.size = cISDataMappings::GetSize(hdr.id);
157  bool inQuotes = false;
158  uint32_t foundQuotes = 0;
159  memset(buf, 0, hdr.size);
160  for (string::const_iterator i = start; i < s.end() && index < columnHeaders.size(); i++)
161  {
162  if (*i == ',' && !inQuotes)
163  {
164  // end field
165  columnData = string(start + foundQuotes, i - foundQuotes);
166  start = i + 1;
167  const data_info_t& data = columnHeaders[index++];
168  if (data.dataOffset < MAX_DATASET_SIZE && !cISDataMappings::StringToData(columnData.c_str(), (int)columnData.length(), &hdr, buf, data))
169  {
170  return false;
171  }
172  foundQuotes = false;
173  }
174  else if (*i == '"')
175  {
176  inQuotes = !inQuotes;
177  foundQuotes |= (uint32_t)inQuotes;
178  }
179  }
180  return true;
181 }
182 
183 
184 bool cDataCSV::DataToStringCSV(const p_data_hdr_t& hdr, const uint8_t* buf, string& csv)
185 {
186  csv.clear();
187  string columnData;
188  const map_name_to_info_t* offsetMap = cISDataMappings::GetMapInfo(hdr.id);
189  if (offsetMap == NULLPTR)
190  {
191  return false;
192  }
194  const uint8_t* bufPtr = buf;
195  uint8_t tmpBuffer[MAX_DATASET_SIZE];
196  uint32_t size = cISDataMappings::GetSize(hdr.id);
197  if (size > hdr.size)
198  {
199  // copy into temp buffer, zeroing out bytes that are not part of this packet
200  memset(tmpBuffer, 0, hdr.offset);
201  memcpy(tmpBuffer + hdr.offset, buf, hdr.size);
202  uint32_t dataEnd = hdr.offset + hdr.size;
203  memset(tmpBuffer + dataEnd, 0, size - dataEnd);
204  bufPtr = tmpBuffer;
205  }
206 
207  // copy header as we are now storing an entire struct, even if we got a partial hdr and buf
208  p_data_hdr_t hdrCopy = hdr;
209  hdrCopy.offset = 0;
210  hdrCopy.size = size;
211 
212  for (map_name_to_info_t::const_iterator offset = offsetMap->begin(); offset != offsetMap->end(); offset++)
213  {
214  cISDataMappings::DataToString(offset->second, &hdrCopy, bufPtr, tmp);
215  if (csv.length() != 0)
216  {
217  csv += ",";
218  }
219  csv += tmp;
220  }
221  csv += "\n";
222  return true;
223 }
224 
static const map_name_to_info_t * GetMapInfo(uint32_t dataId)
ROSCPP_DECL void start()
int WriteHeaderToFile(FILE *pFile, uint32_t id)
Definition: DataCSV.cpp:39
uint32_t id
Definition: ISComm.h:375
CDCHeaderDescriptor header
uint32_t size
Definition: ISComm.h:378
uint32_t dataOffset
Definition: DataCSV.h:49
XmlRpcServer s
#define DID_COUNT
Definition: data_sets.h:138
bool StringCSVToData(string &s, p_data_hdr_t &hdr, uint8_t *buf, uint32_t bufSize, const vector< data_info_t > &columnHeaders)
Definition: DataCSV.cpp:139
#define NULL
Definition: nm_bsp.h:52
bool DataToStringCSV(const p_data_hdr_t &hdr, const uint8_t *buf, string &csv)
Definition: DataCSV.cpp:184
#define NULLPTR
Definition: ISConstants.h:426
static bool StringToData(const char *stringBuffer, int stringLength, const p_data_hdr_t *hdr, uint8_t *dataBuffer, const data_info_t &info, int radix=10, bool json=false)
#define _ARRAY_BYTE_COUNT(a)
Definition: ISConstants.h:322
static uint32_t GetSize(uint32_t dataId)
#define IS_DATA_MAPPING_MAX_STRING_LENGTH
Definition: DataCSV.h:24
#define SNPRINTF
Definition: ISConstants.h:146
USBInterfaceDescriptor data
static bool DataToString(const data_info_t &info, const p_data_hdr_t *hdr, const uint8_t *dataBuffer, data_mapping_string_t stringBuffer, bool json=false)
int WriteDataToFile(uint64_t orderId, FILE *pFile, const p_data_hdr_t &dataHdr, const uint8_t *dataBuf)
Definition: DataCSV.cpp:117
map< string, data_info_t, sCaseInsensitiveCompare > map_name_to_info_t
uint32_t offset
Definition: ISComm.h:381
#define MAX_DATASET_SIZE
Definition: ISComm.h:91
int ReadHeaderFromFile(FILE *pFile, uint32_t id, vector< data_info_t > &columnHeaders)
Definition: DataCSV.cpp:65


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04