1 /*
2 * (C) Copyright 2005- ECMWF.
3 *
4 * This software is licensed under the terms of the Apache Licence Version 2.0
5 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8 * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9 */
10
11 #include "grib_api_internal.h"
12
13 #if HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16
17 #if 0
18 /* This is a mechanism where we generate C code in grib_templates.h
19 * from our GRIB sample files and then include the header so one
20 * can instantiate samples without any disk access.
21 * This is now superseded by MEMFS
22 */
23 typedef struct grib_templates {
24 const char* name;
25 const unsigned char* data;
26 size_t size;
27 } grib_templates;
28
29 #include "grib_templates.h"
30
31 #define NUMBER(x) (sizeof(x) / sizeof(x[0]))
32
33 grib_handle* grib_internal_sample(grib_context* c,const char* name)
34 {
35 size_t i;
36 const size_t num_samples = NUMBER(templates);
37 Assert(0);
38 for(i = 0; i < num_samples; i++)
39 if(strcmp(name,templates[i].name) == 0)
40 return grib_handle_new_from_message_copy(c,templates[i].data,templates[i].size);
41 return NULL;
42 }
43 #endif
44
45 /* Windows always has a colon in pathnames e.g. C:\temp\file. It uses semi-colons as delimiter */
46 #ifdef ECCODES_ON_WINDOWS
47 #define ECC_PATH_DELIMITER_CHAR ';'
48 #else
49 #define ECC_PATH_DELIMITER_CHAR ':'
50 #endif
51
try_template(grib_context * c,const char * dir,const char * name)52 static grib_handle* try_template(grib_context* c, const char* dir, const char* name)
53 {
54 char path[1024];
55 grib_handle* g = NULL;
56 int err = 0;
57
58 sprintf(path, "%s/%s.tmpl", dir, name);
59
60 if (c->debug) {
61 fprintf(stderr, "ECCODES DEBUG try_template path='%s'\n", path);
62 }
63
64 if (codes_access(path, F_OK) == 0) {
65 FILE* f = codes_fopen(path, "r");
66 if (!f) {
67 grib_context_log(c, GRIB_LOG_PERROR, "cannot open %s", path);
68 return NULL;
69 }
70 g = grib_handle_new_from_file(c, f, &err);
71 if (!g) {
72 grib_context_log(c, GRIB_LOG_ERROR, "cannot create GRIB handle from %s", path);
73 }
74 fclose(f);
75 }
76
77 return g;
78 }
79
try_bufr_template(grib_context * c,const char * dir,const char * name)80 static grib_handle* try_bufr_template(grib_context* c, const char* dir, const char* name)
81 {
82 char path[1024];
83 grib_handle* g = NULL;
84 int err = 0;
85
86 sprintf(path, "%s/%s.tmpl", dir, name);
87
88 if (c->debug) {
89 fprintf(stderr, "ECCODES DEBUG try_template path='%s'\n", path);
90 }
91
92 if (codes_access(path, F_OK) == 0) {
93 FILE* f = codes_fopen(path, "r");
94 if (!f) {
95 grib_context_log(c, GRIB_LOG_PERROR, "cannot open %s", path);
96 return NULL;
97 }
98 g = codes_bufr_handle_new_from_file(c, f, &err);
99 if (!g) {
100 grib_context_log(c, GRIB_LOG_ERROR, "cannot create BUFR handle from %s", path);
101 }
102 fclose(f);
103 }
104
105 return g;
106 }
107
try_template_path(grib_context * c,const char * dir,const char * name)108 static char* try_template_path(grib_context* c, const char* dir, const char* name)
109 {
110 char path[2048];
111
112 sprintf(path, "%s/%s.tmpl", dir, name);
113
114 if (codes_access(path, R_OK) == 0) {
115 return grib_context_strdup(c, path);
116 }
117
118 return NULL;
119 }
120
grib_external_template(grib_context * c,const char * name)121 grib_handle* grib_external_template(grib_context* c, const char* name)
122 {
123 const char* base = c->grib_samples_path;
124 char buffer[1024];
125 char* p = buffer;
126 grib_handle* g = NULL;
127
128 if (!base)
129 return NULL;
130
131 while (*base) {
132 if (*base == ECC_PATH_DELIMITER_CHAR) {
133 *p = 0;
134 g = try_template(c, buffer, name);
135 if (g)
136 return g;
137 p = buffer;
138 base++; /*advance past delimiter*/
139 }
140 *p++ = *base++;
141 }
142
143 *p = 0;
144 return g = try_template(c, buffer, name);
145 }
146
bufr_external_template(grib_context * c,const char * name)147 grib_handle* bufr_external_template(grib_context* c, const char* name)
148 {
149 const char* base = c->grib_samples_path;
150 char buffer[1024];
151 char* p = buffer;
152 grib_handle* g = NULL;
153
154 if (!base)
155 return NULL;
156
157 while (*base) {
158 if (*base == ECC_PATH_DELIMITER_CHAR) {
159 *p = 0;
160 g = try_bufr_template(c, buffer, name);
161 if (g)
162 return g;
163 p = buffer;
164 base++; /*advance past delimiter*/
165 }
166 *p++ = *base++;
167 }
168
169 *p = 0;
170 g = try_bufr_template(c, buffer, name);
171 return g;
172 }
173
grib_external_template_path(grib_context * c,const char * name)174 char* grib_external_template_path(grib_context* c, const char* name)
175 {
176 const char* base = c->grib_samples_path;
177 char buffer[1024];
178 char* p = buffer;
179 char* g = NULL;
180
181 if (!base)
182 return NULL;
183
184 while (*base) {
185 if (*base == ECC_PATH_DELIMITER_CHAR) {
186 *p = 0;
187 g = try_template_path(c, buffer, name);
188 if (g)
189 return g;
190 p = buffer;
191 base++;
192 }
193 *p++ = *base++;
194 }
195
196 *p = 0;
197 return g = try_template_path(c, buffer, name);
198 }
199