Coverage Report

Created: 2025-08-28 06:57

/src/gdal/frmts/vrt/vrtrawrasterband.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  Virtual GDAL Datasets
4
 * Purpose:  Implementation of VRTRawRasterBand
5
 * Author:   Frank Warmerdam <warmerdam@pobox.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
9
 * Copyright (c) 2007-2013, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#include "cpl_port.h"
15
#include "rawdataset.h"
16
#include "vrtdataset.h"
17
18
#include <cerrno>
19
#include <cstdio>
20
#include <cstdlib>
21
#include <cstring>
22
23
#include "cpl_conv.h"
24
#include "cpl_error.h"
25
#include "cpl_hash_set.h"
26
#include "cpl_minixml.h"
27
#include "cpl_string.h"
28
#include "cpl_vsi.h"
29
#include "gdal.h"
30
#include "gdal_priv.h"
31
32
/*! @cond Doxygen_Suppress */
33
34
/************************************************************************/
35
/* ==================================================================== */
36
/*                          VRTRawRasterBand                            */
37
/* ==================================================================== */
38
/************************************************************************/
39
40
/************************************************************************/
41
/*                          VRTRawRasterBand()                          */
42
/************************************************************************/
43
44
VRTRawRasterBand::VRTRawRasterBand(GDALDataset *poDSIn, int nBandIn,
45
                                   GDALDataType eType)
46
0
    : m_poRawRaster(nullptr), m_pszSourceFilename(nullptr),
47
0
      m_bRelativeToVRT(FALSE)
48
0
{
49
0
    if (!VRTDataset::IsRawRasterBandEnabled())
50
0
    {
51
        // Safety belt. Not supposed to happen, hence CE_Fatal
52
0
        CPLError(CE_Fatal, CPLE_NotSupported,
53
0
                 "Crashing process: VRTRawRasterBand constructor called "
54
0
                 "whereas not authorized");
55
0
        return;
56
0
    }
57
58
0
    Initialize(poDSIn->GetRasterXSize(), poDSIn->GetRasterYSize());
59
60
    // Declared in GDALRasterBand.
61
0
    poDS = poDSIn;
62
0
    nBand = nBandIn;
63
64
0
    if (eType != GDT_Unknown)
65
0
        eDataType = eType;
66
0
}
67
68
/************************************************************************/
69
/*                         ~VRTRawRasterBand()                          */
70
/************************************************************************/
71
72
VRTRawRasterBand::~VRTRawRasterBand()
73
74
0
{
75
0
    FlushCache(true);
76
0
    ClearRawLink();
77
0
}
78
79
/************************************************************************/
80
/*                             IRasterIO()                              */
81
/************************************************************************/
82
83
CPLErr VRTRawRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
84
                                   int nXSize, int nYSize, void *pData,
85
                                   int nBufXSize, int nBufYSize,
86
                                   GDALDataType eBufType, GSpacing nPixelSpace,
87
                                   GSpacing nLineSpace,
88
                                   GDALRasterIOExtraArg *psExtraArg)
89
0
{
90
0
    if (m_poRawRaster == nullptr)
91
0
    {
92
0
        CPLError(CE_Failure, CPLE_AppDefined,
93
0
                 "No raw raster band configured on VRTRawRasterBand.");
94
0
        return CE_Failure;
95
0
    }
96
97
0
    if (eRWFlag == GF_Write && eAccess == GA_ReadOnly)
98
0
    {
99
0
        CPLError(CE_Failure, CPLE_NoWriteAccess,
100
0
                 "Attempt to write to read only dataset in"
101
0
                 "VRTRawRasterBand::IRasterIO().");
102
103
0
        return CE_Failure;
104
0
    }
105
106
    /* -------------------------------------------------------------------- */
107
    /*      Do we have overviews that would be appropriate to satisfy       */
108
    /*      this request?                                                   */
109
    /* -------------------------------------------------------------------- */
110
0
    if ((nBufXSize < nXSize || nBufYSize < nYSize) && GetOverviewCount() > 0)
111
0
    {
112
0
        if (OverviewRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData,
113
0
                             nBufXSize, nBufYSize, eBufType, nPixelSpace,
114
0
                             nLineSpace, psExtraArg) == CE_None)
115
0
            return CE_None;
116
0
    }
