aboutsummaryrefslogtreecommitdiff
path: root/include/sqfs/data_reader.h
blob: c967a70de065aa4816237ad2296e3c6181358e7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
 * data_reader.h - This file is part of libsquashfs
 *
 * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#ifndef SQFS_DATA_READER_H
#define SQFS_DATA_READER_H

#include "sqfs/predef.h"

/**
 * @file data_reader.h
 *
 * @brief Contains declarations for the @ref sqfs_data_reader_t.
 */

/**
 * @struct sqfs_data_reader_t
 *
 * @implements sqfs_object_t
 *
 * @brief Abstracts access to data blocks stored in a SquashFS image.
 *
 * A SquashFS image can contain a series of file data blocks between the
 * super block and the inode table. Blocks may or may not be compressed.
 * Data chunks that are smaller than the block size indicated by the super
 * block (such as the final chunk of a file or an entire file that is smaller
 * than a signle block) can be grouped in a single fragment block.
 *
 * Regular file inodes referre to the location of the first block and store a
 * sequence of block sizes for all consequitve blocks, as well as a fragment
 * index and fragment offset which is resolved through a fragment table.
 *
 * The data reader abstracts all of this away in a simple interface that allows
 * reading file data through an inode description and a location in the file.
 */

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Create a data reader instance.
 *
 * @memberof sqfs_data_reader_t
 *
 * @param file A file interface through which to access the
 *             underlying filesystem image.
 * @param block_size The data block size from the super block.
 * @param cmp A compressor to use for uncompressing blocks read from disk.
 * @param flags Currently must be 0 or the function will fail.
 *
 * @return A pointer to a new data reader object. NULL means
 *         allocation failure.
 */
SQFS_API sqfs_data_reader_t *sqfs_data_reader_create(sqfs_file_t *file,
						     size_t block_size,
						     sqfs_compressor_t *cmp,
						     sqfs_u32 flags);

/**
 * @brief Read and decode the fragment table from disk.
 *
 * @memberof sqfs_data_reader_t
 *
 * @param data A pointer to a data reader object.
 * @param super A pointer to the super block.
 *
 * @return Zero on succcess, an @ref SQFS_ERROR value on failure.
 */
SQFS_API int sqfs_data_reader_load_fragment_table(sqfs_data_reader_t *data,
						  const sqfs_super_t *super);

/**
 * @brief Get the tail end of a file.
 *
 * @memberof sqfs_data_reader_t
 *
 * @param data A pointer to a data reader object.
 * @param inode A pointer to the inode describing the file.
 * @param size Returns the size of the data read.
 * @param out Returns a pointer to the raw data that must be
 *            released using free.
 *
 * @return Zero on succcess, an @ref SQFS_ERROR value on failure.
 */
SQFS_API int sqfs_data_reader_get_fragment(sqfs_data_reader_t *data,
					   const sqfs_inode_generic_t *inode,
					   size_t *size, sqfs_u8 **out);

/**
 * @brief Get a full sized data block of a file by block index.
 *
 * @memberof sqfs_data_reader_t
 *
 * @param data A pointer to a data reader object.
 * @param inode A pointer to the inode describing the file.
 * @param index The block index in the inodes block list.
 * @param size Returns the size of the data read.
 * @param out Returns a pointer to the raw data that must be
 *            released using free.
 *
 * @return Zero on succcess, an @ref SQFS_ERROR value on failure.
 */
SQFS_API int sqfs_data_reader_get_block(sqfs_data_reader_t *data,
					const sqfs_inode_generic_t *inode,
					size_t index, size_t *size,
					sqfs_u8 **out);

/**
 * @brief A simple UNIX-read-like function to read data from a file.
 *
 * @memberof sqfs_data_reader_t
 *
 * This function acts like the read system call in a Unix-like OS. It takes
 * care of reading accross data blocks and fragment internally, using a
 * data and fragment block cache.
 *
 * @param data A pointer to a data reader object.
 * @param inode A pointer to the inode describing the file.
 * @param offset An arbitrary byte offset into the uncompressed file.
 * @param buffer Returns the data read from the file.
 * @param size The number of uncompressed bytes to read from the given offset.
 *
 * @return The number of bytes read on succcess, zero if attempting to read
 *         past the end of the file and a negative @ref SQFS_ERROR value
 *         on failure.
 */
SQFS_API sqfs_s32 sqfs_data_reader_read(sqfs_data_reader_t *data,
					const sqfs_inode_generic_t *inode,
					sqfs_u64 offset, void *buffer,
					sqfs_u32 size);

#ifdef __cplusplus
}
#endif

#endif /* SQFS_DATA_READER_H */