/* * Convert rows from internal to db API representation */ int convert_rows(db_con_t* _h, db_res_t* _r) { int n, i; dbt_row_p _rp = NULL; if ((!_h) || (!_r)) { #ifdef DBT_EXTRA_DEBUG LOG(L_ERR, "DBT:convert_rows: Invalid parameter\n"); #endif return -1; } n = DBT_CON_RESULT(_h)->nrrows; RES_ROW_N(_r) = n; if (!n) { RES_ROWS(_r) = 0; return 0; } RES_ROWS(_r) = (struct db_row*)pkg_malloc(sizeof(db_row_t) * n); if (!RES_ROWS(_r)) { LOG(L_ERR, "DBT:convert_rows: No memory left\n"); return -2; } i = 0; _rp = DBT_CON_RESULT(_h)->rows; while(_rp) { DBT_CON_ROW(_h) = _rp; if (!DBT_CON_ROW(_h)) { LOG(L_ERR, "DBT:convert_rows: error getting current row\n"); RES_ROW_N(_r) = i; free_rows(_r); return -3; } if (convert_row(_h, _r, &(RES_ROWS(_r)[i])) < 0) { LOG(L_ERR, "DBT:convert_rows: Error while converting row #%d\n", i); RES_ROW_N(_r) = i; free_rows(_r); return -4; } i++; _rp = _rp->next; } return 0; }
/* * Get rows and convert it from oracle to db API representation */ static int get_rows(ora_con_t* con, db_res_t* _r, OCIStmt* _c, dmap_t* _d) { ub4 rcnt; sword status; unsigned n = RES_COL_N(_r); memcpy(_d->len, _d->ilen, sizeof(_d->len[0]) * n); // timelimited operation status = begin_timelimit(con, 0); if (status != OCI_SUCCESS) goto ora_err; do status = OCIStmtFetch2(_c, con->errhp, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT); while (wait_timelimit(con, status)); if (done_timelimit(con, status)) goto stop_load; if (status != OCI_SUCCESS) { if (status != OCI_NO_DATA) goto ora_err; RES_ROW_N(_r) = 0; RES_ROWS(_r) = NULL; return 0; } status = OCIAttrGet(_c, OCI_HTYPE_STMT, &rcnt, NULL, OCI_ATTR_CURRENT_POSITION, con->errhp); if (status != OCI_SUCCESS) goto ora_err; if (!rcnt) { LM_ERR("lastpos==0\n"); goto stop_load; } RES_ROW_N(_r) = rcnt; if (db_allocate_rows( _r, rcnt)!=0) { LM_ERR("no private memory left\n"); return -1; } while ( 1 ) { if (convert_row(_r, &RES_ROWS(_r)[--rcnt], _d) < 0) { LM_ERR("error convert row\n"); goto stop_load; } if (!rcnt) return 0; memcpy(_d->len, _d->ilen, sizeof(_d->len[0]) * n); // timelimited operation status = begin_timelimit(con, 0); if (status != OCI_SUCCESS) goto ora_err; do status = OCIStmtFetch2(_c, con->errhp, 1, OCI_FETCH_PRIOR, 0, OCI_DEFAULT); while (wait_timelimit(con, status)); if (done_timelimit(con, status)) goto stop_load; if (status != OCI_SUCCESS) break; } ora_err: LM_ERR("driver: %s\n", db_oracle_error(con, status)); stop_load: db_free_rows(_r); RES_ROW_N(_r) = 0; /* TODO: skipped in db_res.c :) */ return -3; }
int main(int argc, char *argv[]) { struct GModule *module; struct { struct Option *input; struct Option *output; struct Option *null; struct Option *bytes; struct Option *order; } parm; struct { struct Flag *int_out; struct Flag *float_out; struct Flag *gmt_hd; struct Flag *bil_hd; struct Flag *swap; } flag; char *name; char *outfile; double null_val; int do_stdout; int is_fp; int bytes; int order; int swap_flag; struct Cell_head region; int nrows, ncols; DCELL *in_buf; unsigned char *out_buf; int fd; FILE *fp; struct GRD_HEADER header; int row; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("export")); module->description = _("Exports a GRASS raster to a binary array."); /* Define the different options */ parm.input = G_define_option(); parm.input->key = "input"; parm.input->type = TYPE_STRING; parm.input->required = YES; parm.input->gisprompt = "old,cell,raster"; parm.input->description = _("Name of input raster map"); parm.output = G_define_option(); parm.output->key = "output"; parm.output->type = TYPE_STRING; parm.output->required = NO; parm.output->description = _("Name for output binary map (use output=- for stdout)"); parm.null = G_define_option(); parm.null->key = "null"; parm.null->type = TYPE_DOUBLE; parm.null->required = NO; parm.null->answer = "0"; parm.null->description = _("Value to write out for null"); parm.bytes = G_define_option(); parm.bytes->key = "bytes"; parm.bytes->type = TYPE_INTEGER; parm.bytes->required = NO; parm.bytes->options = "1,2,4,8"; parm.bytes->description = _("Number of bytes per cell"); parm.order = G_define_option(); parm.order->key = "order"; parm.order->type = TYPE_STRING; parm.order->required = NO; parm.order->options = "big,little,native,swap"; parm.order->description = _("Output byte order"); parm.order->answer = "native"; flag.int_out = G_define_flag(); flag.int_out->key = 'i'; flag.int_out->description = _("Generate integer output"); flag.float_out = G_define_flag(); flag.float_out->key = 'f'; flag.float_out->description = _("Generate floating-point output"); flag.gmt_hd = G_define_flag(); flag.gmt_hd->key = 'h'; flag.gmt_hd->description = _("Export array with GMT compatible header"); flag.bil_hd = G_define_flag(); flag.bil_hd->key = 'b'; flag.bil_hd->description = _("Generate BIL world and header files"); flag.swap = G_define_flag(); flag.swap->key = 's'; flag.swap->description = _("Byte swap output"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (sscanf(parm.null->answer, "%lf", &null_val) != 1) G_fatal_error(_("Invalid value for null (integers only)")); name = parm.input->answer; if (parm.output->answer) outfile = parm.output->answer; else { outfile = G_malloc(strlen(name) + 4 + 1); sprintf(outfile, "%s.bin", name); } if (G_strcasecmp(parm.order->answer, "big") == 0) order = 0; else if (G_strcasecmp(parm.order->answer, "little") == 0) order = 1; else if (G_strcasecmp(parm.order->answer, "native") == 0) order = G_is_little_endian() ? 1 : 0; else if (G_strcasecmp(parm.order->answer, "swap") == 0) order = G_is_little_endian() ? 0 : 1; if (flag.swap->answer) { if (strcmp(parm.order->answer, "native") != 0) G_fatal_error(_("order= and -s are mutually exclusive")); order = G_is_little_endian() ? 0 : 1; } swap_flag = order == (G_is_little_endian() ? 0 : 1); do_stdout = strcmp("-", outfile) == 0; if (flag.int_out->answer && flag.float_out->answer) G_fatal_error(_("-i and -f are mutually exclusive")); fd = Rast_open_old(name, ""); if (flag.int_out->answer) is_fp = 0; else if (flag.float_out->answer) is_fp = 1; else is_fp = Rast_get_map_type(fd) != CELL_TYPE; if (parm.bytes->answer) bytes = atoi(parm.bytes->answer); else if (is_fp) bytes = 4; else bytes = 2; if (is_fp && bytes < 4) G_fatal_error(_("Floating-point output requires bytes=4 or bytes=8")); #ifndef HAVE_LONG_LONG_INT if (!is_fp && bytes > 4) G_fatal_error(_("Integer output doesn't support bytes=8 in this build")); #endif G_get_window(®ion); /* open bin file for writing */ if (do_stdout) fp = stdout; else if (NULL == (fp = fopen(outfile, "w"))) G_fatal_error(_("Unable to create file <%s>"), outfile); /* Set up Parameters for GMT header */ if (flag.gmt_hd->answer) { if (!is_fp && bytes > 4) G_fatal_error(_("GMT grid doesn't support 64-bit integers")); make_gmt_header(&header, name, outfile, ®ion, null_val); } /* Write out BIL support files compatible with Arc-View */ if (flag.bil_hd->answer) { G_message(_("Creating BIL support files...")); write_bil_hdr(outfile, ®ion, bytes, order, flag.gmt_hd->answer, null_val); write_bil_wld(outfile, ®ion); } /* Write out GMT Header if required */ if (flag.gmt_hd->answer) write_gmt_header(&header, swap_flag, fp); nrows = Rast_window_rows(); ncols = Rast_window_cols(); in_buf = Rast_allocate_d_buf(); out_buf = G_malloc(ncols * bytes); if (is_fp) { G_message(_("Exporting raster as floating values (bytes=%d)"), bytes); if (flag.gmt_hd->answer) G_message(_("Writing GMT float format ID=1")); } else { G_message(_("Exporting raster as integer values (bytes=%d)"), bytes); if (flag.gmt_hd->answer) G_message(_("Writing GMT integer format ID=2")); } G_verbose_message(_("Using the current region settings...")); G_verbose_message(_("north=%f"), region.north); G_verbose_message(_("south=%f"), region.south); G_verbose_message(_("east=%f"), region.east); G_verbose_message(_("west=%f"), region.west); G_verbose_message(_("r=%d"), region.rows); G_verbose_message(_("c=%d"), region.cols); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_get_d_row(fd, in_buf, row); convert_row(out_buf, in_buf, ncols, is_fp, bytes, swap_flag, null_val); if (fwrite(out_buf, bytes, ncols, fp) != ncols) G_fatal_error(_("Error writing data")); } G_percent(row, nrows, 2); /* finish it off */ Rast_close(fd); fclose(fp); return EXIT_SUCCESS; }