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__);
233 ft.transform_to_jpeg2000();
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);
void set_dds(libdap::DDS *ddsIn)
exception thrown if inernal error encountered
std::string get_name() const
static void conditional_timeout_cancel()
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
virtual string get_context(const string &name, bool &found)
retrieve the value of the specified context from the BES
Abstract exception class for the BES with basic string message.
static TheBESKeys * TheKeys()
error object created from libdap error objects and can handle those errors
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
JPEG2000Transmitter()
Construct the JPEG2000Transmitter, adding it with name geotiff to be able to transmit a data response...
Structure storing information used by the BES to handle the request.
static void send_data_as_jp2(BESResponseObject *obj, BESDataHandlerInterface &dhi)
The static method registered to transmit OPeNDAP data objects as a netcdf file.
map< string, string > data
the map of string data that will be required for the current request.
Abstract base class representing a specific set of information in response to a request to the BES.
Get a new temporary file.