~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to frmts/pcidsk/sdk/segment/cpcidsksegment.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "pcidsk_exception.h"
34
34
#include <cassert>
35
35
#include <cstdlib>
 
36
#include <cstring>
 
37
#include <vector>
 
38
#include <string>
36
39
 
37
40
using namespace PCIDSK;
38
41
 
68
71
    delete metadata;
69
72
}
70
73
 
71
 
std::string CPCIDSKSegment::GetMetadataValue( std::string key ) 
 
74
/************************************************************************/
 
75
/*                          GetMetadataValue()                          */
 
76
/************************************************************************/
 
77
std::string CPCIDSKSegment::GetMetadataValue( const std::string &key ) const
72
78
{
73
79
    return metadata->GetMetadataValue(key);
74
80
}
75
81
 
76
 
void CPCIDSKSegment::SetMetadataValue( std::string key, std::string value ) 
 
82
/************************************************************************/
 
83
/*                          SetMetadataValue()                          */
 
84
/************************************************************************/
 
85
void CPCIDSKSegment::SetMetadataValue( const std::string &key, const std::string &value ) 
77
86
{
78
87
    metadata->SetMetadataValue(key,value);
79
88
}
80
89
 
81
 
std::vector<std::string> CPCIDSKSegment::GetMetadataKeys() 
 
90
/************************************************************************/
 
91
/*                           GetMetdataKeys()                           */
 
92
/************************************************************************/
 
93
std::vector<std::string> CPCIDSKSegment::GetMetadataKeys() const
82
94
{
83
95
    return metadata->GetMetadataKeys();
84
96
}
103
115
/************************************************************************/
104
116
/*                         LoadSegmentHeader()                          */
105
117
/************************************************************************/
106
 
 
 
118
#include <iostream>
107
119
void CPCIDSKSegment::LoadSegmentHeader()
108
120
 
109
121
{
110
122
    header.SetSize(1024);
111
123
 
112
124
    file->ReadFromFile( header.buffer, data_offset, 1024 );
113
 
 
114
 
    // parse out history, etc 
 
125
    
 
126
    // Read the history from the segment header. PCIDSK supports
 
127
    // 8 history entries per segment.
 
128
    std::string hist_msg;
 
129
    history_.clear();
 
130
    for (unsigned int i = 0; i < 8; i++)
 
131
    {
 
132
        header.Get(384 + i * 80, 80, hist_msg);
 
133
 
 
134
        // Some programs seem to push history records with a trailing '\0'
 
135
        // so do some extra processing to cleanup.  FUN records on segment
 
136
        // 3 of eltoro.pix are an example of this.
 
137
        size_t size = hist_msg.size();
 
138
        while( size > 0 
 
139
               && (hist_msg[size-1] == ' ' || hist_msg[size-1] == '\0') )
 
140
            size--;
 
141
 
 
142
        hist_msg.resize(size);
 
143
        
 
144
        history_.push_back(hist_msg);
 
145
    }
 
146
}
 
147
 
 
148
/************************************************************************/
 
149
/*                            FlushHeader()                             */
 
150
/*                                                                      */
 
151
/*      This is used primarily after this class or subclasses have      */
 
152
/*      modified the header buffer and need it pushed back to disk.     */
 
153
/************************************************************************/
 
154
 
 
155
void CPCIDSKSegment::FlushHeader()
 
156
 
 
157
{
 
158
    file->WriteToFile( header.buffer, data_offset, 1024 );
115
159
}
116
160
 
117
161
/************************************************************************/
166
210
 
167
211
std::string CPCIDSKSegment::GetDescription()
168
212
{
169
 
    return "";
 
213
    std::string target;
 
214
 
 
215
    header.Get( 0, 64, target );
 
216
 
 
217
    return target;
 
218
}
 
219
 
 
220
/************************************************************************/
 
221
/*                           SetDescription()                           */
 
222
/************************************************************************/
 
223
 
 
224
void CPCIDSKSegment::SetDescription( const std::string &description )
 
225
{
 
226
    header.Put( description.c_str(), 0, 64);
 
227
 
 
228
    file->WriteToFile( header.buffer, data_offset, 1024 );
170
229
}
171
230
 
172
231
/************************************************************************/
180
239
    else
181
240
        return false;
182
241
}
 
242
 
 
243
/************************************************************************/
 
244
/*                         GetHistoryEntries()                          */
 
