• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polserver / polserver / 21541532363

31 Jan 2026 08:14AM UTC coverage: 60.532% (+0.03%) from 60.507%
21541532363

push

github

web-flow
Tidy modernize for loops (#862)

* trigger loop convert

* Automated clang-tidy change: modernize-loop-convert

* fixed refactor

* Automated clang-tidy change: modernize-loop-convert

* compile

* first look through

* fixes and start to use a few ranges

* revert autogenerated file

* compilation fix

* second pass

* renamed loop variable

---------

Co-authored-by: Clang Tidy <clang-tidy@users.noreply.github.com>

164 of 447 new or added lines in 61 files covered. (36.69%)

6 existing lines in 5 files now uncovered.

44377 of 73312 relevant lines covered (60.53%)

499857.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.95
/pol-core/pol/module/datastore.cpp
1
/** @file
2
 *
3
 * @par History
4
 * - 2005/11/26 Shinigami: changed "strcmp" into "stricmp" to suppress Script Errors
5
 * - 2006/09/26 Shinigami: GCC 3.4.x fix - added "template<>" to TmplExecutorModule
6
 * - 2007/06/17 Shinigami: added config.world_data_path
7
 * - 2009/12/21 Turley:    ._method() call fix
8
 */
9

10

11
#include "datastore.h"
12
#include <exception>
13
#include <filesystem>
14
#include <fstream>
15
#include <ranges>
16
#include <stddef.h>
17

18
#include "../../bscript/berror.h"
19
#include "../../bscript/bobject.h"
20
#include "../../bscript/bstruct.h"
21
#include "../../bscript/executor.h"
22
#include "../../bscript/impstr.h"
23
#include "../../bscript/objmethods.h"
24
#include "../../clib/cfgelem.h"
25
#include "../../clib/cfgfile.h"
26
#include "../../clib/fileutil.h"
27
#include "../../clib/rawtypes.h"
28
#include "../../clib/stlutil.h"
29
#include "../../clib/streamsaver.h"
30
#include "../../plib/pkg.h"
31
#include "../../plib/systemstate.h"
32
#include "../globals/ucfg.h"
33
#include "../proplist.h"
34
#include "datastoreimp.h"
35

36
#include <module_defs/datafile.h>
37

38

39
namespace Pol::Module
40
{
41
///
42
/// Datastore
43
///
44
///  datastore files are stored in
45
///     config.world_data_path + ds/fname.txt
46
///     config.world_data_path + ds/{pkgname}/fname.txt
47
///
48

49
Bscript::BApplicObjType datafileref_type;
50
Bscript::BApplicObjType datafileelem_type;
51

52
DataFileContents::DataFileContents( DataStoreFile* dsf ) : dsf( dsf ), dirty( false ) {}
5✔
53

54
DataFileContents::~DataFileContents()
10✔
55
{
56
  elements_by_integer.clear();
5✔
57
  elements_by_string.clear();
5✔
58
}
10✔
59

60
size_t DataFileContents::estimateSize() const
×
61
{
62
  size_t size = sizeof( DataStoreFile* ) /*dsf*/
×
63
                + sizeof( bool );        /*dirty*/
64

65
  size += Clib::memsize( elements_by_string );
×
66
  for ( const auto& ele : elements_by_string )
×
67
  {
68
    if ( ele.second.get() != nullptr )
×
69
      size += ele.second->proplist.estimatedSize();
×
70
  }
71
  size += Clib::memsize( elements_by_integer );
×
72
  return size;
×
73
}
74

75
void DataFileContents::load( Clib::ConfigFile& cf )
2✔
76
{
77
  Clib::ConfigElem elem;
2✔
78

79
  while ( cf.read( elem ) )
6✔
80
  {
81
    DataFileElement* delem = new DataFileElement( elem );
4✔
82

83
    if ( dsf->flags & DF_KEYTYPE_INTEGER )
4✔
84
    {
85
      elements_by_integer[atol( elem.rest() )].set( delem );
2✔
86
    }
87
    else
88
    {
89
      elements_by_string[elem.rest()].set( delem );
2✔
90
    }
91
  }
92
}
2✔
93

94
void DataFileContents::save( Clib::StreamWriter& sw )
3✔
95
{
96
  for ( const auto& [key, ref] : elements_by_string )
5✔
97
  {
98
    sw.begin( "Element", key );
2✔
99
    ref->printOn( sw );
2✔
100
    sw.end();
2✔
101
  }
102

103
  for ( const auto& [key, ref] : elements_by_integer )
5✔
104
  {
105
    sw.begin( "Element", key );
2✔
106
    ref->printOn( sw );
2✔
107
    sw.end();
2✔
108
  }
109
}
3✔
110

111
Bscript::BObjectImp* DataFileContents::methodCreateElement( int key )
2✔
112
{
113
  ElementsByInteger::iterator itr = elements_by_integer.find( key );
2✔
114
  DataFileElementRef dfelem;
2✔
115
  if ( itr == elements_by_integer.end() )
2✔
116
  {
117
    dfelem.set( new DataFileElement );
2✔
118
    elements_by_integer[key] = dfelem;
2✔
119
    dirty = true;
2✔
120
  }
121
  else
122
  {
123
    dfelem = ( *itr ).second;
×
124
  }
125
  return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
4✔
126
}
2✔
127

128
Bscript::BObjectImp* DataFileContents::methodCreateElement( const std::string& key )
2✔
129
{
130
  ElementsByString::iterator itr = elements_by_string.find( key );
2✔
131
  DataFileElementRef dfelem;
2✔
132
  if ( itr == elements_by_string.end() )
2✔
133
  {
134
    dfelem.set( new DataFileElement );
2✔
135
    elements_by_string[key] = dfelem;
2✔
136
    dirty = true;
2✔
137
  }
138
  else
139
  {
140
    dfelem = ( *itr ).second;
×
141
  }
142
  return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
4✔
143
}
2✔
144

145

146
Bscript::BObjectImp* DataFileContents::methodFindElement( int key )
2✔
147
{
148
  ElementsByInteger::iterator itr = elements_by_integer.find( key );
2✔
149
  if ( itr != elements_by_integer.end() )
2✔
150
  {
151
    DataFileElementRef dfelem = ( *itr ).second;
2✔
152
    return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
2✔
153
  }
2✔
154

155
  return new Bscript::BError( "Element not found" );
×
156
}
157

158
Bscript::BObjectImp* DataFileContents::methodFindElement( const std::string& key )
2✔
159
{
160
  ElementsByString::iterator itr = elements_by_string.find( key );
2✔
161
  if ( itr != elements_by_string.end() )
2✔
162
  {
163
    DataFileElementRef dfelem = ( *itr ).second;
2✔
164
    return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
2✔
165
  }
2✔
166

167
  return new Bscript::BError( "Element not found" );
×
168
}
169

170

171
Bscript::BObjectImp* DataFileContents::methodDeleteElement( int key )
×
172
{
173
  if ( elements_by_integer.erase( key ) )
×
174
  {
175
    dirty = true;
×
176
    return new Bscript::BLong( 1 );
×
177
  }
178
  return new Bscript::BError( "Element not found" );
×
179
}
180

181
Bscript::BObjectImp* DataFileContents::methodDeleteElement( const std::string& key )
×
182
{
183
  if ( elements_by_string.erase( key ) )
×
184
  {
185
    dirty = true;
×
186
    return new Bscript::BLong( 1 );
×
187
  }
188
  return new Bscript::BError( "Element not found" );
×
189
}
190

191
Bscript::BObjectImp* DataFileContents::methodKeys() const
2✔
192
{
193
  std::unique_ptr<Bscript::ObjArray> arr( new Bscript::ObjArray );
2✔
194

195
  for ( const auto& citr : elements_by_string )
4✔
196
  {
197
    arr->addElement( new Bscript::String( citr.first ) );
2✔
198
  }
199

200
  for ( const auto& citr : elements_by_integer )
4✔
201
  {
202
    arr->addElement( new Bscript::BLong( citr.first ) );
2✔
203
  }
204

205
  return arr.release();
4✔
206
}
2✔
207

208

209
DataFileRefObjImp::DataFileRefObjImp( DataFileContentsRef dfcontents )
6✔
210
    : DataFileRefObjImpBase( &datafileref_type, std::move( dfcontents ) )
6✔
211
{
212
}
6✔
213

214
const char* DataFileRefObjImp::typeOf() const
×
215
{
216
  return "DataFileRef";
×
217
}
218
u8 DataFileRefObjImp::typeOfInt() const
×
219
{
220
  return OTDataFileRef;
×
221
}
222

223
Bscript::BObjectImp* DataFileRefObjImp::copy() const
×
224
{
225
  return new DataFileRefObjImp( obj_ );
×
226
}
227

228
Bscript::BObjectImp* DataFileRefObjImp::call_method_id( const int id, Bscript::Executor& ex,
10✔
229
                                                        bool /*forcebuiltin*/ )
230
{
231
  switch ( id )
10✔
232
  {
233
  case Bscript::MTH_CREATEELEMENT:
4✔
234
  {
235
    if ( !ex.hasParams( 1 ) )
4✔
236
    {
237
      return new Bscript::BError( "not enough parameters to datafile.createelement(key)" );
×
238
    }
239
    if ( obj_->dsf->flags & DF_KEYTYPE_INTEGER )
4✔
240
    {
241
      int key;
242
      if ( !ex.getParam( 0, key ) )
2✔
243
      {
244
        return new Bscript::BError( "datafile.createelement(key): key must be an Integer" );
×
245
      }
246
      return obj_->methodCreateElement( key );
2✔
247
    }
248
    const Bscript::String* key;
249
    if ( !ex.getStringParam( 0, key ) )
2✔
250
    {
251
      return new Bscript::BError( "datafile.createelement(key): key must be a String" );
×
252
    }
253
    return obj_->methodCreateElement( key->value() );
2✔
254
  }
255
  case Bscript::MTH_FINDELEMENT:
4✔
256
  {
257
    if ( !ex.hasParams( 1 ) )
4✔
258
    {
259
      return new Bscript::BError( "not enough parameters to datafile.findelement(key)" );
×
260
    }
261
    if ( obj_->dsf->flags & DF_KEYTYPE_INTEGER )
4✔
262
    {
263
      int key;
264
      if ( !ex.getParam( 0, key ) )
2✔
265
      {
266
        return new Bscript::BError( "datafile.findelement(key): key must be an Integer" );
×
267
      }
268
      return obj_->methodFindElement( key );
2✔
269
    }
270
    const Bscript::String* key;
271
    if ( !ex.getStringParam( 0, key ) )
2✔
272
    {
273
      return new Bscript::BError( "datafile.findelement(key): key must be a String" );
×
274
    }
275
    return obj_->methodFindElement( key->value() );
2✔
276
  }
277
  case Bscript::MTH_DELETEELEMENT:
×
278
  {
279
    if ( !ex.hasParams( 1 ) )
×
280
    {
281
      return new Bscript::BError( "not enough parameters to datafile.deleteelement(key)" );
×
282
    }
283
    if ( obj_->dsf->flags & DF_KEYTYPE_INTEGER )
×
284
    {
285
      int key;
286
      if ( !ex.getParam( 0, key ) )
×
287
      {
288
        return new Bscript::BError( "datafile.deleteelement(key): key must be an Integer" );
×
289
      }
290
      return obj_->methodDeleteElement( key );
×
291
    }
292
    const Bscript::String* key;
293
    if ( !ex.getStringParam( 0, key ) )
×
294
    {
295
      return new Bscript::BError( "datafile.deleteelement(key): key must be a String" );
×
296
    }
297
    return obj_->methodDeleteElement( key->value() );
×
298
  }
299
  case Bscript::MTH_KEYS:
2✔
300
    return obj_->methodKeys();
2✔
301
  default:
×
302
    return nullptr;
×
303
  }
304
}
305

306
Bscript::BObjectImp* DataFileRefObjImp::call_method( const char* methodname, Bscript::Executor& ex )
×
307
{
308
  Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
×
309
  if ( objmethod != nullptr )
×
310
    return this->call_method_id( objmethod->id, ex );
×
311
  return nullptr;
×
312
}
313

314

315
DataElemRefObjImp::DataElemRefObjImp( DataFileContentsRef dfcontents, DataFileElementRef dfelem )
8✔
316
    : DataElemRefObjImpBase( &datafileelem_type,
317
                             DataFileElemObj( std::move( dfcontents ), std::move( dfelem ) ) )
8✔
318
{
319
}
8✔
320
const char* DataElemRefObjImp::typeOf() const
×
321
{
322
  return "DataElemRef";
×
323
}
324
u8 DataElemRefObjImp::typeOfInt() const
×
325
{
326
  return OTDataElemRef;
×
327
}
328
Bscript::BObjectImp* DataElemRefObjImp::copy() const
×
329
{
330
  return new DataElemRefObjImp( obj_.dfcontents, obj_.dfelem );
×
331
}
332

333
Bscript::BObjectImp* DataElemRefObjImp::call_method_id( const int id, Bscript::Executor& ex,
12✔
334
                                                        bool /*forcebuiltin*/ )
335
{
336
  bool changed = false;
12✔
337
  Bscript::BObjectImp* res = CallPropertyListMethod_id( obj_.dfelem->proplist, id, ex, changed );
12✔
338
  if ( changed )
12✔
339
    obj_.dfcontents->dirty = true;
6✔
340
  return res;
12✔
341
}
342

343
Bscript::BObjectImp* DataElemRefObjImp::call_method( const char* methodname, Bscript::Executor& ex )
×
344
{
345
  bool changed = false;
×
346
  Bscript::BObjectImp* res =
347
      CallPropertyListMethod( obj_.dfelem->proplist, methodname, ex, changed );
×
348
  if ( changed )
×
349
    obj_.dfcontents->dirty = true;
×
350
  return res;
×
351
}
352

353
DataFileExecutorModule::DataFileExecutorModule( Bscript::Executor& exec )
2,356✔
354
    : Bscript::TmplExecutorModule<DataFileExecutorModule, Bscript::ExecutorModule>( exec )
2,356✔
355
{
356
}
2,356✔
357

358
DataStoreFile* DataFileExecutorModule::GetDataStoreFile( const std::string& inspec )
×
359
{
360
  std::string descriptor;
×
361

362
  const Plib::Package* spec_pkg = nullptr;
×
363
  std::string spec_filename;
×
364
  if ( !Plib::pkgdef_split( inspec, exec.prog()->pkg, &spec_pkg, &spec_filename ) )
×
365
  {
366
    return nullptr;  // new BError( "Error in descriptor" );
×
367
  }
368
  if ( spec_pkg == nullptr )
×
369
  {
370
    // ::filename
371
    descriptor = "::" + spec_filename;
×
372
  }
373
  else
374
  {
375
    // :somepkg:filename
376
    descriptor = ":" + spec_pkg->name() + ":" + spec_filename;
×
377
  }
378

379
  Core::DataStore::iterator itr = Core::configurationbuffer.datastore.find( descriptor );
×
380
  if ( itr != Core::configurationbuffer.datastore.end() )
×
381
  {
382
    DataStoreFile* dsf = ( *itr ).second;
×
383
    return dsf;
×
384
  }
385

386
  return nullptr;
×
387
}
×
388

389
Bscript::BObjectImp* DataFileExecutorModule::mf_ListDataFiles()
×
390
{
391
  std::unique_ptr<Bscript::ObjArray> file_list( new Bscript::ObjArray );
×
NEW
392
  for ( auto dsf : Core::configurationbuffer.datastore | std::views::values )
×
393
  {
394
    std::unique_ptr<Bscript::BStruct> file_name( new Bscript::BStruct );
×
395
    file_name->addMember( "pkg", new Bscript::String( dsf->pkgname ) );
×
396
    file_name->addMember( "name", new Bscript::String( dsf->name ) );
×
397
    file_name->addMember( "descriptor", new Bscript::String( dsf->descriptor ) );
×
398

399
    file_list->addElement( file_name.release() );
×
400
  }
×
401
  return file_list.release();
×
402
}
×
403

404
Bscript::BObjectImp* DataFileExecutorModule::mf_CreateDataFile()
3✔
405
{
406
  const Bscript::String* strob;
407
  int flags;
408
  if ( getStringParam( 0, strob ) && getParam( 1, flags ) )
3✔
409
  {
410
    try
411
    {
412
      std::string descriptor;
3✔
413
      std::string directory;
3✔
414
      std::string d_ds;
3✔
415
      const std::string& inspec = strob->value();
3✔
416

417
      const Plib::Package* spec_pkg = nullptr;
3✔
418
      std::string spec_filename;
3✔
419
      if ( !Plib::pkgdef_split( inspec, exec.prog()->pkg, &spec_pkg, &spec_filename ) )
3✔
420
      {
421
        return new Bscript::BError( "Error in descriptor" );
×
422
      }
423
      if ( spec_pkg == nullptr )
3✔
424
      {
425
        // ::filename
426
        descriptor = "::" + spec_filename;
×
427
        directory = Plib::systemstate.config.world_data_path + "ds/";
×
428
      }
429
      else
430
      {
431
        // :somepkg:filename
432
        descriptor = ":" + spec_pkg->name() + ":" + spec_filename;
3✔
433
        d_ds = Plib::systemstate.config.world_data_path + "ds/";
3✔
434
        directory = Plib::systemstate.config.world_data_path + "ds/" + spec_pkg->name() + "/";
3✔
435
      }
436
      if ( !Clib::FileExists( directory.c_str() ) )
3✔
437
      {
438
        if ( !d_ds.empty() )
1✔
439
          Clib::MakeDirectory( d_ds.c_str() );
1✔
440
        Clib::MakeDirectory( directory.c_str() );
1✔
441
      }
442

443
      DataStoreFile* dsf = nullptr;
3✔
444

445
      Core::DataStore::iterator itr = Core::configurationbuffer.datastore.find( descriptor );
3✔
446
      if ( itr != Core::configurationbuffer.datastore.end() )
3✔
447
      {
448
        dsf = ( *itr ).second;
×
449
      }
450
      else
451
      {
452
        // create a new one
453
        dsf = new DataStoreFile( descriptor, spec_pkg, spec_filename, flags );
3✔
454
        Core::configurationbuffer.datastore[descriptor] = dsf;
3✔
455
      }
456

457
      // didn't find it, time to go open or create.
458
      if ( !dsf->loaded() )
3✔
459
        dsf->load();
3✔
460

461
      return new DataFileRefObjImp( dsf->dfcontents );
3✔
462
    }
3✔
463
    catch ( std::exception& ex )
×
464
    {
465
      std::string message = std::string( "An exception occurred: " ) + ex.what();
×
466
      return new Bscript::BError( message );
×
467
    }
×
468
  }
469
  else
470
  {
471
    return new Bscript::BError( "Invalid parameter type" );
×
472
  }
473
}
474

475
Bscript::BObjectImp* DataFileExecutorModule::mf_OpenDataFile()
3✔
476
{
477
  const Bscript::String* strob;
478
  if ( getStringParam( 0, strob ) )
3✔
479
  {
480
    try
481
    {
482
      std::string descriptor;
3✔
483
      //      string directory;
484
      const std::string& inspec = strob->value();
3✔
485

486
      const Plib::Package* spec_pkg = nullptr;
3✔
487
      std::string spec_filename;
3✔
488
      if ( !Plib::pkgdef_split( inspec, exec.prog()->pkg, &spec_pkg, &spec_filename ) )
3✔
489
      {
490
        return new Bscript::BError( "Error in descriptor" );
×
491
      }
492
      if ( spec_pkg == nullptr )
3✔
493
      {
494
        // ::filename
495
        descriptor = "::" + spec_filename;
×
496
      }
497
      else
498
      {
499
        // :somepkg:filename
500
        descriptor = ":" + spec_pkg->name() + ":" + spec_filename;
3✔
501
      }
502

503
      Core::DataStore::iterator itr = Core::configurationbuffer.datastore.find( descriptor );
3✔
504
      if ( itr != Core::configurationbuffer.datastore.end() )
3✔
505
      {
506
        DataStoreFile* dsf = ( *itr ).second;
3✔
507
        // didn't find it, time to go open or create.
508
        if ( !dsf->loaded() )
3✔
509
          dsf->load();
2✔
510
        return new DataFileRefObjImp( dsf->dfcontents );
3✔
511
      }
512

513
      return new Bscript::BError( "Datafile does not exist" );
×
514
    }
3✔
515
    catch ( std::exception& ex )
×
516
    {
517
      return new Bscript::BError( std::string( "An exception occurred" ) + ex.what() );
×
518
    }
×
519
  }
520
  else
521
  {
522
    return new Bscript::BError( "Invalid parameter type" );
×
523
  }
524
}
525

526
Bscript::BObjectImp* DataFileExecutorModule::mf_UnloadDataFile()
×
527
{
528
  const Bscript::String* strob;
529
  if ( getStringParam( 0, strob ) )
×
530
  {
531
    DataStoreFile* dsf = GetDataStoreFile( strob->value() );
×
532
    if ( !dsf )
×
533
      return new Bscript::BError( "Unable to find data store file" );
×
534

535
    dsf->unload = true;
×
536
    return new Bscript::BLong( 1 );
×
537
  }
538

539
  return new Bscript::BError( "Invalid parameter type" );
×
540
}
541

542
DataStoreFile::DataStoreFile( Clib::ConfigElem& elem )
3✔
543
    : descriptor( elem.remove_string( "Descriptor" ) ),
3✔
544
      name( elem.remove_string( "name" ) ),
3✔
545
      pkgname( elem.remove_string( "package", "" ) ),
3✔
546
      pkg( Plib::find_package( pkgname ) ),
3✔
547
      version( elem.remove_ushort( "Version" ) ),
3✔
548
      oldversion( elem.remove_ushort( "OldVersion" ) ),
3✔
549
      flags( elem.remove_ulong( "Flags" ) ),
3✔
550
      unload( false ),
3✔
551
      delversion( 0 )
3✔
552
{
553
}
3✔
554

555
DataStoreFile::DataStoreFile( const std::string& descriptor, const Plib::Package* pkg,
3✔
556
                              const std::string& name, int flags )
3✔
557
    : descriptor( descriptor ),
3✔
558
      name( name ),
3✔
559
      pkgname( "" ),
3✔
560
      pkg( pkg ),
3✔
561
      version( 0 ),
3✔
562
      oldversion( 0 ),
3✔
563
      flags( flags ),
3✔
564
      unload( false ),
3✔
565
      delversion( 0 )
3✔
566
{
567
  if ( pkg != nullptr )
3✔
568
    pkgname = pkg->name();
3✔
569
}
3✔
570

571
bool DataStoreFile::loaded() const
11✔
572
{
573
  return dfcontents.get() != nullptr;
11✔
574
}
575

576
void DataStoreFile::load()
5✔
577
{
578
  if ( loaded() )
5✔
579
    return;
×
580

581
  dfcontents.set( new DataFileContents( this ) );
5✔
582

583
  std::string fn = filename();
5✔
584
  if ( Clib::FileExists( fn.c_str() ) )
5✔
585
  {
586
    Clib::ConfigFile cf( filename().c_str(), "Element" );
2✔
587
    dfcontents->load( cf );
2✔
588
  }
2✔
589
  else
590
  {
591
    // just force an empty file to be written
592
    dfcontents->dirty = true;
3✔
593
  }
594
}
5✔
595

596
DataStoreFile::~DataStoreFile()
6✔
597
{
598
  dfcontents.clear();
6✔
599
}
6✔
600

601
void DataStoreFile::printOn( Clib::StreamWriter& sw ) const
6✔
602
{
603
  sw.begin( "DataFile" );
6✔
604
  sw.add( "Descriptor", descriptor );
6✔
605
  sw.add( "Name", name );
6✔
606

607
  if ( !pkgname.empty() )
6✔
608
    sw.add( "Package", pkgname );
6✔
609

610
  sw.add( "Flags", flags );
6✔
611
  sw.add( "Version", version );
6✔
612
  sw.add( "OldVersion", oldversion );
6✔
613
  sw.end();
6✔
614
}
6✔
615

616
std::string DataStoreFile::filename( unsigned ver ) const
19✔
617
{
618
  std::string tmp = Plib::systemstate.config.world_data_path + "ds/";
19✔
619
  if ( pkg != nullptr )
19✔
620
    tmp += pkg->name() + "/";
19✔
621
  tmp += name + "." + Clib::tostring( ver % 10 ) + ".txt";
19✔
622
  return tmp;
19✔
623
}
×
624

625
std::string DataStoreFile::filename() const
16✔
626
{
627
  return filename( version );
16✔
628
}
629

630
void DataStoreFile::save() const
3✔
631
{
632
  auto path = std::filesystem::path( filename() );
3✔
633
  path.remove_filename();
3✔
634
  if ( !std::filesystem::exists( path ) )
3✔
635
    std::filesystem::create_directories( path );
×
636

637
  Clib::StreamWriter sw( filename() );
3✔
638
  dfcontents->save( sw );
3✔
639
}
3✔
640

641
size_t DataStoreFile::estimateSize() const
×
642
{
643
  size_t size = descriptor.capacity() + name.capacity() + pkgname.capacity() +
×
644
                sizeof( Plib::Package* ) /*pkg*/
645
                + 3 * sizeof( unsigned ) /*version oldversion delversion*/
646
                + sizeof( int )          /*flags*/
647
                + sizeof( bool )         /*unload*/
648
                + sizeof( DataFileContentsRef );
×
649
  if ( dfcontents.get() )
×
650
    size += dfcontents->estimateSize();
×
651
  return size;
×
652
}
653

654

655
DataFileElement::DataFileElement() : proplist( Core::CPropProfiler::Type::DATAFILEELEMENT ) {}
4✔
656

657
DataFileElement::DataFileElement( Clib::ConfigElem& elem )
4✔
658
    : proplist( Core::CPropProfiler::Type::DATAFILEELEMENT )
4✔
659
{
660
  proplist.readRemainingPropertiesAsStrings( elem );
4✔
661
}
4✔
662

663
void DataFileElement::printOn( Clib::StreamWriter& sw ) const
4✔
664
{
665
  proplist.printPropertiesAsStrings( sw );
4✔
666
}
4✔
667

668
void read_datastore_dat()
2✔
669
{
670
  std::string datastorefile = Plib::systemstate.config.world_data_path + "datastore.txt";
2✔
671

672
  if ( !Clib::FileExists( datastorefile ) )
2✔
673
    return;
1✔
674

675
  Clib::ConfigFile cf( datastorefile, "DataFile" );
1✔
676
  Clib::ConfigElem elem;
1✔
677

678
  while ( cf.read( elem ) )
4✔
679
  {
680
    DataStoreFile* dsf = new DataStoreFile( elem );
3✔
681
    auto path = std::filesystem::path( dsf->filename() );
3✔
682
    if ( !std::filesystem::exists( path ) )
3✔
683
      throw std::runtime_error(
×
684
          fmt::format( "datafile '{}' does not exist, but should due to 'datastore.txt' entry '{}'",
×
685
                       dsf->filename(), dsf->descriptor ) );
×
686
    Core::configurationbuffer.datastore[dsf->descriptor] = dsf;
3✔
687
  }
3✔
688
}
2✔
689

690
void write_datastore( Clib::StreamWriter& sw )
4✔
691
{
692
  for ( auto dsf : Core::configurationbuffer.datastore | std::views::values )
10✔
693
  {
694
    dsf->delversion = dsf->oldversion;
6✔
695
    dsf->oldversion = dsf->version;
6✔
696

697
    if ( dsf->dfcontents.get() && dsf->dfcontents->dirty )
6✔
698
    {
699
      // make a new generation of file and write it.
700
      ++dsf->version;
3✔
701

702
      dsf->save();
3✔
703

704
      dsf->dfcontents->dirty = false;
3✔
705
    }
706

707
    dsf->printOn( sw );
6✔
708
  }
709
}
4✔
710

711
void commit_datastore()
4✔
712
{
713
  for ( auto dsf : Core::configurationbuffer.datastore | std::views::values )
10✔
714
  {
715
    if ( dsf->delversion != dsf->version && dsf->delversion != dsf->oldversion )
6✔
716
    {
717
      Clib::RemoveFile( dsf->filename( dsf->delversion ) );
3✔
718
    }
719

720
    if ( dsf->unload )
6✔
721
    {
722
      if ( dsf->dfcontents.get() != nullptr )
×
723
      {
724
        if ( dsf->dfcontents->count() == 1 )
×
725
        {
726
          dsf->dfcontents.clear();
×
727
        }
728
      }
729
      dsf->unload = false;
×
730
    }
731
  }
732
}
4✔
733
}  // namespace Pol::Module
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc