/Proj4/pj_gridlist.c

http://github.com/route-me/route-me · C · 274 lines · 136 code · 45 blank · 93 comment · 40 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. #define PJ_LIB__
  49. #include "projects.h"
  50. #include <string.h>
  51. #include <math.h>
  52. #ifdef _WIN32_WCE
  53. /* assert.h includes all Windows API headers and causes 'LP' name clash.
  54. * Here assert we disable assert() for Windows CE.
  55. * TODO - mloskot: re-implement porting friendly assert
  56. */
  57. # define assert(exp) ((void)0)
  58. #else
  59. # include <assert.h>
  60. #endif /* _WIN32_WCE */
  61. static PJ_GRIDINFO *grid_list = NULL;
  62. /* used only by pj_load_nadgrids() and pj_deallocate_grids() */
  63. static int last_nadgrids_max = 0;
  64. static int last_nadgrids_count = 0;
  65. static PJ_GRIDINFO **last_nadgrids_list = NULL;
  66. static char *last_nadgrids = NULL;
  67. /************************************************************************/
  68. /* pj_deallocate_grids() */
  69. /* */
  70. /* Deallocate all loaded grids. */
  71. /************************************************************************/
  72. void pj_deallocate_grids()
  73. {
  74. while( grid_list != NULL )
  75. {
  76. PJ_GRIDINFO *item = grid_list;
  77. grid_list = grid_list->next;
  78. item->next = NULL;
  79. pj_gridinfo_free( item );
  80. }
  81. if( last_nadgrids != NULL )
  82. {
  83. pj_dalloc( last_nadgrids );
  84. last_nadgrids = NULL;
  85. pj_dalloc( last_nadgrids_list );
  86. last_nadgrids_list = NULL;
  87. last_nadgrids_count = 0;
  88. last_nadgrids_max = 0;
  89. }
  90. }
  91. /************************************************************************/
  92. /* pj_gridlist_merge_grid() */
  93. /* */
  94. /* Find/load the named gridfile and merge it into the */
  95. /* last_nadgrids_list. */
  96. /************************************************************************/
  97. static int pj_gridlist_merge_gridfile( const char *gridname )
  98. {
  99. int i, got_match=0;
  100. PJ_GRIDINFO *this_grid, *tail = NULL;
  101. /* -------------------------------------------------------------------- */
  102. /* Try to find in the existing list of loaded grids. Add all */
  103. /* matching grids as with NTv2 we can get many grids from one */
  104. /* file (one shared gridname). */
  105. /* -------------------------------------------------------------------- */
  106. for( this_grid = grid_list; this_grid != NULL; this_grid = this_grid->next)
  107. {
  108. if( strcmp(this_grid->gridname,gridname) == 0 )
  109. {
  110. got_match = 1;
  111. /* dont add to the list if it is invalid. */
  112. if( this_grid->ct == NULL )
  113. return 0;
  114. /* do we need to grow the list? */
  115. if( last_nadgrids_count >= last_nadgrids_max - 2 )
  116. {
  117. PJ_GRIDINFO **new_list;
  118. int new_max = last_nadgrids_max + 20;
  119. new_list = (PJ_GRIDINFO **) pj_malloc(sizeof(void*) * new_max);
  120. if( last_nadgrids_list != NULL )
  121. {
  122. memcpy( new_list, last_nadgrids_list,
  123. sizeof(void*) * last_nadgrids_max );
  124. pj_dalloc( last_nadgrids_list );
  125. }
  126. last_nadgrids_list = new_list;
  127. last_nadgrids_max = new_max;
  128. }
  129. /* add to the list */
  130. last_nadgrids_list[last_nadgrids_count++] = this_grid;
  131. last_nadgrids_list[last_nadgrids_count] = NULL;
  132. }
  133. tail = this_grid;
  134. }
  135. if( got_match )
  136. return 1;
  137. /* -------------------------------------------------------------------- */
  138. /* Try to load the named grid. */
  139. /* -------------------------------------------------------------------- */
  140. this_grid = pj_gridinfo_init( gridname );
  141. if( this_grid == NULL )
  142. {
  143. /* we should get at least a stub grid with a missing "ct" member */
  144. assert( FALSE );
  145. return 0;
  146. }
  147. if( tail != NULL )
  148. tail->next = this_grid;
  149. else
  150. grid_list = this_grid;
  151. /* -------------------------------------------------------------------- */
  152. /* Recurse to add the grid now that it is loaded. */
  153. /* -------------------------------------------------------------------- */
  154. return pj_gridlist_merge_gridfile( gridname );
  155. }
  156. /************************************************************************/
  157. /* pj_gridlist_from_nadgrids() */
  158. /* */
  159. /* This functions loads the list of grids corresponding to a */
  160. /* particular nadgrids string into a list, and returns it. The */
  161. /* list is kept around till a request is made with a different */
  162. /* string in order to cut down on the string parsing cost, and */
  163. /* the cost of building the list of tables each time. */
  164. /************************************************************************/
  165. PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *nadgrids, int *grid_count)
  166. {
  167. const char *s;
  168. pj_errno = 0;
  169. *grid_count = 0;
  170. if( last_nadgrids != NULL
  171. && strcmp(nadgrids,last_nadgrids) == 0 )
  172. {
  173. *grid_count = last_nadgrids_count;
  174. if( *grid_count == 0 )
  175. pj_errno = -38;
  176. return last_nadgrids_list;
  177. }
  178. /* -------------------------------------------------------------------- */
  179. /* Free old one, if any, and make space for new list. */
  180. /* -------------------------------------------------------------------- */
  181. if( last_nadgrids != NULL )
  182. {
  183. pj_dalloc(last_nadgrids);
  184. }
  185. last_nadgrids = (char *) pj_malloc(strlen(nadgrids)+1);
  186. strcpy( last_nadgrids, nadgrids );
  187. last_nadgrids_count = 0;
  188. /* -------------------------------------------------------------------- */
  189. /* Loop processing names out of nadgrids one at a time. */
  190. /* -------------------------------------------------------------------- */
  191. for( s = nadgrids; *s != '\0'; )
  192. {
  193. int end_char;
  194. int required = 1;
  195. char name[128];
  196. if( *s == '@' )
  197. {
  198. required = 0;
  199. s++;
  200. }
  201. for( end_char = 0;
  202. s[end_char] != '\0' && s[end_char] != ',';
  203. end_char++ ) {}
  204. if( end_char > sizeof(name) )
  205. {
  206. pj_errno = -38;
  207. return NULL;
  208. }
  209. strncpy( name, s, end_char );
  210. name[end_char] = '\0';
  211. s += end_char;
  212. if( *s == ',' )
  213. s++;
  214. if( !pj_gridlist_merge_gridfile( name ) && required )
  215. {
  216. pj_errno = -38;
  217. return NULL;
  218. }
  219. else
  220. pj_errno = 0;
  221. }
  222. if( last_nadgrids_count > 0 )
  223. {
  224. *grid_count = last_nadgrids_count;
  225. return last_nadgrids_list;
  226. }
  227. else
  228. return NULL;
  229. }