GAMS Data eXchange (GDX) API
Low-level "eXPert level" C++ API for reading and writing GAMS Data eXchange files
Loading...
Searching...
No Matches
gxfile.hpp
1/*
2 * GAMS - General Algebraic Modeling System GDX API
3 *
4 * Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
5 * Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26#pragma once
27
28// Description:
29// This unit defines the GDX Object as a C++ object.
30
31#include "datastorage.hpp" // for TLinkedData
32#include <gclgms.h> // for GLOBAL_MAX_INDEX_DIM, GMS_MAX_INDEX_DIM
33#include "gmsdata.hpp" // for TTblGamsData
34#include "gmsobj.hpp" // for TBooleanBitArray, TXList, TXStrings
35#include "sysutils_p3.hpp" // for p3_global_storage
36#include "strhash.hpp" // for TXCSStrHashList, TXStrHashList
37#include "utils.hpp"
38#include <array> // for array
39#include <cstdint> // for int64_t, uint8_t
40#include <cstring> // for size_t
41#include <initializer_list>// for initializer_list
42#include <limits> // for numeric_limits
43#include <memory> // for unique_ptr, allocator
44#include <optional> // for optional
45#include <string> // for string
46
47#ifndef GDX_NS
48#define GDX_NS gdxlib::
49#endif
50
51namespace GDX_NS gdlib::gmsstrm
52{
53class TXStream;
54}// namespace gdx::gmsstrm
55
56//======================================================================================================================
57
58namespace GDX_NS gdx
59{
60
61class TgdxUELIndex : public std::array<int, GMS_MAX_INDEX_DIM> {
62public:
63 constexpr explicit operator int *() noexcept { return data(); }
64 constexpr explicit operator const int *() const noexcept { return data(); }
65};
66class TgdxValues : public std::array<double, GMS_VAL_SCALE + 1> {
67public:
68 constexpr explicit operator double*() noexcept { return data(); }
69 constexpr explicit operator const double *() const noexcept { return data(); }
70};
71
72using TDomainIndexProc_t = void ( * )( int RawIndex, int MappedIndex, void *Uptr );
73using TDataStoreProc_t = void ( * )( const int *Indx, const double *Vals );
74using TDataStoreFiltProc_t = int ( * )( const int *Indx, const double *Vals, void *Uptr );
75using TDataStoreExProc_t = int ( * )( const int *Indx, const double *Vals, const int afdim, void *Uptr );
76
77using TDataStoreExProc_F = int ( * )( const int *Indx, const double *Vals, const int afdim, int64_t Uptr );
78using TDataStoreFiltProc_F = int ( * )( const int *Indx, const double *Vals, int64_t Uptr );
79using TDomainIndexProc_F = void ( * )( int RawIndex, int MappedIndex, int64_t Uptr );
80
81const std::array<int, GMS_DT_ALIAS + 1> DataTypSize { 1, 1, 5, 5, 0 };
82
83constexpr int DOMC_UNMAPPED = -2,// indicator for unmapped index pos
84 DOMC_EXPAND = -1, // indicator growing index pos
85 DOMC_STRICT = 0; // indicator mapped index pos
86
87constexpr std::string_view BADUEL_PREFIX = "?L__",
88 BADStr_PREFIX = "?Str__",
89 strGDXCOMPRESS = "GDXCOMPRESS",
90 strGDXCONVERT = "GDXCONVERT";
91
92struct TDFilter final {
93 int FiltNumber {}, FiltMaxUel {};
94 gdlib::gmsobj::TBooleanBitArray FiltMap {};
95 bool FiltSorted {};
96
97 TDFilter( int Nr, int UserHigh ) : FiltNumber { Nr },
98 FiltMaxUel { UserHigh }
99 {
100 }
101
102 ~TDFilter() = default;
103
104 [[nodiscard]] int MemoryUsed() const
105 {
106 return FiltMap.MemoryUsed();
107 }
108
109 [[nodiscard]] bool InFilter( int V ) const
110 {
111 return V >= 0 && V <= FiltMaxUel && FiltMap.GetBit( V );
112 }
113
114 void SetFilter( int ix, bool v )
115 {
116 FiltMap.SetBit( ix, v );
117 }
118};
119
120using TSetBitMap = gdlib::gmsobj::TBooleanBitArray;
121
122enum class TgdxDAction : uint8_t
123{
124 dm_unmapped,
125 dm_strict,
126 dm_filter,
127 dm_expand
128};
129
130struct TDomain {
131 TDFilter *DFilter;
132 TgdxDAction DAction;
133};
134
135using TDomainList = std::array<TDomain, GLOBAL_MAX_INDEX_DIM>;
136
137using TCommentsList = gdlib::gmsobj::TXStrings;
138
139struct TgdxSymbRecord final {
140 int SSyNr;
141 int64_t SPosition;
142 int SDim, SDataCount, SErrors;
143 gdxSyType SDataType;
144 int SUserInfo;
145 bool SSetText;
146 utils::sstring SExplTxt;
147 bool SIsCompressed;
148 bool SScalarFrst; // not stored
149 std::unique_ptr<int[]> SDomSymbols,// real domain info
150 SDomStrings;// relaxed domain info
151 std::optional<TCommentsList> SCommentsList;
152 std::unique_ptr<TSetBitMap> SSetBitMap;// for 1-dim sets only
153};
154using PgdxSymbRecord = TgdxSymbRecord *;
155
156enum TgdxIntlValTyp : uint8_t
157{// values stored internally via the indicator byte
158 vm_valund,
159 vm_valna,
160 vm_valpin,
161 vm_valmin,
162 vm_valeps,
163 vm_zero,
164 vm_one,
165 vm_mone,
166 vm_half,
167 vm_two,
168 vm_normal,
169 vm_count
170};
171
172enum TgxFileMode : uint8_t
173{
174 f_not_open,
175 fr_init,
176 fw_init,
177 fw_dom_raw,
178 fw_dom_map,
179 fw_dom_str,
180 fw_raw_data,
181 fw_map_data,
182 fw_str_data,
183 f_raw_elem,
184 f_map_elem,
185 f_str_elem,
186 fr_raw_data,
187 fr_map_data,
188 fr_mapr_data,
189 fr_str_data,
190 fr_filter,
191 fr_slice,
192 tgxfilemode_count
193};
194
195class TgxModeSet final : public utils::IContainsPredicate<TgxFileMode>
196{
197 std::array<bool, tgxfilemode_count> modeActive {};
198 uint8_t count {};
199
200public:
201 constexpr TgxModeSet( const std::initializer_list<TgxFileMode> &modes )
202 {
203 for( const auto mode: modes )
204 {
205 modeActive[mode] = true;
206 count++;
207 }
208 }
209
210 ~TgxModeSet() override = default;
211 [[nodiscard]] bool contains( const TgxFileMode &mode ) const override;
212 [[nodiscard]] bool empty() const;
213};
214
215enum class TgdxElemSize : uint8_t
216{
217 sz_byte,
218 sz_word,
219 sz_integer
220};
221
222// N.B.: we store integers in [0..high(integer)] in TIntegerMapping, so
223// FMAXCAPACITY = high(integer) + 1 is all we will ever need, and we will
224// never get a request to grow any larger. The checks and code
225// in growMapping reflect this
227{
228 int64_t FCapacity {}, FMapBytes {};
229 int64_t FMAXCAPACITY { std::numeric_limits<int>::max() + static_cast<int64_t>( 1 ) };
230 int FHighestIndex {};
231 int *PMap {};
232
233 void growMapping( int F );
234
235public:
236 TIntegerMapping() = default;
238 [[nodiscard]] int MemoryUsed() const;
239 [[nodiscard]] int GetHighestIndex() const;
240 [[nodiscard]] int GetMapping( int F ) const;
241 void SetMapping( int F, int T );
242 [[nodiscard]] int size() const;
243 [[nodiscard]] bool empty() const;
244 void reset();
245};
246
247enum class TUELUserMapStatus : uint8_t
248{
249 map_unknown,
250 map_unsorted,
251 map_sorted,
252 map_sortgrow,
253 map_sortfull
254};
255
256template<typename T>
257using TXStrHashListImpl = gdlib::strhash::TXStrHashList<T>;
258
259template<typename T>
260using TXCSStrHashListImpl = gdlib::strhash::TXCSStrHashList<T>;
261
262class TUELTable final : public TXStrHashListImpl<int>
263{
264 TUELUserMapStatus FMapToUserStatus { TUELUserMapStatus::map_unknown };
265
266public:
267 std::unique_ptr<TIntegerMapping> UsrUel2Ent {};// from user uelnr to table entry
268 TUELTable();
269 [[nodiscard]] int size() const;
270 [[nodiscard]] bool empty() const;
271 [[nodiscard]] int GetUserMap( int i ) const;
272 void SetUserMap( int EN, int N );
273 int NewUsrUel( int EN );
274 int AddUsrNew( const char *s, size_t slen );
275 int AddUsrIndxNew( const char *s, size_t slen, int UelNr );
276 [[nodiscard]] int GetMaxUELLength() const;
277 const char *operator[]( int index ) const;
278 [[nodiscard]] int MemoryUsed() const;
279 void LoadFromStream( gdlib::gmsstrm::TXStream &S );
280 TUELUserMapStatus GetMapToUserStatus();
281 void ResetMapToUserStatus();
282};
283
284int MakeGoodExplText( char *s );
285
286struct TAcronym final {
287 std::string AcrName, AcrText;
288 int AcrMap {}, AcrReadMap { -1 };
289 bool AcrAutoGen {};
290
291 TAcronym( const char *Name, const char *Text, int Map );
292 explicit TAcronym( gdlib::gmsstrm::TXStream &S );
293 TAcronym() = default;
294 ~TAcronym() = default;
295 [[nodiscard]] int MemoryUsed() const;
296 void SaveToStream( gdlib::gmsstrm::TXStream &S ) const;
297 void SetNameAndText( const char *Name, const char *Text );
298};
299
300class TAcronymList final
301{
302 bool useBatchAlloc {};
303 gdlib::gmsobj::TXList<TAcronym> FList;
304 gdlib::batchalloc::BatchAllocator<sizeof(TAcronym)> batchAlloc;
305
306public:
307 TAcronymList() = default;
308 explicit TAcronymList(bool _useBatchAlloc) : useBatchAlloc{_useBatchAlloc} {}
310 int FindEntry( int Map );
311 int FindName( const char *Name );
312 int AddEntry( const char *Name, const char *Text, int Map );
313 void CheckEntry( int Map );
314 void SaveToStream( gdlib::gmsstrm::TXStream &S );
315 void LoadFromStream( gdlib::gmsstrm::TXStream &S );
316 int MemoryUsed();
317 [[nodiscard]] int size() const;
318 TAcronym &operator[]( int Index );
319};
320
321class TFilterList final
322{
323 gdlib::gmsobj::TXList<TDFilter> FList;
324
325public:
326 TFilterList() = default;
327 ~TFilterList();
328 void AddFilter( TDFilter *F );
329 void DeleteFilter( int ix );
330 TDFilter *FindFilter( int Nr );
331 [[nodiscard]] size_t MemoryUsed() const;
332};
333
334using TIntlValueMapDbl = std::array<double, vm_count>;
335using TIntlValueMapI64 = std::array<int64_t, vm_count>;
336
337using LinkedDataType = gdlib::datastorage::TLinkedData<int, double>;
338using LinkedDataIteratorType = gdlib::datastorage::TLinkedDataRec<int, double> *;
339
340using TSetTextList = TXCSStrHashListImpl<int>;
341
342using TNameList = TXStrHashListImpl<PgdxSymbRecord>;
343
344template<typename T>
345using TTblGamsDataImpl = gdlib::gmsdata::TTblGamsData<T>;
346
347using TDomainStrList = TXStrHashListImpl<uint8_t>;
348
349enum tvarvaltype : uint8_t
350{
351 vallevel, // 1
352 valmarginal,// 2
353 vallower, // 3
354 valupper, // 4
355 valscale // 5
356};
357
358extern p3_global_storage std::string DLLLoadPath;// can be set by loader, so the "dll" knows where it is loaded from
359
361{
362 int64_t i;
363 void *p;
364};
365
366bool IsGoodIdent( const char *S );
367bool CanBeQuoted( const char *s, size_t slen );
368bool GoodUELString( const char *s, size_t slen );
369
370int ConvertGDXFile( const std::string &fn, const std::string &MyComp );
371
372}// namespace gdx
Definition: gxfile.hpp:301
Definition: gxfile.hpp:322
Definition: gxfile.hpp:227
Definition: gxfile.hpp:263
Definition: gxfile.hpp:61
Definition: gxfile.hpp:66
Definition: gxfile.hpp:196
Definition: gxfile.hpp:286
Definition: gxfile.hpp:92
Definition: gxfile.hpp:130
Definition: gxfile.hpp:139
Definition: gxfile.hpp:361