1 /******************************************************************************
2  *
3  * Purpose:  Implementation of the CLinkSegment class.
4  *
5  ******************************************************************************
6  * Copyright (c) 2009
7  * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, 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 "core/clinksegment.h"
29 #include "segment/cpcidsksegment.h"
30 #include "core/pcidsk_utils.h"
31 #include "pcidsk_exception.h"
32 
33 #include <vector>
34 #include <string>
35 #include <cassert>
36 #include <cstring>
37 #include <algorithm>
38 #include <functional>
39 
40 using namespace PCIDSK;
41 
CLinkSegment(PCIDSKFile * file,int segment,const char * segment_pointer)42 CLinkSegment::CLinkSegment(PCIDSKFile *file,
43                            int segment,
44                            const char *segment_pointer) :
45     CPCIDSKSegment(file, segment, segment_pointer),
46     loaded_(false), modified_(false)
47 {
48     Load();
49 }
50 
51 
~CLinkSegment()52 CLinkSegment::~CLinkSegment()
53 {
54 }
55 
56 // Load the contents of the segment
Load()57 void CLinkSegment::Load()
58 {
59     // Check if we've already loaded the segment into memory
60     if (loaded_) {
61         return;
62     }
63 
64     assert(data_size - 1024 == 1 * 512);
65 
66     seg_data.SetSize(data_size - 1024); // should be 1 * 512
67 
68     ReadFromFile(seg_data.buffer, 0, data_size - 1024);
69 
70     if (std::strncmp(seg_data.buffer, "SysLinkF", 8))
71     {
72         seg_data.Put("SysLinkF",0,8);
73         return;
74     }
75 
76     path = std::string(&seg_data.buffer[8]);
77     std::string::reverse_iterator first_non_space =
78         std::find_if(path.rbegin(), path.rend(),
79                      std::bind2nd(std::not_equal_to<char>(), ' '));
80 
81     *(--first_non_space) = '\0';
82 
83 
84     // We've now loaded the structure up with data. Mark it as being loaded
85     // properly.
86     loaded_ = true;
87 
88 }
89 
Write(void)90 void CLinkSegment::Write(void)
91 {
92     //We are not writing if nothing was loaded.
93     if (!modified_) {
94         return;
95     }
96 
97     seg_data.Put("SysLinkF",0,8);
98     seg_data.Put(path.c_str(), 8, path.size(), true);
99 
100     WriteToFile(seg_data.buffer, 0, data_size-1024);
101     modified_ = false;
102 }
103 
GetPath(void) const104 std::string CLinkSegment::GetPath(void) const
105 {
106     return path;
107 }
108 
SetPath(const std::string & oPath)109 void CLinkSegment::SetPath(const std::string& oPath)
110 {
111     if(oPath.size() < 504)
112     {
113         path = oPath;
114         modified_ = true;
115     }
116     else
117     {
118         throw PCIDSKException("The size of the path cannot be"
119                               " bigger than 504 characters.");
120     }
121 }
122 
Synchronize()123 void CLinkSegment::Synchronize()
124 {
125     if(modified_)
126     {
127         this->Write();
128     }
129 }
130 
131