mirror of
https://github.com/StefanSchippers/xschem.git
synced 2026-08-22 06:07:29 +02:00
add filter_data() generic file conversion function
This commit is contained in:
+72
-2
@@ -25,8 +25,78 @@
|
|||||||
#include <sys/wait.h> /* waitpid */
|
#include <sys/wait.h> /* waitpid */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* define this if you want 128 char lenght line formatted base64 text */
|
/* get an input databuffer (din[ilen]), and a shell command (cmd) that reads stdin
|
||||||
#undef BASE64_BREAK_LINES
|
* and writes stdout, return the result in dout[olen].
|
||||||
|
* Caller must free the returned buffer.
|
||||||
|
*/
|
||||||
|
int filter_data(const char *din, const size_t ilen,
|
||||||
|
char **dout, size_t *olen,
|
||||||
|
const char *cmd)
|
||||||
|
{
|
||||||
|
int p1[2]; /* parent -> child, 0: read, 1: write */
|
||||||
|
int p2[2]; /* child -> parent, 0: read, 1: write */
|
||||||
|
int ret = 0;
|
||||||
|
pid_t pid;
|
||||||
|
size_t bufsize = 1024, oalloc = 0, n = 0;
|
||||||
|
pipe(p1);
|
||||||
|
pipe(p2);
|
||||||
|
signal(SIGPIPE, SIG_IGN); /* so attempting write/read a broken pipe won't kill program */
|
||||||
|
if( (pid = fork()) == 0) {
|
||||||
|
/* child */
|
||||||
|
close(p1[1]); /* only read from p1 */
|
||||||
|
close(p2[0]); /* only write to p2 */
|
||||||
|
close(0); /* dup2(p1[0],0); */ /* connect read side of read pipe to stdin */
|
||||||
|
dup(p1[0]);
|
||||||
|
close(1); /* dup2(p2[1],1); */ /* connect write side of write pipe to stdout */
|
||||||
|
dup(p2[1]);
|
||||||
|
/* execlp("gm", "gm", "convert", "-", "-quality", "50", "jpg:-", NULL); */
|
||||||
|
if(system(cmd)) {
|
||||||
|
fprintf(stderr, "error: conversion failed\n");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
close(p1[0]);
|
||||||
|
close(p2[1]);
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
/* parent */
|
||||||
|
close(p1[0]); /*only write to p1 */
|
||||||
|
close(p2[1]); /* only read from p2 */
|
||||||
|
if(write(p1[1], din, ilen) != ilen) { /* write input data to pipe */
|
||||||
|
fprintf(stderr, "filter_data() write to pipe failed or not completed\n");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
close(p1[1]);
|
||||||
|
if(!ret) {
|
||||||
|
if((*dout = my_malloc(1480, bufsize))) {
|
||||||
|
oalloc = bufsize + 1; /* add extra space for final '\0' */
|
||||||
|
*olen = 0;
|
||||||
|
while( (n = read(p2[0], *dout + *olen, bufsize)) > 0) {
|
||||||
|
*olen += n;
|
||||||
|
if(*olen + bufsize + 1 >= oalloc) { /* allocate for next read */
|
||||||
|
bufsize = (((bufsize << 2) + bufsize) >> 2); /* bufsize *= 1.25 */
|
||||||
|
oalloc = *olen + bufsize + 1; /* add extra space for final '\0' */
|
||||||
|
my_realloc(1482, dout, oalloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(*olen) (*dout)[*olen] = '\0'; /* so (if ascii) it can be used as a string */
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "filter_data(): malloc error for read buffer\n");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(p2[0]);
|
||||||
|
if(n < 0 || !*olen) {
|
||||||
|
if(oalloc) {
|
||||||
|
my_free(1483, *dout);
|
||||||
|
*olen = 0;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "no data read\n");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
waitpid(pid, NULL, 0); /* write for child process to finish and unzombie it */
|
||||||
|
signal(SIGPIPE, SIG_DFL); /* restore default SIGPIPE signal action */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Caller should free returned buffer */
|
/* Caller should free returned buffer */
|
||||||
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length, int brk) {
|
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length, int brk) {
|
||||||
|
|||||||
@@ -2670,7 +2670,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||||||
else if(argv[1][0] == 't') {
|
else if(argv[1][0] == 't') {
|
||||||
if(!strcmp(argv[1],"test"))
|
if(!strcmp(argv[1],"test"))
|
||||||
{
|
{
|
||||||
|
char *odata = NULL;
|
||||||
|
size_t olen;
|
||||||
cmd_found = 1;
|
cmd_found = 1;
|
||||||
|
if(!filter_data("stefan.", 7, &odata, &olen, "base64")) {
|
||||||
|
dbg(0, "odata=%s, olen=%d\n", odata, olen);
|
||||||
|
}
|
||||||
Tcl_ResetResult(interp);
|
Tcl_ResetResult(interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1000,6 +1000,8 @@ extern int cli_opt_load_initfile;
|
|||||||
extern Xschem_ctx *xctx;
|
extern Xschem_ctx *xctx;
|
||||||
|
|
||||||
/* FUNCTIONS */
|
/* FUNCTIONS */
|
||||||
|
extern int filter_data(const char *din, const size_t ilen,
|
||||||
|
char **dout, size_t *olen, const char *cmd);
|
||||||
extern int embed_rawfile(const char *rawfile);
|
extern int embed_rawfile(const char *rawfile);
|
||||||
extern int read_rawfile_from_attr(const char *b64s, size_t length);
|
extern int read_rawfile_from_attr(const char *b64s, size_t length);
|
||||||
extern int read_embedded_rawfile(void);
|
extern int read_embedded_rawfile(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user