4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 /* Replacement for open_memstream for platforms which lack this function. */
39 #include "open_memstream.h"
41 #ifndef HAVE_OPEN_MEMSTREAM
45 /* Replacement open_memstream for Win32. */
51 /* This is provided by common/utils which hasn't been compiled yet.
52 * Programs using this replacement will need to link to
55 #include "../utils/vector.h"
56 #include "../utils/nbdkit-string.h"
58 /* Map FILE* that we return to the user buffer. */
59 struct file_to_memstream
{
61 char tmpname
[MAX_PATH
];
65 DEFINE_VECTOR_TYPE (file_vector
, struct file_to_memstream
);
66 static file_vector files
= empty_vector
;
69 open_memstream (char **ptr
, size_t *size
)
71 struct file_to_memstream f2m
;
72 char tmppath
[MAX_PATH
];
76 ret
= GetTempPath (MAX_PATH
, tmppath
);
77 if (ret
> MAX_PATH
|| ret
== 0)
80 ret
= GetTempFileName (tmppath
, TEXT ("nbdkit"), 0, f2m
.tmpname
);
84 fp
= fopen (f2m
.tmpname
, "w+");
91 if (file_vector_append (&files
, f2m
) == -1) {
100 close_memstream (FILE *fp
)
104 string content
= empty_vector
;
105 struct file_to_memstream
*f2m
;
107 for (i
= 0; i
< files
.len
; ++i
) {
108 if (files
.ptr
[i
].fp
== fp
)
111 assert (i
< files
.len
);
114 /* Read the file back into memory. */
116 while ((c
= getc (fp
)) != EOF
) {
117 if (string_append (&content
, c
) == -1) {
120 unlink (f2m
->tmpname
);
122 file_vector_remove (&files
, i
);
126 /* Make sure the buffer is \0-terminated but don't include this
127 * in the buffer size returned below.
129 if (string_append (&content
, 0) == -1) goto append_failed
;
132 unlink (f2m
->tmpname
);
135 file_vector_remove (&files
, i
);
139 /* Pass the buffer to the user. User will free it. */
140 *(files
.ptr
[i
].ptr
) = content
.ptr
;
141 *(files
.ptr
[i
].size
) = content
.len
- 1;
142 file_vector_remove (&files
, i
);
147 #error "no replacement open_memstream is available on this platform"
150 #endif /* !HAVE_OPEN_MEMSTREAM */