245
/************************************************************************/
 
246
 
 
247
std::vector<std::string> CPCIDSKSegment::GetHistoryEntries() const
 
248
{
 
249
    return history_;
 
250
}
 
251
 
 
252
/************************************************************************/
 
253
/*                         SetHistoryEntries()                          */
 
254
/************************************************************************/
 
255
 
 
256
void CPCIDSKSegment::SetHistoryEntries(const std::vector<std::string> &entries)
 
257
 
 
258
{
 
259
    for( unsigned int i = 0; i < 8; i++ )
 
260
    {
 
261
        const char *msg = "";
 
262
        if( entries.size() > i )
 
263
            msg = entries[i].c_str();
 
264
 
 
265
        header.Put( msg, 384 + i * 80, 80 );
 
266
    }
 
267
 
 
268
    FlushHeader();
 
269
 
 
270
    // Force reloading of history_
 
271
    LoadSegmentHeader();
 
272
}
 
273
 
 
274
/************************************************************************/
 
275
/*                            PushHistory()                             */
 
276
/************************************************************************/
 
277
 
 
278
void CPCIDSKSegment::PushHistory( const std::string &app,
 
279
                                  const std::string &message )
 
280
 
 
281
{
 
282
#define MY_MIN(a,b)      ((a<b) ? a : b)
 
283
 
 
284
    char current_time[17];
 
285
    char history[81];
 
286
 
 
287
    GetCurrentDateTime( current_time );
 
288
 
 
289
    memset( history, ' ', 80 );
 
290
    history[80] = '\0';
 
291
 
 
292
    memcpy( history + 0, app.c_str(), MY_MIN(app.size(),7) );
 
293
    history[7] = ':';
 
294
    
 
295
    memcpy( history + 8, message.c_str(), MY_MIN(message.size(),56) );
 
296
    memcpy( history + 64, current_time, 16 );
 
297
 
 
298
    std::vector<std::string> history_entries = GetHistoryEntries();
 
299
 
 
300
    history_entries.insert( history_entries.begin(), history );
 
301
    history_entries.resize(8);
 
302
 
 
303
    SetHistoryEntries( history_entries );
 
304
}
 
305
 
 
306
 
 
307
/************************************************************************/
 
308
/*                              MoveData()                              */
 
309
/*                                                                      */
 
310
/*      Move a chunk of data within a segment. Overlapping source       */
 
311
/*      and destination are permitted.                                  */
 
312
/************************************************************************/
 
313
 
 
314
void CPCIDSKSegment::MoveData( uint64 src_offset, uint64 dst_offset, 
 
315
                               uint64 size_in_bytes )
 
316
 
 
317
{
 
318
    bool copy_backwards = false;
 
319
 
 
320
    // We move things backwards if the areas overlap and the destination
 
321
    // is further on in the segment. 
 
322
    if( dst_offset > src_offset
 
323
        && src_offset + size_in_bytes > dst_offset )
 
324
        copy_backwards = true;
 
325
 
 
326
    
 
327
    // Move the segment data to the new location.
 
328
    uint8 copy_buf[16384];
 
329
    uint64 bytes_to_go;
 
330
 
 
331
    bytes_to_go = size_in_bytes;
 
332
 
 
333
    while( bytes_to_go > 0 )
 
334
    {
 
335
        uint64 bytes_this_chunk = sizeof(copy_buf);
 
336
        if( bytes_to_go < bytes_this_chunk )
 
337
            bytes_this_chunk = bytes_to_go;
 
338
 
 
339
        if( copy_backwards )
 
340
        {
 
341
            ReadFromFile( copy_buf, 
 
342
                          src_offset + bytes_to_go - bytes_this_chunk, 
 
343
                          bytes_this_chunk );
 
344
            WriteToFile( copy_buf, 
 
345
                         dst_offset + bytes_to_go - bytes_this_chunk, 
 
346
                         bytes_this_chunk );
 
347
        }
 
348
        else
 
349
        {
 
350
            ReadFromFile( copy_buf, src_offset, bytes_this_chunk );
 
351
            WriteToFile( copy_buf, dst_offset, bytes_this_chunk );
 
352
 
 
353
            src_offset += bytes_this_chunk;
 
354
            dst_offset += bytes_this_chunk;
 
355
        }
 
356
 
 
357
        bytes_to_go -= bytes_this_chunk;
 
358
    }
 
359
}