27 "description" :
"Information structured in rows and columns.",
50 delete (vector< vector<VuoText> > *)data;
60 if (json_object_object_get_ex(js,
"pointer", &o))
64 table.
data = (
void *)json_object_get_int64(o);
67 table.
data =
new vector< vector<VuoText> >;
71 if (json_object_object_get_ex(js,
"rowCount", &o))
72 table.
rowCount = (size_t)json_object_get_int64(o);
74 if (json_object_object_get_ex(js,
"columnCount", &o))
75 table.
columnCount = (
size_t)json_object_get_int64(o);
79 else if (json_object_object_get_ex(js,
"csv", &o))
81 const char *tableAsCsv = json_object_get_string(o);
96 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value.
data));
97 json_object_object_add(js,
"rowCount", json_object_new_int64((int64_t)value.
rowCount));
98 json_object_object_add(js,
"columnCount", json_object_new_int64((int64_t)value.
columnCount));
111 json_object_object_add(js,
"csv", json_object_new_string(tableAsCsv));
123 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)value.
data;
125 const size_t maxTableRows = 4;
126 const size_t maxTableColumns = 4;
131 for (
size_t i = 0; i < value.
rowCount && i < maxTableRows; ++i)
135 for (
size_t j = 0; j < value.
columnCount && j < maxTableColumns; ++j)
137 const char *dataValue =
"";
138 if (i < (*data).size() && j < (*data)[i].size() && (*data)[i][j])
139 dataValue = (*data)[i][j];
140 oss <<
"<td>" << dataValue <<
"</td>";
151 size_t ellipsisColumn = (value.
columnCount > maxTableColumns ? 1 : 0);
152 oss <<
"<tr><td colspan=\"" <<
MIN(value.
columnCount, maxTableColumns + ellipsisColumn) <<
"\">…</td></tr>";
169 VuoTable table = {
new vector< vector<VuoText> >, 0, 0 };
193 tableData =
new vector< vector<VuoText> >;
194 atFirstColumn =
true;
215 ctx->
tableData->push_back( vector<VuoText>() );
219 ctx->
tableData->back().push_back(itemText);
237 struct csv_parser parser;
238 unsigned char options = CSV_APPEND_NULL;
240 int ret = csv_init(&parser, options);
243 VUserLog(
"Error: Couldn't initialize CSV/TSV parser.");
247 if (format == VuoTableFormat_Tsv)
248 csv_set_delim(&parser, CSV_TAB);
254 if (numBytesParsed != numBytes)
256 VUserLog(
"Error: Couldn't parse CSV/TSV text: %s", csv_strerror(csv_error(&parser)));
264 VUserLog(
"Error: Couldn't parse CSV/TSV text (or finalize parser): %s", csv_strerror(csv_error(&parser)));
273 size_t columnCount = 0;
274 for (vector< vector<VuoText> >::iterator i = ctx.
tableData->begin(); i != ctx.
tableData->end(); ++i)
275 columnCount =
MAX((*i).size(), columnCount);
288 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
292 vector< vector<size_t> > srcBytesForData( (*data).size() );
293 vector< vector<size_t> > dstBytesForData( (*data).size() );
294 size_t dstBytesTotal = 0;
296 for (
size_t i = 0; i < table.
rowCount; ++i)
298 if (i < (*data).size())
300 srcBytesForData[i].resize( (*data)[i].size() );
301 dstBytesForData[i].resize( (*data)[i].size() );
306 if (i < (*data).size() && j < (*data)[i].size())
309 dstBytesForData[i][j] = csv_write(NULL, 0, (*data)[i][j], srcBytesForData[i][j]);
310 dstBytesTotal += dstBytesForData[i][j];
319 char delimiter = (format == VuoTableFormat_Tsv ? CSV_TAB : CSV_COMMA);
322 char *dst = (
char *)malloc(dstBytesTotal);
325 for (
size_t i = 0; i < table.
rowCount; ++i)
329 if (i < (*data).size() && j < (*data)[i].size())
331 size_t numBytesWritten = csv_write(dstPtr, dstBytesForData[i][j], (*data)[i][j], srcBytesForData[i][j]);
332 dstPtr += numBytesWritten;
335 *dstPtr = (j+1 < table.
columnCount ? delimiter : newline);
359 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
361 VuoTextComparison containsCaseInsensitive = { VuoTextComparison_Contains,
false,
"" };
365 for (
size_t i = 0; i < table.columnCount; ++i)
366 if (! (*data).empty() && i < (*data)[0].size() &&
VuoText_compare((*data)[0][i], containsCaseInsensitive, header))
371 for (
size_t i = 0; i < table.rowCount; ++i)
372 if (i < (*data).size() && ! (*data)[i].empty() &&
VuoText_compare((*data)[i][0], containsCaseInsensitive, header))
385 return MAX(1,
MIN(maxIndex, index));
405 bool operator() (pair<size_t, VuoText> first, pair<size_t, VuoText> second)
407 if (
sortOrder == VuoSortOrder_Descending)
410 if (
sortType == VuoTextSort_TextCaseSensitive)
412 else if (
sortType == VuoTextSort_Number)
414 else if (
sortType == VuoTextSort_Date)
438 size_t firstDataRow = (firstRowIsHeader ? 1 : 0);
440 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
442 vector< pair<size_t, VuoText> > keyColumn;
443 for (
size_t i = firstDataRow; i < table.
rowCount; ++i)
445 if (i < (*data).size() && columnIndex-1 < (*data)[i].size())
446 keyColumn.push_back( make_pair(i, (*data)[i][columnIndex-1]) );
448 keyColumn.push_back( make_pair(i,
"") );
454 stable_sort(keyColumn.begin(), keyColumn.end(), columnSort);
456 if (firstRowIsHeader)
457 keyColumn.insert(keyColumn.begin(), make_pair(0,
"") );
459 vector< vector<VuoText> > *sortedData =
new vector< vector<VuoText> >(table.
rowCount);
460 for (
size_t i = 0; i < table.
rowCount; ++i)
463 for (
size_t i = 0; i < table.
rowCount; ++i)
465 if (i < (*data).size() && j < (*data)[i].size())
466 (*sortedData)[i][j] = (*data)[ keyColumn[i].first ][j];
482 if (columnIndex == 0)
494 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
496 vector< vector<VuoText> > *transposedData =
new vector< vector<VuoText> >(table.
columnCount);
498 (*transposedData)[i].resize(table.
rowCount);
500 for (
size_t i = 0; i < table.
rowCount; ++i)
502 if (i < (*data).size() && j < (*data)[i].size())
503 (*transposedData)[j][i] = (*data)[i][j];
507 return transposedTable;
520 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
524 size_t startIndex = (includeHeader ? 0 : 1);
528 for (
size_t i = startIndex; i < table.
columnCount; ++i)
529 if (rowIndex-1 < (*data).size() && i < (*data)[rowIndex-1].size())
557 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
561 size_t startIndex = (includeHeader ? 0 : 1);
562 size_t count = table.
rowCount - startIndex;
565 for (
size_t i = startIndex; i < table.
rowCount; ++i)
566 if (i < (*data).size() && columnIndex-1 < (*data)[i].size())
579 if (columnIndex == 0)
590 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
597 return (*data)[rowIndex-1][columnIndex-1];
606 if (columnIndex == 0)
631 if (rowIndex == 0 || columnIndex == 0)
642 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
643 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
645 vector< vector<VuoText> >::iterator rowIter;
647 if (position == VuoListPosition_Beginning)
649 rowIter = (*data).begin();
654 rowIter = (*data).end();
661 (*data).insert(rowIter, vector<VuoText>(count));
662 for (
unsigned long i = 0; i < count; ++i)
663 (*data)[rowIndex][i] = rowArray[i];
675 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
676 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
681 if ((*data).size() < count)
682 (*data).resize(count);
684 for (
size_t i = 0; i < count; ++i)
686 if (position == VuoListPosition_End && (*data)[i].size() < table.
columnCount)
689 vector<VuoText>::iterator columnIter = (position == VuoListPosition_Beginning ? (*data)[i].begin() : (*data)[i].end());
690 (*data)[i].insert(columnIter, columnArray[i]);
708 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
709 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
714 size_t firstDataIndex = (preserveHeader ? 1 : 0);
716 (*data)[rowIndex-1].resize(newValuesCount+firstDataIndex);
718 if (preserveHeader && ! (*origData)[rowIndex-1].empty())
719 (*data)[rowIndex-1][0] = (*origData)[rowIndex-1][0];
721 for (
size_t i = 0; i < newValuesCount; ++i)
722 (*data)[rowIndex-1][i+firstDataIndex] = rowArray[i];
751 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
752 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
757 size_t firstDataIndex = (preserveHeader ? 1 : 0);
759 if ((*data).size() < newValuesCount+firstDataIndex)
760 (*data).resize(newValuesCount+firstDataIndex);
762 for (
size_t i = 0; i < newValuesCount+firstDataIndex; ++i)
763 if ((*data)[i].size() < columnIndex)
764 (*data)[i].resize(columnIndex);
766 if (preserveHeader && (*origData)[0].size() > columnIndex-1)
767 (*data)[0][columnIndex-1] = (*origData)[0][columnIndex-1];
769 for (
size_t i = 0; i <
MAX(table.
rowCount-firstDataIndex, newValuesCount); ++i)
770 (*data)[i+firstDataIndex][columnIndex-1] = (i < newValuesCount ? columnArray[i] : NULL);
783 if (columnIndex == 0)
794 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
795 if ((*origData).empty())
801 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
802 (*data)[rowIndex-1][columnIndex-1] = newValue;
816 if (columnIndex == 0)
841 if (rowIndex == 0 || columnIndex == 0)
855 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
856 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
858 vector< vector<VuoText> >::iterator rowIter = (position == VuoListPosition_Beginning ? (*data).begin() : (*data).end() - 1);
859 (*data).erase(rowIter);
874 vector< vector<VuoText> > *origData = (vector< vector<VuoText> > *)table.
data;
875 vector< vector<VuoText> > *data =
new vector< vector<VuoText> >(*origData);
877 for (
size_t i = 0; i < table.
rowCount; ++i)
879 if (position == VuoListPosition_End && (*data)[i].size() < table.
columnCount)
882 vector<VuoText>::iterator columnIter = (position == VuoListPosition_Beginning ? (*data)[i].begin() : (*data)[i].end() - 1);
883 (*data)[i].erase(columnIter);
901 auto rows =
static_cast<vector<vector<VuoText>
>*>(table.
data);
905 auto foundRow = find_if(rows->begin(), rows->end(), [columnIndex, valueComparison, valueToFind](vector<VuoText> row) {
906 return VuoText_compare(row[columnIndex - 1], valueComparison, valueToFind);
909 if (foundRow == rows->end())
912 size_t startIndex = (includeHeader ? 0 : 1);
913 size_t count = foundRow->size() - startIndex;
916 for (
size_t i = startIndex; i < table.
columnCount; ++i)
930 if (columnIndex == 0)
941 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
942 for (vector< vector<VuoText> >::iterator i = data->begin(); i != data->end(); ++i)
943 for (vector<VuoText>::iterator j = i->begin(); j != i->end(); ++j)
954 vector< vector<VuoText> > *data = (vector< vector<VuoText> > *)table.
data;
955 for (vector< vector<VuoText> >::iterator i = data->begin(); i != data->end(); ++i)
956 for (vector<VuoText>::iterator j = i->begin(); j != i->end(); ++j)