Mercurial > hg > piper-cpp
comparison ext/serd/src/byte_source.c @ 226:c5cdc9e6a4bf
Add these external library files
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Fri, 09 Jun 2017 16:41:31 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
225:025b3e2f7c17 | 226:c5cdc9e6a4bf |
---|---|
1 /* | |
2 Copyright 2011-2017 David Robillard <http://drobilla.net> | |
3 | |
4 Permission to use, copy, modify, and/or distribute this software for any | |
5 purpose with or without fee is hereby granted, provided that the above | |
6 copyright notice and this permission notice appear in all copies. | |
7 | |
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 */ | |
16 | |
17 #include "serd_internal.h" | |
18 | |
19 static inline SerdStatus | |
20 serd_byte_source_page(SerdByteSource* source) | |
21 { | |
22 source->read_head = 0; | |
23 size_t n_read = source->read_func( | |
24 source->file_buf, 1, source->page_size, source->stream); | |
25 if (n_read == 0) { | |
26 source->file_buf[0] = '\0'; | |
27 return (source->error_func(source->stream) | |
28 ? SERD_ERR_UNKNOWN : SERD_FAILURE); | |
29 } else if (n_read < source->page_size) { | |
30 source->file_buf[n_read] = '\0'; | |
31 } | |
32 return SERD_SUCCESS; | |
33 } | |
34 | |
35 SerdStatus | |
36 serd_byte_source_open_source(SerdByteSource* source, | |
37 SerdSource read_func, | |
38 SerdStreamErrorFunc error_func, | |
39 void* stream, | |
40 size_t page_size) | |
41 { | |
42 memset(source, '\0', sizeof(*source)); | |
43 source->stream = stream; | |
44 source->from_stream = true; | |
45 source->page_size = page_size; | |
46 source->error_func = error_func; | |
47 source->read_func = read_func; | |
48 | |
49 if (page_size > 1) { | |
50 source->file_buf = (uint8_t*)serd_bufalloc(page_size); | |
51 source->read_buf = source->file_buf; | |
52 memset(source->file_buf, '\0', page_size); | |
53 } else { | |
54 source->read_buf = &source->read_byte; | |
55 } | |
56 | |
57 return SERD_SUCCESS; | |
58 } | |
59 | |
60 SerdStatus | |
61 serd_byte_source_prepare(SerdByteSource* source) | |
62 { | |
63 if (!source->prepared) { | |
64 source->prepared = true; | |
65 if (source->page_size > 1) { | |
66 return serd_byte_source_page(source); | |
67 } else if (source->from_stream) { | |
68 return serd_byte_source_advance(source); | |
69 } | |
70 } | |
71 return SERD_SUCCESS; | |
72 } | |
73 | |
74 SerdStatus | |
75 serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8) | |
76 { | |
77 memset(source, '\0', sizeof(*source)); | |
78 source->read_buf = utf8; | |
79 source->prepared = true; | |
80 return SERD_SUCCESS; | |
81 } | |
82 | |
83 SerdStatus | |
84 serd_byte_source_close(SerdByteSource* source) | |
85 { | |
86 if (source->page_size > 1) { | |
87 free(source->file_buf); | |
88 } | |
89 memset(source, '\0', sizeof(*source)); | |
90 return SERD_SUCCESS; | |
91 } | |
92 | |
93 SerdStatus | |
94 serd_byte_source_advance(SerdByteSource* source) | |
95 { | |
96 const bool paging = source->page_size > 1; | |
97 SerdStatus st = SERD_SUCCESS; | |
98 if (source->from_stream && !paging) { | |
99 if (source->read_func(&source->read_byte, 1, 1, source->stream) == 0) { | |
100 return (source->error_func(source->stream) | |
101 ? SERD_ERR_UNKNOWN : SERD_FAILURE); | |
102 } | |
103 } else if (++source->read_head == source->page_size && paging) { | |
104 st = serd_byte_source_page(source); | |
105 } | |
106 | |
107 return st; | |
108 } |