diff options
| author | Frank Warmerdam <warmerdam@pobox.com> | 2013-06-22 07:54:57 +0000 |
|---|---|---|
| committer | Frank Warmerdam <warmerdam@pobox.com> | 2013-06-22 07:54:57 +0000 |
| commit | 44ef2bd6b0184d334b020e401026207b38aaa064 (patch) | |
| tree | 347b721fe196a12765ad5c869cb51e77fa3a64ec /src/pj_init.c | |
| parent | 07695742d49418f87338f0ffa48a16b9fae25767 (diff) | |
| download | PROJ-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.c | 191 |
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 */ |
