32 #include <sys/types.h>
44 #include "JPEG2000Transmitter.h"
45 #include "FONgTransform.h"
48 #include <BESInternalError.h>
49 #include <BESDapError.h>
50 #include <BESContextManager.h>
51 #include <BESDataDDSResponse.h>
52 #include <BESDapNames.h>
53 #include <BESDataNames.h>
56 #include <DapFunctionUtils.h>
58 #include <TheBESKeys.h>
60 #define JPEG2000_TEMP_DIR "/tmp"
61 #define JPEG2000_GCS "WGS84"
63 string JPEG2000Transmitter::temp_dir;
64 string JPEG2000Transmitter::default_gcs;
87 if (JPEG2000Transmitter::temp_dir.empty()) {
90 string key =
"JPEG2000.Tempdir";
92 if (!found || JPEG2000Transmitter::temp_dir.empty()) {
93 JPEG2000Transmitter::temp_dir = JPEG2000_TEMP_DIR;
95 string::size_type len = JPEG2000Transmitter::temp_dir.length();
96 if (JPEG2000Transmitter::temp_dir[len - 1] ==
'/') {
97 JPEG2000Transmitter::temp_dir = JPEG2000Transmitter::temp_dir.substr(0, len - 1);
101 if (JPEG2000Transmitter::default_gcs.empty()) {
104 string key =
"JPEG2000.Default_GCS";
106 if (!found || JPEG2000Transmitter::default_gcs.empty()) {
107 JPEG2000Transmitter::default_gcs = JPEG2000_GCS;
134 DDS *dds = bdds->get_dds();
136 throw BESInternalError(
"No DataDDS has been created for transmit", __FILE__, __LINE__);
138 ostream &strm = dhi.get_output_stream();
140 throw BESInternalError(
"Output stream is not set, cannot return as", __FILE__, __LINE__);
142 BESDEBUG(
"JPEG20002",
"JPEG2000Transmitter::send_data - parsing the constraint" << endl);
145 string ce = www2id(dhi.
data[POST_CONSTRAINT],
"%",
"%20%26");
147 bdds->get_ce().parse_constraint(ce, *dds);
150 throw BESDapError(
"Failed to parse the constraint expression: " + e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
153 throw BESInternalError(
"Failed to parse the constraint expression: Unknown exception caught", __FILE__, __LINE__);
157 BESDEBUG(
"JPEG20002",
"JPEG2000Transmitter::send_data - reading data into DataDDS" << endl);
159 bes::TempFile temp_file(JPEG2000Transmitter::temp_dir +
'/' +
"jp2XXXXXX");
163 string temp_file_name = JPEG2000Transmitter::temp_dir +
'/' +
"jp2XXXXXX";
164 vector<char> temp_file(temp_file_name.length() + 1);
165 string::size_type len = temp_file_name.copy(&temp_file[0], temp_file_name.length());
166 temp_file[len] =
'\0';
170 mode_t original_mode = umask(077);
173 int fd = mkstemp(&temp_file[0]);
174 umask(original_mode);
177 throw BESInternalError(
"Failed to open the temporary file: " + temp_file_name, __FILE__, __LINE__);
180 BESDEBUG(
"JPEG20002",
"JPEG2000Transmitter::send_data - transforming into temporary file " << temp_file.get_name() << endl);
185 if (bdds->get_ce().function_clauses()) {
186 BESDEBUG(
"fong2",
"processing a functional constraint clause(s)." << endl);
187 DDS *tmp_dds = bdds->get_ce().eval_function_clauses(*dds);
201 promote_function_output_structures(dds);
207 for (DDS::Vars_iter i = dds->var_begin(); i != dds->var_end(); i++) {
208 if ((*i)->send_p()) {
209 (*i)->intern_data(bdds->get_ce(), *dds);
216 throw BESDapError(
"Failed to read data: " + e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
222 throw BESInternalError(
"Failed to read data: Unknown exception caught", __FILE__, __LINE__);
235 BESDEBUG(
"JPEG20002",
"JPEG2000Transmitter::send_data - transmitting temp file " << temp_file.get_name() << endl );
237 JPEG2000Transmitter::return_temp_stream(temp_file.get_name(), strm);
242 (void) unlink(&temp_file[0]);
244 throw BESDapError(
"Failed to transform data to JPEG2000: " + e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
249 (void) unlink(&temp_file[0]);
256 (void) unlink(&temp_file[0]);
258 throw BESInternalError(
"Fileout GeoTiff, was not able to transform to JPEG2000, unknown error", __FILE__, __LINE__);
263 (void) unlink(&temp_file[0]);
266 BESDEBUG(
"JPEG20002",
"JPEG2000Transmitter::send_data - done transmitting to jp2" << endl);
278 void JPEG2000Transmitter::return_temp_stream(
const string &filename, ostream &strm)
281 os.open(filename.c_str(), ios::binary | ios::in);
283 throw BESInternalError(
"Cannot connect to data source", __FILE__, __LINE__);
286 os.read(block,
sizeof block);
287 int nbytes = os.gcount();
290 throw BESInternalError(
"Internal server error, got zero count on stream buffer.", __FILE__, __LINE__);
294 string context =
"transmit_protocol";
295 string protocol = BESContextManager::TheManager()->
get_context(context, found);
296 if (protocol ==
"HTTP") {
297 strm <<
"HTTP/1.0 200 OK\n";
298 strm <<
"Content-type: application/octet-stream\n";
299 strm <<
"Content-Description: " <<
"BES dataset" <<
"\n";
300 strm <<
"Content-Disposition: filename=" << filename <<
".jp2;\n\n";
303 strm.write(block, nbytes);
306 os.read(block,
sizeof block);
307 nbytes = os.gcount();
308 strm.write(block, nbytes);