GRIB-803: grib_index_release does not close the file

This commit is contained in:
Shahram Najm 2015-07-29 16:29:23 +01:00
parent cf155e26e5
commit 04c370da62
2 changed files with 475 additions and 468 deletions

View File

@ -35,387 +35,390 @@ static short next_id=0;
GRIB_INLINE static int grib_inline_strcmp(const char* a,const char* b)
{
if (*a != *b) return 1;
while((*a!=0 && *b!=0) && *(a) == *(b) ) {a++;b++;}
return (*a==0 && *b==0) ? 0 : 1;
if (*a != *b) return 1;
while((*a!=0 && *b!=0) && *(a) == *(b) ) {a++;b++;}
return (*a==0 && *b==0) ? 0 : 1;
}
static grib_file_pool file_pool= {
0, /* grib_context* context;*/
0, /* grib_file* first;*/
0, /* grib_file* current; */
0, /* size_t size;*/
0, /* int number_of_opened_files;*/
GRIB_MAX_OPENED_FILES /* int max_opened_files; */
0, /* grib_context* context;*/
0, /* grib_file* first;*/
0, /* grib_file* current; */
0, /* size_t size;*/
0, /* int number_of_opened_files;*/
GRIB_MAX_OPENED_FILES /* int max_opened_files; */
};
void grib_file_pool_clean()
{
grib_file *file,*next;
grib_file *file,*next;
if (!file_pool.first) return;
if (!file_pool.first) return;
file=file_pool.first;
while(file) {
next=file->next;
grib_file_delete(file);
file=next;
}
file=file_pool.first;
while(file) {
next=file->next;
grib_file_delete(file);
file=next;
}
}
static void grib_file_pool_change_id()
{
grib_file *file;
grib_file *file;
if (!file_pool.first) return;
if (!file_pool.first) return;
file=file_pool.first;
while(file) {
file->id+=1000;
file=file->next;
}
file=file_pool.first;
while(file) {
file->id+=1000;
file=file->next;
}
}
static grib_file* grib_read_file(grib_context *c,FILE* fh,int *err)
{
short marker=0;
short id=0;
grib_file* file;
*err = grib_read_short(fh,&marker);
if(!marker) return NULL;
short marker=0;
short id=0;
grib_file* file;
*err = grib_read_short(fh,&marker);
if(!marker) return NULL;
file=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
file->buffer=0;
file->name=grib_read_string(c,fh,err);
if (*err) return NULL;
file=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
file->buffer=0;
file->name=grib_read_string(c,fh,err);
if (*err) return NULL;
*err=grib_read_short(fh,&id);
file->id=id;
if (*err) return NULL;
*err=grib_read_short(fh,&id);
file->id=id;
if (*err) return NULL;
file->next=grib_read_file(c,fh,err);
if (*err) return NULL;
file->next=grib_read_file(c,fh,err);
if (*err) return NULL;
return file;
return file;
}
static int grib_write_file(FILE *fh,grib_file* file)
{
int err=0;
int err=0;
if (!file)
return grib_write_null_marker(fh);
if (!file)
return grib_write_null_marker(fh);
err=grib_write_not_null_marker(fh);
if (err) return err;
err=grib_write_not_null_marker(fh);
if (err) return err;
err=grib_write_string(fh,file->name);
if (err) return err;
err=grib_write_string(fh,file->name);
if (err) return err;
err=grib_write_short(fh,(short)file->id);
if (err) return err;
err=grib_write_short(fh,(short)file->id);
if (err) return err;
return grib_write_file(fh,file->next);
return grib_write_file(fh,file->next);
}
grib_file* grib_file_pool_get_files()
{
return file_pool.first;
return file_pool.first;
}
int grib_file_pool_read(grib_context* c,FILE* fh)
{
int err=0;
short marker=0;
grib_file* file;
int err=0;
short marker=0;
grib_file* file;
if (!c) c=grib_context_get_default();
if (!c) c=grib_context_get_default();
err = grib_read_short(fh,&marker);
if(!marker) {
grib_context_log(c,GRIB_LOG_ERROR,
"Unable to find file information in index file\n");
return GRIB_INVALID_FILE;
}
err = grib_read_short(fh,&marker);
if(!marker) {
grib_context_log(c,GRIB_LOG_ERROR,
"Unable to find file information in index file\n");
return GRIB_INVALID_FILE;
}
grib_file_pool_change_id();
file=file_pool.first;
grib_file_pool_change_id();
file=file_pool.first;
while (file->next)
file=file->next;
while (file->next)
file=file->next;
file->next=grib_read_file(c,fh,&err);
if (err) return err;
file->next=grib_read_file(c,fh,&err);
if (err) return err;
return GRIB_SUCCESS;
return GRIB_SUCCESS;
}
int grib_file_pool_write(FILE* fh)
{
int err=0;
if (!file_pool.first)
return grib_write_null_marker(fh);
int err=0;
if (!file_pool.first)
return grib_write_null_marker(fh);
err=grib_write_not_null_marker(fh);
if (err) return err;
err=grib_write_not_null_marker(fh);
if (err) return err;
return grib_write_file(fh,file_pool.first);
return grib_write_file(fh,file_pool.first);
}
grib_file* grib_file_open(const char* filename, const char* mode,int* err)
{
grib_file *file=0,*prev=0;
int same_mode=0;
int is_new=0;
GRIB_PTHREAD_ONCE(&once,&init);
grib_file *file=0,*prev=0;
int same_mode=0;
int is_new=0;
GRIB_PTHREAD_ONCE(&once,&init);
if (!file_pool.context) file_pool.context=grib_context_get_default();
if (!file_pool.context) file_pool.context=grib_context_get_default();
if (file_pool.current && !grib_inline_strcmp(filename,file_pool.current->name)) {
file=file_pool.current;
} else {
GRIB_MUTEX_LOCK(&mutex1);
file=file_pool.first;
while (file) {
if (!grib_inline_strcmp(filename,file->name)) break;
prev=file;
file=file->next;
}
if (!file) {
is_new=1;
file=grib_file_new(file_pool.context,filename,err);
if (prev) prev->next=file;
file_pool.current=file;
if (!prev) file_pool.first=file;
file_pool.size++;
}
GRIB_MUTEX_UNLOCK(&mutex1);
}
if (file_pool.current && !grib_inline_strcmp(filename,file_pool.current->name)) {
file=file_pool.current;
} else {
GRIB_MUTEX_LOCK(&mutex1);
file=file_pool.first;
while (file) {
if (!grib_inline_strcmp(filename,file->name)) break;
prev=file;
file=file->next;
}
if (!file) {
is_new=1;
file=grib_file_new(file_pool.context,filename,err);
if (prev) prev->next=file;
file_pool.current=file;
if (!prev) file_pool.first=file;
file_pool.size++;
}
GRIB_MUTEX_UNLOCK(&mutex1);
}
if (file->mode) same_mode=grib_inline_strcmp(mode,file->mode) ? 0 : 1;
if (file->handle && same_mode) {
*err=0;
return file;
}
if (file->mode) same_mode=grib_inline_strcmp(mode,file->mode) ? 0 : 1;
if (file->handle && same_mode) {
*err=0;
return file;
}
GRIB_MUTEX_LOCK(&mutex1);
if (!same_mode && file->handle) {
/*printf("========== mode=%s file->mode=%s\n",mode,file->mode);*/
fclose(file->handle);
}
GRIB_MUTEX_LOCK(&mutex1);
if (!same_mode && file->handle) {
/*printf("========== mode=%s file->mode=%s\n",mode,file->mode);*/
fclose(file->handle);
}
if (!file->handle) {
/*printf("-- opening file %s %s\n",file->name,mode);*/
if (!is_new && *mode == 'w') {
/* fprintf(stderr,"++++ opening %s as append\n",file->name); */
file->handle = fopen(file->name,"a");
} else {
file->handle = fopen(file->name,mode);
/* fprintf(stderr,"++++ opening %s as mode\n",file->name); */
}
if (!file->handle) {
/*printf("-- opening file %s %s\n",file->name,mode);*/
if (!is_new && *mode == 'w') {
/* fprintf(stderr,"++++ opening %s as append\n",file->name); */
file->handle = fopen(file->name,"a");
} else {
file->handle = fopen(file->name,mode);
/* fprintf(stderr,"++++ opening %s as mode\n",file->name); */
}
file->mode=strdup(mode);
if (!file->handle) {
grib_context_log(file->context,GRIB_LOG_PERROR,"grib_file_open: cannot open file %s",file->name);
*err=GRIB_IO_PROBLEM;
return NULL;
}
if (file_pool.context->io_buffer_size) {
file->mode=strdup(mode);
if (!file->handle) {
grib_context_log(file->context,GRIB_LOG_PERROR,"grib_file_open: cannot open file %s",file->name);
*err=GRIB_IO_PROBLEM;
return NULL;
}
if (file_pool.context->io_buffer_size) {
#ifdef POSIX_MEMALIGN
if (posix_memalign((void**)&(file->buffer),sysconf(_SC_PAGESIZE),file_pool.context->io_buffer_size) ) {
grib_context_log(file->context,GRIB_LOG_FATAL,"posix_memalign unable to allocate io_buffer\n");
}
if (posix_memalign((void**)&(file->buffer),sysconf(_SC_PAGESIZE),file_pool.context->io_buffer_size) ) {
grib_context_log(file->context,GRIB_LOG_FATAL,"posix_memalign unable to allocate io_buffer\n");
}
#else
file->buffer = (void*)malloc(file_pool.context->io_buffer_size);
if (!file->buffer) {
grib_context_log(file->context,GRIB_LOG_FATAL,"Unable to allocate io_buffer\n");
}
file->buffer = (void*)malloc(file_pool.context->io_buffer_size);
if (!file->buffer) {
grib_context_log(file->context,GRIB_LOG_FATAL,"Unable to allocate io_buffer\n");
}
#endif
setvbuf(file->handle,file->buffer,_IOFBF,file_pool.context->io_buffer_size);
}
setvbuf(file->handle,file->buffer,_IOFBF,file_pool.context->io_buffer_size);
}
file_pool.number_of_opened_files++;
file_pool.number_of_opened_files++;
GRIB_MUTEX_UNLOCK(&mutex1);
GRIB_MUTEX_UNLOCK(&mutex1);
}
return file;
}
return file;
}
void grib_file_pool_delete_file(grib_file* file) {
grib_file* prev=NULL;
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
if (file==file_pool.first) {
file_pool.first=file->next;
file_pool.current=file->next;
} else {
if (file==file_pool.first) {
file_pool.first=file->next;
file_pool.current=file->next;
} else {
prev=file_pool.first;
file_pool.current=file_pool.first;
while (prev) {
if (prev->next==file) break;
prev=prev->next;
}
Assert(prev);
prev->next=file->next;
}
prev=file_pool.first;
file_pool.current=file_pool.first;
while (prev) {
if (prev->next==file) break;
prev=prev->next;
}
Assert(prev);
prev->next=file->next;
}
if (file->handle) {
if (file->handle) {
file_pool.number_of_opened_files--;
}
grib_file_delete(file);
GRIB_MUTEX_UNLOCK(&mutex1);
}
grib_file_delete(file);
GRIB_MUTEX_UNLOCK(&mutex1);
}
void grib_file_close_force(const char* filename,int* err)
{
grib_file* file=NULL;
grib_file* file=NULL;
/* fprintf(stderr,"++++ closing file %s\n",filename); */
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
file=grib_get_file(filename,err);
fclose(file->handle);
if (file->buffer) {
free(file->buffer);
file->buffer=0;
}
if (file->buffer) {
free(file->buffer);
file->buffer=0;
}
file->handle=NULL;
file_pool.number_of_opened_files--;
GRIB_MUTEX_UNLOCK(&mutex1);
GRIB_MUTEX_UNLOCK(&mutex1);
}
void grib_file_close(const char* filename,int* err)
{
grib_file* file=NULL;
grib_file* file=NULL;
/* Performance: keep the files open to avoid opening and closing files when writing the output. */
/* So only call fclose() when too many files are open */
if ( file_pool.number_of_opened_files > GRIB_MAX_OPENED_FILES ) {
/*printf("++ closing file %s\n",filename);*/
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
file=grib_get_file(filename,err);
if (file->handle) {
if (fclose(file->handle) != 0) {
*err=GRIB_IO_PROBLEM;
}
if (file->buffer) {
free(file->buffer);
file->buffer=0;
}
file->handle=NULL;
file_pool.number_of_opened_files--;
}
GRIB_MUTEX_UNLOCK(&mutex1);
}
/* Performance: keep the files open to avoid opening and closing files when writing the output. */
/* So only call fclose() when too many files are open */
if ( file_pool.number_of_opened_files > GRIB_MAX_OPENED_FILES ) {
/*printf("++ closing file %s\n",filename);*/
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
file=grib_get_file(filename,err);
if (file->handle) {
if (fclose(file->handle) != 0) {
*err=GRIB_IO_PROBLEM;
}
if (file->buffer) {
free(file->buffer);
file->buffer=0;
}
file->handle=NULL;
file_pool.number_of_opened_files--;
}
GRIB_MUTEX_UNLOCK(&mutex1);
}
}
void grib_file_close_all(int *err)
{
grib_file* file = NULL;
if (!file_pool.first) return;
grib_file* file = NULL;
if (!file_pool.first) return;
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
file = file_pool.first;
while (file) {
if (file->handle) {
if (fclose(file->handle) != 0) {
*err=GRIB_IO_PROBLEM;
}
file->handle=NULL;
}
file = file->next;
}
file = file_pool.first;
while (file) {
if (file->handle) {
if (fclose(file->handle) != 0) {
*err=GRIB_IO_PROBLEM;
}
file->handle=NULL;
}
file = file->next;
}
GRIB_MUTEX_UNLOCK(&mutex1);
GRIB_MUTEX_UNLOCK(&mutex1);
}
grib_file* grib_get_file(const char* filename,int* err)
{
grib_file* file=NULL;
grib_file* file=NULL;
if (file_pool.current->name && !grib_inline_strcmp(filename,file_pool.current->name)) {
return file_pool.current;
}
if (file_pool.current->name && !grib_inline_strcmp(filename,file_pool.current->name)) {
return file_pool.current;
}
file=file_pool.first;
while (file) {
if (!grib_inline_strcmp(filename,file->name)) break;
file=file->next;
}
if (!file) file=grib_file_new(0,filename,err);
file=file_pool.first;
while (file) {
if (!grib_inline_strcmp(filename,file->name)) break;
file=file->next;
}
if (!file) file=grib_file_new(0,filename,err);
return file;
return file;
}
grib_file* grib_find_file(short id)
{
grib_file* file=NULL;
grib_file* file=NULL;
if (file_pool.current->name && id==file_pool.current->id) {
return file_pool.current;
}
if (file_pool.current->name && id==file_pool.current->id) {
return file_pool.current;
}
file=file_pool.first;
while (file) {
if (id==file->id) break;
file=file->next;
}
file=file_pool.first;
while (file) {
if (id==file->id) break;
file=file->next;
}
return file;
return file;
}
grib_file* grib_file_new(grib_context* c, const char* name, int* err)
{
grib_file* file;
grib_file* file;
if (!c) c=grib_context_get_default( );
if (!c) c=grib_context_get_default( );
file=(grib_file*)grib_context_malloc_clear( c,sizeof(grib_file));
file=(grib_file*)grib_context_malloc_clear( c,sizeof(grib_file));
if (!file) {
grib_context_log(c,GRIB_LOG_ERROR,"grib_file_new: unable to allocate memory");
*err=GRIB_OUT_OF_MEMORY;
return NULL;
}
GRIB_PTHREAD_ONCE(&once,&init);
if (!file) {
grib_context_log(c,GRIB_LOG_ERROR,"grib_file_new: unable to allocate memory");
*err=GRIB_OUT_OF_MEMORY;
return NULL;
}
GRIB_PTHREAD_ONCE(&once,&init);
file->name=strdup(name);
file->id=next_id;
file->name=strdup(name);
file->id=next_id;
GRIB_MUTEX_LOCK(&mutex1);
next_id++;
GRIB_MUTEX_UNLOCK(&mutex1);
GRIB_MUTEX_LOCK(&mutex1);
next_id++;
GRIB_MUTEX_UNLOCK(&mutex1);
file->mode=0;
file->handle=0;
file->refcount=0;
file->context=c;
file->next=0;
file->buffer=0;
return file;
file->mode=0;
file->handle=0;
file->refcount=0;
file->context=c;
file->next=0;
file->buffer=0;
return file;
}
void grib_file_delete(grib_file* file)
{
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
if (!file) return;
if(file->name) free(file->name);
if (file->mode) free(file->mode);
if (file->handle) {
fclose(file->handle);
}
if (file->buffer) {
free(file->buffer);
}
grib_context_free(file->context,file);
file=NULL;
GRIB_MUTEX_UNLOCK(&mutex1);
GRIB_PTHREAD_ONCE(&once,&init);
GRIB_MUTEX_LOCK(&mutex1);
if (!file) return;
if (file->handle) {
if (fclose(file->handle) != 0) {
perror(file->name);
}
}
if (file->name) free(file->name);
if (file->mode) free(file->mode);
if (file->buffer) {
free(file->buffer);
}
grib_context_free(file->context,file);
file=NULL;
GRIB_MUTEX_UNLOCK(&mutex1);
}

