1#ifndef _CHUNK_H_
2#define _CHUNK_H_
3
4#include "buffer.h"
5#include "array.h"
6
7typedef enum {
8	UNUSED_CHUNK,
9	MEM_CHUNK,
10	FILE_CHUNK,
11	SMB_CHUNK
12} CHUNK_TYPE;
13
14typedef struct chunk {
15	CHUNK_TYPE type;
16
17	buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */
18
19	struct {
20		/* filechunk */
21		buffer *name; /* name of the file */
22		off_t  start; /* starting offset in the file */
23		off_t  length; /* octets to send from the starting offset */
24
25		int    fd;
26		struct {
27			char   *start; /* the start pointer of the mmap'ed area */
28			size_t length; /* size of the mmap'ed area */
29			off_t  offset; /* start is <n> octet away from the start of the file */
30		} mmap;
31
32		int is_temp; /* file is temporary and will be deleted if on cleanup */
33	} file;
34
35	/* the size of the chunk is either:
36	 * - mem-chunk: buffer_string_length(chunk::mem)
37	 * - file-chunk: chunk::file.length
38	 */
39	off_t  offset; /* octets sent from this chunk */
40
41	struct chunk *next;
42} chunk;
43
44typedef struct {
45	chunk *first;
46	chunk *last;
47
48	chunk *unused;
49	size_t unused_chunks;
50
51	off_t bytes_in, bytes_out;
52
53	array *tempdirs;
54	unsigned int upload_temp_file_size;
55} chunkqueue;
56
57chunkqueue *chunkqueue_init(void);
58void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs, unsigned int upload_temp_file_size);
59void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); /* copies "fn" */
60void chunkqueue_append_mem(chunkqueue *cq, const char *mem, size_t len); /* copies memory */
61void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */
62void chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */
63
64/* functions to handle buffers to read into: */
65/* return a pointer to a buffer in *mem with size *len;
66 *  it should be at least min_size big, and use alloc_size if
67 *  new memory is allocated.
68 * modifying the chunkqueue invalidates the memory area.
69 * should always be followed by chunkqueue_get_memory(),
70 *  even if nothing was read.
71 * pass 0 for min_size/alloc_size for default values
72 */
73void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size);
74/* append first len bytes of the memory queried with
75 * chunkqueue_get_memory to the chunkqueue
76 */
77void chunkqueue_use_memory(chunkqueue *cq, size_t len);
78
79/* mark first "len" bytes as written (incrementing chunk offsets)
80 * and remove finished chunks
81 */
82void chunkqueue_mark_written(chunkqueue *cq, off_t len);
83
84void chunkqueue_remove_finished_chunks(chunkqueue *cq);
85
86void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len);
87struct server;
88int chunkqueue_steal_with_tempfiles(struct server *srv, chunkqueue *dest, chunkqueue *src, off_t len);
89
90off_t chunkqueue_length(chunkqueue *cq);
91void chunkqueue_free(chunkqueue *cq);
92void chunkqueue_reset(chunkqueue *cq);
93
94int chunkqueue_is_empty(chunkqueue *cq);
95
96#endif
97