117
118
0
    m_poRawRaster->SetAccess(eAccess);
119
120
0
    return m_poRawRaster->RasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData,
121
0
                                   nBufXSize, nBufYSize, eBufType, nPixelSpace,
122
0
                                   nLineSpace, psExtraArg);
123
0
}
124
125
/************************************************************************/
126
/*                             IReadBlock()                             */
127
/************************************************************************/
128
129
CPLErr VRTRawRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff,
130
                                    void *pImage)
131
132
0
{
133
0
    if (m_poRawRaster == nullptr)
134
0
    {
135
0
        CPLError(CE_Failure, CPLE_AppDefined,
136
0
                 "No raw raster band configured on VRTRawRasterBand.");
137
0
        return CE_Failure;
138
0
    }
139
140
0
    return m_poRawRaster->ReadBlock(nBlockXOff, nBlockYOff, pImage);
141
0
}
142
143
/************************************************************************/
144
/*                            IWriteBlock()                             */
145
/************************************************************************/
146
147
CPLErr VRTRawRasterBand::IWriteBlock(int nBlockXOff, int nBlockYOff,
148
                                     void *pImage)
149
150
0
{
151
0
    if (m_poRawRaster == nullptr)
152
0
    {
153
0
        CPLError(CE_Failure, CPLE_AppDefined,
154
0
                 "No raw raster band configured on VRTRawRasterBand.");
155
0
        return CE_Failure;
156
0
    }
157
158
0
    m_poRawRaster->SetAccess(eAccess);
159
160
0
    return m_poRawRaster->WriteBlock(nBlockXOff, nBlockYOff, pImage);
161
0
}
162
163
/************************************************************************/
164
/*                             SetRawLink()                             */
165
/************************************************************************/
166
167
CPLErr VRTRawRasterBand::SetRawLink(const char *pszFilename,
168
                                    const char *pszVRTPath,
169
                                    int bRelativeToVRTIn,
170
                                    vsi_l_offset nImageOffset, int nPixelOffset,
171
                                    int nLineOffset, const char *pszByteOrder)