View File

@ -907,7 +907,7 @@ int grib_index_search_same(grib_index* index, grib_handle* h)
}
int grib_index_add_file(grib_index* index,const char* filename) {
return _codes_index_add_file(index,filename,CODES_GRIB);
return _codes_index_add_file(index,filename,CODES_GRIB);
}
grib_handle* new_message_from_file(int message_type, grib_context *c, FILE *f, int *error)
@ -922,155 +922,157 @@ grib_handle* new_message_from_file(int message_type, grib_context *c, FILE *f, i
int _codes_index_add_file(grib_index* index,const char* filename,int message_type)
{
double dval;
size_t svallen;
long length,lval;
char buf[1024]={0,};
int err=0;
grib_file* indfile;
grib_file* newfile;
double dval;
size_t svallen;
long length,lval;
char buf[1024]={0,};
int err=0;
grib_file* indfile;
grib_file* newfile;
grib_index_key* index_key=NULL;
grib_handle* h=NULL;
grib_field* field;
grib_field_tree* field_tree;
grib_file* file=NULL;
grib_context* c;
grib_index_key* index_key=NULL;
grib_handle* h=NULL;
grib_field* field;
grib_field_tree* field_tree;
grib_file* file=NULL;
grib_context* c;
if (!index) return GRIB_NULL_INDEX;
c=index->context;
c=index->context;
file=grib_file_open(filename,"r",&err);
file=grib_file_open(filename,"r",&err);
if (!file || !file->handle) return err;
if (!file || !file->handle) return err;
if (!index->files) {
grib_filesid++;
newfile=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
newfile->id=grib_filesid;
newfile->name=strdup(file->name);
index->files=newfile;
} else {
indfile=index->files;
while(indfile) {
if (!strcmp(indfile->name,file->name)) return 0;
indfile=indfile->next;
}
indfile=index->files;
while(indfile->next) indfile=indfile->next;
grib_filesid++;
newfile=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
newfile->id=grib_filesid;
newfile->name=strdup(file->name);
indfile->next=newfile;
}
if (!index->files) {
grib_filesid++;
newfile=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
newfile->id=grib_filesid;
newfile->name=strdup(file->name);
newfile->handle = file->handle;
index->files=newfile;
} else {
indfile=index->files;
while(indfile) {
if (!strcmp(indfile->name,file->name)) return 0;
indfile=indfile->next;
}
indfile=index->files;
while(indfile->next) indfile=indfile->next;
grib_filesid++;
newfile=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
newfile->id=grib_filesid;
newfile->name=strdup(file->name);
newfile->handle = file->handle;
indfile->next=newfile;
}
fseeko(file->handle,0,SEEK_SET);
fseeko(file->handle,0,SEEK_SET);
while ((h=new_message_from_file(message_type, c, file->handle, &err))!=NULL) {
grib_string_list* v=0;
index_key=index->keys;
field_tree=index->fields;
index_key->value[0]=0;
while ((h=new_message_from_file(message_type, c, file->handle, &err))!=NULL) {
grib_string_list* v=0;
index_key=index->keys;
field_tree=index->fields;
index_key->value[0]=0;
while (index_key) {
if (index_key->type==GRIB_TYPE_UNDEFINED) {
err=grib_get_native_type(h,index_key->name,&(index_key->type));
if (err) index_key->type=GRIB_TYPE_STRING;
}
svallen=1024;
switch (index_key->type) {
case GRIB_TYPE_STRING:
err=grib_get_string(h,index_key->name,buf,&svallen);
if (err==GRIB_NOT_FOUND) sprintf(buf,GRIB_KEY_UNDEF);
break;
case GRIB_TYPE_LONG:
err=grib_get_long(h,index_key->name,&lval);
if (err==GRIB_NOT_FOUND) sprintf(buf,GRIB_KEY_UNDEF);
else sprintf(buf,"%ld",lval);
break;
case GRIB_TYPE_DOUBLE:
err=grib_get_double(h,index_key->name,&dval);
if (err==GRIB_NOT_FOUND) sprintf(buf,GRIB_KEY_UNDEF);
else sprintf(buf,"%g",dval);
break;
default :
err=GRIB_WRONG_TYPE;
return err;
}
if (err && err != GRIB_NOT_FOUND) {
grib_context_log(c,GRIB_LOG_ERROR,"unable to create index. \"%s\": %s",index_key->name,grib_get_error_message(err));
return err;
}
while (index_key) {
if (index_key->type==GRIB_TYPE_UNDEFINED) {
err=grib_get_native_type(h,index_key->name,&(index_key->type));
if (err) index_key->type=GRIB_TYPE_STRING;
}
svallen=1024;
switch (index_key->type) {
case GRIB_TYPE_STRING:
err=grib_get_string(h,index_key->name,buf,&svallen);
if (err==GRIB_NOT_FOUND) sprintf(buf,GRIB_KEY_UNDEF);
break;
case GRIB_TYPE_LONG:
err=grib_get_long(h,index_key->name,&lval);
if (err==GRIB_NOT_FOUND) sprintf(buf,GRIB_KEY_UNDEF);
else sprintf(buf,"%ld",lval);
break;
case GRIB_TYPE_DOUBLE:
err=grib_get_double(h,index_key->name,&dval);
if (err==GRIB_NOT_FOUND) sprintf(buf,GRIB_KEY_UNDEF);
else sprintf(buf,"%g",dval);
break;
default :
err=GRIB_WRONG_TYPE;
return err;
}
if (err && err != GRIB_NOT_FOUND) {
grib_context_log(c,GRIB_LOG_ERROR,"unable to create index. \"%s\": %s",index_key->name,grib_get_error_message(err));
return err;
}
if (!index_key->values->value) {
index_key->values->value=grib_context_strdup(c,buf);
index_key->values_count++;
} else {
v=index_key->values;
while (v->next && strcmp(v->value,buf)) v=v->next;
if (strcmp(v->value,buf)) {
index_key->values_count++;
if (v->next) v=v->next;
v->next=(grib_string_list*)grib_context_malloc_clear(c,sizeof(grib_string_list));
v->next->value=grib_context_strdup(c,buf);
}
}
if (!index_key->values->value) {
index_key->values->value=grib_context_strdup(c,buf);
index_key->values_count++;
} else {
v=index_key->values;
while (v->next && strcmp(v->value,buf)) v=v->next;
if (strcmp(v->value,buf)) {
index_key->values_count++;
if (v->next) v=v->next;
v->next=(grib_string_list*)grib_context_malloc_clear(c,sizeof(grib_string_list));
v->next->value=grib_context_strdup(c,buf);
}
}
if (!field_tree->value) {
field_tree->value=grib_context_strdup(c,buf);
} else {
while (field_tree->next &&
(field_tree->value==NULL ||
strcmp(field_tree->value,buf)))
field_tree=field_tree->next;
if (!field_tree->value) {
field_tree->value=grib_context_strdup(c,buf);
} else {
while (field_tree->next &&
(field_tree->value==NULL ||
strcmp(field_tree->value,buf)))
field_tree=field_tree->next;
if (!field_tree->value || strcmp(field_tree->value,buf)){
field_tree->next=
(grib_field_tree*)grib_context_malloc_clear(c,
sizeof(grib_field_tree));
field_tree=field_tree->next;
field_tree->value=grib_context_strdup(c,buf);
}
}
if (!field_tree->value || strcmp(field_tree->value,buf)){
field_tree->next=
(grib_field_tree*)grib_context_malloc_clear(c,
sizeof(grib_field_tree));
field_tree=field_tree->next;
field_tree->value=grib_context_strdup(c,buf);
}
}
if (index_key->next) {
if (!field_tree->next_level) {
field_tree->next_level=
(grib_field_tree*)grib_context_malloc_clear(c,sizeof(grib_field_tree));
}
field_tree=field_tree->next_level;
}
index_key=index_key->next;
}
if (index_key->next) {
if (!field_tree->next_level) {
field_tree->next_level=
(grib_field_tree*)grib_context_malloc_clear(c,sizeof(grib_field_tree));
}
field_tree=field_tree->next_level;
}
index_key=index_key->next;
}
field=(grib_field*)grib_context_malloc_clear(c,sizeof(grib_field));
field->file=file;
index->count++;
field->offset=h->offset;;
field=(grib_field*)grib_context_malloc_clear(c,sizeof(grib_field));
field->file=file;
index->count++;
field->offset=h->offset;;
err=grib_get_long(h,"totalLength",&length);
if (err) return err;
field->length=length;
err=grib_get_long(h,"totalLength",&length);
if (err) return err;
field->length=length;
if (field_tree->field) {
grib_field* pfield=field_tree->field;
while (pfield->next) pfield=pfield->next;
pfield->next=field;
} else
field_tree->field=field;
if (field_tree->field) {
grib_field* pfield=field_tree->field;
while (pfield->next) pfield=pfield->next;
pfield->next=field;
} else
field_tree->field=field;
if (h) grib_handle_delete(h);
if (h) grib_handle_delete(h);
}
}
grib_file_close(file->name,&err);
grib_file_close(file->name,&err);
if (err) return err;
index->rewind=1;
return GRIB_SUCCESS;
if (err) return err;
index->rewind=1;
return GRIB_SUCCESS;
}
#if 0
@ -1103,6 +1105,7 @@ int grib_index_add_file(grib_index* index, const char* filename)
newfile=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
newfile->id=grib_filesid;
newfile->name=strdup(file->name);
newfile->handle = file->handle;
index->files=newfile;
} else {
indfile=index->files;
@ -1116,6 +1119,7 @@ int grib_index_add_file(grib_index* index, const char* filename)
newfile=(grib_file*)grib_context_malloc_clear(c,sizeof(grib_file));
newfile->id=grib_filesid;
newfile->name=strdup(file->name);
newfile->handle = file->handle;
indfile->next=newfile;
}
@ -1432,36 +1436,36 @@ int grib_index_select_string(grib_index* index,const char* skey,char* value)
}
grib_handle* grib_index_get_handle(grib_field* field,int *err) {
return codes_index_get_handle(field,CODES_GRIB,err);
return codes_index_get_handle(field,CODES_GRIB,err);
}
grib_handle* codes_index_get_handle(grib_field* field,int message_type,int *err)
{
grib_handle* h=NULL;
typedef grib_handle* (*message_new_proc) ( grib_context*,FILE*,int,int* );
message_new_proc message_new=NULL;
Assert(field->file);
grib_file_open(field->file->name,"r",err);
grib_handle* h=NULL;
typedef grib_handle* (*message_new_proc) ( grib_context*,FILE*,int,int* );
message_new_proc message_new=NULL;
Assert(field->file);
grib_file_open(field->file->name,"r",err);
if (*err!=GRIB_SUCCESS) return NULL;
switch (message_type) {
case CODES_GRIB:
message_new=grib_new_from_file;
break;
case CODES_BUFR:
Assert(!"_codes_index_add_file for BUFR: not yet implemented");
/* message_new=bufr_new_from_file; */
break;
default :
Assert(0);
}
if (*err!=GRIB_SUCCESS) return NULL;
switch (message_type) {
case CODES_GRIB:
message_new=grib_new_from_file;
break;
case CODES_BUFR:
Assert(!"_codes_index_add_file for BUFR: not yet implemented");
/* message_new=bufr_new_from_file; */
break;
default :
Assert(0);
}
fseeko(field->file->handle,field->offset,SEEK_SET);
h=message_new(0,field->file->handle,0,err);
if (*err!=GRIB_SUCCESS) return NULL;
fseeko(field->file->handle,field->offset,SEEK_SET);
h=message_new(0,field->file->handle,0,err);
if (*err!=GRIB_SUCCESS) return NULL;
grib_file_close(field->file->name,err);
return h;
grib_file_close(field->file->name,err);
return h;
}
static int grib_index_execute(grib_index* index)
@ -1540,9 +1544,9 @@ static void grib_dump_field(FILE* fout, grib_field* field)
if (!field) return;
fprintf(fout, "field name = %s\n", field->file->name);
/*fprintf(fout, "field FID = %d\n", field->file->id);
* fprintf(fout, "field offset = %ld\n", field->offset);
* fprintf(fout, "field length = %ld\n", field->length);
*/
* fprintf(fout, "field offset = %ld\n", field->offset);
* fprintf(fout, "field length = %ld\n", field->length);
*/
grib_dump_field(fout, field->next);
}
@ -1569,7 +1573,7 @@ int grib_index_dump_file(FILE* fout, const char* filename)
Assert(filename);
index = grib_index_read(c, filename, &err);
if (err) return err;
/* To get the GRIB files referenced we have */
/* to resort to low level reading of the index file! */
fh=fopen(filename,"r");
@ -1592,10 +1596,10 @@ int grib_index_dump_file(FILE* fout, const char* filename)
}
fclose(fh);
}
grib_index_dump(fout, index);
grib_index_delete(index);
return GRIB_SUCCESS;
}
@ -1612,9 +1616,9 @@ void grib_index_dump(FILE* fout, grib_index* index)
grib_dump_index_keys(fout, index->keys);
/*
* fprintf(fout, "Index field tree:\n");
* grib_dump_field_tree(fout, index->fields);
*/
* fprintf(fout, "Index field tree:\n");
* grib_dump_field_tree(fout, index->fields);
*/
fprintf(fout, "Index count = %d\n", index->count);
}
@ -1631,68 +1635,68 @@ char* grib_get_field_file(grib_index* index,off_t *offset)
grib_handle* grib_handle_new_from_index(grib_index* index,int *err)
{
return codes_new_from_index(index,CODES_GRIB,err);
return codes_new_from_index(index,CODES_GRIB,err);
}
grib_handle* codes_new_from_index(grib_index* index,int message_type,int *err)
{
grib_index_key* keys;
grib_field_list *fieldset,*next;
grib_handle* h=NULL;
grib_context* c=NULL;
grib_index_key* keys;
grib_field_list *fieldset,*next;
grib_handle* h=NULL;
grib_context* c=NULL;
if (!index) return NULL;
c=index->context;
if (!index->rewind) {
if (!index->current) {
*err=GRIB_END_OF_INDEX;
return NULL;
}
if (!index) return NULL;
c=index->context;
if (!index->rewind) {
if (!index->current) {
*err=GRIB_END_OF_INDEX;
return NULL;
}
if (index->current->field->next)
index->current->field=index->current->field->next;
else if(index->current->next)
index->current=index->current->next;
else {*err=GRIB_END_OF_INDEX;return NULL;}
if (index->current->field->next)
index->current->field=index->current->field->next;
else if(index->current->next)
index->current=index->current->next;
else {*err=GRIB_END_OF_INDEX;return NULL;}
h=codes_index_get_handle(index->current->field,message_type,err);
return h;
}
h=codes_index_get_handle(index->current->field,message_type,err);
return h;
}
if (!index->fieldset) {
index->fieldset=(grib_field_list*)grib_context_malloc_clear(index->context,
sizeof(grib_field_list));
if (!index->fieldset) {
grib_context_log(index->context,GRIB_LOG_ERROR,
"unable to allocate %d bytes",
sizeof(grib_field_list));
return NULL;
}
index->current=index->fieldset;
} else {
fieldset=index->fieldset;
while(fieldset->next) {
next=fieldset->next;
grib_context_free(c,fieldset);
fieldset=next;
}
fieldset->field=NULL;
fieldset->next=NULL;
index->fieldset=fieldset;
index->current=fieldset;
}
if (!index->fieldset) {
index->fieldset=(grib_field_list*)grib_context_malloc_clear(index->context,
sizeof(grib_field_list));
if (!index->fieldset) {
grib_context_log(index->context,GRIB_LOG_ERROR,
"unable to allocate %d bytes",
sizeof(grib_field_list));
return NULL;
}
index->current=index->fieldset;
} else {
fieldset=index->fieldset;
while(fieldset->next) {
next=fieldset->next;
grib_context_free(c,fieldset);
fieldset=next;
}
fieldset->field=NULL;
fieldset->next=NULL;
index->fieldset=fieldset;
index->current=fieldset;
}
*err=GRIB_END_OF_INDEX;
h=NULL;
keys=index->keys;
*err=GRIB_END_OF_INDEX;
h=NULL;
keys=index->keys;
if ((*err=grib_index_execute(index))==GRIB_SUCCESS) {
if ((*err=grib_index_execute(index))==GRIB_SUCCESS) {
if (!index->fieldset) {*err=GRIB_END_OF_INDEX;return NULL;}
index->current=index->fieldset;
h=codes_index_get_handle(index->current->field,message_type,err);
}
return h;
if (!index->fieldset) {*err=GRIB_END_OF_INDEX;return NULL;}
index->current=index->fieldset;
h=codes_index_get_handle(index->current->field,message_type,err);
}
return h;
}
void grib_index_rewind(grib_index* index)