eccodes/tools/grib_repair.c

115 lines
2.1 KiB
C

/*
* Copyright 2005-2015 ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
*
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
*/
#include "grib_api_internal.h"
static void usage(const char* name) {
fprintf(stderr,"Usage: %s in out [bad]\n", name);
exit(1);
}
#define SIZE 50*1024*1024
char buffer[SIZE];
int main(int argc,char **argv) {
FILE* in, *out, *bad;
char *cin, *cout, *cbad;
size_t data_len = SIZE;
long count = 0;
unsigned char *data;
if(argc != 3 && argc != 4) usage(argv[0]);
cin = argv[1];
in = fopen(argv[1],"r");
if(!in) {
perror(argv[1]);
exit(1);
}
cout = argv[2];
out = fopen(argv[2],"w");
if(!out) {
perror(argv[2]);
exit(1);
}
if(argc == 4) {
cbad = argv[3];
bad = fopen(argv[3],"w");
if(!bad) {
perror(argv[3]);
exit(1);
}
}
else {
bad = out;
cbad = cout;
}
for(;;) {
size_t len = SIZE;
long ret = wmo_read_grib_from_file(in,buffer,&len);
if(ret == GRIB_END_OF_FILE && len == 0)
break;
printf("GRIB %ld: size: %ld code: %ld (%s)\n", ++count, (long)len, ret, grib_get_error_message(ret));
switch(ret) {
case 0:
if(fwrite(buffer,1,len,out) != len) {
perror(cout);
exit(1);
}
break;
case GRIB_WRONG_LENGTH:
case GRIB_PREMATURE_END_OF_FILE:
fseek(in,-4,SEEK_CUR);
memset(buffer + len - 4, '7', 4);
len = data_len = SIZE;
data = (unsigned char*)&buffer[0];
ret = grib_read_any_from_memory(NULL, &data, &data_len, buffer, &len);
printf(" -> GRIB %ld: size: %ld code: %ld (%s)\n", count, (long)len, ret, grib_get_error_message(ret));
if(ret == 0) {
if(fwrite(buffer,1,len,bad) != len) {
perror(cbad);
exit(1);
}
}
break;
}
}
if(fclose(in)) {
perror(argv[1]);
exit(1);
}
if(fclose(out)) {
perror(argv[2]);
exit(1);
}
if(argc == 4) {
if(fclose(bad)) {
perror(argv[3]);
exit(1);
}
}
return 0;
}