SLikeNet  0.1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TableSerializer.h
Go to the documentation of this file.
1 /*
2  * Original work: Copyright (c) 2014, Oculus VR, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7  * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8  *
9  *
10  * Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
11  *
12  * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13  * license found in the license.txt file in the root directory of this source tree.
14  */
15 
16 #ifndef __TABLE_SERIALIZER_H
17 #define __TABLE_SERIALIZER_H
18 
19 #include "memoryoverride.h"
20 #include "DS_Table.h"
21 #include "Export.h"
22 
23 namespace SLNet
24 {
25  class BitStream;
26 }
27 
28 namespace SLNet
29 {
30 
32 {
33 public:
34  static void SerializeTable(DataStructures::Table *in, SLNet::BitStream *out);
35  static bool DeserializeTable(unsigned char *serializedTable, unsigned int dataLength, DataStructures::Table *out);
36  static bool DeserializeTable(SLNet::BitStream *in, DataStructures::Table *out);
37  static void SerializeColumns(DataStructures::Table *in, SLNet::BitStream *out);
38  static void SerializeColumns(DataStructures::Table *in, SLNet::BitStream *out, DataStructures::List<int> &skipColumnIndices);
39  static bool DeserializeColumns(SLNet::BitStream *in, DataStructures::Table *out);
40  static void SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, SLNet::BitStream *out);
41  static void SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, SLNet::BitStream *out, DataStructures::List<int> &skipColumnIndices);
42  static bool DeserializeRow(SLNet::BitStream *in, DataStructures::Table *out);
43  static void SerializeCell(SLNet::BitStream *out, DataStructures::Table::Cell *cell, DataStructures::Table::ColumnType columnType);
44  static bool DeserializeCell(SLNet::BitStream *in, DataStructures::Table::Cell *cell, DataStructures::Table::ColumnType columnType);
45  static void SerializeFilterQuery(SLNet::BitStream *in, DataStructures::Table::FilterQuery *query);
46  // Note that this allocates query->cell->c!
47  static bool DeserializeFilterQuery(SLNet::BitStream *out, DataStructures::Table::FilterQuery *query);
48  static void SerializeFilterQueryList(SLNet::BitStream *in, DataStructures::Table::FilterQuery *query, unsigned int numQueries, unsigned int maxQueries);
49  // Note that this allocates queries, cells, and query->cell->c!. Use DeallocateQueryList to free.
50  static bool DeserializeFilterQueryList(SLNet::BitStream *out, DataStructures::Table::FilterQuery **query, unsigned int *numQueries, unsigned int maxQueries, int allocateExtraQueries=0);
51  static void DeallocateQueryList(DataStructures::Table::FilterQuery *query, unsigned int numQueries);
52 };
53 
54 } // namespace SLNet
55 
56 #endif
57 
58 // Test code for the table
59 /*
60 #include "LightweightDatabaseServer.h"
61 #include "LightweightDatabaseClient.h"
62 #include "TableSerializer.h"
63 #include "BitStream.h"
64 #include "StringCompressor.h"
65 #include "DS_Table.h"
66 void main(void)
67 {
68  DataStructures::Table table;
69  DataStructures::Table::Row *row;
70  unsigned int dummydata=12345;
71 
72  // Add columns Name (string), IP (binary), score (int), and players (int).
73  table.AddColumn("Name", DataStructures::Table::STRING);
74  table.AddColumn("IP", DataStructures::Table::BINARY);
75  table.AddColumn("Score", DataStructures::Table::NUMERIC);
76  table.AddColumn("Players", DataStructures::Table::NUMERIC);
77  table.AddColumn("Empty Test Column", DataStructures::Table::STRING);
78  RakAssert(table.GetColumnCount()==5);
79  row=table.AddRow(0);
80  RakAssert(row);
81  row->UpdateCell(0,"Kevin Jenkins");
82  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
83  row->UpdateCell(2,5);
84  row->UpdateCell(3,10);
85  //row->UpdateCell(4,"should be unique");
86 
87  row=table.AddRow(1);
88  row->UpdateCell(0,"Kevin Jenkins");
89  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
90  row->UpdateCell(2,5);
91  row->UpdateCell(3,15);
92 
93  row=table.AddRow(2);
94  row->UpdateCell(0,"Kevin Jenkins");
95  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
96  row->UpdateCell(2,5);
97  row->UpdateCell(3,20);
98 
99  row=table.AddRow(3);
100  RakAssert(row);
101  row->UpdateCell(0,"Kevin Jenkins");
102  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
103  row->UpdateCell(2,15);
104  row->UpdateCell(3,5);
105  row->UpdateCell(4,"col index 4");
106 
107  row=table.AddRow(4);
108  RakAssert(row);
109  row->UpdateCell(0,"Kevin Jenkins");
110  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
111  //row->UpdateCell(2,25);
112  row->UpdateCell(3,30);
113  //row->UpdateCell(4,"should be unique");
114 
115  row=table.AddRow(5);
116  RakAssert(row);
117  row->UpdateCell(0,"Kevin Jenkins");
118  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
119  //row->UpdateCell(2,25);
120  row->UpdateCell(3,5);
121  //row->UpdateCell(4,"should be unique");
122 
123  row=table.AddRow(6);
124  RakAssert(row);
125  row->UpdateCell(0,"Kevin Jenkins");
126  row->UpdateCell(1,sizeof(dummydata), (char*)&dummydata);
127  row->UpdateCell(2,35);
128  //row->UpdateCell(3,40);
129  //row->UpdateCell(4,"should be unique");
130 
131  row=table.AddRow(7);
132  RakAssert(row);
133  row->UpdateCell(0,"Bob Jenkins");
134 
135  row=table.AddRow(8);
136  RakAssert(row);
137  row->UpdateCell(0,"Zack Jenkins");
138 
139  // Test multi-column sorting
140  DataStructures::Table::Row *rows[30];
141  DataStructures::Table::SortQuery queries[4];
142  queries[0].columnIndex=0;
143  queries[0].operation=DataStructures::Table::QS_INCREASING_ORDER;
144  queries[1].columnIndex=1;
145  queries[1].operation=DataStructures::Table::QS_INCREASING_ORDER;
146  queries[2].columnIndex=2;
147  queries[2].operation=DataStructures::Table::QS_INCREASING_ORDER;
148  queries[3].columnIndex=3;
149  queries[3].operation=DataStructures::Table::QS_DECREASING_ORDER;
150  table.SortTable(queries, 4, rows);
151  unsigned i;
152  char out[256];
153  RAKNET_DEBUG_PRINTF("Sort: Ascending except for column index 3\n");
154  for (i=0; i < table.GetRowCount(); i++)
155  {
156  table.PrintRow(out,256,',',true, rows[i]);
157  RAKNET_DEBUG_PRINTF("%s\n", out);
158  }
159 
160  // Test query:
161  // Don't return column 3, and swap columns 0 and 2
162  unsigned columnsToReturn[4];
163  columnsToReturn[0]=2;
164  columnsToReturn[1]=1;
165  columnsToReturn[2]=0;
166  columnsToReturn[3]=4;
167  DataStructures::Table resultsTable;
168  table.QueryTable(columnsToReturn,4,0,0,&resultsTable);
169  RAKNET_DEBUG_PRINTF("Query: Don't return column 3, and swap columns 0 and 2:\n");
170  for (i=0; i < resultsTable.GetRowCount(); i++)
171  {
172  resultsTable.PrintRow(out,256,',',true, resultsTable.GetRowByIndex(i));
173  RAKNET_DEBUG_PRINTF("%s\n", out);
174  }
175 
176  // Test filter:
177  // Only return rows with column index 4 empty
178  DataStructures::Table::FilterQuery inclusionFilters[3];
179  inclusionFilters[0].columnIndex=4;
180  inclusionFilters[0].operation=DataStructures::Table::QF_IS_EMPTY;
181  // inclusionFilters[0].cellValue; // Unused for IS_EMPTY
182  table.QueryTable(0,0,inclusionFilters,1,&resultsTable);
183  RAKNET_DEBUG_PRINTF("Filter: Only return rows with column index 4 empty:\n");
184  for (i=0; i < resultsTable.GetRowCount(); i++)
185  {
186  resultsTable.PrintRow(out,256,',',true, resultsTable.GetRowByIndex(i));
187  RAKNET_DEBUG_PRINTF("%s\n", out);
188  }
189 
190  // Column 5 empty and column 0 == Kevin Jenkins
191  inclusionFilters[0].columnIndex=4;
192  inclusionFilters[0].operation=DataStructures::Table::QF_IS_EMPTY;
193  inclusionFilters[1].columnIndex=0;
194  inclusionFilters[1].operation=DataStructures::Table::QF_EQUAL;
195  inclusionFilters[1].cellValue.Set("Kevin Jenkins");
196  table.QueryTable(0,0,inclusionFilters,2,&resultsTable);
197  RAKNET_DEBUG_PRINTF("Filter: Column 5 empty and column 0 == Kevin Jenkins:\n");
198  for (i=0; i < resultsTable.GetRowCount(); i++)
199  {
200  resultsTable.PrintRow(out,256,',',true, resultsTable.GetRowByIndex(i));
201  RAKNET_DEBUG_PRINTF("%s\n", out);
202  }
203 
204  SLNet::BitStream bs;
205  RAKNET_DEBUG_PRINTF("PreSerialize:\n");
206  for (i=0; i < table.GetRowCount(); i++)
207  {
208  table.PrintRow(out,256,',',true, table.GetRowByIndex(i));
209  RAKNET_DEBUG_PRINTF("%s\n", out);
210  }
211  StringCompressor::AddReference();
212  TableSerializer::Serialize(&table, &bs);
213  TableSerializer::Deserialize(&bs, &table);
214  StringCompressor::RemoveReference();
215  RAKNET_DEBUG_PRINTF("PostDeserialize:\n");
216  for (i=0; i < table.GetRowCount(); i++)
217  {
218  table.PrintRow(out,256,',',true, table.GetRowByIndex(i));
219  RAKNET_DEBUG_PRINTF("%s\n", out);
220  }
221  int a=5;
222 }
223 */