PageRenderTime 48ms CodeModel.GetById 29ms app.highlight 14ms RepoModel.GetById 2ms app.codeStats 0ms

/Proj4/pj_gridlist.c

http://github.com/route-me/route-me
C | 274 lines | 136 code | 45 blank | 93 comment | 39 complexity | c1cf4e2eec921f92b85cd2adf8780880 MD5 | raw file
  1/******************************************************************************
  2 * $Id: pj_gridlist.c,v 1.5 2006/11/17 22:16:30 mloskot Exp $
  3 *
  4 * Project:  PROJ.4
  5 * Purpose:  Code to manage the list of currently loaded (cached) PJ_GRIDINFOs
  6 *           See pj_gridinfo.c for details of loading individual grids.
  7 * Author:   Frank Warmerdam, warmerdam@pobox.com
  8 *
  9 ******************************************************************************
 10 * Copyright (c) 2000, Frank Warmerdam <warmerdam@pobox.com>
 11 *
 12 * Permission is hereby granted, free of charge, to any person obtaining a
 13 * copy of this software and associated documentation files (the "Software"),
 14 * to deal in the Software without restriction, including without limitation
 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 16 * and/or sell copies of the Software, and to permit persons to whom the
 17 * Software is furnished to do so, subject to the following conditions:
 18 *
 19 * The above copyright notice and this permission notice shall be included
 20 * in all copies or substantial portions of the Software.
 21 *
 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 28 * DEALINGS IN THE SOFTWARE.
 29 ******************************************************************************
 30 *
 31 * $Log: pj_gridlist.c,v $
 32 * Revision 1.5  2006/11/17 22:16:30  mloskot
 33 * Uploaded PROJ.4 port for Windows CE.
 34 *
 35 * Revision 1.4  2005/11/01 05:56:13  fwarmerdam
 36 * improved error handling if gridcount is zero
 37 *
 38 * Revision 1.3  2003/03/18 16:26:58  warmerda
 39 * clear error if missing file is not required
 40 *
 41 * Revision 1.2  2003/03/17 19:45:47  warmerda
 42 * support '@' marker for optional grids
 43 *
 44 * Revision 1.1  2003/03/15 06:01:18  warmerda
 45 * New
 46 *
 47 */
 48
 49#define PJ_LIB__
 50
 51#include "projects.h"
 52#include <string.h>
 53#include <math.h>
 54
 55#ifdef _WIN32_WCE
 56/* assert.h includes all Windows API headers and causes 'LP' name clash.
 57 * Here assert we disable assert() for Windows CE.
 58 * TODO - mloskot: re-implement porting friendly assert
 59 */
 60# define assert(exp)	((void)0)
 61#else
 62# include <assert.h>
 63#endif /* _WIN32_WCE */
 64
 65static PJ_GRIDINFO *grid_list = NULL;
 66
 67/* used only by pj_load_nadgrids() and pj_deallocate_grids() */
 68
 69static int           last_nadgrids_max = 0;
 70static int           last_nadgrids_count = 0;
 71static PJ_GRIDINFO **last_nadgrids_list = NULL;
 72static char         *last_nadgrids = NULL;
 73
 74/************************************************************************/
 75/*                        pj_deallocate_grids()                         */
 76/*                                                                      */
 77/*      Deallocate all loaded grids.                                    */
 78/************************************************************************/
 79
 80void pj_deallocate_grids()
 81
 82{
 83    while( grid_list != NULL )
 84    {
 85        PJ_GRIDINFO *item = grid_list;
 86        grid_list = grid_list->next;
 87        item->next = NULL;
 88
 89        pj_gridinfo_free( item );
 90    }
 91
 92    if( last_nadgrids != NULL )
 93    {
 94        pj_dalloc( last_nadgrids );
 95        last_nadgrids = NULL;
 96
 97        pj_dalloc( last_nadgrids_list );
 98        last_nadgrids_list = NULL;
 99
100        last_nadgrids_count = 0;
101        last_nadgrids_max = 0;
102    }
103}
104
105/************************************************************************/
106/*                       pj_gridlist_merge_grid()                       */
107/*                                                                      */
108/*      Find/load the named gridfile and merge it into the              */
109/*      last_nadgrids_list.                                             */
110/************************************************************************/
111
112static int pj_gridlist_merge_gridfile( const char *gridname )
113
114{
115    int i, got_match=0;
116    PJ_GRIDINFO *this_grid, *tail = NULL;
117
118/* -------------------------------------------------------------------- */
119/*      Try to find in the existing list of loaded grids.  Add all      */
120/*      matching grids as with NTv2 we can get many grids from one      */
121/*      file (one shared gridname).                                     */
122/* -------------------------------------------------------------------- */
123    for( this_grid = grid_list; this_grid != NULL; this_grid = this_grid->next)
124    {
125        if( strcmp(this_grid->gridname,gridname) == 0 )
126        {
127            got_match = 1;
128
129            /* dont add to the list if it is invalid. */
130            if( this_grid->ct == NULL )
131                return 0;
132
133            /* do we need to grow the list? */
134            if( last_nadgrids_count >= last_nadgrids_max - 2 )
135            {
136                PJ_GRIDINFO **new_list;
137                int new_max = last_nadgrids_max + 20;
138
139                new_list = (PJ_GRIDINFO **) pj_malloc(sizeof(void*) * new_max);
140                if( last_nadgrids_list != NULL )
141                {
142                    memcpy( new_list, last_nadgrids_list, 
143                            sizeof(void*) * last_nadgrids_max );
144                    pj_dalloc( last_nadgrids_list );
145                }
146
147                last_nadgrids_list = new_list;
148                last_nadgrids_max = new_max;
149            }
150
151            /* add to the list */
152            last_nadgrids_list[last_nadgrids_count++] = this_grid;
153            last_nadgrids_list[last_nadgrids_count] = NULL;
154        }
155
156        tail = this_grid;
157    }
158
159    if( got_match )
160        return 1;
161
162/* -------------------------------------------------------------------- */
163/*      Try to load the named grid.                                     */
164/* -------------------------------------------------------------------- */
165    this_grid = pj_gridinfo_init( gridname );
166
167    if( this_grid == NULL )
168    {
169        /* we should get at least a stub grid with a missing "ct" member */
170        assert( FALSE );
171        return 0;
172    }
173    
174    if( tail != NULL )
175        tail->next = this_grid;
176    else
177        grid_list = this_grid;
178
179/* -------------------------------------------------------------------- */
180/*      Recurse to add the grid now that it is loaded.                  */
181/* -------------------------------------------------------------------- */
182    return pj_gridlist_merge_gridfile( gridname );
183}
184
185/************************************************************************/
186/*                     pj_gridlist_from_nadgrids()                      */
187/*                                                                      */
188/*      This functions loads the list of grids corresponding to a       */
189/*      particular nadgrids string into a list, and returns it.  The    */
190/*      list is kept around till a request is made with a different     */
191/*      string in order to cut down on the string parsing cost, and     */
192/*      the cost of building the list of tables each time.              */
193/************************************************************************/
194
195PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *nadgrids, int *grid_count)
196
197{
198    const char *s;
199
200    pj_errno = 0;
201    *grid_count = 0;
202
203    if( last_nadgrids != NULL 
204        && strcmp(nadgrids,last_nadgrids) == 0 )
205    {
206        *grid_count = last_nadgrids_count;
207        if( *grid_count == 0 )
208            pj_errno = -38;
209
210        return last_nadgrids_list;
211    }
212
213/* -------------------------------------------------------------------- */
214/*      Free old one, if any, and make space for new list.              */
215/* -------------------------------------------------------------------- */
216    if( last_nadgrids != NULL )
217    {
218        pj_dalloc(last_nadgrids);
219    }
220    
221    last_nadgrids = (char *) pj_malloc(strlen(nadgrids)+1);
222    strcpy( last_nadgrids, nadgrids );
223
224    last_nadgrids_count = 0;
225
226/* -------------------------------------------------------------------- */
227/*      Loop processing names out of nadgrids one at a time.            */
228/* -------------------------------------------------------------------- */
229    for( s = nadgrids; *s != '\0'; )
230    {
231        int   end_char;
232        int   required = 1;
233        char  name[128];
234
235        if( *s == '@' )
236        {
237            required = 0;
238            s++;
239        }
240
241        for( end_char = 0; 
242             s[end_char] != '\0' && s[end_char] != ','; 
243             end_char++ ) {}
244
245        if( end_char > sizeof(name) )
246        {
247            pj_errno = -38;
248            return NULL;
249        }
250        
251        strncpy( name, s, end_char );
252        name[end_char] = '\0';
253
254        s += end_char;
255        if( *s == ',' )
256            s++;
257
258        if( !pj_gridlist_merge_gridfile( name ) && required )
259        {
260            pj_errno = -38;
261            return NULL;
262        }
263        else
264            pj_errno = 0;
265    }
266
267    if( last_nadgrids_count > 0 )
268    {
269        *grid_count = last_nadgrids_count;
270        return last_nadgrids_list;
271    }
272    else
273        return NULL;
274}