172
173
0
{
174
0
    ClearRawLink();
175
176
0
    static_cast<VRTDataset *>(poDS)->SetNeedsFlush();
177
178
    /* -------------------------------------------------------------------- */
179
    /*      Prepare filename.                                               */
180
    /* -------------------------------------------------------------------- */
181
0
    if (pszFilename == nullptr)
182
0
    {
183
0
        CPLError(CE_Warning, CPLE_AppDefined,
184
0
                 "Missing <SourceFilename> element in VRTRasterBand.");
185
0
        return CE_Failure;
186
0
    }
187
188
0
    const std::string osExpandedFilename =
189
0
        (pszVRTPath && bRelativeToVRTIn)
190
0
            ? CPLProjectRelativeFilenameSafe(pszVRTPath, pszFilename)
191
0
            : pszFilename;
192
193
0
    const char *pszAllowedPaths =
194
0
        CPLGetConfigOption("GDAL_VRT_RAWRASTERBAND_ALLOWED_SOURCE", nullptr);
195
0
    if (pszAllowedPaths == nullptr ||
196
0
        EQUAL(pszAllowedPaths, "SIBLING_OR_CHILD_OF_VRT_PATH"))
197
0
    {
198
0
        const char *pszErrorMsgPart =
199
0
            pszAllowedPaths
200
0
                ? "GDAL_VRT_RAWRASTERBAND_ALLOWED_SOURCE=SIBLING_OR_CHILD_OF_"
201
0
                  "VRT_PATH"
202
0
                : "the GDAL_VRT_RAWRASTERBAND_ALLOWED_SOURCE configuration "
203
0
                  "option is not set (and thus defaults to "
204
0
                  "SIBLING_OR_CHILD_OF_VRT_PATH. Consult "
205
0
                  "https://gdal.org/drivers/raster/"
206
0
                  "vrt.html#vrtrawrasterband_restricted_access for more "
207
0
                  "details)";
208
0
        if (!bRelativeToVRTIn)
209
0
        {
210
0
            CPLError(CE_Failure, CPLE_AppDefined,
211
0
                     "'%s' is invalid because the relativeToVRT flag is not "
212
0
                     "set and %s",
213
0
                     pszFilename, pszErrorMsgPart);
214
0
            return CE_Failure;
215
0
        }
216
0
        if (!CPLIsFilenameRelative(pszFilename))
217
0
        {
218
0
            CPLError(CE_Failure, CPLE_AppDefined,
219
0
                     "'%s' is invalid because it is not relative to the VRT "
220
0
                     "path and %s",
221
0
                     pszFilename, pszErrorMsgPart);
222
0
            return CE_Failure;
223
0
        }
224
0
        if (strstr(pszFilename, "../") || strstr(pszFilename, "..\\"))
225
0
        {
226
0
            CPLError(CE_Failure, CPLE_AppDefined,
227
0
                     "'%s' is invalid because it may not be a sibling or "
228
0
                     "child of the VRT path and %s",
229
0
                     pszFilename, pszErrorMsgPart);
230
0
            return CE_Failure;
231
0
        }
232
0
    }
233
0
    else if (EQUAL(pszAllowedPaths, "ALL"))
234
0
    {
235
        // ok
236
0
    }
237
0
    else if (EQUAL(pszAllowedPaths, "ONLY_REMOTE"))
238
0
    {
239
0
        if (VSIIsLocal(pszFilename))
240
0
        {
241
0
            CPLError(CE_Failure, CPLE_AppDefined,
242
0
                     "'%s' is a local file, whereas "
243
0
                     "GDAL_VRT_RAWRASTERBAND_ALLOWED_SOURCE=ONLY_REMOTE is set",
244
0
                     pszFilename);
245
0
            return CE_Failure;
246
0
        }
247
0
    }
248
0
    else
249
0
    {
250
0
        if (strstr(pszFilename, "../") || strstr(pszFilename, "..\\"))
251
0
        {
252
0
            CPLError(CE_Failure, CPLE_AppDefined,
253
0
                     "'%s' is invalid because the presence of ../ in it may "
254
0
                     "escape from the allowed path(s)",
255
0
                     pszFilename);
256
0
            return CE_Failure;
257
0
        }
258
#ifdef _WIN32
259
        constexpr const char *pszSep = ";";
260
#else
261
0
        constexpr const char *pszSep = ":";
262
0
#endif
263
0
        bool bOK = false;
264
0
        const CPLStringList aosPaths(
265
0
            CSLTokenizeString2(pszAllowedPaths, pszSep, 0));
266
0
        for (const char *pszPath : aosPaths)
267
0
        {
268
0
            if (CPLIsFilenameRelative(pszPath))
269
0
            {
270
0
                CPLError(
271
0
                    CE_Failure, CPLE_AppDefined,
272
0
                    "Invalid value for GDAL_VRT_RAWRASTERBAND_ALLOWED_SOURCE. "
273
0
                    "'%s' is not an absolute path",
274
0
                    pszPath);
275
0
                return CE_Failure;
276
0
            }
277
0
            if (STARTS_WITH(osExpandedFilename.c_str(), pszPath))
278
0
            {
279
0
                bOK = true;
280
0
                break;
281
0
            }
282
0
        }
283
0
        if (!bOK)
284
0
        {
285
0
            CPLError(CE_Failure, CPLE_AppDefined,
286
0
                     "'%s' is invalid because it is not contained in one of "
287
0
                     "the allowed path(s)",
288
0
                     pszFilename);
289
0
            return CE_Failure;
290
0
        }
291
0
    }
292
293
    /* -------------------------------------------------------------------- */
294
    /*      Try and open the file.  We always use the large file API.       */
295
    /* -------------------------------------------------------------------- */
296
0
    CPLPushErrorHandler(CPLQuietErrorHandler);
297
0
    FILE *fp = CPLOpenShared(osExpandedFilename.c_str(), "rb+", TRUE);
298
299
0
    if (fp == nullptr)
300
0
        fp = CPLOpenShared(osExpandedFilename.c_str(), "rb", TRUE);
301
302
0
    if (fp == nullptr &&
303
0
        static_cast<VRTDataset *>(poDS)->GetAccess() == GA_Update)
304
0
    {
305
0
        fp = CPLOpenShared(osExpandedFilename.c_str(), "wb+", TRUE);
306
0
    }
307
0
    CPLPopErrorHandler();
308
0
    CPLErrorReset();
309
310
0
    if (fp == nullptr)
311
0
    {
312
0
        CPLError(CE_Failure, CPLE_OpenFailed, "Unable to open %s.%s",
313
0
                 osExpandedFilename.c_str(), VSIStrerror(errno));
314
315
0
        return CE_Failure;
316
0
    }
317
318
0
    if (!RAWDatasetCheckMemoryUsage(
319
0
            nRasterXSize, nRasterYSize, 1,
320
0
            GDALGetDataTypeSizeBytes(GetRasterDataType()), nPixelOffset,
321
0
            nLineOffset, nImageOffset, 0, reinterpret_cast<VSILFILE *>(fp)))
322
0
    {
323
0
        CPLCloseShared(fp);
324
0
        return CE_Failure;
325
0
    }
326
327
0
    m_pszSourceFilename = CPLStrdup(pszFilename);
328
0
    m_bRelativeToVRT = bRelativeToVRTIn;
329
330
    /* -------------------------------------------------------------------- */
331
    /*      Work out if we are in native mode or not.                       */
332
    /* -------------------------------------------------------------------- */
333
0
    RawRasterBand::ByteOrder eByteOrder =
334
0
#if CPL_IS_LSB
335
0
        RawRasterBand::ByteOrder::ORDER_LITTLE_ENDIAN;
336
#else
337
        RawRasterBand::ByteOrder::ORDER_BIG_ENDIAN;
338
#endif
339
340
0
    if (pszByteOrder != nullptr)
341
0
    {
342
0
        if (EQUAL(pszByteOrder, "LSB"))
343
0
            eByteOrder = RawRasterBand::ByteOrder::ORDER_LITTLE_ENDIAN;
344
0
        else if (EQUAL(pszByteOrder, "MSB"))
345
0
            eByteOrder = RawRasterBand::ByteOrder::ORDER_BIG_ENDIAN;
346
0
        else if (EQUAL(pszByteOrder, "VAX"))
347
0
            eByteOrder = RawRasterBand::ByteOrder::ORDER_VAX;
348
0
        else
349
0
        {
350
0
            CPLError(CE_Failure, CPLE_AppDefined,
351
0
                     "Illegal ByteOrder value '%s', should be LSB, MSB or VAX.",
352
0
                     pszByteOrder);
353
0
            CPLCloseShared(fp);
354
0
            return CE_Failure;
355
0
        }
356
0
    }
357
358
    /* -------------------------------------------------------------------- */
359
    /*      Create a corresponding RawRasterBand.                           */
360
    /* -------------------------------------------------------------------- */
361
0
    m_poRawRaster =
362
0
        RawRasterBand::Create(reinterpret_cast<VSILFILE *>(fp), nImageOffset,
363
0
                              nPixelOffset, nLineOffset, GetRasterDataType(),
364
0
                              eByteOrder, GetXSize(), GetYSize(),
365
0
                              RawRasterBand::OwnFP::NO)
366
0
            .release();
367
0
    if (!m_poRawRaster)
368
0
    {
369
0
        CPLCloseShared(fp);
370
0
        return CE_Failure;
371
0
    }
372
373
    /* -------------------------------------------------------------------- */
374
    /*      Reset block size to match the raw raster.                       */
375
    /* -------------------------------------------------------------------- */
376
0
    m_poRawRaster->GetBlockSize(&nBlockXSize, &nBlockYSize);
377
378
0
    return CE_None;
379
0
}
380
381
/************************************************************************/
382
/*                            ClearRawLink()                            */
383
/************************************************************************/
384
385
void VRTRawRasterBand::ClearRawLink()
386
387
0
{
388
0
    if (m_poRawRaster != nullptr)
389
0
    {
390
0
        VSILFILE *fp = m_poRawRaster->GetFPL();
391
0
        delete m_poRawRaster;
392
0
        m_poRawRaster = nullptr;
393
        // We close the file after deleting the raster band
394
        // since data can be flushed in the destructor.
395
0
        if (fp != nullptr)
396
0
        {
397
0
            CPLCloseShared(reinterpret_cast<FILE *>(fp));
398
0
        }
399
0
    }
400
0
    CPLFree(m_pszSourceFilename);
401
0
    m_pszSourceFilename = nullptr;
402
0
}
403
404
/************************************************************************/
405
/*                            GetVirtualMemAuto()                       */
406
/************************************************************************/
407
408
CPLVirtualMem *VRTRawRasterBand::GetVirtualMemAuto(GDALRWFlag eRWFlag,
409
                                                   int *pnPixelSpace,
410
                                                   GIntBig *pnLineSpace,
411
                                                   char **papszOptions)
