From a89962b923788cf6db8910262042cb769ce0b9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 7 Aug 2008 07:29:29 +0000 Subject: [PATCH] * read_cdda_data() needs to know the last frame of the track, so that it can cut down the buffer size on the last request. This fixes bug #2565. * cdda_read() did report an incorrect number of bytes read. This fixes bug #2511, and also that you couldn't copy tracks via "cp". * cdda_read_stat() did not include the WAV header in its reported size. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26853 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/cdda/cdda.cpp | 6 ++++-- src/add-ons/kernel/file_systems/cdda/cdda.h | 6 +++--- .../file_systems/cdda/kernel_interface.cpp | 19 ++++++++++--------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/add-ons/kernel/file_systems/cdda/cdda.cpp b/src/add-ons/kernel/file_systems/cdda/cdda.cpp index b7f9ec03c8..7059a2c1fe 100644 --- a/src/add-ons/kernel/file_systems/cdda/cdda.cpp +++ b/src/add-ons/kernel/file_systems/cdda/cdda.cpp @@ -602,7 +602,7 @@ read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length) status_t -read_cdda_data(int fd, off_t offset, void *data, size_t length, +read_cdda_data(int fd, off_t endFrame, off_t offset, void *data, size_t length, off_t bufferOffset, void *buffer, size_t bufferSize) { if (bufferOffset >= 0 && bufferOffset <= offset + length @@ -627,12 +627,14 @@ read_cdda_data(int fd, off_t offset, void *data, size_t length, length -= bytes; } - // we don't handle the case we would need to split the request + // we don't handle the case where we would need to split the request } while (length > 0) { off_t frame = offset / kFrameSize; uint32 count = bufferSize / kFrameSize; + if (frame + count > endFrame) + count = endFrame - frame; status_t status = read_frames(fd, frame, (uint8 *)buffer, count); if (status < B_OK) diff --git a/src/add-ons/kernel/file_systems/cdda/cdda.h b/src/add-ons/kernel/file_systems/cdda/cdda.h index d0a5a9437b..293a0d3260 100644 --- a/src/add-ons/kernel/file_systems/cdda/cdda.h +++ b/src/add-ons/kernel/file_systems/cdda/cdda.h @@ -1,5 +1,5 @@ /* - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2007-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #ifndef CDDA_H @@ -30,7 +30,7 @@ struct cdtext { status_t read_cdtext(int fd, cdtext &text); status_t read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length); -status_t read_cdda_data(int fd, off_t offset, void *data, size_t length, - off_t bufferOffset, void *buffer, size_t bufferSize); +status_t read_cdda_data(int fd, off_t endFrame, off_t offset, void *data, + size_t length, off_t bufferOffset, void *buffer, size_t bufferSize); #endif // CDDA_H diff --git a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp index 730482abd3..71c4d5c0a1 100644 --- a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp @@ -388,7 +388,6 @@ read_attributes(int fd, Inode *inode) return false; count = B_BENDIAN_TO_HOST_INT32(count); -dprintf("inode %s read %lu attrs\n", inode->Name(), count); if (count > kMaxAttributes) return false; @@ -405,7 +404,6 @@ dprintf("inode %s read %lu attrs\n", inode->Name(), count); type = B_BENDIAN_TO_HOST_INT32(type); size = B_BENDIAN_TO_HOST_INT32(size); name[length] = '\0'; -dprintf(" type %08lx, size %lu, name %s\n", type, size, name); Attribute *attribute = new Attribute(name, type); if (attribute->SetSize(size) != B_OK @@ -431,7 +429,7 @@ fill_stat_buffer(Volume *volume, Inode *inode, Attribute *attribute, stat.st_mode = S_ATTR | 0666; stat.st_type = attribute->Type(); } else { - stat.st_size = inode->Size(); + stat.st_size = inode->Size() + sizeof(wav_header); stat.st_mode = inode->Type(); stat.st_type = 0; } @@ -782,7 +780,6 @@ Volume::_OpenAttributes(int mode, enum attr_mode attrMode) } else strlcat(path, "/shared", B_PATH_NAME_LENGTH); -dprintf("PATH: %s\n", path); int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644); free(path); @@ -807,7 +804,6 @@ Volume::_RestoreAttributes() return; } -dprintf("VOLUME %s\n", line); SetName(line); for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) { @@ -815,7 +811,6 @@ dprintf("VOLUME %s\n", line); break; inode->SetName(line); -dprintf("INODE %s\n", line); } if (read_attributes(fd, fRootNode)) { @@ -1546,17 +1541,20 @@ cdda_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t offset, length = maxSize - offset; status_t status = B_OK; + size_t bytesRead = 0; if (offset < sizeof(wav_header)) { // read fake WAV header size_t size = sizeof(wav_header) - offset; size = min_c(size, length); - if (user_memcpy(buffer, (uint8 *)inode->WAVHeader() + offset, size) < B_OK) + if (user_memcpy(buffer, (uint8 *)inode->WAVHeader() + offset, size) + < B_OK) return B_BAD_ADDRESS; buffer = (void *)((uint8 *)buffer + size); length -= size; + bytesRead += size; offset = 0; } else offset -= sizeof(wav_header); @@ -1565,11 +1563,14 @@ cdda_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t offset, // read actual CD data offset += inode->StartFrame() * kFrameSize; - status = read_cdda_data(volume->Device(), offset, buffer, length, + status = read_cdda_data(volume->Device(), + inode->StartFrame() + inode->FrameCount(), offset, buffer, length, cookie->buffer_offset, cookie->buffer, volume->BufferSize()); + + bytesRead += length; } if (status == B_OK) - *_length = length; + *_length = bytesRead; return status; }