Now you can download a copy of these docs so you can use them offline! Download now
Dashboard.cpp
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2008. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5 /*----------------------------------------------------------------------------*/
6 
7 #include "Dashboard.h"
8 #include "DriverStation.h"
9 #include "NetworkCommunication/UsageReporting.h"
10 #include "Synchronized.h"
11 #include "WPIErrors.h"
12 #include <strLib.h>
13 
14 const int32_t Dashboard::kMaxDashboardDataSize;
15 
21 Dashboard::Dashboard(SEM_ID statusDataSem)
22  : m_userStatusData (NULL)
23  , m_userStatusDataSize (0)
24  , m_localBuffer (NULL)
25  , m_localPrintBuffer (NULL)
26  , m_packPtr (NULL)
27  , m_printSemaphore (0)
28  , m_statusDataSemaphore (statusDataSem)
29 {
30  m_userStatusData = new char[kMaxDashboardDataSize];
31  m_localBuffer = new char[kMaxDashboardDataSize];
32  m_localPrintBuffer = new char[kMaxDashboardDataSize * 2];
33  m_localPrintBuffer[0] = 0;
34  m_packPtr = m_localBuffer;
35  m_printSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
36 }
37 
44 {
45  semDelete(m_printSemaphore);
46  m_packPtr = NULL;
47  delete [] m_localPrintBuffer;
48  m_localPrintBuffer = NULL;
49  delete [] m_localBuffer;
50  m_localBuffer = NULL;
51  delete [] m_userStatusData;
52  m_userStatusData = NULL;
53 }
54 
59 void Dashboard::AddI8(int8_t value)
60 {
61  if (!ValidateAdd(sizeof(int8_t))) return;
62  memcpy(m_packPtr, (char*)&value, sizeof(value));
63  m_packPtr += sizeof(value);
64  AddedElement(kI8);
65 }
66 
71 void Dashboard::AddI16(int16_t value)
72 {
73  if (!ValidateAdd(sizeof(int16_t))) return;
74  memcpy(m_packPtr, (char*)&value, sizeof(value));
75  m_packPtr += sizeof(value);
76  AddedElement(kI16);
77 }
78 
83 void Dashboard::AddI32(int32_t value)
84 {
85  if (!ValidateAdd(sizeof(int32_t))) return;
86  memcpy(m_packPtr, (char*)&value, sizeof(value));
87  m_packPtr += sizeof(value);
88  AddedElement(kI32);
89 }
90 
95 void Dashboard::AddU8(uint8_t value)
96 {
97  if (!ValidateAdd(sizeof(uint8_t))) return;
98  memcpy(m_packPtr, (char*)&value, sizeof(value));
99  m_packPtr += sizeof(value);
100  AddedElement(kU8);
101 }
102 
107 void Dashboard::AddU16(uint16_t value)
108 {
109  if (!ValidateAdd(sizeof(uint16_t))) return;
110  memcpy(m_packPtr, (char*)&value, sizeof(value));
111  m_packPtr += sizeof(value);
112  AddedElement(kU16);
113 }
114 
119 void Dashboard::AddU32(uint32_t value)
120 {
121  if (!ValidateAdd(sizeof(uint32_t))) return;
122  memcpy(m_packPtr, (char*)&value, sizeof(value));
123  m_packPtr += sizeof(value);
124  AddedElement(kU32);
125 }
126 
131 void Dashboard::AddFloat(float value)
132 {
133  if (!ValidateAdd(sizeof(float))) return;
134  memcpy(m_packPtr, (char*)&value, sizeof(value));
135  m_packPtr += sizeof(value);
136  AddedElement(kFloat);
137 }
138 
143 void Dashboard::AddDouble(double value)
144 {
145  if (!ValidateAdd(sizeof(double))) return;
146  memcpy(m_packPtr, (char*)&value, sizeof(value));
147  m_packPtr += sizeof(value);
148  AddedElement(kDouble);
149 }
150 
155 void Dashboard::AddBoolean(bool value)
156 {
157  if (!ValidateAdd(sizeof(char))) return;
158  *m_packPtr = value ? 1 : 0;
159  m_packPtr += sizeof(char);
160  AddedElement(kBoolean);
161 }
162 
167 void Dashboard::AddString(char* value)
168 {
169  AddString(value, strlen(value));
170 }
171 
177 void Dashboard::AddString(char* value, int32_t length)
178 {
179  if (!ValidateAdd(length + sizeof(length))) return;
180  memcpy(m_packPtr, (char*)&length, sizeof(length));
181  m_packPtr += sizeof(length);
182  memcpy(m_packPtr, value, length);
183  m_packPtr += length;
184  AddedElement(kString);
185 }
186 
197 {
198  if (!ValidateAdd(sizeof(int32_t))) return;
199  m_complexTypeStack.push(kArray);
200  m_arrayElementCount.push_back(0);
201  m_arraySizePtr.push_back((int32_t*)m_packPtr);
202  m_packPtr += sizeof(int32_t);
203 }
204 
212 {
213  if (m_complexTypeStack.top() != kArray)
214  {
215  wpi_setWPIError(MismatchedComplexTypeClose);
216  return;
217  }
218  m_complexTypeStack.pop();
219  *(m_arraySizePtr.back()) = m_arrayElementCount.back();
220  m_arraySizePtr.pop_back();
221  if (m_arrayElementCount.back() != 0)
222  {
223  m_expectedArrayElementType.pop_back();
224  }
225  m_arrayElementCount.pop_back();
226  AddedElement(kOther);
227 }
228 
237 {
238  m_complexTypeStack.push(kCluster);
239 }
240 
248 {
249  if (m_complexTypeStack.top() != kCluster)
250  {
251  wpi_setWPIError(MismatchedComplexTypeClose);
252  return;
253  }
254  m_complexTypeStack.pop();
255  AddedElement(kOther);
256 }
257 
264 void Dashboard::Printf(const char *writeFmt, ...)
265 {
266  va_list args;
267  int32_t size;
268 
269  // Check if the buffer has already been used for packing.
270  if (m_packPtr != m_localBuffer)
271  {
272  wpi_setWPIError(DashboardDataCollision);
273  return;
274  }
275  va_start (args, writeFmt);
276  {
277  Synchronized sync(m_printSemaphore);
278  vsprintf(m_localPrintBuffer + strlen(m_localPrintBuffer), writeFmt, args);
279  size = strlen(m_localPrintBuffer);
280  }
281  if (size > kMaxDashboardDataSize)
282  {
283  wpi_setWPIError(DashboardDataOverflow);
284  }
285 
286  va_end (args);
287 }
288 
299 {
300  if (!m_complexTypeStack.empty())
301  {
302  wpi_setWPIError(MismatchedComplexTypeClose);
303  return 0;
304  }
305 
306  static bool reported = false;
307  if (!reported)
308  {
309  nUsageReporting::report(nUsageReporting::kResourceType_Dashboard, 0);
310  reported = true;
311  }
312 
313  Synchronized sync(m_statusDataSemaphore);
314 
315  // Sequence number
316  DriverStation::GetInstance()->IncrementUpdateNumber();
317 
318  // Packed Dashboard Data
319  m_userStatusDataSize = m_packPtr - m_localBuffer;
320  memcpy(m_userStatusData, m_localBuffer, m_userStatusDataSize);
321  m_packPtr = m_localBuffer;
322 
323  return m_userStatusDataSize;
324 }
325 
331 void Dashboard::GetStatusBuffer(char **userStatusData, int32_t* userStatusDataSize)
332 {
333  // User printed strings
334  if (m_localPrintBuffer[0] != 0)
335  {
336  // Sequence number
337  DriverStation::GetInstance()->IncrementUpdateNumber();
338 
339  int32_t printSize;
340  Synchronized syncPrint(m_printSemaphore);
341  printSize = strlen(m_localPrintBuffer);
342  m_userStatusDataSize = printSize;
343  memcpy(m_userStatusData, m_localPrintBuffer, m_userStatusDataSize);
344  m_localPrintBuffer[0] = 0;
345  }
346 
347  *userStatusData = m_userStatusData;
348  *userStatusDataSize = m_userStatusDataSize;
349 }
350 
354 bool Dashboard::ValidateAdd(int32_t size)
355 {
356  if ((m_packPtr - m_localBuffer) + size > kMaxDashboardDataSize)
357  {
358  wpi_setWPIError(DashboardDataOverflow);
359  return false;
360  }
361  // Make sure printf is not being used at the same time.
362  if (m_localPrintBuffer[0] != 0)
363  {
364  wpi_setWPIError(DashboardDataCollision);
365  return false;
366  }
367  return true;
368 }
369 
373 void Dashboard::AddedElement(Type type)
374 {
375  if(IsArrayRoot())
376  {
377  if (m_arrayElementCount.back() == 0)
378  {
379  m_expectedArrayElementType.push_back(type);
380  }
381  else
382  {
383  if (type != m_expectedArrayElementType.back())
384  {
385  wpi_setWPIError(InconsistentArrayValueAdded);
386  }
387  }
388  m_arrayElementCount.back() = m_arrayElementCount.back() + 1;
389  }
390 }
391 
395 bool Dashboard::IsArrayRoot()
396 {
397  return !m_complexTypeStack.empty() && m_complexTypeStack.top() == kArray;
398 }
399 
void AddBoolean(bool value)
Definition: Dashboard.cpp:155
void AddArray()
Definition: Dashboard.cpp:196
void AddU8(uint8_t value)
Definition: Dashboard.cpp:95
void AddI32(int32_t value)
Definition: Dashboard.cpp:83
void AddCluster()
Definition: Dashboard.cpp:236
void AddU16(uint16_t value)
Definition: Dashboard.cpp:107
void AddI16(int16_t value)
Definition: Dashboard.cpp:71
void Printf(const char *writeFmt,...)
Definition: Dashboard.cpp:264
virtual ~Dashboard()
Definition: Dashboard.cpp:43
void AddI8(int8_t value)
Definition: Dashboard.cpp:59
void FinalizeCluster()
Definition: Dashboard.cpp:247
static DriverStation * GetInstance()
int32_t Finalize()
Definition: Dashboard.cpp:298
void AddU32(uint32_t value)
Definition: Dashboard.cpp:119
void FinalizeArray()
Definition: Dashboard.cpp:211
void AddString(char *value)
Definition: Dashboard.cpp:167
void AddDouble(double value)
Definition: Dashboard.cpp:143
void GetStatusBuffer(char **userStatusData, int32_t *userStatusDataSize)
Definition: Dashboard.cpp:331
void AddFloat(float value)
Definition: Dashboard.cpp:131
Dashboard(SEM_ID statusDataSemaphore)
Definition: Dashboard.cpp:21

Generated on Sat Apr 26 2014 12:26:45 for WPILibC++ by doxygen 1.8.6