NDEVR
API Documentation
INIReader.h
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: INIReader
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include "DLLInfo.h"
34#include <NDEVR/String.h>
35#include <NDEVR/Resource.h>
36#include <NDEVR/Scanner.h>
37#include <NDEVR/Buffer.h>
38#include <NDEVR/Dictionary.h>
39#include <NDEVR/Matrix.h>
40#include <stdio.h>
41namespace NDEVR
42{
43 class LogPtr;
48 class NDEVR_BASE_API INIOption
49 {
50 public:
54 explicit INIOption();
55
59 virtual ~INIOption() {}
60
65 virtual void readOptionAscii(String option) = 0;
66
71 virtual void readOptionAscii(Scanner& option) = 0;
72
77 virtual String writeOptionAscii() const = 0;
78
83 virtual void writeOptionBinary(FILE* stream) const = 0;
84
89 virtual void readOptionBinary(const char* bytes) = 0;
90
95 virtual INIOption* copy() const = 0;
96 };
97
106 class NDEVR_BASE_API INIFactory
107 {
108 public:
113
115 INIFactory(const INIFactory& reader) = delete;
116
121 INIFactory(INIFactory&& reader) noexcept;
122
126 virtual ~INIFactory();
127
133 void addINIOption(const StringView& label, INIOption* option);
134
140 template<uint01 t_dims, class t_type>
142 {
143 addINIOption(label, new INIObject<Vector<t_dims, t_type>>(mem_loc));
144 }
145
151 template<uint01 t_dims, class t_type>
152 void addOption(const StringView& label, Vector<t_dims, t_type>& mem_loc)
153 {
154 addINIOption(label, new INIObject<Vector<t_dims, t_type>>(mem_loc));
155 }
156
158 template<class t_type>
159 void addOption(const StringView& label, const Resource<t_type>& mem_loc) = delete;
160
166 template<class t_type>
167 void addOption(const StringView& label, Resource<t_type>& mem_loc)
168 {
169 addINIOption(label, new INIObject<t_type>(mem_loc));
170 }
171
173 template<class t_type>
174 void addOption(const StringView& label, const t_type& mem_loc) = delete;
175
181 template<class t_type>
182 void addOption(const StringView& label, t_type& mem_loc)
183 {
184 addINIOption(label, new INIObject<t_type>(mem_loc));
185 }
186
192 template<class t_type, uint01 t_row_dims, uint01 t_col_dims>
194 {
195 addINIOption(label, new INIObject<Matrix<t_type, t_row_dims, t_col_dims>>(mem_loc));
196 }
197
201 void clear();
202
210 bool addManagedOption(const StringView& option_label, const StringView& option, bool replace = true);
211
217 bool hasOption(const StringView& option) const;
218
224 bool hasOption(uint08 hash_option) const;
225
230 void setDelimiter(char delimiter);
231
236 void setComment(char comment) { m_comment = comment; };
237
242 void read(Scanner& file);
243
248 void readAsciiFile(File& file);
249
254 void readBinaryFile(File& file);
255
260 void setPreserveOrder(bool preserve_order) { m_preserve_order = preserve_order; }
261
266 bool preserveOrder() const { return m_preserve_order; }
267
273 void writeToAsciiFile(File& file, bool include_end_comment = false);
274
280
287 void writeToLog(const StringView& title, LogPtr& log, uint01 log_level = 2);
288
293 void setUseHashLabels(bool use_hash_labels);
294
300
305 Dictionary<String, String*>& extraOptionsRef() { return m_extra_options; };
306
313 String getOption(const StringView& option, const StringView& default_value = StringView()) const;
314
319 static void ConvertToINIString(String& s);
320
326
332 template<class t_type>
333 static INIOption* ToOption(t_type& mem_loc)
334 {
335 return new INIObject<t_type>(mem_loc);
336 }
337
343 template<class t_type>
345 {
346 return new INIObject<t_type>(value);
347 }
348 private:
353 template<class t_type>
354 class INIObject : public INIOption
355 {
356 public:
361 INIObject(Resource<t_type>& value)
362 : INIOption()
363 , m_type_pointer_shared(&value)
364 , m_type_pointer(nullptr)
365 {}
366
371 INIObject(t_type& value)
372 : INIOption()
373 , m_type_pointer_shared(nullptr)
374 , m_type_pointer(&value)
375 {}
376
381 INIObject(const INIObject& other)
382 : INIOption()
383 , m_type_pointer_shared(other.m_type_pointer_shared)
384 , m_type_pointer(other.m_type_pointer)
385 {}
386
390 ~INIObject() {}
391
396 void readOptionAscii(Scanner& scan) override
397 {
398 readOptionAscii(scan.getNext<String>());
399 }
400
405 void readOptionAscii(String option) override
406 {
407 INIFactory::ConvertFromINIString(option);
408 if (option.size() > 0)
409 {
410 if (m_type_pointer_shared != nullptr)
411 m_type_pointer_shared->set(option.getAs<t_type>());
412 else
413 *m_type_pointer = option.getAs<t_type>();
414 }
415 }
416
421 String writeOptionAscii() const override
422 {
423 String s;
424 if (m_type_pointer_shared != nullptr)
425 s.setFrom(m_type_pointer_shared->get());
426 else
427 s.setFrom(*m_type_pointer);
428 INIFactory::ConvertToINIString(s);
429 return s;
430 }
431
437 void readOptionBinary(const char* bytes) override
438 {
439 if (ObjectInfo<t_type>::Primitive)
440 {
441 t_type value;
442 memcpy(&value, bytes, sizeof(t_type));
443 if (m_type_pointer_shared != nullptr)
444 m_type_pointer_shared->set(value);
445 else
446 *m_type_pointer = value;
447 }
448 else
449 {
450 readOptionAscii(String(bytes));
451 }
452 }
453
459 void writeOptionBinary(FILE* stream) const override
460 {
461 if (ObjectInfo<t_type>::Primitive)
462 {
463 uint04 size = sizeof(t_type);
464 fwrite(&size, sizeof(uint04), 1, stream);
465 if (m_type_pointer_shared != nullptr)
466 fwrite(&(m_type_pointer_shared->get()), sizeof(t_type), 1, stream);
467 else
468 fwrite(m_type_pointer, sizeof(t_type), 1, stream);
469 }
470 else
471 {
472 const String value = writeOptionAscii();
473 const uint04 value_size = value.size();
474 fwrite(&value_size, sizeof(uint04), 1, stream);
475 fwrite(value.c_str(), sizeof(char), value_size, stream);
476 }
477 }
478
483 INIObject<t_type>* copy() const override
484 {
485 return new INIObject<t_type>(*this);
486 }
487 protected:
488 Resource<t_type>* const m_type_pointer_shared;
489 t_type* const m_type_pointer;
490 };
491
496 template<class t_type>
497 class INIObject<Angle<t_type>> : public INIOption
498 {
499 public:
504 INIObject(Resource<Angle<t_type>>& value)
505 : INIOption()
506 , m_type_pointer_shared(&value)
507 , m_type_pointer(nullptr)
508 {}
509
514 INIObject(Angle<t_type>& value)
515 : INIOption()
516 , m_type_pointer_shared(nullptr)
517 , m_type_pointer(&value)
518 {}
519
524 INIObject(const INIObject& other)
525 : INIOption()
526 , m_type_pointer_shared(other.m_type_pointer_shared)
527 , m_type_pointer(other.m_type_pointer)
528 {}
529
533 ~INIObject() {}
534
539 void readOptionAscii(Scanner& scan) override
540 {
541 readOptionAscii(scan.getNext<String>());
542 }
543
548 void readOptionAscii(String option) override
549 {
550 INIFactory::ConvertFromINIString(option);
551 if (option.size() > 0)
552 {
553 if (m_type_pointer_shared != nullptr)
554 m_type_pointer_shared->set(Angle<t_type>(DEGREES, option.getAs<fltp08>()));
555 else
556 *m_type_pointer = Angle<t_type>(DEGREES, option.getAs<fltp08>());
557 }
558 }
559
564 String writeOptionAscii() const override
565 {
566 String s;
567 if (m_type_pointer_shared != nullptr)
568 s.setFrom(m_type_pointer_shared->get().template as<DEGREES>());
569 else
570 s.setFrom(m_type_pointer->template as<DEGREES>());
571 INIFactory::ConvertToINIString(s);
572 return s;
573 }
574
579 void readOptionBinary(const char* bytes) override
580 {
581 Angle<t_type> value;
582 memcpy(&value, bytes, sizeof(Angle<t_type>));
583 if (m_type_pointer_shared != nullptr)
584 m_type_pointer_shared->set(value);
585 else
586 *m_type_pointer = value;
587 }
588
593 void writeOptionBinary(FILE* stream) const override
594 {
595 uint04 size = sizeof(Angle<t_type>);
596 fwrite(&size, sizeof(uint04), 1, stream);
597 if (m_type_pointer_shared != nullptr)
598 fwrite(&(m_type_pointer_shared->get()), sizeof(Angle<t_type>), 1, stream);
599 else
600 fwrite(m_type_pointer, sizeof(Angle<t_type>), 1, stream);
601 }
602
607 INIObject<Angle<t_type>>* copy() const override
608 {
609 return new INIObject<Angle<t_type>>(*this);
610 }
611 protected:
612 Resource<Angle<t_type>>* const m_type_pointer_shared;
613 Angle<t_type>* const m_type_pointer;
614 };
615 private:
616 Dictionary<String, INIOption*> m_options;
617 Dictionary<uint08, INIOption*> m_hashed_options;
618 Dictionary<String, String*> m_extra_options;
619 Buffer<String> m_ordered_options;
620 char m_delimiter;
621 char m_comment;
622 bool m_preserve_order = false;
623 bool m_use_hash_labels = false;
624 };
625
626}
A hash-based key-value store, useful for quick associative lookups.
Definition Dictionary.h:64
Logic for reading or writing to a file as well as navigating filesystems or other common file operati...
Definition File.h:53
void addOption(const StringView &label, t_type &mem_loc)
Registers a raw typed option that will be read/written by the factory.
Definition INIReader.h:182
void clear()
Removes all registered options and frees their memory.
void setDelimiter(char delimiter)
Sets the delimiter character used to separate keys from values.
void addOption(const StringView &label, Resource< t_type > &mem_loc)
Registers a Resource option that will be read/written by the factory.
Definition INIReader.h:167
void writeToAsciiFile(File &file, bool include_end_comment=false)
Writes all registered options to an ASCII-formatted INI file.
void setPreserveOrder(bool preserve_order)
Sets whether to preserve the order in which options appear in the file.
Definition INIReader.h:260
INIFactory(INIFactory &&reader) noexcept
Move constructor that transfers ownership of all options and state.
void addOption(const StringView &label, const t_type &mem_loc)=delete
Deleted overload to prevent binding to const references.
void addOption(const StringView &label, const Resource< t_type > &mem_loc)=delete
Deleted overload to prevent binding to const Resource references.
void setUseHashLabels(bool use_hash_labels)
Enables or disables using hashed labels for option lookup.
INIFactory(const INIFactory &reader)=delete
Deleted copy constructor to prevent unintended duplication of option ownership.
void readAsciiFile(File &file)
Reads all options from an ASCII-formatted INI file.
Dictionary< String, String * > & extraOptionsRef()
Returns a mutable reference to the extra options dictionary.
Definition INIReader.h:305
bool hasOption(const StringView &option) const
Checks whether an option with the given label has been registered.
INIFactory()
Constructs a default INIFactory with default delimiter and comment settings.
Dictionary< String, String > extraOptions() const
Returns a copy of all extra (unregistered) options as key-value pairs.
static void ConvertFromINIString(String &s)
Converts INI escape sequences in a string back to their original characters.
void writeToBinaryFile(File &file)
Writes all registered options to a binary-formatted INI file.
virtual ~INIFactory()
Virtual destructor that cleans up all owned INIOption instances.
void addINIOption(const StringView &label, INIOption *option)
Registers an INIOption under the given label.
static INIOption * ToOption(t_type &mem_loc)
Creates an INIOption wrapper for a raw typed variable.
Definition INIReader.h:333
static INIOption * ToOption(Resource< t_type > &value)
Creates an INIOption wrapper for a Resource variable.
Definition INIReader.h:344
bool hasOption(uint08 hash_option) const
Checks whether an option with the given hash exists.
void addOption(const String &label, Resource< Matrix< t_type, t_row_dims, t_col_dims > > &mem_loc)
Registers a Matrix Resource option that will be read/written by the factory.
Definition INIReader.h:193
static void ConvertToINIString(String &s)
Converts special characters in a string to INI-safe escape sequences.
void writeToLog(const StringView &title, LogPtr &log, uint01 log_level=2)
Writes all registered options to a log with the given title and level.
void addOption(const StringView &label, Vector< t_dims, t_type > &mem_loc)
Registers a raw Vector option that will be read/written by the factory.
Definition INIReader.h:152
void readBinaryFile(File &file)
Reads all options from a binary-formatted INI file.
void setComment(char comment)
Sets the comment character used to identify comment lines in the INI file.
Definition INIReader.h:236
void read(Scanner &file)
Reads option values from a Scanner stream, applying them to registered options.
void addOption(const StringView &label, Resource< Vector< t_dims, t_type > > &mem_loc)
Registers a Vector Resource option that will be read/written by the factory.
Definition INIReader.h:141
bool addManagedOption(const StringView &option_label, const StringView &option, bool replace=true)
Adds or updates a managed string option that is stored internally by the factory.
String getOption(const StringView &option, const StringView &default_value=StringView()) const
Retrieves the string value of a registered or extra option by label.
bool preserveOrder() const
Returns whether the factory preserves option ordering.
Definition INIReader.h:266
A class used with INIFactory to store a reference to an object in the program that can be inherited t...
Definition INIReader.h:49
virtual void readOptionBinary(const char *bytes)=0
Reads the option value from a raw binary byte buffer.
virtual ~INIOption()
Virtual destructor for safe polymorphic cleanup.
Definition INIReader.h:59
INIOption()
Constructs a default INIOption.
virtual void readOptionAscii(Scanner &option)=0
Reads an option value from a Scanner stream.
virtual String writeOptionAscii() const =0
Writes the option value to an ASCII string representation.
virtual void writeOptionBinary(FILE *stream) const =0
Writes the option value in binary format to a file stream.
virtual void readOptionAscii(String option)=0
Reads an option value from an ASCII string representation.
virtual INIOption * copy() const =0
Creates a deep copy of this INIOption.
A light-weight wrapper that will be a no-op if there is not a valid log reference,...
Templated logic for doing matrix multiplication.
Definition Matrix.hpp:182
A core part of the engine, stores variables that can be listened to with ResourceListener which will ...
Definition Resource.h:42
Contains methods for easily reading objects in an ascii stream using set deliminators and line logic.
Definition Scanner.h:47
The core String View class for the NDEVR API.
Definition StringView.h:58
The core String class for the NDEVR API.
Definition String.h:95
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
The primary namespace for the NDEVR SDK.
uint64_t uint08
-Defines an alias representing an 8 byte, unsigned integer
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...