2 * Copyright (c) 2017-2019 Tilman Sauerbeck (tilman at code-monkey de)
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 pub enum BufferUserData {
32 callback: extern fn(*mut BufferUserData, *const u8, usize, usize) -> isize,
33 user_data: *mut BufferUserData,
38 extern fn dummy_callback(_: *mut BufferUserData, _: *const u8, _: usize, _: usize) -> isize {
43 pub unsafe extern fn buffer_init(_buffer: *mut Buffer, buf: *mut u8, bufsiz: usize, callback: extern fn(*mut BufferUserData, *const u8, usize, usize) -> isize, user_data: *mut BufferUserData) {
44 let buffer = &mut *_buffer;
47 buffer.allocated = bufsiz;
48 buffer.callback = callback;
49 buffer.user_data = user_data;
53 unsafe fn buffer_consume(buffer: &mut Buffer, length: usize) {
54 buffer.length -= length;
56 ptr::copy(buffer.buf.offset(length as isize), buffer.buf, buffer.length);
60 pub unsafe extern fn buffer_flush(_buffer: *mut Buffer) -> i32 {
61 let buffer = &mut *_buffer;
63 while buffer.length > 0 {
64 let nwritten = (buffer.callback)(buffer.user_data, buffer.buf, buffer.allocated, buffer.length);
70 buffer_consume(buffer, nwritten as usize);
76 fn min(a: usize, b: usize) -> usize {
85 pub unsafe extern fn buffer_write(_buffer: *mut Buffer, src: *const u8, srcsiz: usize) -> isize {
86 let buffer = &mut *_buffer;
88 if buffer.allocated == buffer.length {
89 if buffer_flush(_buffer) < 0 {
94 let nwrite = min(buffer.allocated - buffer.length, srcsiz);
96 ptr::copy_nonoverlapping(src, buffer.buf.offset(buffer.length as isize), nwrite);
98 buffer.length += nwrite;
104 pub unsafe extern fn buffer_write_all(_buffer: *mut Buffer, src: *const u8, srcsiz: usize) -> isize {
106 let mut left = srcsiz;
109 let data = src.offset(offset);
110 let nwritten = buffer_write(_buffer, data, left);
116 left -= nwritten as usize;
124 // Allocates and initializes a buffer.
125 pub fn new(buf: *mut u8, bufsiz: usize, callback: extern fn(*mut BufferUserData, *const u8, usize, usize) -> isize, user_data: *mut BufferUserData) -> Buffer {
129 user_data: user_data,
135 // Allocates a buffer, but does not initialize it.
136 // The buffer won't be usable until the init() function is called on it.
137 pub fn alloc() -> Buffer {
140 callback: dummy_callback,
141 user_data: 0 as *mut BufferUserData,
147 pub fn init(&mut self, buf: *mut u8, bufsiz: usize, callback: extern fn(*mut BufferUserData, *const u8, usize, usize) -> isize, user_data: *mut BufferUserData) {
149 buffer_init(self, buf, bufsiz, callback, user_data);
153 pub fn write(&mut self, data: &[u8]) {
155 buffer_write_all(self, data.as_ptr(), data.len());
159 pub fn flush(&mut self) -> i32 {
165 pub fn len(&self) -> usize {