Browse files

o report opening error.

o Close() in destructors, but not a feature of the FileHandler
  interface anymore.
o Better end-skip-detection: looks like some programs try to read
  beyond the end; pretend that we're exactly the reported file size
  long.
  • Loading branch information...
1 parent 15b305a commit 680f59094a79ee1e4110520ca738ac3fb946e093 @hzeller committed Sep 13, 2012
Showing with 30 additions and 17 deletions.
  1. +24 −14 convolver.cc
  2. +1 −1 file-handler.h
  3. +5 −2 fuse-convolve.c
View
38 convolver.cc
@@ -44,16 +44,15 @@ class PassThroughFilter : public FileHandler {
PassThroughFilter(int filedes, const char *path) : filedes_(filedes) {
fprintf(stderr, "Creating PassThrough filter for '%s'\n", path);
}
+ ~PassThroughFilter() { close(filedes_); }
+
virtual int Read(char *buf, size_t size, off_t offset) {
const int result = pread(filedes_, buf, size, offset);
return result == -1 ? -errno : result;
}
virtual int Stat(struct stat *st) {
return fstat(filedes_, st);
}
- virtual int Close() {
- return close(filedes_) == -1 ? -errno : 0;
- }
private:
const int filedes_;
@@ -100,6 +99,7 @@ class SndFileHandler :
}
virtual ~SndFileHandler() {
+ Close();
if (zita_.convproc) {
zita_.convproc->stop_process();
zita_.convproc->cleanup();
@@ -116,10 +116,15 @@ class SndFileHandler :
// Programs sometimes do this apparently.
// But of course only if this is really a detected skip.
if (output_buffer_->FileSize() < offset
- && (int) (offset + size) == file_stat_.st_size) {
+ && (int) (offset + size) >= file_stat_.st_size) {
fprintf(stderr, "[>> Skip to the very end detected. Avoid convolving.]\n");
- memset(buf, 0x00, size);
- return size;
+ const int pretended_available_bytes = file_stat_.st_size - offset;
+ if (pretended_available_bytes > 0) {
+ memset(buf, 0x00, pretended_available_bytes);
+ return pretended_available_bytes;
+ } else {
+ return 0;
+ }
}
// The following read might block and call WriteToSoundfile() until the
// buffer is filled.
@@ -144,13 +149,6 @@ class SndFileHandler :
*st = file_stat_;
return 0;
}
-
- virtual int Close() {
- output_buffer_->set_sndfile_writes_enabled(false);
- if (snd_in_) sf_close(snd_in_);
- if (snd_out_) sf_close(snd_out_);
- return close(filedes_) == -1 ? -errno : 0;
- }
private:
SndFileHandler(const char *path, int filedes, SNDFILE *snd_in,
@@ -300,6 +298,7 @@ class SndFileHandler :
sf_writef_float(snd_out_, raw_sample_buffer_, r);
input_frames_left_ -= r;
if (input_frames_left_ == 0) {
+ Close();
fprintf(stderr, "(fully decoded)\n");
}
return input_frames_left_;
@@ -371,6 +370,15 @@ class SndFileHandler :
}
}
+ void Close() {
+ if (snd_out_ == NULL) return; // done.
+ output_buffer_->set_sndfile_writes_enabled(false);
+ if (snd_in_) sf_close(snd_in_);
+ if (snd_out_) sf_close(snd_out_);
+ snd_out_ = NULL;
+ close(filedes_);
+ }
+
const int filedes_;
SNDFILE *const snd_in_;
const unsigned int total_frames_;
@@ -393,7 +401,7 @@ class SndFileHandler :
} // namespace
-static FileHandlerCache open_files_(10);
+static FileHandlerCache open_files_(1);
static FileHandler *CreateFilterFromFileType(int filedes,
const char *underlying_file) {
@@ -411,6 +419,8 @@ struct filter_object_t *create_filter(const char *fs_path,
FileHandler *handler = open_files_.FindAndPin(fs_path);
if (handler == NULL) {
int filedes = open(underlying_path, O_RDONLY);
+ if (filedes < 0)
+ return NULL;
handler = CreateFilterFromFileType(filedes, underlying_path);
handler = open_files_.InsertPinned(fs_path, handler);
}
View
2 file-handler.h
@@ -1,3 +1,4 @@
+// -*- c++ -*-
// Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
//
// This program is free software; you can redistribute it and/or modify
@@ -20,6 +21,5 @@ class FileHandler : public filter_object_t {
// Returns bytes read or a negative value indicating a negative errno.
virtual int Read(char *buf, size_t size, off_t offset) = 0;
virtual int Stat(struct stat *st) = 0;
- virtual int Close() = 0;
virtual ~FileHandler() {}
};
View
7 fuse-convolve.c
@@ -142,8 +142,11 @@ static int fuseconv_open(const char *path, struct fuse_file_info *fi) {
// (Yay, someone was thinking while developing that API).
char path_buf[PATH_MAX];
const char *orig_path = assemble_orig_path(path_buf, path);
- fi->fh = (uint64_t) create_filter(path, orig_path);
- return fi->fh == 0 ? -1 : 0;
+ struct filter_object_t* handler = create_filter(path, orig_path);
+ if (handler == NULL)
+ return -errno;
+ fi->fh = (uint64_t) handler;
+ return 0;
}
static int fuseconv_read(const char *path, char *buf, size_t size, off_t offset,

0 comments on commit 680f590

Please sign in to comment.