412
413
0
{
414
    // check the pointer to RawRasterBand
415
0
    if (m_poRawRaster == nullptr)
416
0
    {
417
        // use the super class method
418
0
        return VRTRasterBand::GetVirtualMemAuto(eRWFlag, pnPixelSpace,
419
0
                                                pnLineSpace, papszOptions);
420
0
    }
421
    // if available, use the RawRasterBand method (use mmap if available)
422
0
    return m_poRawRaster->GetVirtualMemAuto(eRWFlag, pnPixelSpace, pnLineSpace,
423
0
                                            papszOptions);
424
0
}
425
426
/************************************************************************/
427
/*                              XMLInit()                               */
428
/************************************************************************/
429
430
CPLErr VRTRawRasterBand::XMLInit(const CPLXMLNode *psTree,
431
                                 const char *pszVRTPath,
432
                                 VRTMapSharedResources &oMapSharedSources)
433
434
0
{
435
0
    const CPLErr eErr =
436
0
        VRTRasterBand::XMLInit(psTree, pszVRTPath, oMapSharedSources);
437
0
    if (eErr != CE_None)
438
0
        return eErr;
439
440
    /* -------------------------------------------------------------------- */
441
    /*      Validate a bit.                                                 */
442
    /* -------------------------------------------------------------------- */
443
0
    if (psTree == nullptr || psTree->eType != CXT_Element ||
444
0
        !EQUAL(psTree->pszValue, "VRTRasterBand") ||
445
0
        !EQUAL(CPLGetXMLValue(psTree, "subClass", ""), "VRTRawRasterBand"))
446
0
    {
447
0
        CPLError(CE_Failure, CPLE_AppDefined,
448
0
                 "Invalid node passed to VRTRawRasterBand::XMLInit().");
449
0
        return CE_Failure;
450
0
    }
451
452
    /* -------------------------------------------------------------------- */
453
    /*      Prepare filename.                                               */
454
    /* -------------------------------------------------------------------- */
455
0
    const char *pszFilename = CPLGetXMLValue(psTree, "SourceFilename", nullptr);
456
457
0
    if (pszFilename == nullptr)
458
0
    {
459
0
        CPLError(CE_Warning, CPLE_AppDefined,
460
0
                 "Missing <SourceFilename> element in VRTRasterBand.");
461
0
        return CE_Failure;
462
0
    }
463
464
0
    const bool l_bRelativeToVRT = CPLTestBool(
465
0
        CPLGetXMLValue(psTree, "SourceFilename.relativeToVRT", "1"));
466
467
    /* -------------------------------------------------------------------- */
468
    /*      Collect layout information.                                     */
469
    /* -------------------------------------------------------------------- */
470
0
    int nWordDataSize = GDALGetDataTypeSizeBytes(GetRasterDataType());
471
472
0
    const char *pszImageOffset = CPLGetXMLValue(psTree, "ImageOffset", "0");
473
0
    const vsi_l_offset nImageOffset = CPLScanUIntBig(
474
0
        pszImageOffset, static_cast<int>(strlen(pszImageOffset)));
475
476
0
    int nPixelOffset = nWordDataSize;
477
0
    const char *pszPixelOffset = CPLGetXMLValue(psTree, "PixelOffset", nullptr);
478
0
    if (pszPixelOffset != nullptr)
479
0
    {
480
0
        nPixelOffset = atoi(pszPixelOffset);
481
0
    }
482
0
    if (nPixelOffset <= 0)
483
0
    {
484
0
        CPLError(CE_Failure, CPLE_AppDefined,
485
0
                 "Invalid value for <PixelOffset> element : %d", nPixelOffset);
486
0
        return CE_Failure;
487
0
    }
488
489
0
    int nLineOffset = 0;
490
0
    const char *pszLineOffset = CPLGetXMLValue(psTree, "LineOffset", nullptr);
491
0
    if (pszLineOffset == nullptr)
492
0
    {
493
0
        if (nPixelOffset > INT_MAX / GetXSize())
494
0
        {
495
0
            CPLError(CE_Failure, CPLE_AppDefined, "Int overflow");
496
0
            return CE_Failure;
497
0
        }
498
0
        nLineOffset = nPixelOffset * GetXSize();
499
0
    }
500
0
    else
501
0
        nLineOffset = atoi(pszLineOffset);
502
503
0
    const char *pszByteOrder = CPLGetXMLValue(psTree, "ByteOrder", nullptr);
504
505
    /* -------------------------------------------------------------------- */
506
    /*      Open the file, and setup the raw layer access to the data.      */
507
    /* -------------------------------------------------------------------- */
508
0
    return SetRawLink(pszFilename, pszVRTPath, l_bRelativeToVRT, nImageOffset,
509
0
                      nPixelOffset, nLineOffset, pszByteOrder);
510
0
}
511
512
/************************************************************************/
513
/*                           SerializeToXML()                           */
514
/************************************************************************/
515
516
CPLXMLNode *VRTRawRasterBand::SerializeToXML(const char *pszVRTPath,
517
                                             bool &bHasWarnedAboutRAMUsage,
518
                                             size_t &nAccRAMUsage)
