1 /*--------------------------------------------------------------------
2  *
3  *	Copyright (c) 1991-2021 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
4  *	See LICENSE.TXT file for copying and redistribution conditions.
5  *
6  *	This program is free software; you can redistribute it and/or modify
7  *	it under the terms of the GNU Lesser General Public License as published by
8  *	the Free Software Foundation; version 3 or any later version.
9  *
10  *	This program is distributed in the hope that it will be useful,
11  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *	GNU Lesser General Public License for more details.
14  *
15  *	Contact info: www.generic-mapping-tools.org
16  *--------------------------------------------------------------------*/
17 
18 /*
19  * THese are the private parts of the GMTAPI_CTRL which we will not expose
20  * to the API users; they are only accessible by GMT developers.
21  *
22  * Author: 	Paul Wessel
23  * Date:	06-FEB-2013
24  * Version:	6 API
25  */
26 
27 /*!
28  * \file gmt_private.h
29  * \brief Private parts of the GMTAPI_CTRL which we will not expose to the API users
30  */
31 
32 #ifndef _GMTAPI_PRIVATE_H
33 #define _GMTAPI_PRIVATE_H
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <stdbool.h>
39 
40 #ifdef __cplusplus /* Basic C++ support */
41 extern "C" {
42 #endif
43 
44 enum GMT_enum_apidim {
45 	GMTAPI_N_GRID_ARGS	= 6,	/* Minimum size of information array used to specify grid parameters */
46 	GMTAPI_N_ARRAY_ARGS	= 8		/* Minimum size of information array used to specify array parameters */
47 };
48 
49 /*! p_func_uint64_t is used as a pointer to functions that returns a uint64_t index */
50 typedef uint64_t (*p_func_uint64_t) (uint64_t row, uint64_t col, uint64_t dim);
51 typedef void (*GMT_putfunction)(union GMT_UNIVECTOR *, uint64_t, double  );
52 typedef void (*GMT_getfunction)(union GMT_UNIVECTOR *, uint64_t, double *);
53 
54 /* Index parameters used to access the information arrays [PW: Is this still relevant?] */
55 
56 #if 0
57 enum GMT_enum_pars {GMTAPI_TYPE = 0,	/* ipar[0] = data type (GMTAPI_{BYTE|SHORT|FLOAT|INT|DOUBLE}) */
58 	GMTAPI_NDIM,		/* ipar[1] = dimensionality of data (1, 2, or 3) (GMT grids = 2 yet stored internally as 1D) */
59 	GMTAPI_NROW,		/* ipar[2] = number_of_rows (or length of 1-D array) */
60 	GMTAPI_NCOL,		/* ipar[3] = number_of_columns (1 for 1-D array) */
61 	GMTAPI_KIND,		/* ipar[4] = arrangement of rows/col (0 = rows (C), 1 = columns (Fortran)) */
62 	GMTAPI_DIML,		/* ipar[5] = length of dimension for row (C) or column (Fortran) */
63 	GMTAPI_FREE,		/* ipar[6] = 1 to free array after use (IN) or before filling with output (OUT), 0 to leave alone */
64 	GMTAPI_NODE};		/* ipar[7] = 1 for pixel registration, 0 for node */
65 #endif
66 
67 /*=====================================================================================
68  *	GMT API STRUCTURE DEFINITIONS
69  *===================================================================================*/
70 
71 struct GMT_CTRL; /* forward declaration of GMT_CTRL */
72 struct GMT_COMMON; /* forward declaration of GMT_COMMON */
73 
74 struct GMTAPI_DATA_OBJECT {
75 	/* Information for each input or output data entity, including information
76 	 * needed while reading/writing from a table (file or array) */
77 	uint64_t rec;				/* Current rec to read [GMT_DATASET to/from MATRIX/VECTOR only] */
78 	uint64_t n_rows;			/* Number or rows in this array [GMT_DATASET to/from MATRIX/VECTOR only] */
79 	uint64_t n_columns;			/* Number of columns to process in this dataset [GMT_DATASET only] */
80 	uint64_t n_expected_fields;		/* Number of expected columns for this dataset [GMT_DATASET only] */
81 	uint64_t delay;				/* Number of leading NaN-records we oculd not write initially before knowning the row dim */
82 	size_t n_alloc;				/* Number of items allocated so far if writing to memory */
83 	unsigned int ID;			/* Unique identifier which is >= 0 */
84 	unsigned int alloc_level;		/* Nested module level when object was allocated */
85 	unsigned int status;			/* 0 when first registered, 1 after reading/writing has started, 2 when finished */
86 	unsigned int orig_pad[4];		/* Original grid pad */
87 	unsigned int reset_pad;			/* 1 for input memory grids from which a subregion was requested */
88 	bool h_delay;				/* We must delay writing table headers until memory allocated */
89 	bool s_delay;				/* We must delay writing segment header until memory allocated  */
90 	bool selected;				/* true if requested by current module, false otherwise */
91 	bool close_file;			/* true if we opened source as a file and thus need to close it when done */
92 	bool region;				/* true if wesn was passed, false otherwise */
93 	bool no_longer_owner;			/* true if the data pointed to by the object was passed on to another object */
94 	bool messenger;				/* true for output objects passed from the outside to receive data from GMT. If true we destroy data pointer before writing */
95 	bool module_input;			/* true for input objects that will serve as module input(s) and not option inputs */
96 	enum GMT_enum_alloc alloc_mode;		/* GMT_ALLOCATED_{BY_GMT|EXTERNALLY} */
97 	enum GMT_enum_std direction;		/* GMT_IN or GMT_OUT */
98 	enum GMT_enum_family family;		/* One of GMT_IS_{DATASET|TEXTSET|PALETTE|IMAGE|GRID|POSTSCRIPT|MATRIX|VECTOR|COORD} */
99 	enum GMT_enum_family actual_family;	/* May be GMT_IS_MATRIX|VECTOR when one of the others are created via those */
100 	enum GMT_enum_type type;		/* Desired output array type for auto-allocated VECTOR and MATRIX */
101 	unsigned method;			/* One of GMT_IS_{FILE,STREAM,FDESC,DUPLICATE,REFERENCE} or sum with enum GMT_enum_via (GMT_VIA_{NONE,VECTOR,MATRIX,OUTPUT}); using unsigned type because sum exceeds enum GMT_enum_method */
102 	enum GMT_enum_geometry geometry;	/* One of GMT_IS_{POINT|LINE|POLY|PLP|SURFACE|NONE} */
103 	double wesn[GMTAPI_N_GRID_ARGS];	/* Active Grid domain limits */
104 	double orig_wesn[GMTAPI_N_GRID_ARGS];	/* Original Grid domain limits */
105 	void *resource;				/* Points to a GMT container, where data can be obtained or are placed. */
106 	FILE *fp;				/* Pointer to source/destination stream [For rec-by-rec procession, NULL if memory location] */
107 	char *filename;				/* Filename, stream, of file handle (otherwise NULL) */
108 	void * (*import) (struct GMT_CTRL *, FILE *, uint64_t *, int *);	/* Pointer to input function (for DATASET/TEXTSET only) */
109 #ifdef DEBUG
110 	/* Start of temporary variables for API debug - They are only set when building with /DEBUG */
111 	struct GMT_GRID *G;
112 	struct GMT_DATASET *D;
113 	struct GMT_PALETTE *C;
114 	struct GMT_POSTSCRIPT *P;
115 	struct GMT_MATRIX *M;
116 	struct GMT_VECTOR *V;
117 	struct GMT_IMAGE *I;
118 	struct GMT_CUBE *U;
119 	/* End of temporary variables for API debug - will be removed eventually */
120 #endif
121 };
122 
123 struct GMTAPI_CTRL {
124 	/* Master controller which holds all GMT API related information at run-time for a single session.
125 	 * Users can run several GMT sessions concurrently; each session requires its own structure.
126 	 * Use GMTAPI_Create_Session to initialize a new session and GMTAPI_Destroy_Session to end it. */
127 
128 	uint64_t current_rec[2];		/* Current record number >= 0 in the combined virtual dataset (in and out) */
129 	unsigned int n_objects;			/* Number of currently active input and output data objects */
130 	unsigned int unique_ID;			/* Used to create unique IDs for duration of session */
131 	unsigned int session_ID;		/* ID of this session */
132 	unsigned int unique_var_ID;		/* Used to create unique object IDs (grid,dataset, etc) for duration of session */
133 	int current_item[2];			/* Array number of current dataset being processed (in and out)*/
134 	unsigned int pad;			/* Session default for number of rows/cols padding for grids [2] */
135 	unsigned int external;			/* 1 if called via external API (MATLAB, Python) [0] */
136 	unsigned int runmode;			/* nonzero for GMT modern runmode [0 = classic] */
137 	enum GMT_enum_fmt shape;		/* GMT_IS_COL_FORMAT (2) if column-major (MATLAB, Fortran), GMT_IS_ROW_FORMAT (1) if row-major (Python, C/C++) [1] */
138 	unsigned int leave_grid_scaled;		/* 1 if we don't want to unpack a grid after we packed it for writing [0] */
139 	unsigned int n_cores;			/* Number of available cores on this system */
140 	unsigned int verbose;			/* Used until GMT is set up */
141 	unsigned int n_tmp_headers;		/* Number of temporarily held table headers */
142 	unsigned int terminal_width;	/* Width of the terminal */
143 	bool registered[2];			/* true if at least one source/destination has been registered (in and out) */
144 	bool io_enabled[2];			/* true if access has been allowed (in and out) */
145 	bool module_input;			/* true when we are about to read inputs to the module (command line) */
146 	bool usage;				/* Flag when 1-liner modern mode modules just want usage */
147 	bool allow_reuse;				/* Flag when get_region_from_data can read a file and not flag it as "used" */
148 	bool is_file;					/* True if current rec-by-rec i/o is from a physical file */
149 	bool cache;					/* true if we want to read a cache file via GDAL */
150 	bool no_history;					/* true if we want to disable the gmt.history mechanism */
151 	bool got_remote_wesn;				/* true if we obtained w/e/sn via a remote grid/image with no resolution given */
152 	size_t n_objects_alloc;			/* Allocation counter for data objects */
153 	int error;				/* Error code from latest API call [GMT_OK] */
154 	int last_error;				/* Error code from previous API call [GMT_OK] */
155 	int shelf;				/* Place to pass hidden values within API */
156 	unsigned int log_level;			/* 0 = stderr, 1 = just this module, 2 = set until unset */
157 	unsigned int io_mode[2];		/* 1 if access as set, 0 if record-by-record */
158 	double tile_wesn[GMTAPI_N_GRID_ARGS];	/* Original region used when getting tiles (perhaps result of -Roblique -J) */
159 	double tile_inc;	/* Remote grid increment in degrees */
160 	char tile_reg;		/* Remote grid registration */
161 	struct GMT_CTRL *GMT;			/* Key structure with low-level GMT internal parameters */
162 	struct GMTAPI_DATA_OBJECT **object;	/* List of registered data objects */
163 	char *session_tag;			/* Name tag for this session (or NULL) */
164 	char *session_name;			/* Unique name for modern mode session (NULL for classic) */
165 	char *tmp_dir;				/* System tmp_dir (NULL if not found) */
166 	char *session_dir;			/* GMT Session dir (NULL if not running in modern mode) */
167 	char *gwf_dir;				/* GMT WorkFlow dir (NULL if not running in modern mode) */
168 	char **tmp_header;			/* Temporary table headers held until we are able to write them to destination */
169 	char *tmp_segmentheader;		/* Temporary segment header held until we are able to write it to destination */
170 	char *message;				/* To be allocated by Create_Session and used for messages */
171 	char error_msg[4096];			/* The cached last error message */
172 	bool internal;				/* true if session was initiated by gmt.c */
173 	bool deep_debug;			/* temporary for debugging */
174 	int (*print_func) (FILE *, const char *);	/* Pointer to fprintf function (may be reset by external APIs like MEX) */
175 	unsigned int do_not_exit;		/* 0 by default, meaning it is OK to call exit  (may be reset by external APIs like MEX to call return instead) */
176 	struct GMT_LIBINFO *lib;		/* List of shared libs to consider */
177 	unsigned int n_shared_libs;		/* How many in lib */
178 	/* Items used by GMT_Put_Record and sub-functions */
179 	int (*api_put_record) (struct GMTAPI_CTRL *API, unsigned int, struct GMT_RECORD *);
180 	/*   Items used by api_put_record_fp */
181 	FILE *current_fp;
182 	struct GMTAPI_DATA_OBJECT *current_put_obj;
183 	uint64_t current_put_n_columns;
184 	/*   Items used by api_put_record_dataset */
185 	struct GMT_DATATABLE *current_put_D_table;
186 	/*   Items used by api_put_record_matrix */
187 	struct GMT_MATRIX *current_put_M;
188 	p_func_uint64_t current_put_M_index;
189 	GMT_putfunction current_put_M_val;
190 	/*   Items used by api_put_record_vector */
191 	struct GMT_VECTOR *current_put_V;
192 	GMT_putfunction *current_put_V_val;
193 	/* Items used by GMT_Put_Record and sub-functions */
194 	struct GMT_RECORD * (*api_get_record) (struct GMTAPI_CTRL *, unsigned int, int *);
195 	struct GMTAPI_DATA_OBJECT *current_get_obj;
196 	bool get_next_record;
197 	/*   Items used by api_get_record_dataset */
198 	struct GMT_DATASET *current_get_D_set;
199 	/*   Items used by api_get_record_matrix */
200 	struct GMT_MATRIX *current_get_M;
201 	p_func_uint64_t current_get_M_index;
202 	GMT_getfunction current_get_M_val;
203 	uint64_t current_get_n_columns;
204 	/*   Items used by api_get_record_vector */
205 	struct GMT_VECTOR *current_get_V;
206 	p_func_uint64_t current_get_V_index;
207 	GMT_getfunction *current_get_V_val;
208 	/* These are used for -O -K -P -c and set to blank under modern/classic modes */
209 	char *O_OPT, *K_OPT, *P_OPT, *c_OPT;
210 	/* structure array of remote file information (sorted alphabetically) */
211 	int n_remote_info;	/* How many remote server files we know of */
212 	struct GMT_DATA_INFO *remote_info;
213 	bool server_announced;	/* Set to true after we have announced which GMT data server we are using */
214 	struct GMT_COMMON *common_snapshot;	/* Holds the latest GMT common option settings after a module completes. */
215 };
216 
217 /* Macro to test if filename is a special name indicating memory location */
218 
219 #define GMTAPI_PREFIX_LEN 9U		/* The length of the unique leading prefix of virtual filenames */
220 #define GMTAPI_MEMFILE_LEN 27U		/* The length of the virtual filenames (see gmtapi_encode_id) */
221 #define GMTAPI_OBJECT_DIR_START 11U		/* Start position of the encoded object direction in the virtual filename */
222 #define GMTAPI_OBJECT_FAMILY_START 15U	/* Start position of the encoded actual family in the virtual filename */
223 #define GMTAPI_OBJECT_ID_START 21U		/* Start position of the encoded object ID in the virtual filename */
224 #define gmt_M_file_is_memory(file) (file && !strncmp (file, "@GMTAPI@-", GMTAPI_PREFIX_LEN) && strlen (file) == GMTAPI_MEMFILE_LEN)
225 
226 #ifdef __cplusplus
227 }
228 #endif
229 
230 #endif /* _GMTAPI_PRIVATE_H */
231