aboutsummaryrefslogtreecommitdiff
path: root/src/pj_init.c
diff options
context:
space:
mode:
authorFrank Warmerdam <warmerdam@pobox.com>2013-06-22 07:54:57 +0000
committerFrank Warmerdam <warmerdam@pobox.com>2013-06-22 07:54:57 +0000
commit44ef2bd6b0184d334b020e401026207b38aaa064 (patch)
tree347b721fe196a12765ad5c869cb51e77fa3a64ec /src/pj_init.c
parent07695742d49418f87338f0ffa48a16b9fae25767 (diff)
downloadPROJ-44ef2bd6b0184d334b020e401026207b38aaa064.tar.gz
PROJ-44ef2bd6b0184d334b020e401026207b38aaa064.zip
bulk of file api implementation complete and working
git-svn-id: http://svn.osgeo.org/metacrs/proj/trunk@2345 4e78687f-474d-0410-85f9-8d5e500ac6b2
Diffstat (limited to 'src/pj_init.c')
-rw-r--r--src/pj_init.c191
1 files changed, 162 insertions, 29 deletions
diff --git a/src/pj_init.c b/src/pj_init.c
index bc8691f4..fef2b5ff 100644
--- a/src/pj_init.c
+++ b/src/pj_init.c
@@ -35,48 +35,181 @@
#include <string.h>
#include <errno.h>
#include <locale.h>
+#include <ctype.h>
PJ_CVSID("$Id$");
+typedef struct {
+ projCtx ctx;
+ PAFile fid;
+ char buffer[8193];
+ int buffer_filled;
+ int at_eof;
+} pj_read_state;
+
+/************************************************************************/
+/* fill_buffer() */
+/************************************************************************/
+
+static const char *fill_buffer(pj_read_state *state, const char *last_char)
+{
+ size_t bytes_read;
+ int char_remaining, char_requested;
+
+/* -------------------------------------------------------------------- */
+/* Don't bother trying to read more if we are at eof, or if the */
+/* buffer is still over half full. */
+/* -------------------------------------------------------------------- */
+ if (last_char == NULL)
+ last_char = state->buffer;
+
+ if (state->at_eof)
+ return last_char;
+
+ char_remaining = state->buffer_filled - (last_char - state->buffer);
+ if (char_remaining >= sizeof(state->buffer) / 2)
+ return last_char;
+
+/* -------------------------------------------------------------------- */
+/* Move the existing data to the start of the buffer. */
+/* -------------------------------------------------------------------- */
+ memmove(state->buffer, last_char, char_remaining);
+ state->buffer_filled = char_remaining;
+ last_char = state->buffer;
+
+/* -------------------------------------------------------------------- */
+/* Refill. */
+/* -------------------------------------------------------------------- */
+ char_requested = sizeof(state->buffer) - state->buffer_filled - 1;
+ bytes_read = pj_ctx_fread( state->ctx, state->buffer + state->buffer_filled,
+ 1, char_requested, state->fid );
+ if (bytes_read < char_requested)
+ {
+ state->at_eof = 1;
+ state->buffer[state->buffer_filled + bytes_read] = '\0';
+ }
+
+ state->buffer_filled += bytes_read;
+ return last_char;
+}
+
/************************************************************************/
/* get_opt() */
/************************************************************************/
static paralist *
-get_opt(projCtx ctx, paralist **start, FILE *fid, char *name, paralist *next) {
- char sword[302], *word = sword+1;
- int first = 1, len, c;
+get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next) {
+ pj_read_state *state = (pj_read_state*) calloc(1,sizeof(pj_read_state));
+ char sword[302];
+ int len;
+ int in_target = 0;
+ const char *next_char = NULL;
+
+ state->fid = fid;
+ state->ctx = ctx;
+ next_char = fill_buffer(state, NULL);
len = strlen(name);
*sword = 't';
- while (fscanf(fid, "%300s", word) == 1) {
- if (*word == '#') /* skip comments */
- while((c = fgetc(fid)) != EOF && c != '\n') ;
- else if (*word == '<') { /* control name */
- if (first && !strncmp(name, word + 1, len)
- && word[len + 1] == '>')
- first = 0;
- else if (!first && *word == '<') {
- while((c = fgetc(fid)) != EOF && c != '\n') ;
+
+ /* loop till we find our target keyword */
+ while (*next_char)
+ {
+ next_char = fill_buffer(state, next_char);
+
+ /* Skip white space. */
+ while( isspace(*next_char) )
+ next_char++;
+
+ next_char = fill_buffer(state, next_char);
+
+ /* for comments, skip past end of line. */
+ if( *next_char == '#' )
+ {
+ while( *next_char && *next_char != '\n' )
+ next_char++;
+
+ next_char = fill_buffer(state, next_char);
+ if (*next_char == '\n')
+ next_char++;
+ if (*next_char == '\r')
+ next_char++;
+
+ }
+
+ /* Is this our target? */
+ else if( *next_char == '<' )
+ {
+ /* terminate processing target on the next block definition */
+ if (in_target)
break;
+
+ next_char++;
+ if (strncmp(name, next_char, len) == 0
+ && next_char[len] == '>')
+ {
+ /* skip past target word */
+ next_char += len + 1;
+ in_target = 1;
}
- } else if (!first && !pj_param(ctx, *start, sword).i) {
- /* don't default ellipse if datum, ellps or any earth model
- information is set. */
- if( strncmp(word,"ellps=",6) != 0
- || (!pj_param(ctx, *start, "tdatum").i
- && !pj_param(ctx, *start, "tellps").i
- && !pj_param(ctx, *start, "ta").i
- && !pj_param(ctx, *start, "tb").i
- && !pj_param(ctx, *start, "trf").i
- && !pj_param(ctx, *start, "tf").i) )
+ else
{
- next = next->next = pj_mkparam(word);
+ /* skip past end of line */
+ while( *next_char && *next_char != '\n' )
+ next_char++;
}
}
- }
+ else if (in_target)
+ {
+ const char *start_of_word = next_char;
+ int word_len = 0;
+
+ if (*start_of_word == '+')
+ {
+ start_of_word++;
+ next_char++;
+ }
+
+ /* capture parameter */
+ while( *next_char && !isspace(*next_char) )
+ {
+ next_char++;
+ word_len++;
+ }
+
+ strncpy(sword+1, start_of_word, word_len);
+ sword[word_len+1] = '\0';
+
+ /* do not override existing parameter value of same name */
+ if (!pj_param(ctx, *start, sword).i) {
+ /* don't default ellipse if datum, ellps or any earth model
+ information is set. */
+ if( strncmp(sword+1,"ellps=",6) != 0
+ || (!pj_param(ctx, *start, "tdatum").i
+ && !pj_param(ctx, *start, "tellps").i
+ && !pj_param(ctx, *start, "ta").i
+ && !pj_param(ctx, *start, "tb").i
+ && !pj_param(ctx, *start, "trf").i
+ && !pj_param(ctx, *start, "tf").i) )
+ {
+ next = next->next = pj_mkparam(sword+1);
+ }
+ }
+
+ }
+ else
+ {
+ /* skip past word */
+ while( *next_char && !isspace(*next_char) )
+ next_char++;
+
+ }
+ }
if (errno == 25)
errno = 0;
+
+ free(state);
+
return next;
}
@@ -85,13 +218,13 @@ get_opt(projCtx ctx, paralist **start, FILE *fid, char *name, paralist *next) {
/************************************************************************/
static paralist *
get_defaults(projCtx ctx, paralist **start, paralist *next, char *name) {
- FILE *fid;
+ PAFile fid;
if ( (fid = pj_open_lib(ctx,"proj_def.dat", "rt")) != NULL) {
next = get_opt(ctx, start, fid, "general", next);
- rewind(fid);
+ pj_ctx_fseek(ctx, fid, 0, SEEK_SET);
next = get_opt(ctx, start, fid, name, next);
- (void)fclose(fid);
+ pj_ctx_fclose(ctx, fid);
}
if (errno)
errno = 0; /* don't care if can't open file */
@@ -106,7 +239,7 @@ get_defaults(projCtx ctx, paralist **start, paralist *next, char *name) {
static paralist *
get_init(projCtx ctx, paralist **start, paralist *next, char *name) {
char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt;
- FILE *fid;
+ PAFile fid;
paralist *init_items = NULL;
const paralist *orig_next = next;
@@ -136,7 +269,7 @@ get_init(projCtx ctx, paralist **start, paralist *next, char *name) {
next = get_opt(ctx, start, fid, opt, next);
else
return NULL;
- (void)fclose(fid);
+ pj_ctx_fclose(ctx, fid);
if (errno == 25)
errno = 0; /* unknown problem with some sys errno<-25 */