SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StringTable.cpp
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) 2016-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 #include "slikenet/StringTable.h"
17 #include <string.h>
18 #include "slikenet/assert.h"
19 #include <stdio.h>
20 #include "slikenet/BitStream.h"
21 #include "slikenet/StringCompressor.h"
22 #include "slikenet/linux_adapter.h"
23 #include "slikenet/osx_adapter.h"
24 using namespace SLNet;
25
26 StringTable* StringTable::instance=0;
27 int StringTable::referenceCount=0;
28
29
30 int SLNet::StrAndBoolComp( char *const &key, const StrAndBool &data )
31 {
32 return strcmp(key,(const char*)data.str);
33 }
34
35 StringTable::StringTable()
36 {
37
38 }
39
40 StringTable::~StringTable()
41 {
42 unsigned i;
43 for (i=0; i < orderedStringList.Size(); i++)
44 {
45 if (orderedStringList[i].b)
46 rakFree_Ex(orderedStringList[i].str, _FILE_AND_LINE_ );
47 }
48 }
49
50 void StringTable::AddReference(void)
51 {
52 if (++referenceCount==1)
53 {
54 instance = SLNet::OP_NEW<StringTable>( _FILE_AND_LINE_ );
55 }
56 }
57 void StringTable::RemoveReference(void)
58 {
59 RakAssert(referenceCount > 0);
60
61 if (referenceCount > 0)
62 {
63 if (--referenceCount==0)
64 {
65 SLNet::OP_DELETE(instance, _FILE_AND_LINE_);
66 instance=0;
67 }
68 }
69 }
70
71 StringTable* StringTable::Instance(void)
72 {
73 return instance;
74 }
75
76 void StringTable::AddString(const char *str, bool copyString)
77 {
78 StrAndBool sab;
79 sab.b=copyString;
80 if (copyString)
81 {
82 sab.str = (char*) rakMalloc_Ex( strlen(str)+1, _FILE_AND_LINE_ );
83 strcpy_s(sab.str, strlen(str)+1, str);
84 }
85 else
86 {
87 sab.str=(char*)str;
88 }
89
90 // If it asserts inside here you are adding duplicate strings.
91 orderedStringList.Insert(sab.str,sab, true, _FILE_AND_LINE_);
92
93 // If this assert hits you need to increase the range of StringTableType
94 RakAssert(orderedStringList.Size() < (StringTableType)-1);
95
96 }
97 void StringTable::EncodeString( const char *input, int maxCharsToWrite, SLNet::BitStream *output )
98 {
99 unsigned index;
100 bool objectExists;
101 // This is fast because the list is kept ordered.
102 index=orderedStringList.GetIndexFromKey((char*)input, &objectExists);
103 if (objectExists)
104 {
105 output->Write(true);
106 output->Write((StringTableType)index);
107 }
108 else
109 {
110 LogStringNotFound(input);
111 output->Write(false);
112 StringCompressor::Instance()->EncodeString(input, maxCharsToWrite, output);
113 }
114 }
115
116 bool StringTable::DecodeString( char *output, int maxCharsToWrite, SLNet::BitStream *input )
117 {
118 bool hasIndex=false;
119 RakAssert(maxCharsToWrite>0);
120
121 if (maxCharsToWrite==0)
122 return false;
123 if (!input->Read(hasIndex))
124 return false;
125 if (hasIndex==false)
126 {
127 StringCompressor::Instance()->DecodeString(output, maxCharsToWrite, input);
128 }
129 else
130 {
131 StringTableType index;
132 if (!input->Read(index))
133 return false;
134 if (index >= orderedStringList.Size())
135 {
136 #ifdef _DEBUG
137 // Critical error - got a string index out of range, which means AddString was called more times on the remote system than on this system.
138 // All systems must call AddString the same number of types, with the same strings in the same order.
139 RakAssert(0);
140 #endif
141 return false;
142 }
143
144 strncpy_s(output, maxCharsToWrite, orderedStringList[index].str, maxCharsToWrite);
145 output[maxCharsToWrite-1]=0;
146 }
147
148 return true;
149 }
150 void StringTable::LogStringNotFound(const char *strName)
151 {
152 (void) strName;
153
154 #ifdef _DEBUG
155 RAKNET_DEBUG_PRINTF("Efficiency Warning! Unregistered String %s sent to StringTable.\n", strName);
156 #endif
157 }