519
520
0
{
521
522
    /* -------------------------------------------------------------------- */
523
    /*      We can't set the layout if there is no open rawband.            */
524
    /* -------------------------------------------------------------------- */
525
0
    if (m_poRawRaster == nullptr)
526
0
    {
527
0
        CPLError(CE_Failure, CPLE_AppDefined,
528
0
                 "VRTRawRasterBand::SerializeToXML() fails because "
529
0
                 "m_poRawRaster is NULL.");
530
0
        return nullptr;
531
0
    }
532
533
0
    CPLXMLNode *psTree = VRTRasterBand::SerializeToXML(
534
0
        pszVRTPath, bHasWarnedAboutRAMUsage, nAccRAMUsage);
535
536
    /* -------------------------------------------------------------------- */
537
    /*      Set subclass.                                                   */
538
    /* -------------------------------------------------------------------- */
539
0
    CPLCreateXMLNode(CPLCreateXMLNode(psTree, CXT_Attribute, "subClass"),
540
0
                     CXT_Text, "VRTRawRasterBand");
541
542
    /* -------------------------------------------------------------------- */
543
    /*      Setup the filename with relative flag.                          */
544
    /* -------------------------------------------------------------------- */
545
0
    CPLXMLNode *psNode = CPLCreateXMLElementAndValue(psTree, "SourceFilename",
546
0
                                                     m_pszSourceFilename);
547
548
0
    CPLCreateXMLNode(CPLCreateXMLNode(psNode, CXT_Attribute, "relativeToVRT"),
549
0
                     CXT_Text, m_bRelativeToVRT ? "1" : "0");
550
551
    /* -------------------------------------------------------------------- */
552
    /*      Set other layout information.                                   */
553
    /* -------------------------------------------------------------------- */
554
555
0
    CPLCreateXMLElementAndValue(
556
0
        psTree, "ImageOffset",
557
0
        CPLSPrintf(CPL_FRMT_GUIB, m_poRawRaster->GetImgOffset()));
558
559
0
    CPLCreateXMLElementAndValue(
560
0
        psTree, "PixelOffset",
561
0
        CPLSPrintf("%d", m_poRawRaster->GetPixelOffset()));
562
563
0
    CPLCreateXMLElementAndValue(
564
0
        psTree, "LineOffset", CPLSPrintf("%d", m_poRawRaster->GetLineOffset()));
565
566
0
    switch (m_poRawRaster->GetByteOrder())
567
0
    {
568
0
        case RawRasterBand::ByteOrder::ORDER_LITTLE_ENDIAN:
569
0
            CPLCreateXMLElementAndValue(psTree, "ByteOrder", "LSB");
570
0
            break;
571
0
        case RawRasterBand::ByteOrder::ORDER_BIG_ENDIAN:
572
0
            CPLCreateXMLElementAndValue(psTree, "ByteOrder", "MSB");
573
0
            break;
574
0
        case RawRasterBand::ByteOrder::ORDER_VAX:
575
0
            CPLCreateXMLElementAndValue(psTree, "ByteOrder", "VAX");
576
0
            break;
577
0
    }
578
579
0
    return psTree;
580
0
}
581
582
/************************************************************************/
583
/*                             GetFileList()                            */
584
/************************************************************************/
585
586
void VRTRawRasterBand::GetFileList(char ***ppapszFileList, int *pnSize,
587
                                   int *pnMaxSize, CPLHashSet *hSetFiles)
