-
Notifications
You must be signed in to change notification settings - Fork 6
/
imageflow.h
271 lines (237 loc) · 12 KB
/
imageflow.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#ifndef generated_imageflow_h
#define generated_imageflow_h
// Incremented for breaking changes
#define IMAGEFLOW_ABI_VER_MAJOR 3
// Incremented for non-breaking additions
#define IMAGEFLOW_ABI_VER_MINOR 0
struct imageflow_context;
struct imageflow_json_response;
struct imageflow_job;
struct imageflow_job_io;
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
//
// How long the provided pointer/buffer will remain valid.
// Callers must prevent the memory from being freed or moved until this contract expires.
//
typedef enum imageflow_lifetime {
// Pointer will outlive function call. If the host language has a garbage collector, call the appropriate method to ensure the object pointed to will not be collected or moved until the call returns. You may think host languages do this automatically in their FFI system. Most do not.
imageflow_lifetime_lifetime_outlives_function_call = 0,
// Pointer will outlive context. If the host language has a GC, ensure that you are using a data type guaranteed to neither be moved or collected automatically.
imageflow_lifetime_lifetime_outlives_context = 1,
} imageflow_lifetime;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
//
// Call this method before doing anything else to ensure that your header or FFI bindings are compatible
// with the libimageflow that is currently loaded.
//
// Provide the values `IMAGEFLOW_ABI_VER_MAJOR` and `IMAGEFLOW_ABI_VER_MINOR` to this function.
//
// False means that
//
bool imageflow_abi_compatible(uint32_t imageflow_abi_ver_major,
uint32_t imageflow_abi_ver_minor);
uint32_t imageflow_abi_version_major(void);
uint32_t imageflow_abi_version_minor(void);
//
// Adds an input buffer to the job context.
// You are ALWAYS responsible for freeing the memory provided (at the time specified by imageflow_lifetime).
// If you specify `OutlivesFunctionCall`, then the buffer will be copied.
//
//
bool imageflow_context_add_input_buffer(struct imageflow_context *context,
int32_t io_id,
const uint8_t *buffer,
size_t buffer_byte_count,
imageflow_lifetime lifetime);
//
// Adds an output buffer to the job context.
// The buffer will be freed with the context.
//
//
// Returns null if allocation failed; check the context for error details.
bool imageflow_context_add_output_buffer(struct imageflow_context *context, int32_t io_id);
// Begins the process of destroying the context, yet leaves error information intact
// so that any errors in the tear-down process can be
// debugged with `imageflow_context_error_write_to_buffer`.
//
// Returns true if no errors occurred. Returns false if there were tear-down issues.
bool imageflow_context_begin_terminate(struct imageflow_context *context);
// Creates and returns an imageflow context.
// An imageflow context is required for all other imageflow API calls.
//
// An imageflow context tracks
// * error state
// * error messages
// * stack traces for errors (in C land, at least)
// * context-managed memory allocations
// * performance profiling information
//
// **Contexts are not thread-safe!** Once you create a context, *you* are responsible for ensuring that it is never involved in two overlapping API calls.
//
// Returns a null pointer if allocation fails or the provided interface version is incompatible
struct imageflow_context *imageflow_context_create(uint32_t imageflow_abi_ver_major,
uint32_t imageflow_abi_ver_minor);
// Destroys the imageflow context and frees the context object.
// Only use this with contexts created using `imageflow_context_create`
void imageflow_context_destroy(struct imageflow_context *context);
// Converts the error (or lack thereof) into an unix process exit code
//
// ## Values
//
// * 0 - No error
// * 64 - Invalid usage (graph invalid, node argument invalid, action not supported)
// * 65 - Invalid Json, Image malformed, Image type not supported
// * 66 - Primary or secondary file or resource not found.
// * 69 - Upstream server errored or timed out
// * 70 - Possible bug: internal error, custom error, unknown error, or no graph solution found
// * 71 - Out Of Memory condition (malloc/calloc/realloc failed).
// * 74 - I/O Error
// * 77 - Action forbidden under imageflow security policy
// * 402 - License error
// * 401 - Imageflow server authorization required
//
int32_t imageflow_context_error_as_exit_code(struct imageflow_context *context);
// Converts the error (or lack thereof) into an equivalent http status code
//
// ## Values
//
// * 200 - No error
// * 400 - Bad argument/node parameters/graph/json/image/image type
// * 401 - Authorization to imageflow server required
// * 402 - License error
// * 403 - Action forbidden under imageflow security policy
// * 404 - Primary resource/file not found
// * 500 - Secondary resource/file not found, IO error, no solution error, unknown error, custom error, internal error
// * 502 - Upstream server error
// * 503 - Out Of Memory condition (malloc/calloc/realloc failed).
// * 504 - Upstream timeout
int32_t imageflow_context_error_as_http_code(struct imageflow_context *context);
// Returns the numeric code associated with the error category. 0 means no error.
//
// These will be stabilized after 1.0, once error categories have passed rigorous real-world testing
// `imageflow_context_error_as_exit_code` and `imageflow_context_error_as_http_status` are suggested in the meantime.
//
int32_t imageflow_context_error_code(struct imageflow_context *context);
// Returns true if the context is "ok" or in an error state that is recoverable.
// You must immediately deal with the error,
// as subsequent API calls will fail or cause undefined behavior until the error state is cleared
bool imageflow_context_error_recoverable(struct imageflow_context *context);
// Returns true if the context is "ok" or in an error state that is recoverable.
// You must immediately deal with the error,
// as subsequent API calls will fail or cause undefined behavior until the error state is cleared
bool imageflow_context_error_try_clear(struct imageflow_context *context);
// Prints the error messages (and optional stack frames) to the given buffer in UTF-8 form; writes a null
// character to terminate the string, and *ALSO* provides the number of bytes written (excluding the null terminator)
//
// Returns false if the buffer was too small (or null) and the output was truncated.
// Returns true if all data was written OR if there was a bug in error serialization (that gets written, too).
//
// If the data is truncated, "\n[truncated]\n" is written to the buffer
//
// Please be accurate with the buffer length, or a buffer overflow will occur.
bool imageflow_context_error_write_to_buffer(struct imageflow_context *context,
char *buffer,
size_t buffer_length,
size_t *bytes_written);
//
// Provides access to the underlying buffer for the given io id
//
bool imageflow_context_get_output_buffer_by_id(struct imageflow_context *context,
int32_t io_id,
const uint8_t **result_buffer,
size_t *result_buffer_length);
// Returns true if the context is in an error state. You must immediately deal with the error,
// as subsequent API calls will fail or cause undefined behavior until the error state is cleared
bool imageflow_context_has_error(struct imageflow_context *context);
//
// Allocates zeroed memory that will be freed with the context.
//
// * filename/line may be used for debugging purposes. They are optional. Provide null/-1 to skip.
// * If provided, `filename` should be an null-terminated UTF-8 or ASCII string which will outlive the context.
//
// Returns null(0) on failure.
//
void *imageflow_context_memory_allocate(struct imageflow_context *context,
size_t bytes,
const char *filename,
int32_t line);
//
// Frees memory allocated with `imageflow_context_memory_allocate` early.
//
// * filename/line may be used for debugging purposes. They are optional. Provide null/-1 to skip.
// * If provided, `filename` should be an null-terminated UTF-8 or ASCII string which will outlive the context.
//
// Returns false on failure. Returns true on success, or if `pointer` is null.
//
bool imageflow_context_memory_free(struct imageflow_context *context,
void *pointer,
const char *filename,
int32_t line);
// Prints the error to stderr and exits the process if an error has been raised on the context.
// If no error is present, the function returns false.
//
// THIS PRINTS DIRECTLY TO STDERR! Do not use in any kind of service! Command-line usage only!
bool imageflow_context_print_and_exit_if_error(struct imageflow_context *context);
//
// Sends a JSON message to the `imageflow_context` using endpoint `method`.
//
// ## Endpoints
//
// * 'v1/build`
//
// For endpoints supported by the latest nightly build, see
// `https://s3-us-west-1.amazonaws.com/imageflow-nightlies/master/doc/context_json_api.txt`
//
// ## Notes
//
// * `method` and `json_buffer` are only borrowed for the duration of the function call. You are
// responsible for their cleanup (if necessary - static strings are handy for things like
// `method`).
// * `method` should be a UTF-8 null-terminated string.
// `json_buffer` should be a UTF-8 encoded buffer (not null terminated) of length `json_buffer_size`.
//
// You should call `imageflow_context_has_error()` to see if this succeeded.
//
// A `struct imageflow_json_response` is returned for success and most error conditions.
// Call `imageflow_json_response_destroy` when you're done with it (or dispose the context).
const struct imageflow_json_response *imageflow_context_send_json(struct imageflow_context *context,
const char *method,
const uint8_t *json_buffer,
size_t json_buffer_size);
// Frees memory associated with the given object (and owned objects) after
// running any owned or attached destructors. Returns false if something went wrong during tear-down.
//
// Returns true if the object to destroy is a null pointer, or if tear-down was successful.
//
// Behavior is undefined if the pointer is dangling or not a valid memory reference.
// Although certain implementations catch
// some kinds of invalid pointers, a segfault is likely in future revisions).
//
// Behavior is undefined if the context provided does not match the context with which the
// object was created.
//
bool imageflow_json_response_destroy(struct imageflow_context *context,
struct imageflow_json_response *response);
//
// Writes fields from the given `imageflow_json_response` to the locations referenced.
// The buffer pointer sent out will be a UTF-8 byte array of the given length (not null-terminated). It will
// also become invalid if the `struct imageflow_json_response` associated is freed, or if the context is destroyed.
//
// See `imageflow_context_error_as_http_code` for just the http status code equivalent.
//
// Most errors are not recoverable; you must destroy the context and retry.
//
bool imageflow_json_response_read(struct imageflow_context *context,
const struct imageflow_json_response *response_in,
int64_t *status_as_http_code_out,
const uint8_t **buffer_utf8_no_nulls_out,
size_t *buffer_size_out);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // generated_imageflow_h