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 : * Permission is hereby granted, free of charge, to any person obtaining a
10 : * copy of this software and associated documentation files (the "Software"),
11 : * to deal in the Software without restriction, including without limitation
12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 : * and/or sell copies of the Software, and to permit persons to whom the
14 : * Software is furnished to do so, subject to the following conditions:
15 : *
16 : * The above copyright notice and this permission notice shall be included
17 : * in all copies or substantial portions of the Software.
18 : *
19 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 : * DEALINGS IN THE SOFTWARE.
26 : ****************************************************************************/
27 :
28 : #include "segment/cpcidskbinarysegment.h"
29 : #include "segment/cpcidsksegment.h"
30 : #include "core/pcidsk_utils.h"
31 : #include "pcidsk_exception.h"
32 : #include "core/pcidsk_utils.h"
33 :
34 : #include <limits>
35 : #include <vector>
36 : #include <string>
37 : #include <cassert>
38 : #include <cstring>
39 :
40 : using namespace PCIDSK;
41 :
42 : /**
43 : * Binary Segment constructor
44 : * @param[in,out] fileIn the PCIDSK file
45 : * @param[in] segmentIn the segment index
46 : * @param[in] segment_pointer the segment pointer
47 : * @param[in] bLoad true to load the segment, else false (default true)
48 : */
49 0 : CPCIDSKBinarySegment::CPCIDSKBinarySegment(PCIDSKFile *fileIn,
50 : int segmentIn,
51 : const char *segment_pointer,
52 0 : bool bLoad) :
53 : CPCIDSKSegment(fileIn, segmentIn, segment_pointer),
54 0 : loaded_(false),mbModified(false)
55 : {
56 0 : if (true == bLoad)
57 : {
58 0 : Load();
59 : }
60 0 : return;
61 : }// Initializer constructor
62 :
63 :
64 0 : CPCIDSKBinarySegment::~CPCIDSKBinarySegment()
65 : {
66 0 : }
67 :
68 : /**
69 : * Load the contents of the segment
70 : */
71 0 : void CPCIDSKBinarySegment::Load()
72 : {
73 : // Check if we've already loaded the segment into memory
74 0 : if (loaded_) {
75 0 : return;
76 : }
77 :
78 0 : if( data_size < 1024 )
79 : {
80 0 : return ThrowPCIDSKException("Wrong data_size in CPCIDSKBinarySegment");
81 : }
82 :
83 0 : if( data_size - 1024 > static_cast<uint64_t>(std::numeric_limits<int>::max()) )
84 : {
85 0 : return ThrowPCIDSKException("too large data_size");
86 : }
87 :
88 0 : seg_data.SetSize((int)(data_size - 1024));
89 :
90 0 : ReadFromFile(seg_data.buffer, 0, data_size - 1024);
91 :
92 : // Mark it as being loaded properly.
93 0 : loaded_ = true;
94 : }
95 :
96 : /**
97 : * Write the segment on disk
98 : */
99 0 : void CPCIDSKBinarySegment::Write(void)
100 : {
101 : //We are not writing if nothing was loaded.
102 0 : if (!loaded_) {
103 0 : return;
104 : }
105 :
106 0 : WriteToFile(seg_data.buffer, 0, seg_data.buffer_size);
107 :
108 0 : mbModified = false;
109 : }
110 :
111 : /**
112 : * Synchronize the segment, if it was modified then
113 : * write it into disk.
114 : */
115 0 : void CPCIDSKBinarySegment::Synchronize()
116 : {
117 0 : if(mbModified)
118 : {
119 0 : this->Write();
120 : }
121 0 : }
122 :
123 : void
124 0 : CPCIDSKBinarySegment::SetBuffer(const char* pabyBuf,
125 : unsigned int nBufSize)
126 : {
127 : // Round the buffer size up to the next multiple of 512.
128 0 : int nNumBlocks = nBufSize / 512 + ((0 == nBufSize % 512) ? 0 : 1);
129 0 : unsigned int nAllocBufSize = 512 * nNumBlocks;
130 :
131 0 : seg_data.SetSize((int)nAllocBufSize);
132 0 : data_size = nAllocBufSize + 1024; // Incl. header
133 :
134 0 : memcpy(seg_data.buffer, pabyBuf, nBufSize);
135 :
136 : // Fill unused data at end with zeroes.
137 0 : if (nBufSize < nAllocBufSize)
138 : {
139 0 : memset(seg_data.buffer + nBufSize, 0,
140 0 : nAllocBufSize - nBufSize);
141 : }
142 0 : mbModified = true;
143 :
144 0 : return;
145 : }// SetBuffer
|