588
0
{
589
0
    if (m_pszSourceFilename == nullptr)
590
0
        return;
591
592
    /* -------------------------------------------------------------------- */
593
    /*      Is it already in the list ?                                     */
594
    /* -------------------------------------------------------------------- */
595
0
    CPLString osSourceFilename;
596
0
    if (m_bRelativeToVRT && strlen(poDS->GetDescription()) > 0)
597
0
        osSourceFilename = CPLFormFilenameSafe(
598
0
            CPLGetDirnameSafe(poDS->GetDescription()).c_str(),
599
0
            m_pszSourceFilename, nullptr);
600
0
    else
601
0
        osSourceFilename = m_pszSourceFilename;
602
603
0
    if (CPLHashSetLookup(hSetFiles, osSourceFilename.c_str()) != nullptr)
604
0
        return;
605
606
    /* -------------------------------------------------------------------- */
607
    /*      Grow array if necessary                                         */
608
    /* -------------------------------------------------------------------- */
609
0
    if (*pnSize + 1 >= *pnMaxSize)
610
0
    {
611
0
        *pnMaxSize = 2 + 2 * (*pnMaxSize);
612
0
        *ppapszFileList = static_cast<char **>(
613
0
            CPLRealloc(*ppapszFileList, sizeof(char *) * (*pnMaxSize)));
614
0
    }
615
616
    /* -------------------------------------------------------------------- */
617
    /*      Add the string to the list                                      */
618
    /* -------------------------------------------------------------------- */
619
0
    (*ppapszFileList)[*pnSize] = CPLStrdup(osSourceFilename);
620
0
    (*ppapszFileList)[(*pnSize + 1)] = nullptr;
621
0
    CPLHashSetInsert(hSetFiles, (*ppapszFileList)[*pnSize]);
622
623
0
    (*pnSize)++;
624
625
0
    VRTRasterBand::GetFileList(ppapszFileList, pnSize, pnMaxSize, hSetFiles);
626
0
}
627
628
/*! @endcond */