LTP GCOV extension - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidsksegment.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 94
Code covered: 56.4 % Executed lines: 53

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CPCIDSKSegment 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 "segment/cpcidsksegment.h"
      29                 : #include "core/metadataset.h"
      30                 : #include "core/cpcidskfile.h"
      31                 : #include "core/pcidsk_utils.h"
      32                 : #include "pcidsk_buffer.h"
      33                 : #include "pcidsk_exception.h"
      34                 : #include <cassert>
      35                 : #include <cstdlib>
      36                 : #include <cstring>
      37                 : #include <vector>
      38                 : #include <string>
      39                 : 
      40                 : using namespace PCIDSK;
      41                 : 
      42                 : /************************************************************************/
      43                 : /*                           PCIDSKSegment()                            */
      44                 : /************************************************************************/
      45                 : 
      46                 : CPCIDSKSegment::CPCIDSKSegment( PCIDSKFile *file, int segment,
      47             121 :                               const char *segment_pointer )
      48                 : 
      49                 : {
      50             121 :     this->file = file;
      51             121 :     this->segment = segment;
      52                 : 
      53             121 :     LoadSegmentPointer( segment_pointer );
      54             121 :     LoadSegmentHeader(); // eventually we might want to defer this.
      55                 : 
      56                 : /* -------------------------------------------------------------------- */
      57                 : /*      Initialize the metadata object, but do not try to load till     */
      58                 : /*      needed.                                                         */
      59                 : /* -------------------------------------------------------------------- */
      60             121 :     metadata = new MetadataSet;
      61             242 :     metadata->Initialize( file, SegmentTypeName(segment_type), segment );
      62             121 : }
      63                 : 
      64                 : /************************************************************************/
      65                 : /*                           ~PCIDSKSegment()                           */
      66                 : /************************************************************************/
      67                 : 
      68             121 : CPCIDSKSegment::~CPCIDSKSegment()
      69                 : 
      70                 : {
      71             121 :     delete metadata;
      72             121 : }
      73                 : 
      74                 : /************************************************************************/
      75                 : /*                          GetMetadataValue()                          */
      76                 : /************************************************************************/
      77               0 : std::string CPCIDSKSegment::GetMetadataValue( const std::string &key ) const
      78                 : {
      79               0 :     return metadata->GetMetadataValue(key);
      80                 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                          SetMetadataValue()                          */
      84                 : /************************************************************************/
      85               0 : void CPCIDSKSegment::SetMetadataValue( const std::string &key, const std::string &value ) 
      86                 : {
      87               0 :     metadata->SetMetadataValue(key,value);
      88               0 : }
      89                 : 
      90                 : /************************************************************************/
      91                 : /*                           GetMetdataKeys()                           */
      92                 : /************************************************************************/
      93               1 : std::vector<std::string> CPCIDSKSegment::GetMetadataKeys() const
      94                 : {
      95               1 :     return metadata->GetMetadataKeys();
      96                 : }
      97                 : 
      98                 : /************************************************************************/
      99                 : /*                         LoadSegmentPointer()                         */
     100                 : /************************************************************************/
     101                 : 
     102             121 : void CPCIDSKSegment::LoadSegmentPointer( const char *segment_pointer )
     103                 : 
     104                 : {
     105             121 :     PCIDSKBuffer segptr( segment_pointer, 32 );
     106                 : 
     107             121 :     segment_flag = segptr.buffer[0];
     108             121 :     segment_type = (eSegType) (atoi(segptr.Get(1,3)));
     109             121 :     data_offset = (atouint64(segptr.Get(12,11))-1) * 512;
     110             121 :     data_size = atouint64(segptr.Get(23,9)) * 512;
     111                 : 
     112             121 :     segptr.Get(4,8,segment_name);
     113             121 : }
     114                 : 
     115                 : /************************************************************************/
     116                 : /*                         LoadSegmentHeader()                          */
     117                 : /************************************************************************/
     118                 : #include <iostream>
     119             121 : void CPCIDSKSegment::LoadSegmentHeader()
     120                 : 
     121                 : {
     122             121 :     header.SetSize(1024);
     123                 : 
     124             121 :     file->ReadFromFile( header.buffer, data_offset, 1024 );
     125                 :     
     126                 :     // Read the history from the segment header. PCIDSK supports
     127                 :     // 8 history entries per segment.
     128             121 :     std::string hist_msg;
     129             121 :     history_.clear();
     130            1089 :     for (unsigned int i = 0; i < 8; i++)
     131                 :     {
     132             968 :         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             968 :         size_t size = hist_msg.size();
     138            1936 :         while( size > 0 
     139                 :                && (hist_msg[size-1] == ' ' || hist_msg[size-1] == '\0') )
     140               0 :             size--;
     141                 : 
     142             968 :         hist_msg.resize(size);
     143                 :         
     144             968 :         history_.push_back(hist_msg);
     145             121 :     }
     146             121 : }
     147                 : 
     148                 : /************************************************************************/
     149                 : /*                            ReadFromFile()                            */
     150                 : /************************************************************************/
     151                 : 
     152             294 : void CPCIDSKSegment::ReadFromFile( void *buffer, uint64 offset, uint64 size )
     153                 : 
     154                 : {
     155             294 :     if( offset+size+1024 > data_size )
     156                 :         ThrowPCIDSKException( 
     157                 :             "Attempt to read past end of segment %d (%d bytes at offset %d)",
     158               0 :             segment, (int) offset, (int) size );
     159             294 :     file->ReadFromFile( buffer, offset + data_offset + 1024, size );
     160             294 : }
     161                 : 
     162                 : /************************************************************************/
     163                 : /*                            WriteToFile()                             */
     164                 : /************************************************************************/
     165                 : 
     166             191 : void CPCIDSKSegment::WriteToFile( const void *buffer, uint64 offset, uint64 size )
     167                 : {
     168             191 :     if( offset+size > data_size-1024 )
     169                 :     {
     170              17 :         CPCIDSKFile *poFile = dynamic_cast<CPCIDSKFile *>(file);
     171                 :         
     172              17 :         if (poFile == NULL) {
     173                 :             ThrowPCIDSKException("Attempt to dynamic_cast the file interface "
     174                 :                 "to a CPCIDSKFile failed. This is a programmer error, and should "
     175               0 :                 "be reported to your software provider.");
     176                 :         }
     177                 :         
     178              17 :         if( !IsAtEOF() )
     179               0 :             poFile->MoveSegmentToEOF( segment );
     180                 : 
     181                 :         uint64 blocks_to_add = 
     182              17 :             ((offset+size+511) - (data_size - 1024)) / 512;
     183                 : 
     184                 :         // prezero if we aren't directly writing all the new blocks.
     185                 :         poFile->ExtendSegment( segment, blocks_to_add, 
     186                 :                              !(offset == data_size - 1024
     187              17 :                                && size == blocks_to_add * 512) );
     188              17 :         data_size += blocks_to_add * 512;
     189                 :     }
     190                 : 
     191             191 :     file->WriteToFile( buffer, offset + data_offset + 1024, size );
     192             191 : }
     193                 : 
     194                 : /************************************************************************/
     195                 : /*                           GetDescription()                           */
     196                 : /************************************************************************/
     197                 : 
     198               0 : std::string CPCIDSKSegment::GetDescription()
     199                 : {
     200               0 :     std::string target;
     201                 : 
     202               0 :     header.Get( 0, 64, target );
     203                 : 
     204               0 :     return target;
     205                 : }
     206                 : 
     207                 : /************************************************************************/
     208                 : /*                           SetDescription()                           */
     209                 : /************************************************************************/
     210                 : 
     211               0 : void CPCIDSKSegment::SetDescription( const std::string &description )
     212                 : {
     213               0 :     header.Put( description.c_str(), 0, 64);
     214                 : 
     215               0 :     file->WriteToFile( header.buffer, data_offset, 1024 );
     216               0 : }
     217                 : 
     218                 : /************************************************************************/
     219                 : /*                              IsAtEOF()                               */
     220                 : /************************************************************************/
     221                 : 
     222              17 : bool CPCIDSKSegment::IsAtEOF()
     223                 : {
     224              17 :     if( 512 * file->GetFileSize() == data_offset + data_size )
     225              17 :         return true;
     226                 :     else
     227               0 :         return false;
     228                 : }
     229                 : 
     230                 : /************************************************************************/
     231                 : /*                         GetHistoryEntries()                          */
     232                 : /************************************************************************/
     233                 : 
     234               0 : std::vector<std::string> CPCIDSKSegment::GetHistoryEntries() const
     235                 : {
     236               0 :     return history_;
     237                 : }
     238                 : 
     239                 : /************************************************************************/
     240                 : /*                         SetHistoryEntries()                          */
     241                 : /************************************************************************/
     242                 : 
     243               0 : void CPCIDSKSegment::SetHistoryEntries(const std::vector<std::string> &entries)
     244                 : 
     245                 : {
     246               0 :     for( unsigned int i = 0; i < 8; i++ )
     247                 :     {
     248               0 :         const char *msg = "";
     249               0 :         if( entries.size() > i )
     250               0 :             msg = entries[i].c_str();
     251                 : 
     252               0 :         header.Put( msg, 384 + i * 80, 80 );
     253                 :     }
     254                 : 
     255               0 :     file->WriteToFile( header.buffer, data_offset, 1024 );
     256                 : 
     257                 :     // Force reloading of history_
     258               0 :     LoadSegmentHeader();
     259               0 : }
     260                 : 
     261                 : /************************************************************************/
     262                 : /*                            PushHistory()                             */
     263                 : /************************************************************************/
     264                 : 
     265                 : void CPCIDSKSegment::PushHistory( const std::string &app,
     266               0 :                                   const std::string &message )
     267                 : 
     268                 : {
     269                 : #define MY_MIN(a,b)      ((a<b) ? a : b)
     270                 : 
     271                 :     char current_time[17];
     272                 :     char history[81];
     273                 : 
     274               0 :     GetCurrentDateTime( current_time );
     275                 : 
     276               0 :     memset( history, ' ', 80 );
     277               0 :     history[80] = '\0';
     278                 : 
     279               0 :     memcpy( history + 0, app.c_str(), MY_MIN(app.size(),7) );
     280               0 :     history[7] = ':';
     281                 :     
     282               0 :     memcpy( history + 8, message.c_str(), MY_MIN(message.size(),56) );
     283               0 :     memcpy( history + 64, current_time, 16 );
     284                 : 
     285               0 :     std::vector<std::string> history_entries = GetHistoryEntries();
     286                 : 
     287               0 :     history_entries.insert( history_entries.begin(), history );
     288               0 :     history_entries.resize(8);
     289                 : 
     290               0 :     SetHistoryEntries( history_entries );
     291             896 : }
     292             448 : 
     293                 : 

Generated by: LTP GCOV extension version 1.5