UPnPsdk 0.1
Universal Plug and Play +, Software Development Kit
 
Loading...
Searching...
No Matches
strintmap.hpp
Go to the documentation of this file.
1#ifndef UPnPdsk_STRINTMAP_HPP
2#define UPnPdsk_STRINTMAP_HPP
3// Copyright (C) 2024+ GPL 3 and higher by Ingo Höft, <Ingo@Hoeft-online.de>
4// Redistribution only with this Copyright remark. Last modified: 2025-04-07
5
16#include <UPnPsdk/synclog.hpp>
17#include <UPnPsdk/port.hpp>
19#include <cstddef> // for size_t
20#include <cstring>
21#include <climits>
23
24
25namespace UPnPsdk {
26
29 const char* name;
30 int id;
31};
32
36// Don't export class symbol; only used library intern.
37template <typename T> //
39 public:
46 static constexpr size_t npos = size_t(-1);
47
54 CStrIntMap(T& a_table) : m_table(a_table) {}
55
60 size_t index_of(
62 const char* a_name,
65 bool a_case_sensitive = false);
66
72 size_t index_of(
74 const int a_id);
75
76 private:
77 T& m_table;
78};
79
80template <typename T>
81size_t CStrIntMap<T>::index_of(const char* a_name, bool a_case_sensitive) {
82 TRACE("Executing index_of(const char*)");
83 if (a_name == nullptr || a_name[0] == '\0')
84 return this->npos;
85
86 // Select library compare function outside the loop with a function pointer
87 // so we do not have to check on every loop for nothing.
88 int (*str_cmp)(const char*, const char*);
89 str_cmp = a_case_sensitive ? strcmp : strcasecmp;
90
91 size_t top, mid, bot, idxmax;
92 int cmp;
93
94 top = 0;
95 bot = m_table.size() - 1;
96 idxmax = bot;
97
98 while (top <= bot) {
99 mid = (top + bot) / 2;
100 if (mid > idxmax) // unsigned index outer low bound
101 break;
102 cmp = str_cmp(a_name, m_table[mid].name);
103 if (cmp > 0) {
104 top = mid + 1; /* look below mid */
105 } else if (cmp < 0) {
106 bot = mid - 1; /* look above mid */
107 } else if (mid > INT_MAX) { // guard for the following type cast
108 UPnPsdk_LOGCRIT("MSG1026") "Index mid="
109 << mid
110 << "exceeds integer limit. This program error MUST be fixed! "
111 "Program is stable but may have ignored runtime "
112 "conditions.\n";
113 return this->npos;
114 } else {
115 return mid; /* match, return table index. */
116 }
117 }
118 return this->npos;
119}
120
121template <typename T> //
122size_t CStrIntMap<T>::index_of(int a_id) {
123 TRACE("Executing index_of(int)");
124 for (size_t i{0}; i < m_table.size(); i++) {
125 if (m_table[i].id == a_id) {
126 return i;
127 }
128 }
129 return this->npos;
130}
131
132} // namespace UPnPsdk
133
134#endif /* UPnPdsk_STRINTMAP_HPP */
Table with C-strings mapped to an integer id.
Definition strintmap.hpp:38
static constexpr size_t npos
Value returned on error or when an index on a container is not found.
Definition strintmap.hpp:46
size_t index_of(const char *a_name, bool a_case_sensitive=false)
Match the given name with names from the entries in the table.
Definition strintmap.hpp:81
CStrIntMap(T &a_table)
Needs to know what table to use.
Definition strintmap.hpp:54
Reengineered Object Oriented UPnP+ program code.
int id
Same value in integer form.
Definition strintmap.hpp:30
const char * name
A value in string form.
Definition strintmap.hpp:29
String to integer map entry.
Definition strintmap.hpp:28
Specifications to be portable between different platforms.
Define macro for synced logging to the console for detailed info and debug.