SLikeNet  0.1.3
 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"
22 #include "slikenet/linux_adapter.h"
23 #include "slikenet/osx_adapter.h"
24 using namespace SLNet;
25 
28 
29 
30 int SLNet::StrAndBoolComp( char *const &key, const StrAndBool &data )
31 {
32  return strcmp(key,(const char*)data.str);
33 }
34 
36 {
37 
38 }
39 
41 {
42  unsigned i;
43  for (i=0; i < orderedStringList.Size(); i++)
44  {
45  if (orderedStringList[i].b)
47  }
48 }
49 
51 {
52  if (++referenceCount==1)
53  {
54  instance = SLNet::OP_NEW<StringTable>( _FILE_AND_LINE_ );
55  }
56 }
58 {
60 
61  if (referenceCount > 0)
62  {
63  if (--referenceCount==0)
64  {
66  instance=0;
67  }
68  }
69 }
70 
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.
92 
93  // If this assert hits you need to increase the range of StringTableType
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 }