1 /*
2     OWFS -- One-Wire filesystem
3     OWHTTPD -- One-Wire Web Server
4     Written 2003 Paul H Alfille
5 	email: paul.alfille@gmail.com
6 	Released under the GPL
7 	See the header file: ow.h for full attribution
8 	1wire/iButton system from Dallas Semiconductor
9 */
10 
11 /* ow_interate.c */
12 /* routines to split reads and writes if longer than page */
13 
14 #include <config.h>
15 #include "owfs_config.h"
16 #include "ow.h"
17 
COMMON_readwrite_paged(struct one_wire_query * owq,size_t page,size_t pagelen,GOOD_OR_BAD (* readwritefunc)(BYTE *,size_t,off_t,struct parsedname *))18 GOOD_OR_BAD COMMON_readwrite_paged(struct one_wire_query *owq, size_t page, size_t pagelen, GOOD_OR_BAD (*readwritefunc) (BYTE *, size_t, off_t, struct parsedname *))
19 {
20 	size_t size = OWQ_size(owq);
21 	off_t offset = OWQ_offset(owq) + pagelen * page;
22 	BYTE *buffer_position = (BYTE *) OWQ_buffer(owq);
23 	struct parsedname *pn = PN(owq);
24 
25 	/* successive pages, will start at page start */
26 	OWQ_length(owq) = size;
27 	while (size > 0) {
28 		size_t thispage = pagelen - (offset % pagelen);
29 		if (thispage > size) {
30 			thispage = size;
31 		}
32 		RETURN_BAD_IF_BAD( readwritefunc(buffer_position, thispage, offset, pn) ) ;
33 		buffer_position += thispage;
34 		size -= thispage;
35 		offset += thispage;
36 	}
37 
38 	return gbGOOD;
39 }
40 
41 
42 // The same as COMMON_readwrite_paged above except the results are nicely placed in the OWQ buffers with sizes and offsets.
COMMON_OWQ_readwrite_paged(struct one_wire_query * owq,size_t page,size_t pagelen,GOOD_OR_BAD (* readwritefunc)(struct one_wire_query *,size_t,size_t))43 GOOD_OR_BAD COMMON_OWQ_readwrite_paged(struct one_wire_query *owq, size_t page, size_t pagelen, GOOD_OR_BAD (*readwritefunc) (struct one_wire_query *, size_t, size_t))
44 {
45 	size_t size = OWQ_size(owq);
46 	off_t offset = OWQ_offset(owq) + pagelen * page;
47 	struct parsedname *pn = PN(owq);
48 	OWQ_allocate_struct_and_pointer(owq_page);
49 
50 	/* holds a pointer to a position in owq's buffer */
51 	OWQ_create_temporary(owq_page, OWQ_buffer(owq), size, offset, pn);
52 
53 	/* successive pages, will start at page start */
54 	OWQ_length(owq) = size;
55 	while (size > 0) {
56 		size_t thispage = pagelen - (offset % pagelen);
57 		if (thispage > size) {
58 			thispage = size;
59 		}
60 		OWQ_size(owq_page) = thispage;
61 		if (readwritefunc(owq_page, 0, pagelen)) {
62 			LEVEL_DEBUG("error at offset %ld", (long) offset);
63 			return gbBAD;
64 		}
65 		OWQ_buffer(owq_page) += thispage;
66 		size -= thispage;
67 		offset += thispage;
68 		// This is permitted (changing OWQ_offset and not restoring) since owq_page is a scratch var
69 		OWQ_offset(owq_page) = offset;
70 	}
71 
72 	return gbGOOD;
73 }
74