haiku/src/apps/soundrecorder/FileUtils.cpp

140 lines
3.1 KiB
C++

/******************************************************************************
/
/ File: FileUtils.cpp
/
/ Description: Utility functions for copying file data and attributes.
/
/ Copyright 1998-1999, Be Incorporated, All Rights Reserved
/
******************************************************************************/
#include "FileUtils.h"
#include <algorithm>
#include <new>
#include <stdio.h>
#include <string.h>
#include <fs_attr.h>
#include "AutoDeleter.h"
using std::nothrow;
status_t
CopyFileData(BFile& dst, BFile& src)
{
struct stat src_stat;
status_t err = src.GetStat(&src_stat);
if (err != B_OK) {
printf("couldn't get stat: %#010" B_PRIx32 "\n", err);
return err;
}
size_t bufSize = src_stat.st_blksize;
if (bufSize == 0)
bufSize = 32768;
char* buf = new (nothrow) char[bufSize];
if (buf == NULL)
return B_NO_MEMORY;
ArrayDeleter<char> _(buf);
printf("copy data, bufSize = %ld\n", bufSize);
// copy data
while (true) {
ssize_t bytes = src.Read(buf, bufSize);
if (bytes > 0) {
ssize_t result = dst.Write(buf, bytes);
if (result != bytes) {
fprintf(stderr, "Failed to write %ld bytes: %s\n", bytes,
strerror((status_t)result));
if (result < 0)
return (status_t)result;
else
return B_IO_ERROR;
}
} else {
if (bytes < 0) {
fprintf(stderr, "Failed to read file: %s\n", strerror(
(status_t)bytes));
return (status_t)bytes;
} else {
// EOF
break;
}
}
}
// finish up miscellaneous stat stuff
dst.SetPermissions(src_stat.st_mode);
dst.SetOwner(src_stat.st_uid);
dst.SetGroup(src_stat.st_gid);
dst.SetModificationTime(src_stat.st_mtime);
dst.SetCreationTime(src_stat.st_crtime);
return B_OK;
}
status_t
CopyAttributes(BNode& dst, BNode& src)
{
// copy attributes
src.RewindAttrs();
char attrName[B_ATTR_NAME_LENGTH];
while (src.GetNextAttrName(attrName) == B_OK) {
attr_info info;
if (src.GetAttrInfo(attrName, &info) != B_OK) {
fprintf(stderr, "Failed to read info for attribute '%s'\n",
attrName);
continue;
}
// copy one attribute in chunks of 4096 bytes
size_t size = 4096;
uint8 buffer[size];
off_t offset = 0;
ssize_t read = src.ReadAttr(attrName, info.type, offset, buffer,
std::min((off_t)size, info.size));
if (read < 0) {
fprintf(stderr, "Error reading attribute '%s'\n", attrName);
return (status_t)read;
}
// NOTE: Attributes of size 0 are perfectly valid!
while (read >= 0) {
ssize_t written = dst.WriteAttr(attrName, info.type, offset,
buffer, read);
if (written != read) {
fprintf(stderr, "Error writing attribute '%s'\n", attrName);
if (written < 0)
return (status_t)written;
else
return B_IO_ERROR;
}
offset += read;
read = src.ReadAttr(attrName, info.type, offset, buffer,
std::min((off_t)size, info.size - offset));
if (read < 0) {
fprintf(stderr, "Error reading attribute '%s'\n", attrName);
return (status_t)read;
}
if (read == 0)
break;
}
}
return B_OK;
}
status_t
CopyFile(BFile& dst, BFile& src)
{
status_t err = CopyFileData(dst, src);
if (err != B_OK)
return err;
return CopyAttributes(dst, src);
}