summaryrefslogtreecommitdiff
path: root/csum-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'csum-file.c')
-rw-r--r--csum-file.c139
1 files changed, 60 insertions, 79 deletions
diff --git a/csum-file.c b/csum-file.c
index b7174c6c05..4d50cc5ce1 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -8,15 +8,16 @@
* able to verify hasn't been messed with afterwards.
*/
#include "cache.h"
+#include "progress.h"
#include "csum-file.h"
-static void sha1flush(struct sha1file *f, unsigned int count)
+static void flush(struct sha1file *f, void * buf, unsigned int count)
{
- void *buf = f->buffer;
-
for (;;) {
int ret = xwrite(f->fd, buf, count);
if (ret > 0) {
+ f->total += ret;
+ display_throughput(f->tp, f->total);
buf = (char *) buf + ret;
count -= ret;
if (count)
@@ -25,26 +26,41 @@ static void sha1flush(struct sha1file *f, unsigned int count)
}
if (!ret)
die("sha1 file '%s' write error. Out of diskspace", f->name);
- die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
+ die_errno("sha1 file '%s' write error", f->name);
}
}
-int sha1close(struct sha1file *f, unsigned char *result, int update)
+void sha1flush(struct sha1file *f)
{
unsigned offset = f->offset;
+
if (offset) {
- SHA1_Update(&f->ctx, f->buffer, offset);
- sha1flush(f, offset);
+ git_SHA1_Update(&f->ctx, f->buffer, offset);
+ flush(f, f->buffer, offset);
+ f->offset = 0;
}
- SHA1_Final(f->buffer, &f->ctx);
+}
+
+int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
+{
+ int fd;
+
+ sha1flush(f);
+ git_SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
- if (update)
- sha1flush(f, 20);
- if (close(f->fd))
- die("%s: sha1 file error on close (%s)", f->name, strerror(errno));
+ if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
+ /* write checksum and close fd */
+ flush(f, f->buffer, 20);
+ if (flags & CSUM_FSYNC)
+ fsync_or_die(f->fd, f->name);
+ if (close(f->fd))
+ die_errno("%s: sha1 file error on close", f->name);
+ fd = 0;
+ } else
+ fd = f->fd;
free(f);
- return 0;
+ return fd;
}
int sha1write(struct sha1file *f, void *buf, unsigned int count)
@@ -53,15 +69,26 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
unsigned offset = f->offset;
unsigned left = sizeof(f->buffer) - offset;
unsigned nr = count > left ? left : count;
+ void *data;
+
+ if (f->do_crc)
+ f->crc32 = crc32(f->crc32, buf, nr);
+
+ if (nr == sizeof(f->buffer)) {
+ /* process full buffer directly without copy */
+ data = buf;
+ } else {
+ memcpy(f->buffer + offset, buf, nr);
+ data = f->buffer;
+ }
- memcpy(f->buffer + offset, buf, nr);
count -= nr;
offset += nr;
buf = (char *) buf + nr;
left -= nr;
if (!left) {
- SHA1_Update(&f->ctx, f->buffer, offset);
- sha1flush(f, offset);
+ git_SHA1_Update(&f->ctx, data, offset);
+ flush(f, data, offset);
offset = 0;
}
f->offset = offset;
@@ -69,78 +96,32 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
return 0;
}
-struct sha1file *sha1create(const char *fmt, ...)
+struct sha1file *sha1fd(int fd, const char *name)
{
- struct sha1file *f;
- unsigned len;
- va_list arg;
- int fd;
-
- f = xmalloc(sizeof(*f));
-
- va_start(arg, fmt);
- len = vsnprintf(f->name, sizeof(f->name), fmt, arg);
- va_end(arg);
- if (len >= PATH_MAX)
- die("you wascally wabbit, you");
- f->namelen = len;
-
- fd = open(f->name, O_CREAT | O_EXCL | O_WRONLY, 0666);
- if (fd < 0)
- die("unable to open %s (%s)", f->name, strerror(errno));
- f->fd = fd;
- f->error = 0;
- f->offset = 0;
- SHA1_Init(&f->ctx);
- return f;
+ return sha1fd_throughput(fd, name, NULL);
}
-struct sha1file *sha1fd(int fd, const char *name)
+struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp)
{
- struct sha1file *f;
- unsigned len;
-
- f = xmalloc(sizeof(*f));
-
- len = strlen(name);
- if (len >= PATH_MAX)
- die("you wascally wabbit, you");
- f->namelen = len;
- memcpy(f->name, name, len+1);
-
+ struct sha1file *f = xmalloc(sizeof(*f));
f->fd = fd;
- f->error = 0;
f->offset = 0;
- SHA1_Init(&f->ctx);
+ f->total = 0;
+ f->tp = tp;
+ f->name = name;
+ f->do_crc = 0;
+ git_SHA1_Init(&f->ctx);
return f;
}
-int sha1write_compressed(struct sha1file *f, void *in, unsigned int size)
+void crc32_begin(struct sha1file *f)
{
- z_stream stream;
- unsigned long maxsize;
- void *out;
-
- memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, zlib_compression_level);
- maxsize = deflateBound(&stream, size);
- out = xmalloc(maxsize);
-
- /* Compress it */
- stream.next_in = in;
- stream.avail_in = size;
-
- stream.next_out = out;
- stream.avail_out = maxsize;
-
- while (deflate(&stream, Z_FINISH) == Z_OK)
- /* nothing */;
- deflateEnd(&stream);
-
- size = stream.total_out;
- sha1write(f, out, size);
- free(out);
- return size;
+ f->crc32 = crc32(0, Z_NULL, 0);
+ f->do_crc = 1;
}
-
+uint32_t crc32_end(struct sha1file *f)
+{
+ f->do_crc = 0;
+ return f->crc32;
+}