]> git.proxmox.com Git - libgit2.git/blob - src/blob.c
Merge pull request #474 from schu/clang-unused
[libgit2.git] / src / blob.c
1 /*
2 * Copyright (C) 2009-2011 the libgit2 contributors
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 "git2/common.h"
9 #include "git2/object.h"
10 #include "git2/repository.h"
11
12 #include "common.h"
13 #include "blob.h"
14
15 const void *git_blob_rawcontent(git_blob *blob)
16 {
17 assert(blob);
18 return blob->odb_object->raw.data;
19 }
20
21 size_t git_blob_rawsize(git_blob *blob)
22 {
23 assert(blob);
24 return blob->odb_object->raw.len;
25 }
26
27 void git_blob__free(git_blob *blob)
28 {
29 git_odb_object_free(blob->odb_object);
30 git__free(blob);
31 }
32
33 int git_blob__parse(git_blob *blob, git_odb_object *odb_obj)
34 {
35 assert(blob);
36 git_cached_obj_incref((git_cached_obj *)odb_obj);
37 blob->odb_object = odb_obj;
38 return GIT_SUCCESS;
39 }
40
41 int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len)
42 {
43 int error;
44 git_odb *odb;
45 git_odb_stream *stream;
46
47 error = git_repository_odb__weakptr(&odb, repo);
48 if (error < GIT_SUCCESS)
49 return error;
50
51 if ((error = git_odb_open_wstream(&stream, odb, len, GIT_OBJ_BLOB)) < GIT_SUCCESS)
52 return git__rethrow(error, "Failed to create blob");
53
54 if ((error = stream->write(stream, buffer, len)) < GIT_SUCCESS) {
55 stream->free(stream);
56 return error;
57 }
58
59 error = stream->finalize_write(oid, stream);
60 stream->free(stream);
61
62 if (error < GIT_SUCCESS)
63 return git__rethrow(error, "Failed to create blob");
64
65 return GIT_SUCCESS;
66 }
67
68 int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
69 {
70 int error = GIT_SUCCESS;
71 git_buf full_path = GIT_BUF_INIT;
72 git_off_t size;
73 git_odb_stream *stream = NULL;
74 struct stat st;
75 const char *workdir;
76 git_odb *odb;
77
78 workdir = git_repository_workdir(repo);
79 if (workdir == NULL)
80 return git__throw(GIT_ENOTFOUND, "Failed to create blob. (No working directory found)");
81
82 error = git_buf_joinpath(&full_path, workdir, path);
83 if (error < GIT_SUCCESS)
84 return error;
85
86 error = p_lstat(full_path.ptr, &st);
87 if (error < 0) {
88 error = git__throw(GIT_EOSERR, "Failed to stat blob. %s", strerror(errno));
89 goto cleanup;
90 }
91
92 size = st.st_size;
93
94 error = git_repository_odb__weakptr(&odb, repo);
95 if (error < GIT_SUCCESS)
96 goto cleanup;
97
98 if ((error = git_odb_open_wstream(&stream, odb, (size_t)size, GIT_OBJ_BLOB)) < GIT_SUCCESS)
99 goto cleanup;
100
101 if (S_ISLNK(st.st_mode)) {
102 char *link_data;
103 ssize_t read_len;
104
105 link_data = git__malloc(size);
106 if (!link_data) {
107 error = GIT_ENOMEM;
108 goto cleanup;
109 }
110
111 read_len = p_readlink(full_path.ptr, link_data, size);
112
113 if (read_len != (ssize_t)size) {
114 error = git__throw(GIT_EOSERR, "Failed to create blob. Can't read symlink");
115 free(link_data);
116 goto cleanup;
117 }
118
119 stream->write(stream, link_data, size);
120 free(link_data);
121
122 } else {
123 int fd;
124 char buffer[2048];
125
126 if ((fd = p_open(full_path.ptr, O_RDONLY)) < 0) {
127 error = git__throw(GIT_ENOTFOUND, "Failed to create blob. Could not open '%s'", full_path.ptr);
128 goto cleanup;
129 }
130
131 while (size > 0) {
132 ssize_t read_len = p_read(fd, buffer, sizeof(buffer));
133
134 if (read_len < 0) {
135 error = git__throw(GIT_EOSERR, "Failed to create blob. Can't read full file");
136 p_close(fd);
137 goto cleanup;
138 }
139
140 stream->write(stream, buffer, read_len);
141 size -= read_len;
142 }
143
144 p_close(fd);
145 }
146
147 error = stream->finalize_write(oid, stream);
148
149 cleanup:
150 if (stream)
151 stream->free(stream);
152
153 git_buf_free(&full_path);
154
155 return error;
156 }
157