File Coverage

deps/libgit2/src/reader.c
Criterion Covered Total %
statement 0 104 0.0
branch 0 84 0.0
condition n/a
subroutine n/a
pod n/a
total 0 188 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
4             * This file is part of libgit2, distributed under the GNU GPL v2 with
5             * a Linking Exception. For full terms see the included COPYING file.
6             */
7              
8             #include "reader.h"
9              
10             #include "futils.h"
11             #include "blob.h"
12              
13             #include "git2/tree.h"
14             #include "git2/blob.h"
15             #include "git2/index.h"
16             #include "git2/repository.h"
17              
18             /* tree reader */
19              
20             typedef struct {
21             git_reader reader;
22             git_tree *tree;
23             } tree_reader;
24              
25 0           static int tree_reader_read(
26             git_buf *out,
27             git_oid *out_id,
28             git_filemode_t *out_filemode,
29             git_reader *_reader,
30             const char *filename)
31             {
32 0           tree_reader *reader = (tree_reader *)_reader;
33 0           git_tree_entry *tree_entry = NULL;
34 0           git_blob *blob = NULL;
35             git_object_size_t blobsize;
36             int error;
37              
38 0 0         if ((error = git_tree_entry_bypath(&tree_entry, reader->tree, filename)) < 0 ||
    0          
39 0           (error = git_blob_lookup(&blob, git_tree_owner(reader->tree), git_tree_entry_id(tree_entry))) < 0)
40             goto done;
41              
42 0           blobsize = git_blob_rawsize(blob);
43 0 0         GIT_ERROR_CHECK_BLOBSIZE(blobsize);
44              
45 0 0         if ((error = git_buf_set(out, git_blob_rawcontent(blob), (size_t)blobsize)) < 0)
46 0           goto done;
47              
48 0 0         if (out_id)
49 0           git_oid_cpy(out_id, git_tree_entry_id(tree_entry));
50              
51 0 0         if (out_filemode)
52 0           *out_filemode = git_tree_entry_filemode(tree_entry);
53              
54             done:
55 0           git_blob_free(blob);
56 0           git_tree_entry_free(tree_entry);
57 0           return error;
58             }
59              
60 0           int git_reader_for_tree(git_reader **out, git_tree *tree)
61             {
62             tree_reader *reader;
63              
64 0 0         assert(out && tree);
    0          
65              
66 0           reader = git__calloc(1, sizeof(tree_reader));
67 0 0         GIT_ERROR_CHECK_ALLOC(reader);
68              
69 0           reader->reader.read = tree_reader_read;
70 0           reader->tree = tree;
71              
72 0           *out = (git_reader *)reader;
73 0           return 0;
74             }
75              
76             /* workdir reader */
77              
78             typedef struct {
79             git_reader reader;
80             git_repository *repo;
81             git_index *index;
82             } workdir_reader;
83              
84 0           static int workdir_reader_read(
85             git_buf *out,
86             git_oid *out_id,
87             git_filemode_t *out_filemode,
88             git_reader *_reader,
89             const char *filename)
90             {
91 0           workdir_reader *reader = (workdir_reader *)_reader;
92 0           git_buf path = GIT_BUF_INIT;
93             struct stat st;
94             git_filemode_t filemode;
95 0           git_filter_list *filters = NULL;
96             const git_index_entry *idx_entry;
97             git_oid id;
98             int error;
99              
100 0 0         if ((error = git_buf_joinpath(&path,
101 0           git_repository_workdir(reader->repo), filename)) < 0)
102 0           goto done;
103              
104 0 0         if ((error = p_lstat(path.ptr, &st)) < 0) {
105 0 0         if (error == -1 && errno == ENOENT)
    0          
106 0           error = GIT_ENOTFOUND;
107              
108 0           git_error_set(GIT_ERROR_OS, "could not stat '%s'", path.ptr);
109 0           goto done;
110             }
111              
112 0           filemode = git_futils_canonical_mode(st.st_mode);
113              
114             /*
115             * Patch application - for example - uses the filtered version of
116             * the working directory data to match git. So we will run the
117             * workdir -> ODB filter on the contents in this workdir reader.
118             */
119 0 0         if ((error = git_filter_list_load(&filters, reader->repo, NULL, filename,
120             GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT)) < 0)
121 0           goto done;
122              
123 0 0         if ((error = git_filter_list_apply_to_file(out,
124 0           filters, reader->repo, path.ptr)) < 0)
125 0           goto done;
126              
127 0 0         if (out_id || reader->index) {
    0          
128 0 0         if ((error = git_odb_hash(&id, out->ptr, out->size, GIT_OBJECT_BLOB)) < 0)
129 0           goto done;
130             }
131              
132 0 0         if (reader->index) {
133 0 0         if (!(idx_entry = git_index_get_bypath(reader->index, filename, 0)) ||
    0          
134 0 0         filemode != idx_entry->mode ||
135 0           !git_oid_equal(&id, &idx_entry->id)) {
136 0           error = GIT_READER_MISMATCH;
137 0           goto done;
138             }
139             }
140              
141 0 0         if (out_id)
142 0           git_oid_cpy(out_id, &id);
143              
144 0 0         if (out_filemode)
145 0           *out_filemode = filemode;
146              
147             done:
148 0           git_filter_list_free(filters);
149 0           git_buf_dispose(&path);
150 0           return error;
151             }
152              
153 0           int git_reader_for_workdir(
154             git_reader **out,
155             git_repository *repo,
156             bool validate_index)
157             {
158             workdir_reader *reader;
159             int error;
160              
161 0 0         assert(out && repo);
    0          
162              
163 0           reader = git__calloc(1, sizeof(workdir_reader));
164 0 0         GIT_ERROR_CHECK_ALLOC(reader);
165              
166 0           reader->reader.read = workdir_reader_read;
167 0           reader->repo = repo;
168              
169 0 0         if (validate_index &&
    0          
170 0           (error = git_repository_index__weakptr(&reader->index, repo)) < 0) {
171 0           git__free(reader);
172 0           return error;
173             }
174              
175 0           *out = (git_reader *)reader;
176 0           return 0;
177             }
178              
179             /* index reader */
180              
181             typedef struct {
182             git_reader reader;
183             git_repository *repo;
184             git_index *index;
185             } index_reader;
186              
187 0           static int index_reader_read(
188             git_buf *out,
189             git_oid *out_id,
190             git_filemode_t *out_filemode,
191             git_reader *_reader,
192             const char *filename)
193             {
194 0           index_reader *reader = (index_reader *)_reader;
195             const git_index_entry *entry;
196             git_blob *blob;
197             int error;
198              
199 0 0         if ((entry = git_index_get_bypath(reader->index, filename, 0)) == NULL)
200 0           return GIT_ENOTFOUND;
201              
202 0 0         if ((error = git_blob_lookup(&blob, reader->repo, &entry->id)) < 0)
203 0           goto done;
204              
205 0 0         if (out_id)
206 0           git_oid_cpy(out_id, &entry->id);
207              
208 0 0         if (out_filemode)
209 0           *out_filemode = entry->mode;
210              
211 0           error = git_blob__getbuf(out, blob);
212              
213             done:
214 0           git_blob_free(blob);
215 0           return error;
216             }
217              
218 0           int git_reader_for_index(
219             git_reader **out,
220             git_repository *repo,
221             git_index *index)
222             {
223             index_reader *reader;
224             int error;
225              
226 0 0         assert(out && repo);
    0          
227              
228 0           reader = git__calloc(1, sizeof(index_reader));
229 0 0         GIT_ERROR_CHECK_ALLOC(reader);
230              
231 0           reader->reader.read = index_reader_read;
232 0           reader->repo = repo;
233              
234 0 0         if (index) {
235 0           reader->index = index;
236 0 0         } else if ((error = git_repository_index__weakptr(&reader->index, repo)) < 0) {
237 0           git__free(reader);
238 0           return error;
239             }
240              
241 0           *out = (git_reader *)reader;
242 0           return 0;
243             }
244              
245             /* generic */
246              
247 0           int git_reader_read(
248             git_buf *out,
249             git_oid *out_id,
250             git_filemode_t *out_filemode,
251             git_reader *reader,
252             const char *filename)
253             {
254 0 0         assert(out && reader && filename);
    0          
    0          
255              
256 0           return reader->read(out, out_id, out_filemode, reader, filename);
257             }
258              
259 0           void git_reader_free(git_reader *reader)
260             {
261 0 0         if (!reader)
262 0           return;
263              
264 0           git__free(reader);
265             }