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 : /** 27 : * Binary Segment constructor 28 : * @param[in,out] fileIn the PCIDSK file 29 : * @param[in] segmentIn the segment index 30 : * @param[in] segment_pointer the segment pointer 31 : * @param[in] bLoad true to load the segment, else false (default true) 32 : */ 33 0 : CPCIDSKBinarySegment::CPCIDSKBinarySegment(PCIDSKFile *fileIn, 34 : int segmentIn, 35 : const char *segment_pointer, 36 0 : bool bLoad) : 37 : CPCIDSKSegment(fileIn, segmentIn, segment_pointer), 38 0 : loaded_(false),mbModified(false) 39 : { 40 0 : if (true == bLoad) 41 : { 42 0 : Load(); 43 : } 44 0 : return; 45 : }// Initializer constructor 46 : 47 : 48 0 : CPCIDSKBinarySegment::~CPCIDSKBinarySegment() 49 : { 50 0 : } 51 : 52 : /** 53 : * Load the contents of the segment 54 : */ 55 0 : void CPCIDSKBinarySegment::Load() 56 : { 57 : // Check if we've already loaded the segment into memory 58 0 : if (loaded_) { 59 0 : return; 60 : } 61 : 62 0 : if( data_size < 1024 ) 63 : { 64 0 : return ThrowPCIDSKException("Wrong data_size in CPCIDSKBinarySegment"); 65 : } 66 : 67 0 : if( data_size - 1024 > static_cast<uint64_t>(std::numeric_limits<int>::max()) ) 68 : { 69 0 : return ThrowPCIDSKException("too large data_size"); 70 : } 71 : 72 0 : seg_data.SetSize((int)(data_size - 1024)); 73 : 74 0 : ReadFromFile(seg_data.buffer, 0, data_size - 1024); 75 : 76 : // Mark it as being loaded properly. 77 0 : loaded_ = true; 78 : } 79 : 80 : /** 81 : * Write the segment on disk 82 : */ 83 0 : void CPCIDSKBinarySegment::Write(void) 84 : { 85 : //We are not writing if nothing was loaded. 86 0 : if (!loaded_) { 87 0 : return; 88 : } 89 : 90 0 : WriteToFile(seg_data.buffer, 0, seg_data.buffer_size); 91 : 92 0 : mbModified = false; 93 : } 94 : 95 : /** 96 : * Synchronize the segment, if it was modified then 97 : * write it into disk. 98 : */ 99 0 : void CPCIDSKBinarySegment::Synchronize() 100 : { 101 0 : if(mbModified) 102 : { 103 0 : this->Write(); 104 : } 105 0 : } 106 : 107 : void 108 0 : CPCIDSKBinarySegment::SetBuffer(const char* pabyBuf, 109 : unsigned int nBufSize) 110 : { 111 : // Round the buffer size up to the next multiple of 512. 112 0 : int nNumBlocks = nBufSize / 512 + ((0 == nBufSize % 512) ? 0 : 1); 113 0 : unsigned int nAllocBufSize = 512 * nNumBlocks; 114 : 115 0 : seg_data.SetSize((int)nAllocBufSize); 116 0 : data_size = nAllocBufSize + 1024; // Incl. header 117 : 118 0 : memcpy(seg_data.buffer, pabyBuf, nBufSize); 119 : 120 : // Fill unused data at end with zeroes. 121 0 : if (nBufSize < nAllocBufSize) 122 : { 123 0 : memset(seg_data.buffer + nBufSize, 0, 124 0 : nAllocBufSize - nBufSize); 125 : } 126 0 : mbModified = true; 127 : 128 0 : return; 129 : }// SetBuffer