Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Purpose: Implementation of the CPCIDSKBinarySegment class. 4 : * 5 : ****************************************************************************** 6 : * Copyright (c) 2010 7 : * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada. 8 : * 9 : * SPDX-License-Identifier: MIT 10 : ****************************************************************************/ 11 : 12 : #include "segment/cpcidskbinarysegment.h" 13 : #include "segment/cpcidsksegment.h" 14 : #include "core/pcidsk_utils.h" 15 : #include "pcidsk_exception.h" 16 : #include "core/pcidsk_utils.h" 17 : 18 : #include <limits> 19 : #include <vector> 20 : #include <string> 21 : #include <cassert> 22 : #include <cstring> 23 : 24 : using namespace PCIDSK; 25 : 26 : PCIDSKBinarySegment::~PCIDSKBinarySegment() = default; 27 : 28 : /** 29 : * Binary Segment constructor 30 : * @param[in,out] fileIn the PCIDSK file 31 : * @param[in] segmentIn the segment index 32 : * @param[in] segment_pointer the segment pointer 33 : * @param[in] bLoad true to load the segment, else false (default true) 34 : */ 35 0 : CPCIDSKBinarySegment::CPCIDSKBinarySegment(PCIDSKFile *fileIn, 36 : int segmentIn, 37 : const char *segment_pointer, 38 0 : bool bLoad) : 39 : CPCIDSKSegment(fileIn, segmentIn, segment_pointer), 40 0 : loaded_(false),mbModified(false) 41 : { 42 0 : if (true == bLoad) 43 : { 44 0 : Load(); 45 : } 46 0 : return; 47 : }// Initializer constructor 48 : 49 : 50 0 : CPCIDSKBinarySegment::~CPCIDSKBinarySegment() 51 : { 52 0 : } 53 : 54 : /** 55 : * Load the contents of the segment 56 : */ 57 0 : void CPCIDSKBinarySegment::Load() 58 : { 59 : // Check if we've already loaded the segment into memory 60 0 : if (loaded_) { 61 0 : return; 62 : } 63 : 64 0 : if( data_size < 1024 ) 65 : { 66 0 : return ThrowPCIDSKException("Wrong data_size in CPCIDSKBinarySegment"); 67 : } 68 : 69 0 : if( data_size - 1024 > static_cast<uint64_t>(std::numeric_limits<int>::max()) ) 70 : { 71 0 : return ThrowPCIDSKException("too large data_size"); 72 : } 73 : 74 0 : seg_data.SetSize((int)(data_size - 1024)); 75 : 76 0 : ReadFromFile(seg_data.buffer, 0, data_size - 1024); 77 : 78 : // Mark it as being loaded properly. 79 0 : loaded_ = true; 80 : } 81 : 82 : /** 83 : * Write the segment on disk 84 : */ 85 0 : void CPCIDSKBinarySegment::Write(void) 86 : { 87 : //We are not writing if nothing was loaded. 88 0 : if (!loaded_) { 89 0 : return; 90 : } 91 : 92 0 : WriteToFile(seg_data.buffer, 0, seg_data.buffer_size); 93 : 94 0 : mbModified = false; 95 : } 96 : 97 : /** 98 : * Synchronize the segment, if it was modified then 99 : * write it into disk. 100 : */ 101 0 : void CPCIDSKBinarySegment::Synchronize() 102 : { 103 0 : if(mbModified) 104 : { 105 0 : this->Write(); 106 : } 107 0 : } 108 : 109 : void 110 0 : CPCIDSKBinarySegment::SetBuffer(const char* pabyBuf, 111 : unsigned int nBufSize) 112 : { 113 : // Round the buffer size up to the next multiple of 512. 114 0 : int nNumBlocks = nBufSize / 512 + ((0 == nBufSize % 512) ? 0 : 1); 115 0 : unsigned int nAllocBufSize = 512 * nNumBlocks; 116 : 117 0 : seg_data.SetSize((int)nAllocBufSize); 118 0 : data_size = nAllocBufSize + 1024; // Incl. header 119 : 120 0 : memcpy(seg_data.buffer, pabyBuf, nBufSize); 121 : 122 : // Fill unused data at end with zeroes. 123 0 : if (nBufSize < nAllocBufSize) 124 : { 125 0 : memset(seg_data.buffer + nBufSize, 0, 126 0 : nAllocBufSize - nBufSize); 127 : } 128 0 : mbModified = true; 129 : 130 0 : return; 131 : }// SetBuffer