LCOV - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidskvectorsegment.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 256 0 0.0 %
Date: 2010-01-09 Functions: 21 0 0.0 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CPCIDSKVectorSegment 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 "pcidsk_exception.h"
      29                 : #include "core/pcidsk_utils.h"
      30                 : #include "segment/cpcidskvectorsegment.h"
      31                 : #include <cassert>
      32                 : #include <cstring>
      33                 : 
      34                 : using namespace PCIDSK;
      35                 : 
      36                 : /* -------------------------------------------------------------------- */
      37                 : /*      Size of a block in the record/vertice block tables.  This is    */
      38                 : /*      determined by the PCIDSK format and may not be changed.         */
      39                 : /* -------------------------------------------------------------------- */
      40                 : static const int block_page_size = 8192;  
      41                 : 
      42                 : /* -------------------------------------------------------------------- */
      43                 : /*      Size of one page of loaded shapeids.  This is not related to    */
      44                 : /*      the file format, and may be changed to alter the number of      */
      45                 : /*      shapeid pointers kept in RAM at one time from the shape         */
      46                 : /*      index.                                                          */
      47                 : /* -------------------------------------------------------------------- */
      48                 : static const int shapeid_page_size = 1024;
      49                 : 
      50                 : const int CPCIDSKVectorSegment::sec_raw = 0;
      51                 : const int CPCIDSKVectorSegment::sec_vert = 1;
      52                 : const int CPCIDSKVectorSegment::sec_record = 2;
      53                 :         
      54                 : /************************************************************************/
      55                 : /*                        CPCIDSKVectorSegment()                        */
      56                 : /************************************************************************/
      57                 : 
      58               0 : CPCIDSKVectorSegment::CPCIDSKVectorSegment( PCIDSKFile *file, int segment,
      59                 :                                             const char *segment_pointer )
      60               0 :         : CPCIDSKSegment( file, segment, segment_pointer )
      61                 : 
      62                 : {
      63               0 :     base_initialized = false;
      64                 :     
      65               0 :     last_shapes_id = NullShapeId;
      66               0 :     last_shapes_index = -1;
      67                 : 
      68               0 :     raw_loaded_data_offset = 0;
      69               0 :     vert_loaded_data_offset = 0;
      70               0 :     record_loaded_data_offset = 0;
      71                 : 
      72               0 :     shapeid_map_active = false;
      73               0 :     shapeid_pages_certainly_mapped = -1;
      74               0 : }
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                       ~CPCIDSKVectorSegment()                        */
      78                 : /************************************************************************/
      79                 : 
      80               0 : CPCIDSKVectorSegment::~CPCIDSKVectorSegment()
      81                 : 
      82                 : {
      83               0 : }
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                             Initialize()                             */
      87                 : /*                                                                      */
      88                 : /*      Initialize minimum information from the vector segment          */
      89                 : /*      header.  We defer this till an actual vector related action     */
      90                 : /*      is taken.                                                       */
      91                 : /************************************************************************/
      92                 : 
      93               0 : void CPCIDSKVectorSegment::Initialize()
      94                 : 
      95                 : {
      96               0 :     if( base_initialized )
      97               0 :         return;
      98                 : 
      99               0 :     base_initialized = true;
     100                 : 
     101                 :     // vector segment data is always big endian. 
     102                 : 
     103               0 :     needs_swap = !BigEndianSystem();
     104                 : 
     105                 : /* -------------------------------------------------------------------- */
     106                 : /*      Check fixed portion of the header to ensure this is a V6        */
     107                 : /*      style vector segment.                                           */
     108                 : /* -------------------------------------------------------------------- */
     109                 :     static const unsigned char magic[24] = 
     110                 :         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     111                 :           0, 0, 0, 21, 0, 0, 0, 4, 0, 0, 0, 19, 0, 0, 0, 69 };
     112                 : 
     113               0 :     if( memcmp( GetData( sec_raw, 0, NULL, 24 ), magic, 24 ) != 0 )
     114                 :     {
     115               0 :         ThrowPCIDSKException( "Unexpected vector header values, possibly it is not a V6 vector segment?" );
     116                 :     }
     117                 :     
     118                 : /* -------------------------------------------------------------------- */
     119                 : /*      Load section offsets.                                           */
     120                 : /* -------------------------------------------------------------------- */
     121               0 :     memcpy( section_offsets, GetData( sec_raw, 72, NULL, 16 ), 16 );
     122               0 :     if( needs_swap )
     123               0 :         SwapData( section_offsets, 4, 4 );
     124                 : 
     125                 : /* -------------------------------------------------------------------- */
     126                 : /*      Load the field definitions.                                     */
     127                 : /* -------------------------------------------------------------------- */
     128               0 :     ShapeField work_value;
     129                 :     int  field_count, i;
     130                 : 
     131               0 :     uint32 next_off = section_offsets[2];
     132                 :     
     133               0 :     next_off = ReadField( next_off, work_value, FieldTypeInteger, sec_raw );
     134               0 :     field_count = work_value.GetValueInteger();
     135                 : 
     136               0 :     for( i = 0; i < field_count; i++ )
     137                 :     {
     138               0 :         next_off = ReadField( next_off, work_value, FieldTypeString, sec_raw );
     139               0 :         field_names.push_back( work_value.GetValueString() );
     140                 :         
     141               0 :         next_off = ReadField( next_off, work_value, FieldTypeString, sec_raw );
     142               0 :         field_descriptions.push_back( work_value.GetValueString() );
     143                 :         
     144               0 :         next_off = ReadField( next_off, work_value, FieldTypeInteger, sec_raw );
     145               0 :         field_types.push_back( (ShapeFieldType) work_value.GetValueInteger() );
     146                 :         
     147               0 :         next_off = ReadField( next_off, work_value, FieldTypeString, sec_raw );
     148               0 :         field_formats.push_back( work_value.GetValueString() );
     149                 :         
     150               0 :         next_off = ReadField( next_off, work_value, field_types[i], sec_raw );
     151               0 :         field_defaults.push_back( work_value );
     152                 :     }
     153                 : 
     154                 : /* -------------------------------------------------------------------- */
     155                 : /*      Fetch the vertex block basics.                                  */
     156                 : /* -------------------------------------------------------------------- */
     157               0 :     next_off = section_offsets[3];
     158               0 :     vertex_block_initialized = false;
     159                 : 
     160               0 :     memcpy( &vertex_block_count, GetData(sec_raw,next_off,NULL,4), 4);
     161               0 :     memcpy( &vertex_bytes, GetData(sec_raw,next_off+4,NULL,4), 4);
     162                 : 
     163               0 :     if( needs_swap )
     164                 :     {
     165               0 :         SwapData( &vertex_block_count, 4, 1 );
     166               0 :         SwapData( &vertex_bytes, 4, 1 );
     167                 :     }
     168                 : 
     169               0 :     next_off += 8 + 4 * vertex_block_count;
     170                 : 
     171                 : /* -------------------------------------------------------------------- */
     172                 : /*      Fetch the record block basics.                                  */
     173                 : /* -------------------------------------------------------------------- */
     174               0 :     record_block_initialized = false;
     175                 : 
     176               0 :     memcpy( &record_block_count, GetData(sec_raw,next_off,NULL,4), 4);
     177               0 :     memcpy( &record_bytes, GetData(sec_raw,next_off+4,NULL,4), 4);
     178                 : 
     179               0 :     if( needs_swap )
     180                 :     {
     181               0 :         SwapData( &record_block_count, 4, 1 );
     182               0 :         SwapData( &record_bytes, 4, 1 );
     183                 :     }
     184                 : 
     185               0 :     next_off += 8 + 4 * record_block_count;
     186                 : 
     187                 : /* -------------------------------------------------------------------- */
     188                 : /*      Fetch the shapeid basics.                                       */
     189                 : /* -------------------------------------------------------------------- */
     190               0 :     memcpy( &shape_count, GetData(sec_raw,next_off,NULL,4), 4);
     191               0 :     if( needs_swap )
     192               0 :         SwapData( &shape_count, 4, 1 );
     193                 : 
     194               0 :     next_off += 4;
     195               0 :     shape_index_byte_offset = next_off;
     196                 :     
     197               0 :     shape_index_start = 0;
     198                 : }
     199                 : 
     200                 : /************************************************************************/
     201                 : /*                             ReadField()                              */
     202                 : /*                                                                      */
     203                 : /*      Read a value from the indicated offset in a section of the      */
     204                 : /*      vector segment, and place the value into a ShapeField           */
     205                 : /*      structure based on the passed in field type.                    */
     206                 : /************************************************************************/
     207                 : 
     208               0 : uint32 CPCIDSKVectorSegment::ReadField( uint32 offset, ShapeField& field,
     209                 :                                         ShapeFieldType field_type,
     210                 :                                         int section )
     211                 : 
     212                 : {
     213               0 :     switch( field_type )
     214                 :     {
     215                 :       case FieldTypeInteger:
     216                 :       {
     217                 :           int32 value;
     218               0 :           memcpy( &value, GetData( section, offset, NULL, 4), 4 );
     219               0 :           if( needs_swap )
     220               0 :               SwapData( &value, 4, 1 );
     221               0 :           field.SetValue( value );
     222               0 :           return offset + 4;
     223                 :       }
     224                 : 
     225                 :       case FieldTypeFloat:
     226                 :       {
     227                 :           float value;
     228               0 :           memcpy( &value, GetData( section, offset, NULL, 4), 4 );
     229               0 :           if( needs_swap )
     230               0 :               SwapData( &value, 4, 1 );
     231               0 :           field.SetValue( value );
     232               0 :           return offset + 4;
     233                 :       }
     234                 : 
     235                 :       case FieldTypeDouble:
     236                 :       {
     237                 :           double value;
     238               0 :           memcpy( &value, GetData( section, offset, NULL, 8), 8 );
     239               0 :           if( needs_swap )
     240               0 :               SwapData( &value, 8, 1 );
     241               0 :           field.SetValue( value );
     242               0 :           return offset + 8;
     243                 :       }
     244                 : 
     245                 :       case FieldTypeString:
     246                 :       {
     247                 :           int available;
     248               0 :           char *srcdata = GetData( section, offset, &available, 1 );
     249                 :         
     250                 :           // Simple case -- all initially available.
     251               0 :           int string_len = 0;
     252                 : 
     253               0 :           while( srcdata[string_len] != '\0' && available - string_len > 0 )
     254               0 :               string_len++;
     255                 : 
     256               0 :           if( string_len < available && srcdata[string_len] == '\0' )
     257                 :           {
     258               0 :               std::string value( srcdata, string_len );
     259               0 :               field.SetValue( value );
     260               0 :               return offset + string_len + 1;
     261                 :           }
     262                 : 
     263               0 :           std::string value;
     264                 :         
     265               0 :           while( *srcdata != '\0' )
     266                 :           {
     267               0 :               value += *(srcdata++);
     268               0 :               offset++;
     269               0 :               available--;
     270               0 :               if( available == 0 )
     271               0 :                   srcdata = GetData( section, offset, &available, 1 );
     272                 :           }
     273                 : 
     274               0 :           field.SetValue( value );
     275               0 :           return offset+1;
     276                 :       }
     277                 : 
     278                 :       case FieldTypeCountedInt:
     279                 :       {
     280               0 :           std::vector<int32> value;
     281                 :           int32 count;
     282               0 :           char *srcdata = GetData( section, offset, NULL, 4 );
     283               0 :           memcpy( &count, srcdata, 4 );
     284               0 :           if( needs_swap )
     285               0 :               SwapData( &count, 4, 1 );
     286                 : 
     287               0 :           value.resize( count );
     288               0 :           memcpy( &(value[0]), GetData(section,offset+4,NULL,4*count), 4*count );
     289               0 :           if( needs_swap )
     290               0 :               SwapData( &(value[0]), 4, count );
     291               0 :           field.SetValue( value );
     292               0 :           return offset + 4 + 4*count;
     293                 :       }
     294                 : 
     295                 :       default:
     296               0 :         assert( 0 );
     297                 :         return offset;
     298                 :     }
     299                 : }
     300                 : 
     301                 : /************************************************************************/
     302                 : /*                              GetData()                               */
     303                 : /************************************************************************/
     304                 : 
     305               0 : char *CPCIDSKVectorSegment::GetData( int section, uint32 offset, 
     306                 :                                      int *bytes_available, int min_bytes )
     307                 : 
     308                 : {
     309               0 :     if( min_bytes == 0 )
     310               0 :         min_bytes = 1;
     311                 : 
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      Select the section to act on.                                   */
     314                 : /* -------------------------------------------------------------------- */
     315                 :     PCIDSKBuffer *pbuf;
     316                 :     uint32       *pbuf_offset;
     317                 : 
     318               0 :     if( section == sec_raw )
     319                 :     {
     320               0 :         pbuf = &raw_loaded_data;
     321               0 :         pbuf_offset = &raw_loaded_data_offset;
     322                 :     }
     323               0 :     else if( section == sec_vert )
     324                 :     {
     325               0 :         pbuf = &vert_loaded_data;
     326               0 :         pbuf_offset = &vert_loaded_data_offset;
     327                 :     }
     328               0 :     else if( section == sec_record )
     329                 :     {
     330               0 :         pbuf = &record_loaded_data;
     331               0 :         pbuf_offset = &record_loaded_data_offset;
     332                 :     }
     333                 : 
     334                 : /* -------------------------------------------------------------------- */
     335                 : /*      If the desired data is not within our loaded section, reload    */
     336                 : /*      one or more blocks around the request.                          */
     337                 : /* -------------------------------------------------------------------- */
     338               0 :     if( offset < *pbuf_offset
     339                 :         || offset+min_bytes > *pbuf_offset + pbuf->buffer_size )
     340                 :     {
     341                 :         // read whole 8K blocks around the target region.
     342               0 :         uint32 load_offset = offset - (offset % block_page_size);
     343               0 :         int size = (offset + min_bytes - load_offset + block_page_size - 1);
     344                 :         
     345               0 :         size -= (size % block_page_size);
     346                 : 
     347               0 :         *pbuf_offset = load_offset;
     348               0 :         pbuf->SetSize( size );
     349                 : 
     350                 :         ReadSecFromFile( section, pbuf->buffer, 
     351               0 :                          load_offset / block_page_size, size / block_page_size );
     352                 :     }
     353                 : 
     354                 : /* -------------------------------------------------------------------- */
     355                 : /*      Return desired info.                                            */
     356                 : /* -------------------------------------------------------------------- */
     357               0 :     if( bytes_available != NULL )
     358               0 :         *bytes_available = *pbuf_offset + pbuf->buffer_size - offset;
     359                 : 
     360               0 :     return pbuf->buffer + offset - *pbuf_offset;
     361                 : }
     362                 : 
     363                 : /************************************************************************/
     364                 : /*                          ReadSecFromFile()                           */
     365                 : /*                                                                      */
     366                 : /*      Read one or more blocks from the desired "section" of the       */
     367                 : /*      segment data, going through the block pointer map for           */
     368                 : /*      vect/record sections.                                           */
     369                 : /************************************************************************/
     370                 : 
     371               0 : void CPCIDSKVectorSegment::ReadSecFromFile( int section, char *buffer, 
     372                 :                                             int block_offset, 
     373                 :                                             int block_count )
     374                 : 
     375                 : {
     376                 : /* -------------------------------------------------------------------- */
     377                 : /*      Raw is a simple case, directly gulp.                            */
     378                 : /* -------------------------------------------------------------------- */
     379               0 :     if( section == sec_raw )
     380                 :     {
     381               0 :         ReadFromFile( buffer, block_offset*block_page_size, block_count*block_page_size );
     382               0 :         return;
     383                 :     }
     384                 : 
     385                 : /* -------------------------------------------------------------------- */
     386                 : /*      Load vertex block map if needed.                                */
     387                 : /* -------------------------------------------------------------------- */
     388               0 :     if( section == sec_vert && !vertex_block_initialized )
     389                 :     {
     390               0 :         vertex_block_index.resize( vertex_block_count );
     391                 :         ReadFromFile( &(vertex_block_index[0]), 
     392               0 :                       section_offsets[3] + 8,
     393               0 :                       4 * vertex_block_count );
     394               0 :         if( needs_swap )
     395               0 :             SwapData( &(vertex_block_index[0]), 4, vertex_block_count );
     396                 : 
     397               0 :         vertex_block_initialized = true;
     398                 :     }
     399                 : 
     400                 : /* -------------------------------------------------------------------- */
     401                 : /*      Load record block map if needed.                                */
     402                 : /* -------------------------------------------------------------------- */
     403               0 :     if( section == sec_record && !record_block_initialized )
     404                 :     {
     405               0 :         record_block_index.resize( record_block_count );
     406                 :         ReadFromFile( &(record_block_index[0]), 
     407               0 :                       section_offsets[3] + 16 + 4*vertex_block_count,
     408               0 :                       4 * record_block_count );
     409               0 :         if( needs_swap )
     410               0 :             SwapData( &(record_block_index[0]), 4, record_block_count );
     411                 : 
     412               0 :         record_block_initialized = true;
     413                 :     }
     414                 : 
     415                 : /* -------------------------------------------------------------------- */
     416                 : /*      Process one 8K block at a time in case they are discontigous    */
     417                 : /*      which they often are.                                           */
     418                 : /* -------------------------------------------------------------------- */
     419                 :     int i;
     420                 :     std::vector<uint32> *block_map;
     421                 : 
     422               0 :     if( section == sec_vert )
     423               0 :         block_map = &vertex_block_index;
     424                 :     else
     425               0 :         block_map = &record_block_index;
     426                 : 
     427               0 :     assert( block_count + block_offset <= (int) block_map->size() );
     428                 : 
     429               0 :     for( i = 0; i < block_count; i++ )
     430                 :     {
     431                 :         ReadFromFile( buffer + i * block_page_size, 
     432                 :                       block_page_size * (*block_map)[block_offset+i], 
     433               0 :                       block_page_size );
     434                 :     }
     435                 : }
     436                 : 
     437                 : /************************************************************************/
     438                 : /*                          IndexFromShapeId()                          */
     439                 : /*                                                                      */
     440                 : /*      Translate a shapeid into a shape index.  Several mechanisms     */
     441                 : /*      are used to accelerate this when possible.                      */
     442                 : /************************************************************************/
     443                 : 
     444               0 : int CPCIDSKVectorSegment::IndexFromShapeId( ShapeId id )
     445                 : 
     446                 : {
     447               0 :     if( id == NullShapeId )
     448               0 :         return -1;
     449                 : 
     450               0 :     Initialize();
     451                 : 
     452                 : /* -------------------------------------------------------------------- */
     453                 : /*      Does this match our last lookup?                                */
     454                 : /* -------------------------------------------------------------------- */
     455               0 :     if( id == last_shapes_id )
     456               0 :         return last_shapes_index;
     457                 : 
     458                 : /* -------------------------------------------------------------------- */
     459                 : /*      Is this the next shapeid in sequence, and is it in our          */
     460                 : /*      loaded index cache?                                             */
     461                 : /* -------------------------------------------------------------------- */
     462               0 :     if( id == last_shapes_id + 1 
     463                 :         && last_shapes_index + 1 >= shape_index_start
     464                 :         && last_shapes_index + 1 < shape_index_start + (int) shape_index_ids.size() )
     465                 :     {
     466               0 :         last_shapes_index++;
     467               0 :         last_shapes_id++;
     468               0 :         return last_shapes_index;
     469                 :     }
     470                 : 
     471                 : /* -------------------------------------------------------------------- */
     472                 : /*      Activate the shapeid map, if it is not already active.          */
     473                 : /* -------------------------------------------------------------------- */
     474               0 :     shapeid_map_active = true;
     475                 : 
     476                 : /* -------------------------------------------------------------------- */
     477                 : /*      Is this already in our shapeid map?                             */
     478                 : /* -------------------------------------------------------------------- */
     479               0 :     if( shapeid_map.count( id ) == 1 )
     480               0 :         return shapeid_map[id];
     481                 : 
     482                 : /* -------------------------------------------------------------------- */
     483                 : /*      Load shapeid index pages until we find the desired shapeid,     */
     484                 : /*      or we run out.                                                  */
     485                 : /* -------------------------------------------------------------------- */
     486               0 :     int shapeid_pages = (shape_count+shapeid_page_size-1) / shapeid_page_size;
     487                 : 
     488               0 :     while( shapeid_pages_certainly_mapped+1 < shapeid_pages )
     489                 :     {
     490                 :         AccessShapeByIndex( 
     491               0 :             (shapeid_pages_certainly_mapped+1) * shapeid_page_size );
     492                 :         
     493               0 :         if( shapeid_map.count( id ) == 1 )
     494               0 :             return shapeid_map[id];
     495                 :     }
     496                 :     
     497               0 :     return -1;
     498                 : }
     499                 : 
     500                 : /************************************************************************/
     501                 : /*                         AccessShapeByIndex()                         */
     502                 : /*                                                                      */
     503                 : /*      This method is responsible for loading the set of               */
     504                 : /*      information for shape "shape_index" into the shape_index data   */
     505                 : /*      structures if it is not already there.                          */
     506                 : /************************************************************************/
     507                 : 
     508               0 : void CPCIDSKVectorSegment::AccessShapeByIndex( int shape_index )
     509                 : 
     510                 : {
     511               0 :     Initialize();
     512                 : 
     513                 : /* -------------------------------------------------------------------- */
     514                 : /*      Is the requested index already loaded?                          */
     515                 : /* -------------------------------------------------------------------- */
     516               0 :     if( shape_index >= shape_index_start
     517                 :         && shape_index < shape_index_start + (int) shape_index_ids.size() )
     518               0 :         return;
     519                 : 
     520                 : /* -------------------------------------------------------------------- */
     521                 : /*      Load a chunk of shape index information into a                  */
     522                 : /*      PCIDSKBuffer.                                                   */
     523                 : /* -------------------------------------------------------------------- */
     524               0 :     int entries_to_load = shapeid_page_size;
     525                 : 
     526               0 :     shape_index_start = shape_index - (shape_index % shapeid_page_size);
     527               0 :     if( shape_index_start + entries_to_load > shape_count )
     528               0 :         entries_to_load = shape_count - shape_index_start;
     529                 : 
     530               0 :     PCIDSKBuffer wrk_index;
     531               0 :     wrk_index.SetSize( entries_to_load * 12 );
     532                 :     
     533                 :     ReadFromFile( wrk_index.buffer, 
     534                 :                   shape_index_byte_offset + shape_index_start*12,
     535               0 :                   wrk_index.buffer_size );
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      Parse into the vectors for easier use.                          */
     539                 : /* -------------------------------------------------------------------- */
     540                 :     int i;
     541                 : 
     542               0 :     shape_index_ids.resize( entries_to_load );
     543               0 :     shape_index_vertex_off.resize( entries_to_load );
     544               0 :     shape_index_record_off.resize( entries_to_load );
     545                 : 
     546               0 :     for( i = 0; i < entries_to_load; i++ )
     547                 :     {
     548               0 :         memcpy( &(shape_index_ids[i]), wrk_index.buffer + i*12, 4 );
     549               0 :         memcpy( &(shape_index_vertex_off[i]), wrk_index.buffer + i*12+4, 4 );
     550               0 :         memcpy( &(shape_index_record_off[i]), wrk_index.buffer + i*12+8, 4 );
     551                 :     }
     552                 : 
     553               0 :     if( needs_swap )
     554                 :     {
     555               0 :         SwapData( &(shape_index_ids[0]), 4, entries_to_load );
     556               0 :         SwapData( &(shape_index_vertex_off[0]), 4, entries_to_load );
     557               0 :         SwapData( &(shape_index_record_off[0]), 4, entries_to_load );
     558                 :     }
     559                 : 
     560                 : /* -------------------------------------------------------------------- */
     561                 : /*      If the shapeid map is active, apply the current pages           */
     562                 : /*      shapeids if it does not already appear to have been             */
     563                 : /*      applied.                                                        */
     564                 : /* -------------------------------------------------------------------- */
     565               0 :     int loaded_page = shape_index_start / shapeid_page_size;
     566                 : 
     567               0 :     if( shapeid_map_active 
     568                 :         && shape_index_ids.size() > 0 
     569                 :         && shapeid_map.count( shape_index_ids[0] ) == 0 )
     570                 :     {
     571               0 :         for( i = 0; i < entries_to_load; i++ )
     572                 :         {
     573               0 :             if( shape_index_ids[i] != NullShapeId )
     574               0 :                 shapeid_map[shape_index_ids[i]] = i+shape_index_start;
     575                 :         }
     576                 : 
     577               0 :         if( loaded_page == shapeid_pages_certainly_mapped+1 )
     578               0 :             shapeid_pages_certainly_mapped++;
     579               0 :     }
     580                 : }
     581                 : 
     582                 : /************************************************************************/
     583                 : /*                             FindFirst()                              */
     584                 : /************************************************************************/
     585                 : 
     586               0 : ShapeId CPCIDSKVectorSegment::FindFirst()
     587                 : { 
     588               0 :     Initialize();
     589                 : 
     590               0 :     if( shape_count == 0 )
     591               0 :         return NullShapeId;
     592                 : 
     593               0 :     AccessShapeByIndex( 0 );
     594                 : 
     595               0 :     last_shapes_id = shape_index_ids[0];
     596               0 :     last_shapes_index = 0;
     597                 : 
     598               0 :     return last_shapes_id;
     599                 : }
     600                 : 
     601                 : /************************************************************************/
     602                 : /*                              FindNext()                              */
     603                 : /************************************************************************/
     604                 : 
     605               0 : ShapeId CPCIDSKVectorSegment::FindNext( ShapeId previous_id )
     606                 : { 
     607               0 :     if( previous_id == NullShapeId ) 
     608               0 :         return FindFirst();
     609                 : 
     610               0 :     int previous_index = IndexFromShapeId( previous_id );
     611                 :     
     612               0 :     if( previous_index == shape_count - 1 )
     613               0 :         return NullShapeId;
     614                 : 
     615               0 :     AccessShapeByIndex( previous_index+1 );
     616                 : 
     617               0 :     last_shapes_index = previous_index+1;
     618               0 :     last_shapes_id = shape_index_ids[last_shapes_index - shape_index_start];
     619                 :     
     620               0 :     return last_shapes_id;
     621                 : }
     622                 : 
     623                 : /************************************************************************/
     624                 : /*                            GetVertices()                             */
     625                 : /************************************************************************/
     626                 : 
     627               0 : void CPCIDSKVectorSegment::GetVertices( ShapeId shape_id,
     628                 :                                         std::vector<ShapeVertex> &vertices )
     629                 : 
     630                 : {
     631               0 :     int shape_index = IndexFromShapeId( shape_id );
     632                 : 
     633               0 :     AccessShapeByIndex( shape_index );
     634                 : 
     635               0 :     uint32 vert_off = shape_index_vertex_off[shape_index - shape_index_start];
     636                 :     uint32 vertex_count;
     637                 : 
     638               0 :     memcpy( &vertex_count, GetData( sec_vert, vert_off+4, NULL, 4 ), 4 );
     639               0 :     if( needs_swap )
     640               0 :         SwapData( &vertex_count, 4, 1 );
     641                 : 
     642               0 :     vertices.resize( vertex_count );
     643                 :     
     644                 :     // We ought to change this to process the available data and
     645                 :     // then request more. 
     646                 :     memcpy( &(vertices[0]), 
     647                 :             GetData( sec_vert, vert_off+8, NULL, vertex_count*24),
     648               0 :             vertex_count * 24 );
     649               0 :     if( needs_swap )
     650               0 :         SwapData( &(vertices[0]), 8, vertex_count*3 );
     651               0 : }
     652                 : 
     653                 : /************************************************************************/
     654                 : /*                           GetFieldCount()                            */
     655                 : /************************************************************************/
     656                 : 
     657               0 : int CPCIDSKVectorSegment::GetFieldCount()
     658                 : 
     659                 : {
     660               0 :     Initialize();
     661                 : 
     662               0 :     return field_names.size();
     663                 : }
     664                 : 
     665                 : /************************************************************************/
     666                 : /*                            GetFieldName()                            */
     667                 : /************************************************************************/
     668                 : 
     669               0 : std::string CPCIDSKVectorSegment::GetFieldName( int field_index )
     670                 : 
     671                 : {
     672               0 :     Initialize();
     673                 : 
     674               0 :     return field_names[field_index];
     675                 : }
     676                 : 
     677                 : /************************************************************************/
     678                 : /*                        GetFieldDescription()                         */
     679                 : /************************************************************************/
     680                 : 
     681               0 : std::string CPCIDSKVectorSegment::GetFieldDescription( int field_index )
     682                 : 
     683                 : {
     684               0 :     Initialize();
     685                 : 
     686               0 :     return field_descriptions[field_index];
     687                 : }
     688                 : 
     689                 : /************************************************************************/
     690                 : /*                            GetFieldType()                            */
     691                 : /************************************************************************/
     692                 : 
     693               0 : ShapeFieldType CPCIDSKVectorSegment::GetFieldType( int field_index )
     694                 : 
     695                 : {
     696               0 :     Initialize();
     697                 : 
     698               0 :     return field_types[field_index];
     699                 : }
     700                 : 
     701                 : /************************************************************************/
     702                 : /*                           GetFieldFormat()                           */
     703                 : /************************************************************************/
     704                 : 
     705               0 : std::string CPCIDSKVectorSegment::GetFieldFormat( int field_index )
     706                 : 
     707                 : {
     708               0 :     Initialize();
     709                 : 
     710               0 :     return field_formats[field_index];
     711                 : }
     712                 : 
     713                 : /************************************************************************/
     714                 : /*                          GetFieldDefault()                           */
     715                 : /************************************************************************/
     716                 : 
     717               0 : ShapeField CPCIDSKVectorSegment::GetFieldDefault( int field_index )
     718                 : 
     719                 : {
     720               0 :     Initialize();
     721                 : 
     722               0 :     return field_defaults[field_index];
     723                 : }
     724                 : 
     725                 : /************************************************************************/
     726                 : /*                             GetFields()                              */
     727                 : /************************************************************************/
     728                 : 
     729               0 : void CPCIDSKVectorSegment::GetFields( ShapeId id, 
     730                 :                                       std::vector<ShapeField>& list )
     731                 : 
     732                 : {
     733                 :     unsigned int i;
     734               0 :     int shape_index = IndexFromShapeId( id );
     735                 : 
     736               0 :     AccessShapeByIndex( shape_index );
     737                 : 
     738               0 :     uint32 offset = shape_index_record_off[shape_index - shape_index_start] + 4;
     739                 : 
     740               0 :     list.resize(field_names.size());
     741               0 :     for( i = 0; i < field_names.size(); i++ )
     742               0 :         offset = ReadField( offset, list[i], field_types[i], sec_record );
     743               0 : }

Generated by: LCOV version 1.7