makeudfimage: Remove this tool completely
The AllocatorTest suite fails, and when investigating why it was broken I realized that it was testing code that has been dead and unused for quite some time. makeudfimage hasn't been touched since 2004 (5f2185ea0), and was removed from the build in 2006 (5adca30a1). The only changes that have been made to it since then are build fixes for the tests. Adding it back to the build would require some work since many things have changed since then. Since there are many other tools and libraries out there which can make UDF images (and which have been ported to Haiku), this code doesn't really seem worth maintaining at this point. This patch just removes it, as well as the associated tests. Change-Id: I23da8df83b7f141b3394a022030545d42a287881 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2332 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
ddb8a39005
commit
2a0d1eb890
@@ -257,7 +257,6 @@ SubInclude HAIKU_TOP src bin listdev ;
|
||||
SubInclude HAIKU_TOP src bin listusb ;
|
||||
SubInclude HAIKU_TOP src bin locale ;
|
||||
SubInclude HAIKU_TOP src bin makebootable ;
|
||||
#SubInclude HAIKU_TOP src bin makeudfimage ;
|
||||
SubInclude HAIKU_TOP src bin mail_utils ;
|
||||
SubInclude HAIKU_TOP src bin media_client ;
|
||||
SubInclude HAIKU_TOP src bin mkdos ;
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Allocator.cpp
|
||||
|
||||
Physical block allocator class implementation.
|
||||
*/
|
||||
|
||||
#include "Allocator.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
/*! \brief Creates a new Allocator object.
|
||||
*/
|
||||
Allocator::Allocator(uint32 blockSize)
|
||||
: fLength(0)
|
||||
, fBlockSize(blockSize)
|
||||
, fBlockShift(0)
|
||||
, fInitStatus(B_NO_INIT)
|
||||
{
|
||||
status_t error = get_block_shift(BlockSize(), fBlockShift);
|
||||
if (!error)
|
||||
fInitStatus = B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
Allocator::InitCheck() const
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
/*! \brief Allocates the given block, if available.
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure, the block has already been allocated.
|
||||
*/
|
||||
status_t
|
||||
Allocator::GetBlock(uint32 block)
|
||||
{
|
||||
extent_address extent(block, BlockSize());
|
||||
return GetExtent(extent);
|
||||
}
|
||||
|
||||
/*! \brief Allocates the given extent, if available.
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure, the extent (or some portion of it) has already
|
||||
been allocated.
|
||||
*/
|
||||
status_t
|
||||
Allocator::GetExtent(extent_address extent)
|
||||
{
|
||||
status_t error = InitCheck();
|
||||
if (!error) {
|
||||
uint32 offset = extent.location();
|
||||
uint32 length = BlocksFor(extent.length());
|
||||
// First see if the extent is past the allocation tail,
|
||||
// since we then don't have to do any chunklist traversal
|
||||
if (offset >= Length()) {
|
||||
// Add a new chunk to the end of the chunk list if
|
||||
// necessary
|
||||
if (offset > Length()) {
|
||||
extent_address chunk(Length(), (offset-Length())<<BlockShift());
|
||||
fChunkList.push_back(chunk);
|
||||
}
|
||||
// Adjust the tail
|
||||
fLength = offset+length;
|
||||
return B_OK;
|
||||
} else {
|
||||
// Block is not past tail, so check the chunk list
|
||||
for (list<extent_address>::iterator i = fChunkList.begin();
|
||||
i != fChunkList.end();
|
||||
i++)
|
||||
{
|
||||
uint32 chunkOffset = i->location();
|
||||
uint32 chunkLength = BlocksFor(i->length());
|
||||
if (chunkOffset <= offset && (offset+length) <= (chunkOffset+chunkLength)) {
|
||||
// Found it. Split the chunk. First look for an orphan
|
||||
// before the block, then after.
|
||||
if (chunkOffset < offset) {
|
||||
// Orhpan before; add a new chunk in front
|
||||
// of the current one
|
||||
extent_address chunk(chunkOffset, (offset-chunkOffset)<<BlockShift());
|
||||
fChunkList.insert(i, chunk);
|
||||
}
|
||||
if ((offset+length) < (chunkOffset+chunkLength)) {
|
||||
// Orphan after; resize the original chunk
|
||||
i->set_location(offset+length);
|
||||
i->set_length(((chunkOffset+chunkLength)-(offset+length))<<BlockSize());
|
||||
} else {
|
||||
// No orphan after; remove the original chunk
|
||||
fChunkList.erase(i);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
// No matching chunk found, we're SOL.
|
||||
error = B_ERROR;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*! \brief Allocates the next available block.
|
||||
|
||||
\param block Output parameter into which the number of the
|
||||
allocated block is stored.
|
||||
\param minimumBlock The minimum acceptable block number (used
|
||||
by the physical partition allocator).
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure, no blocks available.
|
||||
*/
|
||||
status_t
|
||||
Allocator::GetNextBlock(uint32 &block, uint32 minimumBlock)
|
||||
{
|
||||
status_t error = InitCheck();
|
||||
if (!error) {
|
||||
extent_address extent;
|
||||
error = GetNextExtent(BlockSize(), true, extent, minimumBlock);
|
||||
if (!error)
|
||||
block = extent.location();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*! \brief Allocates the next available extent of given length.
|
||||
|
||||
\param length The desired length (in bytes) of the extent.
|
||||
\param contiguous If false, signals that an extent of shorter length will
|
||||
be accepted. This allows for small chunks of
|
||||
unallocated space to be consumed, provided a
|
||||
contiguous chunk is not needed.
|
||||
\param extent Output parameter into which the extent as allocated
|
||||
is stored. Note that the length field of the extent
|
||||
may be shorter than the length parameter passed
|
||||
to this function is \a contiguous is false.
|
||||
\param minimumStartingBlock The minimum acceptable starting block
|
||||
for the extent (used by the physical
|
||||
partition allocator).
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure.
|
||||
*/
|
||||
status_t
|
||||
Allocator::GetNextExtent(uint32 _length, bool contiguous,
|
||||
extent_address &extent,
|
||||
uint32 minimumStartingBlock)
|
||||
{
|
||||
DEBUG_INIT_ETC("Allocator", ("length: %lld, contiguous: %d", _length, contiguous));
|
||||
uint32 length = BlocksFor(_length);
|
||||
bool isPartial = false;
|
||||
status_t error = InitCheck();
|
||||
PRINT(("allocation length: %lu\n", Length()));
|
||||
if (!error) {
|
||||
for (list<extent_address>::iterator i = fChunkList.begin();
|
||||
i != fChunkList.end();
|
||||
i++)
|
||||
{
|
||||
uint32 chunkOffset = i->location();
|
||||
uint32 chunkLength = BlocksFor(i->length());
|
||||
if (chunkOffset < minimumStartingBlock)
|
||||
{
|
||||
if (minimumStartingBlock < chunkOffset+chunkLength) {
|
||||
// Start of chunk is below min starting block. See if
|
||||
// any part of the chunk would make for an acceptable
|
||||
// allocation
|
||||
uint32 difference = minimumStartingBlock - chunkOffset;
|
||||
uint32 newOffset = minimumStartingBlock;
|
||||
uint32 newLength = chunkLength-difference;
|
||||
if (length <= newLength) {
|
||||
// new chunk is still long enough
|
||||
extent_address newExtent(newOffset, _length);
|
||||
if (GetExtent(newExtent) == B_OK) {
|
||||
extent = newExtent;
|
||||
return B_OK;
|
||||
}
|
||||
} else if (!contiguous) {
|
||||
// new chunk is too short, but we're allowed to
|
||||
// allocate a shorter extent, so we'll do it.
|
||||
extent_address newExtent(newOffset, newLength<<BlockShift());
|
||||
if (GetExtent(newExtent) == B_OK) {
|
||||
extent = newExtent;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (length <= chunkLength) {
|
||||
// Chunk is larger than necessary. Allocate first
|
||||
// length blocks, and resize the chunk appropriately.
|
||||
extent.set_location(chunkOffset);
|
||||
extent.set_length(_length);
|
||||
if (length != chunkLength) {
|
||||
i->set_location(chunkOffset+length);
|
||||
i->set_length((chunkLength-length)<<BlockShift());
|
||||
} else {
|
||||
fChunkList.erase(i);
|
||||
}
|
||||
return B_OK;
|
||||
} else if (!contiguous) {
|
||||
extent.set_location(chunkOffset);
|
||||
extent.set_length(chunkLength<<BlockShift());
|
||||
fChunkList.erase(i);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
// No sufficient chunk found, so try to allocate from the tail
|
||||
PRINT(("ULONG_MAX: %lu\n", ULONG_MAX));
|
||||
uint32 maxLength = ULONG_MAX-Length();
|
||||
PRINT(("maxLength: %lu\n", maxLength));
|
||||
error = maxLength > 0 ? B_OK : B_DEVICE_FULL;
|
||||
if (!error) {
|
||||
if (minimumStartingBlock > Tail())
|
||||
maxLength -= minimumStartingBlock - Tail();
|
||||
uint32 tail = minimumStartingBlock > Tail() ? minimumStartingBlock : Tail();
|
||||
if (length > maxLength) {
|
||||
if (contiguous)
|
||||
error = B_DEVICE_FULL;
|
||||
else {
|
||||
isPartial = true;
|
||||
length = maxLength;
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
extent_address newExtent(tail, isPartial ? length<<BlockShift() : _length);
|
||||
if (GetExtent(newExtent) == B_OK) {
|
||||
extent = newExtent;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*! \brief Returns the number of blocks needed to accomodate the
|
||||
given number of bytes.
|
||||
*/
|
||||
uint32
|
||||
Allocator::BlocksFor(off_t bytes)
|
||||
{
|
||||
if (BlockSize() == 0) {
|
||||
DEBUG_INIT_ETC("Allocator", ("bytes: %ld\n", bytes));
|
||||
PRINT(("WARNING: Allocator::BlockSize() == 0!\n"));
|
||||
return 0;
|
||||
} else {
|
||||
off_t blocks = bytes >> BlockShift();
|
||||
if (bytes % BlockSize() != 0)
|
||||
blocks++;
|
||||
uint64 mask = 0xffffffff;
|
||||
mask <<= 32;
|
||||
if (blocks & mask) {
|
||||
// ToDo: Convert this to actually signal an error
|
||||
DEBUG_INIT_ETC("Allocator", ("bytes: %ld\n", bytes));
|
||||
PRINT(("WARNING: bytes argument too large for corresponding number "
|
||||
"of blocks to be specified with a uint32! (bytes: %Ld, blocks: %Ld, "
|
||||
"maxblocks: %ld).\n", bytes, blocks, ULONG_MAX));
|
||||
blocks = 0;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Allocator.h
|
||||
|
||||
Physical block allocator class declarations.
|
||||
*/
|
||||
|
||||
#ifndef _UDF_ALLOCATOR_H
|
||||
#define _UDF_ALLOCATOR_H
|
||||
|
||||
#include <list>
|
||||
using std::list;
|
||||
|
||||
#include "UdfStructures.h"
|
||||
|
||||
/*! \brief This class keeps track of allocated and unallocated
|
||||
blocks in the range of 0 to 2^32.
|
||||
|
||||
By default, all blocks are unallocated.
|
||||
*/
|
||||
class Allocator {
|
||||
public:
|
||||
Allocator(uint32 blockSize);
|
||||
status_t InitCheck() const;
|
||||
|
||||
status_t GetBlock(uint32 block);
|
||||
status_t GetExtent(extent_address extent);
|
||||
|
||||
status_t GetNextBlock(uint32 &block, uint32 minimumBlock = 0);
|
||||
status_t GetNextExtent(uint32 length, bool contiguous,
|
||||
extent_address &extent,
|
||||
uint32 minimumStartingBlock = 0);
|
||||
|
||||
uint32 Length() const { return fLength; }
|
||||
uint32 Tail() const { return fLength; } //!< Returns the first unallocated block in the tail
|
||||
uint32 BlockSize() const { return fBlockSize; }
|
||||
uint32 BlockShift() const { return fBlockShift; }
|
||||
|
||||
uint32 BlocksFor(off_t bytes);
|
||||
private:
|
||||
list<extent_address> fChunkList;
|
||||
uint32 fLength; //!< Length of allocation so far, in blocks.
|
||||
uint32 fBlockSize;
|
||||
uint32 fBlockShift;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
#endif // _UDF_ALLOCATOR_H
|
||||
@@ -1,31 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Attribute.h
|
||||
|
||||
BDataIO wrapper around a given attribute for a file. (implementation)
|
||||
*/
|
||||
|
||||
#include "Attribute.h"
|
||||
|
||||
Attribute::Attribute(BNode &node, const char *attribute)
|
||||
: fNode(node)
|
||||
, fAttribute(attribute)
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t
|
||||
Attribute::Read(void *buffer, size_t size)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
Attribute::Write(const void *buffer, size_t size)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Attribute.h
|
||||
|
||||
BDataIO wrapper around a given attribute for a file. (declarations)
|
||||
*/
|
||||
|
||||
#ifndef _ATTRIBUTE_H
|
||||
#define _ATTRIBUTE_H
|
||||
|
||||
#include <DataIO.h>
|
||||
#include <Node.h>
|
||||
#include <string>
|
||||
|
||||
class Attribute : public BDataIO {
|
||||
public:
|
||||
Attribute(BNode &node, const char *attribute);
|
||||
virtual ssize_t Read(void *buffer, size_t size);
|
||||
virtual ssize_t Write(const void *buffer, size_t size);
|
||||
private:
|
||||
BNode fNode;
|
||||
string fAttribute;
|
||||
};
|
||||
|
||||
#endif // _ATTRIBUTE_H
|
||||
@@ -1,111 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file ConsoleListener.cpp
|
||||
|
||||
Console-based implementation of ProgressListener interface.
|
||||
*/
|
||||
|
||||
#include "ConsoleListener.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char * const kDivider =
|
||||
"----------------------------------------------------------------------";
|
||||
|
||||
/*! \brief Creates a new ConsoleListener object with the given verbosity level.
|
||||
|
||||
All output from said listener is sent to standard output via printf().
|
||||
|
||||
\param level All update messages with verbosity levels below this value
|
||||
will be ignored. If level is \c VERBOSITY_NONE, no output
|
||||
whatsoever (including errors and warnings) will be
|
||||
generated.
|
||||
*/
|
||||
ConsoleListener::ConsoleListener(VerbosityLevel level)
|
||||
: fLevel(level)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleListener::OnStart(const char *sourceDirectory, const char *outputFile,
|
||||
const char *udfVolumeName, uint16 udfRevision) const
|
||||
{
|
||||
if (Level() > VERBOSITY_NONE) {
|
||||
printf("%s\n", kDivider);
|
||||
printf("Source directory: `%s'\n", sourceDirectory);
|
||||
printf("Output file: `%s'\n", outputFile);
|
||||
printf("UDF Volume Name: `%s'\n", udfVolumeName);
|
||||
printf("UDF Revision: %01x.%01x%01x\n",
|
||||
(udfRevision & 0x0f00) >> 8,
|
||||
(udfRevision & 0x00f0) >> 4,
|
||||
(udfRevision & 0x000f));
|
||||
printf("%s\n", kDivider);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleListener::OnError(const char *message) const
|
||||
{
|
||||
if (Level() > VERBOSITY_NONE)
|
||||
printf("ERROR: %s\n", message);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleListener::OnWarning(const char *message) const
|
||||
{
|
||||
if (Level() > VERBOSITY_NONE)
|
||||
printf("WARNING: %s\n", message);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleListener::OnUpdate(VerbosityLevel level, const char *message) const
|
||||
{
|
||||
if (Level() > VERBOSITY_NONE && level <= Level()) {
|
||||
switch (level) {
|
||||
case VERBOSITY_MEDIUM:
|
||||
printf(" ");
|
||||
break;
|
||||
case VERBOSITY_HIGH:
|
||||
printf(" ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("%s\n", message);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleListener::OnCompletion(status_t result, const Statistics &statistics) const
|
||||
{
|
||||
if (Level() > VERBOSITY_NONE) {
|
||||
if (result == B_OK) {
|
||||
uint64 directories = statistics.Directories();
|
||||
uint64 files = statistics.Files();
|
||||
uint64 symlinks = statistics.Symlinks();
|
||||
printf("Finished\n");
|
||||
printf("- Build time: %s\n", statistics.ElapsedTimeString().c_str());
|
||||
printf("- Directories: %Ld director%s in %s\n",
|
||||
directories, directories == 1 ? "y" : "ies",
|
||||
statistics.DirectoryBytesString().c_str());
|
||||
printf("- Files: %Ld file%s in %s\n",
|
||||
files, files == 1 ? "" : "s",
|
||||
statistics.FileBytesString().c_str());
|
||||
if (symlinks > 0)
|
||||
printf("- Symlinks: No symlink support yet; %Ld symlink%s ommitted\n", symlinks,
|
||||
symlinks == 1 ? "" : "s");
|
||||
printf("- Image size: %s\n", statistics.ImageSizeString().c_str());
|
||||
} else {
|
||||
printf("----------------------------------------------------------------------\n");
|
||||
printf("Build failed with error: 0x%lx, `%s'\n", result,
|
||||
strerror(result));
|
||||
printf("----------------------------------------------------------------------\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file ConsoleListener.h
|
||||
|
||||
Declarations for a console-based implementation of ProgressListener
|
||||
interface.
|
||||
*/
|
||||
|
||||
#ifndef _CONSOLE_LISTENER_H
|
||||
#define _CONSOLE_LISTENER_H
|
||||
|
||||
#include "ProgressListener.h"
|
||||
|
||||
class ConsoleListener : public ProgressListener {
|
||||
public:
|
||||
ConsoleListener(VerbosityLevel level);
|
||||
virtual void OnStart(const char *sourceDirectory, const char *outputFile,
|
||||
const char *udfVolumeName, uint16 udfRevision) const;
|
||||
virtual void OnError(const char *message) const;
|
||||
virtual void OnWarning(const char *message) const;
|
||||
virtual void OnUpdate(VerbosityLevel level, const char *message) const;
|
||||
virtual void OnCompletion(status_t result, const Statistics &statistics) const;
|
||||
|
||||
VerbosityLevel Level() const { return fLevel; }
|
||||
private:
|
||||
VerbosityLevel fLevel;
|
||||
};
|
||||
|
||||
#endif // _CONSOLE_LISTENER_H
|
||||
@@ -1,38 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file DataStream.h
|
||||
*/
|
||||
|
||||
#ifndef _DATA_STREAM_H
|
||||
#define _DATA_STREAM_H
|
||||
|
||||
#include <DataIO.h>
|
||||
|
||||
class DataStream : public BPositionIO {
|
||||
public:
|
||||
virtual status_t InitCheck() const = 0;
|
||||
|
||||
virtual ssize_t Read(void *buffer, size_t size) = 0;
|
||||
virtual ssize_t ReadAt(off_t pos, void *buffer, size_t size) = 0;
|
||||
|
||||
virtual ssize_t Write(const void *buffer, size_t size) = 0;
|
||||
virtual ssize_t WriteAt(off_t pos, const void *buffer, size_t size) = 0;
|
||||
|
||||
virtual ssize_t Write(BDataIO &data, size_t size) = 0;
|
||||
virtual ssize_t WriteAt(off_t pos, BDataIO &data, size_t size) = 0;
|
||||
|
||||
virtual ssize_t Zero(size_t size) = 0;
|
||||
virtual ssize_t ZeroAt(off_t pos, size_t size) = 0;
|
||||
|
||||
virtual off_t Seek(off_t position, uint32 seek_mode) = 0;
|
||||
virtual off_t Position() const = 0;
|
||||
|
||||
virtual status_t SetSize(off_t size) = 0;
|
||||
};
|
||||
|
||||
#endif // _DATA_STREAM_H
|
||||
@@ -1,51 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file EmbeddedStream.cpp
|
||||
*/
|
||||
|
||||
#include "EmbeddedStream.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
EmbeddedStream::EmbeddedStream(DataStream &stream, off_t offset, size_t size)
|
||||
: SimulatedStream(stream)
|
||||
, fOffset(offset)
|
||||
, fSize(size)
|
||||
{
|
||||
}
|
||||
|
||||
/*! \brief Returns the largest extent in the underlying data stream
|
||||
corresponding to the extent starting at byte position \a pos of
|
||||
byte length \a size in the output parameter \a extent.
|
||||
|
||||
NOTE: If the position is at or beyond the end of the stream, the
|
||||
function will return B_OK, but the value of extent.size will be 0.
|
||||
*/
|
||||
status_t
|
||||
EmbeddedStream::_GetExtent(off_t pos, size_t size, data_extent &extent)
|
||||
{
|
||||
if (pos >= fSize) {
|
||||
// end of stream
|
||||
extent.offset = fOffset + fSize;
|
||||
extent.size = 0;
|
||||
} else {
|
||||
// valid position
|
||||
extent.offset = fOffset + pos;
|
||||
extent.size = fSize - pos;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*! \brief Returns the current size of the stream.
|
||||
*/
|
||||
off_t
|
||||
EmbeddedStream::_Size()
|
||||
{
|
||||
return fSize;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file EmbeddedStream.h
|
||||
*/
|
||||
|
||||
#ifndef _EMBEDDED_STREAM_H
|
||||
#define _EMBEDDED_STREAM_H
|
||||
|
||||
#include "SimulatedStream.h"
|
||||
|
||||
/*! \brief SimulatedStream implementation that takes a single,
|
||||
not-neccessarily-block-aligned extent.
|
||||
*/
|
||||
class EmbeddedStream : public SimulatedStream {
|
||||
public:
|
||||
EmbeddedStream(DataStream &stream, off_t offset, size_t size);
|
||||
|
||||
protected:
|
||||
virtual status_t _GetExtent(off_t pos, size_t size, data_extent &extent);
|
||||
virtual off_t _Size();
|
||||
|
||||
private:
|
||||
off_t fOffset;
|
||||
size_t fSize;
|
||||
};
|
||||
|
||||
#endif // _EMBEDDED_STREAM_H
|
||||
@@ -1,77 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file ExtentStream.cpp
|
||||
*/
|
||||
|
||||
#include "ExtentStream.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
ExtentStream::ExtentStream(DataStream &stream,
|
||||
const std::list<Udf::extent_address> &extentList,
|
||||
uint32 blockSize)
|
||||
: SimulatedStream(stream)
|
||||
, fExtentList(extentList)
|
||||
, fBlockSize(blockSize)
|
||||
, fSize(0)
|
||||
{
|
||||
for (std::list<Udf::extent_address>::const_iterator i = fExtentList.begin();
|
||||
i != fExtentList.end();
|
||||
i++)
|
||||
{
|
||||
fSize += i->length();
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Returns the largest extent in the underlying data stream
|
||||
corresponding to the extent starting at byte position \a pos of
|
||||
byte length \a size in the output parameter \a extent.
|
||||
|
||||
NOTE: If the position is at or beyond the end of the stream, the
|
||||
function will return B_OK, but the value of extent.size will be 0.
|
||||
*/
|
||||
status_t
|
||||
ExtentStream::_GetExtent(off_t pos, size_t size, data_extent &extent)
|
||||
{
|
||||
status_t error = pos >= 0 ? B_OK : B_BAD_VALUE;
|
||||
if (!error) {
|
||||
off_t finalOffset = 0;
|
||||
off_t streamPos = 0;
|
||||
for (std::list<Udf::extent_address>::const_iterator i = fExtentList.begin();
|
||||
i != fExtentList.end();
|
||||
i++)
|
||||
{
|
||||
off_t offset = i->location() * fBlockSize;
|
||||
finalOffset = offset + i->length();
|
||||
if (streamPos <= pos && pos < streamPos+i->length()) {
|
||||
// Found it
|
||||
off_t difference = pos - streamPos;
|
||||
extent.offset = offset + difference;
|
||||
extent.size = i->length() - difference;
|
||||
if (extent.size > size)
|
||||
extent.size = size;
|
||||
return B_OK;
|
||||
} else {
|
||||
streamPos += i->length();
|
||||
}
|
||||
}
|
||||
// Didn't find it, so pos is past the end of the stream
|
||||
extent.offset = finalOffset;
|
||||
extent.size = 0;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*! \brief Returns the current size of the stream.
|
||||
*/
|
||||
off_t
|
||||
ExtentStream::_Size()
|
||||
{
|
||||
return fSize;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file ExtentStream.h
|
||||
*/
|
||||
|
||||
#ifndef _EXTENT_STREAM_H
|
||||
#define _EXTENT_STREAM_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "SimulatedStream.h"
|
||||
#include "UdfStructures.h"
|
||||
|
||||
/*! \brief SimulatedStream implementation that takes a list of
|
||||
block-aligned data extents.
|
||||
*/
|
||||
class ExtentStream : public SimulatedStream {
|
||||
public:
|
||||
ExtentStream(DataStream &stream, const std::list<Udf::extent_address> &extentList, uint32 blockSize);
|
||||
|
||||
protected:
|
||||
virtual status_t _GetExtent(off_t pos, size_t size, data_extent &extent);
|
||||
virtual off_t _Size();
|
||||
|
||||
private:
|
||||
const std::list<Udf::extent_address> &fExtentList;
|
||||
const uint32 fBlockSize;
|
||||
off_t fSize;
|
||||
};
|
||||
|
||||
#endif // _EXTENT_STREAM_H
|
||||
@@ -1,30 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file FileStream.cpp
|
||||
*/
|
||||
|
||||
#include "FileStream.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
FileStream::FileStream(const char *path, uint32 open_mode)
|
||||
: PositionIOStream(fFile)
|
||||
, fFile(path, open_mode)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
FileStream::InitCheck() const
|
||||
{
|
||||
status_t error = PositionIOStream::InitCheck();
|
||||
if (!error)
|
||||
error = fFile.InitCheck();
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file FileStream.h
|
||||
*/
|
||||
|
||||
#ifndef _FILE_STREAM_H
|
||||
#define _FILE_STREAM_H
|
||||
|
||||
#include <File.h>
|
||||
|
||||
#include "PositionIOStream.h"
|
||||
|
||||
/*! \brief DataStream implementation that writes directly to a file.
|
||||
*/
|
||||
class FileStream : public PositionIOStream {
|
||||
public:
|
||||
FileStream(const char *path, uint32 open_mode);
|
||||
virtual status_t InitCheck() const;
|
||||
void Flush() { fFile.Sync(); }
|
||||
|
||||
private:
|
||||
BFile fFile;
|
||||
};
|
||||
|
||||
#endif // _FILE_STREAM_H
|
||||
@@ -1,42 +0,0 @@
|
||||
SubDir HAIKU_TOP src bin makeudfimage ;
|
||||
|
||||
UsePrivateHeaders [ FDirName kernel util ] ; # For kernel_cpp.h
|
||||
SubDirHdrs [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems udf ] ;
|
||||
|
||||
{
|
||||
local defines = [ FDefines USER ] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) ;
|
||||
}
|
||||
|
||||
BinCommand makeudfimage
|
||||
: makeudfimage.cpp
|
||||
Allocator.cpp
|
||||
Attribute.cpp
|
||||
ConsoleListener.cpp
|
||||
EmbeddedStream.cpp
|
||||
ExtentStream.cpp
|
||||
FileStream.cpp
|
||||
MemoryStream.cpp
|
||||
PhysicalPartitionAllocator.cpp
|
||||
PositionIOStream.cpp
|
||||
Shell.cpp
|
||||
SimulatedStream.cpp
|
||||
Statistics.cpp
|
||||
UdfBuilder.cpp
|
||||
|
||||
# Common Udf source files
|
||||
DString.cpp
|
||||
UdfDebug.cpp
|
||||
UdfString.cpp
|
||||
UdfStructures.cpp
|
||||
Utils.cpp
|
||||
|
||||
: stdc++.r4
|
||||
be
|
||||
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles DString.cpp UdfDebug.cpp UdfString.cpp UdfStructures.cpp Utils.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems udf ] ;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file MemoryStream.cpp
|
||||
*/
|
||||
|
||||
#include "MemoryStream.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
MemoryStream::MemoryStream(void *buffer, size_t length)
|
||||
: PositionIOStream(fMemory)
|
||||
, fMemory(buffer, length)
|
||||
, fInitStatus(buffer ? B_OK : B_NO_INIT)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
MemoryStream::InitCheck() const
|
||||
{
|
||||
status_t error = PositionIOStream::InitCheck();
|
||||
if (!error)
|
||||
error = fInitStatus;
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file MemoryStream.h
|
||||
*/
|
||||
|
||||
#ifndef _MEMORY_STREAM_H
|
||||
#define _MEMORY_STREAM_H
|
||||
|
||||
#include <DataIO.h>
|
||||
|
||||
#include "PositionIOStream.h"
|
||||
|
||||
/*! \brief DataStream implementation that writes directly to a chunk of memory.
|
||||
*/
|
||||
class MemoryStream : public PositionIOStream {
|
||||
public:
|
||||
MemoryStream(void *buffer, size_t length);
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
private:
|
||||
BMemoryIO fMemory;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
#endif // _MEMORY_STREAM_H
|
||||
@@ -1,142 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file PartitionAllocator.h
|
||||
|
||||
Udf physical partition allocator (implementation).
|
||||
*/
|
||||
|
||||
#include "PhysicalPartitionAllocator.h"
|
||||
|
||||
extent_address PhysicalPartitionAllocator::dummyExtent;
|
||||
|
||||
PhysicalPartitionAllocator::PhysicalPartitionAllocator(uint16 number,
|
||||
uint32 offset,
|
||||
Allocator &allocator)
|
||||
: fNumber(number)
|
||||
, fOffset(offset)
|
||||
, fAllocator(allocator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! \brief Allocates the next available block.
|
||||
|
||||
\param block Output parameter into which the number of the
|
||||
allocated block (in the partition) is stored.
|
||||
\param physicalBlock Output parameter into which the number of the
|
||||
allocated block (on the physical volume) is
|
||||
stored.
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure, no blocks available.
|
||||
*/
|
||||
status_t
|
||||
PhysicalPartitionAllocator::GetNextBlock(uint32 &block, uint32 &physicalBlock)
|
||||
{
|
||||
status_t error = fAllocator.GetNextBlock(physicalBlock, fOffset);
|
||||
if (!error)
|
||||
block = physicalBlock-fOffset;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*! \brief Allocates the next available extent of given length.
|
||||
|
||||
\param length The desired length (in bytes) of the extent.
|
||||
\param contiguous If false, signals that an extent of shorter length will
|
||||
be accepted. This allows for small chunks of
|
||||
unallocated space to be consumed, provided a
|
||||
contiguous chunk is not needed.
|
||||
\param extent Output parameter into which the extent as allocated
|
||||
in the partition is stored. Note that the length
|
||||
field of the extent may be shorter than the length
|
||||
parameter passed to this function is \a contiguous is
|
||||
false.
|
||||
\param physicalExtent Output parameter into which the extent as allocated
|
||||
on the physical volume is stored. Note that the length
|
||||
field of the extent may be shorter than the length
|
||||
parameter passed to this function is \a contiguous is
|
||||
false.
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure.
|
||||
*/
|
||||
status_t
|
||||
PhysicalPartitionAllocator::GetNextExtent(uint32 length,
|
||||
bool contiguous,
|
||||
long_address &extent,
|
||||
extent_address &physicalExtent)
|
||||
{
|
||||
status_t error = fAllocator.GetNextExtent(length, contiguous, physicalExtent, fOffset);
|
||||
if (!error) {
|
||||
extent.set_partition(PartitionNumber());
|
||||
extent.set_block(physicalExtent.location()-fOffset);
|
||||
extent.set_length(physicalExtent.length());
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*! \brief Allocates enough extents to add up to length bytes and stores said
|
||||
extents in the given address lists.
|
||||
|
||||
\param length The desired length (in bytes) to be allocated.
|
||||
\param extents Output parameter into which the extents as allocated
|
||||
in the partition are stored.
|
||||
\param physicalExtent Output parameter into which the extents as allocated
|
||||
on the physical volume are stored.
|
||||
|
||||
\return
|
||||
- B_OK: Success.
|
||||
- error code: Failure.
|
||||
*/
|
||||
status_t
|
||||
PhysicalPartitionAllocator::GetNextExtents(off_t length, std::list<long_address> &extents,
|
||||
std::list<extent_address> &physicalExtents)
|
||||
{
|
||||
DEBUG_INIT_ETC("PhysicalPartitionAllocator", ("length: %lld", length));
|
||||
extents.empty();
|
||||
physicalExtents.empty();
|
||||
|
||||
// Allocate extents until we're done or we hit an error
|
||||
status_t error = B_OK;
|
||||
while (error == B_OK) {
|
||||
long_address extent;
|
||||
extent_address physicalExtent;
|
||||
uint32 chunkLength = length <= ULONG_MAX ? uint32(length) : ULONG_MAX;
|
||||
error = GetNextExtent(chunkLength, false, extent, physicalExtent);
|
||||
if (!error) {
|
||||
extents.push_back(extent);
|
||||
physicalExtents.push_back(physicalExtent);
|
||||
if (physicalExtent.length() > chunkLength) {
|
||||
// This should never happen, but just to be safe
|
||||
PRINT(("ERROR: allocated extent length longer than requested "
|
||||
" extent length (allocated: %ld, requested: %ld)\n",
|
||||
physicalExtent.length(), chunkLength));
|
||||
error = B_ERROR;
|
||||
} else {
|
||||
// ToDo: Might want to add some checks for 0 length allocations here
|
||||
length -= physicalExtent.length();
|
||||
if (length == 0) {
|
||||
// All done
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RETURN(error);
|
||||
}
|
||||
|
||||
/*! \brief Returns the length of the partition in blocks.
|
||||
*/
|
||||
uint32
|
||||
PhysicalPartitionAllocator::Length() const
|
||||
{
|
||||
uint32 length = fAllocator.Length();
|
||||
return fOffset >= length ? 0 : length-fOffset;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file PhysicalPartitionAllocator.h
|
||||
|
||||
Udf physical partition allocator (declarations).
|
||||
*/
|
||||
|
||||
#ifndef _PHYSICAL_PARTITION_ALLOCATOR_H
|
||||
#define _PHYSICAL_PARTITION_ALLOCATOR_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "Allocator.h"
|
||||
#include "UdfStructures.h"
|
||||
|
||||
/*! \brief Allocates blocks and extents from a Udf physical partition.
|
||||
*/
|
||||
class PhysicalPartitionAllocator {
|
||||
public:
|
||||
PhysicalPartitionAllocator(uint16 number, uint32 offset, Allocator &allocator);
|
||||
|
||||
status_t GetNextBlock(uint32 &block, uint32 &physicalBlock);
|
||||
status_t GetNextExtent(uint32 length, bool contiguous, long_address &extent,
|
||||
extent_address &physicalExtent = dummyExtent);
|
||||
status_t GetNextExtents(off_t length, std::list<long_address> &extents,
|
||||
std::list<extent_address> &physicalExtents);
|
||||
|
||||
|
||||
uint16 PartitionNumber() const { return fNumber; }
|
||||
uint32 Length() const;
|
||||
private:
|
||||
static extent_address dummyExtent;
|
||||
uint16 fNumber; //!< The partition number of this partition
|
||||
uint32 fOffset; //!< The offset of the start of this partition in physical space
|
||||
Allocator &fAllocator;
|
||||
};
|
||||
|
||||
#endif // _PHYSICAL_PARTITION_ALLOCATOR_H
|
||||
@@ -1,207 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file PositionIOStream.cpp
|
||||
*/
|
||||
|
||||
#include "PositionIOStream.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
PositionIOStream::PositionIOStream(BPositionIO &stream)
|
||||
: fStream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t
|
||||
PositionIOStream::Read(void *buffer, size_t size)
|
||||
{
|
||||
return fStream.Read(buffer, size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
PositionIOStream::ReadAt(off_t pos, void *buffer, size_t size)
|
||||
{
|
||||
return fStream.ReadAt(pos, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
PositionIOStream::Write(const void *buffer, size_t size)
|
||||
{
|
||||
return fStream.Write(buffer, size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
PositionIOStream::WriteAt(off_t pos, const void *buffer, size_t size)
|
||||
{
|
||||
return fStream.WriteAt(pos, buffer, size);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of data from \a data at the current
|
||||
position in the file, incrementing the file's position marker as it goes.
|
||||
*/
|
||||
ssize_t
|
||||
PositionIOStream::Write(BDataIO &data, size_t size)
|
||||
{
|
||||
status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE;
|
||||
size_t bytes = 0;
|
||||
if (!error) {
|
||||
void *buffer = malloc(kBufferSize);
|
||||
error = buffer ? B_OK : B_NO_MEMORY;
|
||||
if (!error) {
|
||||
// Fudge the buffer size from here out if the requested
|
||||
// number of bytes to write is smaller than the buffer
|
||||
size_t bufferSize = (size < kBufferSize ? size : kBufferSize);
|
||||
// Zero
|
||||
memset(buffer, 0, bufferSize);
|
||||
// Write
|
||||
while (bytes < size) {
|
||||
ssize_t bytesRead = data.Read(buffer, bufferSize);
|
||||
if (bytesRead >= 0) {
|
||||
ssize_t bytesWritten = fStream.Write(buffer, bytesRead);
|
||||
if (bytesWritten >= 0) {
|
||||
bytes += bytesWritten;
|
||||
} else {
|
||||
error = status_t(bytesWritten);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
error = status_t(bytesRead);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
return error ? ssize_t(error) : ssize_t(bytes);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of data from \a data at position
|
||||
\a pos in the file without incrementing the file's position marker.
|
||||
*/
|
||||
ssize_t
|
||||
PositionIOStream::WriteAt(off_t pos, BDataIO &data, size_t size)
|
||||
{
|
||||
status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE;
|
||||
size_t bytes = 0;
|
||||
if (!error) {
|
||||
void *buffer = malloc(kBufferSize);
|
||||
error = buffer ? B_OK : B_NO_MEMORY;
|
||||
if (!error) {
|
||||
// Fudge the buffer size from here out if the requested
|
||||
// number of bytes to write is smaller than the buffer
|
||||
size_t bufferSize = (size < kBufferSize ? size : kBufferSize);
|
||||
// Zero
|
||||
memset(buffer, 0, bufferSize);
|
||||
// Write
|
||||
while (bytes < size) {
|
||||
ssize_t bytesRead = data.Read(buffer, bufferSize);
|
||||
if (bytesRead >= 0) {
|
||||
ssize_t bytesWritten = fStream.WriteAt(pos, buffer, bytesRead);
|
||||
if (bytesWritten >= 0) {
|
||||
bytes += bytesWritten;
|
||||
pos += bytesWritten;
|
||||
} else {
|
||||
error = status_t(bytesWritten);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
error = status_t(bytesRead);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
return error ? ssize_t(error) : ssize_t(bytes);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of zeros at the current position
|
||||
in the file, incrementing the file's position marker as it goes.
|
||||
*/
|
||||
ssize_t
|
||||
PositionIOStream::Zero(size_t size)
|
||||
{
|
||||
status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE;
|
||||
size_t bytes = 0;
|
||||
if (!error) {
|
||||
void *buffer = malloc(kBufferSize);
|
||||
error = buffer ? B_OK : B_NO_MEMORY;
|
||||
if (!error) {
|
||||
// Fudge the buffer size from here out if the requested
|
||||
// number of bytes to write is smaller than the buffer
|
||||
size_t bufferSize = (size < kBufferSize ? size : kBufferSize);
|
||||
// Zero
|
||||
memset(buffer, 0, bufferSize);
|
||||
// Write
|
||||
while (bytes < size) {
|
||||
ssize_t bytesWritten = fStream.Write(buffer, bufferSize);
|
||||
if (bytesWritten >= 0) {
|
||||
bytes += bytesWritten;
|
||||
} else {
|
||||
error = status_t(bytesWritten);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
return error ? ssize_t(error) : ssize_t(bytes);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of zeros at position \a pos
|
||||
in the file without incrementing the file's position marker.
|
||||
*/
|
||||
ssize_t
|
||||
PositionIOStream::ZeroAt(off_t pos, size_t size)
|
||||
{
|
||||
status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE;
|
||||
size_t bytes = 0;
|
||||
if (!error) {
|
||||
void *buffer = malloc(kBufferSize);
|
||||
error = buffer ? B_OK : B_NO_MEMORY;
|
||||
if (!error) {
|
||||
// Fudge the buffer size from here out if the requested
|
||||
// number of bytes to write is smaller than the buffer
|
||||
size_t bufferSize = (size < kBufferSize ? size : kBufferSize);
|
||||
// Zero
|
||||
memset(buffer, 0, bufferSize);
|
||||
// Write
|
||||
while (bytes < size) {
|
||||
ssize_t bytesWritten = fStream.WriteAt(pos, buffer, bufferSize);
|
||||
if (bytesWritten >= 0) {
|
||||
bytes += bytesWritten;
|
||||
pos += bytesWritten;
|
||||
} else {
|
||||
error = status_t(bytesWritten);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
return error ? ssize_t(error) : ssize_t(bytes);
|
||||
}
|
||||
|
||||
off_t
|
||||
PositionIOStream::Seek(off_t position, uint32 seek_mode)
|
||||
{
|
||||
return fStream.Seek(position, seek_mode);
|
||||
}
|
||||
|
||||
off_t
|
||||
PositionIOStream::Position() const
|
||||
{
|
||||
return fStream.Position();
|
||||
}
|
||||
|
||||
status_t
|
||||
PositionIOStream::SetSize(off_t size)
|
||||
{
|
||||
return fStream.SetSize(size);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file PositionIOStream.h
|
||||
*/
|
||||
|
||||
#ifndef _POSITION_IO_STREAM_H
|
||||
#define _POSITION_IO_STREAM_H
|
||||
|
||||
#include <DataIO.h>
|
||||
|
||||
#include "DataStream.h"
|
||||
|
||||
/*! \brief DataStream implementation that writes to a BPositionIO.
|
||||
*/
|
||||
class PositionIOStream : public DataStream {
|
||||
public:
|
||||
PositionIOStream(BPositionIO &stream);
|
||||
virtual status_t InitCheck() const { return B_OK; }
|
||||
|
||||
static const size_t kBufferSize = 32 * 1024;
|
||||
|
||||
virtual ssize_t Read(void *buffer, size_t size);
|
||||
virtual ssize_t ReadAt(off_t pos, void *buffer, size_t size);
|
||||
|
||||
virtual ssize_t Write(const void *buffer, size_t size);
|
||||
virtual ssize_t WriteAt(off_t pos, const void *buffer, size_t size);
|
||||
|
||||
virtual ssize_t Write(BDataIO &data, size_t size);
|
||||
virtual ssize_t WriteAt(off_t pos, BDataIO &data, size_t size);
|
||||
|
||||
virtual ssize_t Zero(size_t size);
|
||||
virtual ssize_t ZeroAt(off_t pos, size_t size);
|
||||
|
||||
virtual off_t Seek(off_t position, uint32 seek_mode);
|
||||
virtual off_t Position() const;
|
||||
|
||||
virtual status_t SetSize(off_t size);
|
||||
private:
|
||||
BPositionIO &fStream;
|
||||
};
|
||||
|
||||
#endif // _POSITION_IO_STREAM_H
|
||||
@@ -1,36 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file ProgressListener.h
|
||||
|
||||
Interface for receiving progress information updates from an
|
||||
executing UdfBuilder object.
|
||||
*/
|
||||
|
||||
#ifndef _PROGRESS_LISTENER_H
|
||||
#define _PROGRESS_LISTENER_H
|
||||
|
||||
#include "Statistics.h"
|
||||
|
||||
enum VerbosityLevel {
|
||||
VERBOSITY_NONE,
|
||||
VERBOSITY_LOW,
|
||||
VERBOSITY_MEDIUM,
|
||||
VERBOSITY_HIGH,
|
||||
};
|
||||
|
||||
class ProgressListener {
|
||||
public:
|
||||
virtual void OnStart(const char *sourceDirectory, const char *outputFile,
|
||||
const char *udfVolumeName, uint16 udfRevision) const = 0;
|
||||
virtual void OnError(const char *message) const = 0;
|
||||
virtual void OnWarning(const char *message) const = 0;
|
||||
virtual void OnUpdate(VerbosityLevel level, const char *message) const = 0;
|
||||
virtual void OnCompletion(status_t result, const Statistics &statistics) const = 0;
|
||||
};
|
||||
|
||||
#endif // _PROGRESS_LISTENER_H
|
||||
@@ -1,173 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Shell.cpp
|
||||
|
||||
Command-line shell for makeudfimage
|
||||
*/
|
||||
|
||||
#include "Shell.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ConsoleListener.h"
|
||||
#include "UdfDebug.h"
|
||||
#include "UdfBuilder.h"
|
||||
|
||||
Shell::Shell()
|
||||
// The following settings are essentially default values
|
||||
// for all the command-line options (except for the last
|
||||
// three vars).
|
||||
: fVerbosityLevel(VERBOSITY_LOW)
|
||||
, fBlockSize(2048)
|
||||
, fDoUdf(true)
|
||||
, fDoIso(false)
|
||||
, fSourceDirectory("")
|
||||
, fOutputFile("")
|
||||
, fUdfVolumeName("")
|
||||
, fUdfRevision(0x0201)
|
||||
, fTruncate(true)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
Shell::Run(int argc, char *argv[])
|
||||
{
|
||||
DEBUG_INIT("Shell");
|
||||
status_t error = _ProcessArguments(argc, argv);
|
||||
if (!error) {
|
||||
if (fUdfVolumeName == "")
|
||||
fUdfVolumeName = "(Unnamed UDF Volume)";
|
||||
ConsoleListener listener(fVerbosityLevel);
|
||||
UdfBuilder builder(fOutputFile.c_str(), fBlockSize, fDoUdf,
|
||||
fUdfVolumeName.c_str(), fUdfRevision, fDoIso, "ISO_VOLUME",
|
||||
fSourceDirectory.c_str(), listener, fTruncate);
|
||||
error = builder.InitCheck();
|
||||
if (!error)
|
||||
error = builder.Build();
|
||||
}
|
||||
|
||||
if (error)
|
||||
_PrintHelp();
|
||||
|
||||
RETURN(error);
|
||||
}
|
||||
|
||||
status_t
|
||||
Shell::_ProcessArguments(int argc, char *argv[]) {
|
||||
DEBUG_INIT_ETC("Shell", ("argc: %d", argc));
|
||||
|
||||
// Throw all the arguments into a handy list
|
||||
std::list<std::string> argumentList;
|
||||
for (int i = 1; i < argc; i++)
|
||||
argumentList.push_back(std::string(argv[i]));
|
||||
|
||||
bool foundSourceDirectory = false;
|
||||
bool foundOutputFile = false;
|
||||
bool foundUdfVolumeName = false;
|
||||
|
||||
// Now bust out some processing
|
||||
int argumentCount = argumentList.size();
|
||||
int index = 0;
|
||||
for(std::list<std::string>::iterator i = argumentList.begin();
|
||||
i != argumentList.end();
|
||||
)
|
||||
{
|
||||
std::string &arg = *i;
|
||||
if (arg == "-h" || arg == "--help") {
|
||||
_PrintTitle();
|
||||
RETURN(B_ERROR);
|
||||
} else if (arg == "-v0" || arg == "--quiet") {
|
||||
fVerbosityLevel = VERBOSITY_NONE;
|
||||
} else if (arg == "-v1") {
|
||||
fVerbosityLevel = VERBOSITY_LOW;
|
||||
} else if (arg == "-v2") {
|
||||
fVerbosityLevel = VERBOSITY_MEDIUM;
|
||||
} else if (arg == "-v3") {
|
||||
fVerbosityLevel = VERBOSITY_HIGH;
|
||||
} else if (arg == "-r" || arg == "--revision") {
|
||||
i++;
|
||||
index++;
|
||||
if (*i == "1.50")
|
||||
fUdfRevision = 0x0150;
|
||||
else if (*i == "2.01")
|
||||
fUdfRevision = 0x0201;
|
||||
else {
|
||||
printf("ERROR: invalid UDF revision `%s'; please specify `1.50' "
|
||||
"or `2.01'\n", i->c_str());
|
||||
RETURN(B_ERROR);
|
||||
}
|
||||
} else if (arg == "-t" || arg == "--no-truncate") {
|
||||
fTruncate = 0;
|
||||
} else {
|
||||
if (index == argumentCount-3) {
|
||||
// Take this argument as the source dir
|
||||
fSourceDirectory = arg;
|
||||
foundSourceDirectory = true;
|
||||
} else if (index == argumentCount-2) {
|
||||
// Take this argument as the output filename
|
||||
fOutputFile = arg;
|
||||
foundOutputFile = true;
|
||||
} else if (index == argumentCount-1) {
|
||||
// Take this argument as the udf volume name
|
||||
fUdfVolumeName = arg;
|
||||
foundUdfVolumeName = true;
|
||||
} else {
|
||||
printf("ERROR: invalid argument `%s'\n", arg.c_str());
|
||||
printf("\n");
|
||||
RETURN(B_ERROR);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
index++;
|
||||
}
|
||||
|
||||
status_t error = B_OK;
|
||||
if (!foundSourceDirectory) {
|
||||
printf("ERROR: no source directory specified\n");
|
||||
error = B_ERROR;
|
||||
}
|
||||
if (!foundOutputFile) {
|
||||
printf("ERROR: no output file specified\n");
|
||||
error = B_ERROR;
|
||||
}
|
||||
if (!foundUdfVolumeName) {
|
||||
printf("ERROR: no volume name specified\n");
|
||||
error = B_ERROR;
|
||||
}
|
||||
|
||||
if (error)
|
||||
printf("\n");
|
||||
RETURN(error);
|
||||
}
|
||||
|
||||
void
|
||||
Shell::_PrintHelp() {
|
||||
printf("usage: makeudfimage [options] <source-directory> <output-file> <udf-volume-name>\n");
|
||||
printf("example: makeudfimage /boot/home/mail mail.udf \"Mail Backup\"\n");
|
||||
printf("\n");
|
||||
printf("VALID OPTIONS:\n");
|
||||
printf(" -h, --help Displays this help text.\n");
|
||||
printf(" --quiet Turns off console output.\n");
|
||||
printf(" -r, --revision <udf-revision> Selects the UDF revision to use. Supported\n");
|
||||
printf(" revisions are 1.50 and 2.01. Defaults to 2.01.\n");
|
||||
printf(" -t, --no-trunc Don't truncate output file if it already\n");
|
||||
printf(" exists.\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#define MAKEUDFIMAGE_VERSION "1.0.0"
|
||||
#ifndef MAKEUDFIMAGE_VERSION
|
||||
# define MAKEUDFIMAGE_VERSION ("development version " __DATE__ ", " __TIME__)
|
||||
#endif
|
||||
|
||||
void
|
||||
Shell::_PrintTitle() {
|
||||
printf("makeudfimage %s\n", MAKEUDFIMAGE_VERSION);
|
||||
printf("Copyright © 2004 Tyler Dauwalder\n");
|
||||
printf("\n");
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Shell.h
|
||||
*/
|
||||
|
||||
#ifndef _SHELL_H
|
||||
#define _SHELL_H
|
||||
|
||||
#include <string>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "ProgressListener.h"
|
||||
|
||||
class Shell {
|
||||
public:
|
||||
Shell();
|
||||
status_t Run(int argc, char *argv[]);
|
||||
|
||||
private:
|
||||
status_t _ProcessArguments(int argc, char *argv[]);
|
||||
void _PrintHelp();
|
||||
void _PrintTitle();
|
||||
|
||||
VerbosityLevel fVerbosityLevel;
|
||||
uint32 fBlockSize;
|
||||
bool fDoUdf;
|
||||
bool fDoIso;
|
||||
std::string fSourceDirectory;
|
||||
std::string fOutputFile;
|
||||
std::string fUdfVolumeName;
|
||||
uint16 fUdfRevision;
|
||||
bool fTruncate;
|
||||
};
|
||||
|
||||
|
||||
#endif // _SHELL_H
|
||||
@@ -1,297 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file SimulatedStream.cpp
|
||||
*/
|
||||
|
||||
#include "SimulatedStream.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "UdfDebug.h"
|
||||
|
||||
SimulatedStream::SimulatedStream(DataStream &stream)
|
||||
: fPosition(0)
|
||||
, fStream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
SimulatedStream::InitCheck() const
|
||||
{
|
||||
return fStream.InitCheck();
|
||||
}
|
||||
|
||||
ssize_t
|
||||
SimulatedStream::Read(void *_buffer, size_t size)
|
||||
{
|
||||
uint8 *buffer = reinterpret_cast<uint8*>(_buffer);
|
||||
status_t error = buffer ? B_OK : B_BAD_VALUE;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(fPosition, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.ReadAt(extent.offset, buffer, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
fPosition += bytes;
|
||||
buffer += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
SimulatedStream::ReadAt(off_t pos, void *_buffer, size_t size)
|
||||
{
|
||||
uint8 *buffer = reinterpret_cast<uint8*>(_buffer);
|
||||
status_t error = buffer ? B_OK : B_BAD_VALUE;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(pos, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.ReadAt(extent.offset, buffer, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
pos += bytes;
|
||||
buffer += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of data from \a buffer at the current
|
||||
position in the stream, incrementing the stream's position marker as it goes.
|
||||
*/
|
||||
ssize_t
|
||||
SimulatedStream::Write(const void *_buffer, size_t size)
|
||||
{
|
||||
const uint8 *buffer = reinterpret_cast<const uint8*>(_buffer);
|
||||
status_t error = buffer ? B_OK : B_BAD_VALUE;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(fPosition, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.WriteAt(extent.offset, buffer, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
fPosition += bytes;
|
||||
buffer += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of data from \a buffer at position
|
||||
\a pos in the stream without incrementing the stream's position marker.
|
||||
*/
|
||||
ssize_t
|
||||
SimulatedStream::WriteAt(off_t pos, const void *_buffer, size_t size)
|
||||
{
|
||||
const uint8 *buffer = reinterpret_cast<const uint8*>(_buffer);
|
||||
status_t error = buffer ? B_OK : B_BAD_VALUE;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(pos, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.WriteAt(extent.offset, buffer, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
pos += bytes;
|
||||
buffer += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of data from \a data at the current
|
||||
position in the stream, incrementing the stream's position marker as it goes.
|
||||
*/
|
||||
ssize_t
|
||||
SimulatedStream::Write(BDataIO &data, size_t size)
|
||||
{
|
||||
DEBUG_INIT_ETC("SimulatedStream", ("size: %ld", size));
|
||||
status_t error = B_OK;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(fPosition, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
PRINT(("writing to underlying stream (offset: %llu, size: %ld)\n", extent.offset, extent.size));
|
||||
ssize_t bytes = fStream.WriteAt(extent.offset, data, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
fPosition += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RETURN(!error ? bytesTotal : ssize_t(error));
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of data from \a data at position
|
||||
\a pos in the stream without incrementing the stream's position marker.
|
||||
*/
|
||||
ssize_t
|
||||
SimulatedStream::WriteAt(off_t pos, BDataIO &data, size_t size)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(pos, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.WriteAt(extent.offset, data, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
pos += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of zeros at the current position
|
||||
in the stream, incrementing the stream's position marker as it goes.
|
||||
*/
|
||||
ssize_t
|
||||
SimulatedStream::Zero(size_t size)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(fPosition, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.ZeroAt(extent.offset, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
fPosition += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
/*! \brief Writes \a size bytes worth of zeros at position \a pos
|
||||
in the stream without incrementing the stream's position marker.
|
||||
*/
|
||||
ssize_t
|
||||
SimulatedStream::ZeroAt(off_t pos, size_t size)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
ssize_t bytesTotal = 0;
|
||||
while (error == B_OK && size > 0) {
|
||||
data_extent extent;
|
||||
error = _GetExtent(pos, size, extent);
|
||||
if (!error) {
|
||||
if (extent.size > 0) {
|
||||
ssize_t bytes = fStream.ZeroAt(extent.offset, extent.size);
|
||||
if (bytes >= 0) {
|
||||
size -= bytes;
|
||||
pos += bytes;
|
||||
bytesTotal += bytes;
|
||||
} else {
|
||||
error = status_t(bytes);
|
||||
}
|
||||
} else {
|
||||
// end of simulated stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !error ? bytesTotal : ssize_t(error);
|
||||
}
|
||||
|
||||
off_t
|
||||
SimulatedStream::Seek(off_t pos, uint32 seek_mode)
|
||||
{
|
||||
off_t size = _Size();
|
||||
switch (seek_mode) {
|
||||
case SEEK_SET:
|
||||
fPosition = pos;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
fPosition += pos;
|
||||
break;
|
||||
case SEEK_END:
|
||||
fPosition = size + pos;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Range check
|
||||
if (fPosition < 0)
|
||||
fPosition = 0;
|
||||
else if (fPosition > size && SetSize(fPosition) != B_OK)
|
||||
fPosition = size;
|
||||
return fPosition;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file SimulatedStream.h
|
||||
*/
|
||||
|
||||
#ifndef _SIMULATED_STREAM_H
|
||||
#define _SIMULATED_STREAM_H
|
||||
|
||||
#include "DataStream.h"
|
||||
|
||||
/*! \brief Abstract DataStream wrapper around another DataStream and a sequence of
|
||||
extents in said stream that allows for easy write access to said sequence
|
||||
of extents as though they were a continuous chunk of data.
|
||||
|
||||
NOTE: The SimulatedStream object never modifies the data stream position
|
||||
of the underlying data stream; all read/write/zero calls use the underlying
|
||||
stream's ReadAt()/WriteAt()/ZeroAt() functions.
|
||||
*/
|
||||
class SimulatedStream : public DataStream {
|
||||
public:
|
||||
SimulatedStream(DataStream &stream);
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
virtual ssize_t Read(void *buffer, size_t size);
|
||||
virtual ssize_t ReadAt(off_t pos, void *buffer, size_t size);
|
||||
|
||||
virtual ssize_t Write(const void *buffer, size_t size);
|
||||
virtual ssize_t WriteAt(off_t pos, const void *buffer, size_t size);
|
||||
|
||||
virtual ssize_t Write(BDataIO &data, size_t size);
|
||||
virtual ssize_t WriteAt(off_t pos, BDataIO &data, size_t size);
|
||||
|
||||
virtual ssize_t Zero(size_t size);
|
||||
virtual ssize_t ZeroAt(off_t pos, size_t size);
|
||||
|
||||
virtual off_t Seek(off_t pos, uint32 seek_mode);
|
||||
virtual off_t Position() const { return fPosition; }
|
||||
|
||||
virtual status_t SetSize(off_t size) { return B_ERROR; }
|
||||
|
||||
protected:
|
||||
struct data_extent {
|
||||
data_extent(off_t offset = 0, size_t size = 0)
|
||||
: offset(offset)
|
||||
, size(size)
|
||||
{
|
||||
}
|
||||
|
||||
off_t offset;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/*! \brief Should be implemented to return (via the output parameter
|
||||
\a extent) the largest extent in the underlying data stream corresponding
|
||||
to the extent in the simulated data stream starting at byte position
|
||||
\a pos of byte length \a size.
|
||||
|
||||
NOTE: If the position is at or beyond the end of the simulated stream, the
|
||||
function should return B_OK, and the value of extent.size should be 0.
|
||||
*/
|
||||
virtual status_t _GetExtent(off_t pos, size_t size, data_extent &extent) = 0;
|
||||
|
||||
/*! \brief Should be implemented to return the current size of the stream.
|
||||
*/
|
||||
virtual off_t _Size() = 0;
|
||||
|
||||
private:
|
||||
off_t fPosition;
|
||||
DataStream &fStream;
|
||||
};
|
||||
|
||||
#endif // _SIMULATED_STREAM_H
|
||||
@@ -1,158 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Statistics.h
|
||||
|
||||
BDataIO wrapper around a given attribute for a file. (implementation)
|
||||
*/
|
||||
|
||||
#include "Statistics.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*! \brief Returns a string describing the given number of bytes
|
||||
in the most appropriate units (i.e. bytes, KB, MB, etc.).
|
||||
*/
|
||||
std::string
|
||||
bytes_to_string(uint64 bytes)
|
||||
{
|
||||
const uint64 kb = 1024; // kilo
|
||||
const uint64 mb = 1024 * kb; // mega
|
||||
const uint64 gb = 1024 * mb; // giga
|
||||
const uint64 tb = 1024 * gb; // tera
|
||||
const uint64 pb = 1024 * tb; // peta
|
||||
const uint64 eb = 1024 * pb; // exa
|
||||
std::string units;
|
||||
uint64 divisor = 1;
|
||||
if (bytes >= eb) {
|
||||
units = "EB";
|
||||
divisor = eb;
|
||||
} else if (bytes >= pb) {
|
||||
units = "PB";
|
||||
divisor = pb;
|
||||
} else if (bytes >= tb) {
|
||||
units = "TB";
|
||||
divisor = tb;
|
||||
} else if (bytes >= gb) {
|
||||
units = "GB";
|
||||
divisor = gb;
|
||||
} else if (bytes >= mb) {
|
||||
units = "MB";
|
||||
divisor = mb;
|
||||
} else if (bytes >= kb) {
|
||||
units = "KB";
|
||||
divisor = kb;
|
||||
} else {
|
||||
units = "bytes";
|
||||
divisor = 1;
|
||||
}
|
||||
double scaledValue = double(bytes) / double(divisor);
|
||||
char scaledString[10];
|
||||
// Should really only need 7 chars + NULL...
|
||||
sprintf(scaledString, divisor == 1 ? "%.0f " : "%.1f ", scaledValue);
|
||||
return std::string(scaledString) + units;
|
||||
}
|
||||
|
||||
/*! \brief Creates a new statistics object and sets the start time
|
||||
for the duration timer.
|
||||
*/
|
||||
Statistics::Statistics()
|
||||
: fStartTime(real_time_clock())
|
||||
, fDirectories(0)
|
||||
, fFiles(0)
|
||||
, fSymlinks(0)
|
||||
, fAttributes(0)
|
||||
, fDirectoryBytes(0)
|
||||
, fFileBytes(0)
|
||||
, fImageSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*! \brief Resets all statistics fields, including the start time of
|
||||
the duration timer.
|
||||
*/
|
||||
void
|
||||
Statistics::Reset()
|
||||
{
|
||||
Statistics null;
|
||||
*this = null;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns a string describing the amount of time
|
||||
elapsed since the object was created..
|
||||
*/
|
||||
std::string
|
||||
Statistics::ElapsedTimeString() const
|
||||
{
|
||||
time_t time = ElapsedTime();
|
||||
std::string result;
|
||||
char buffer[256];
|
||||
// seconds
|
||||
uint32 seconds = time % 60;
|
||||
sprintf(buffer, "%ld second%s", seconds, seconds == 1 ? "" : "s");
|
||||
result = buffer;
|
||||
time /= 60;
|
||||
if (time > 0) {
|
||||
// minutes
|
||||
uint32 minutes = time % 60;
|
||||
sprintf(buffer, "%ld minute%s", minutes, minutes == 1 ? "" : "s");
|
||||
result = std::string(buffer) + ", " + result;
|
||||
time /= 60;
|
||||
if (time > 0) {
|
||||
// hours
|
||||
uint32 hours = time % 24;
|
||||
sprintf(buffer, "%ld hour%s", hours, hours == 1 ? "" : "s");
|
||||
result = std::string(buffer) + ", " + result;
|
||||
time /= 24;
|
||||
if (time > 0) {
|
||||
// days
|
||||
uint32 days = time % 365;
|
||||
sprintf(buffer, "%ld day%s", days, days == 1 ? "" : "s");
|
||||
result = std::string(buffer) + ", " + result;
|
||||
time /= 365;
|
||||
if (time > 0) {
|
||||
// years
|
||||
sprintf(buffer, "%ld year%s", time, time == 1 ? "" : "s");
|
||||
result = std::string(buffer) + ", " + result;
|
||||
time /= 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! \brief Returns a string describing the number of bytes
|
||||
allocated to directory data and metadata, displayed in the
|
||||
appropriate units (i.e. bytes, KB, MB, etc.).
|
||||
*/
|
||||
std::string
|
||||
Statistics::DirectoryBytesString() const
|
||||
{
|
||||
return bytes_to_string(DirectoryBytes());
|
||||
}
|
||||
|
||||
/*! \brief Returns a string describing the number of bytes
|
||||
allocated to file data and metadata, displayed in the
|
||||
appropriate units (i.e. bytes, KB, MB, etc.).
|
||||
*/
|
||||
std::string
|
||||
Statistics::FileBytesString() const
|
||||
{
|
||||
return bytes_to_string(FileBytes());
|
||||
}
|
||||
|
||||
/*! \brief Returns a string describing the total image size,
|
||||
displayed in the appropriate units (i.e. bytes, KB, MB, etc.).
|
||||
*/
|
||||
std::string
|
||||
Statistics::ImageSizeString() const
|
||||
{
|
||||
return bytes_to_string(ImageSize());
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file Statistics.h
|
||||
|
||||
BDataIO wrapper around a given attribute for a file. (declarations)
|
||||
*/
|
||||
|
||||
#ifndef _STATISTICS_H
|
||||
#define _STATISTICS_H
|
||||
|
||||
#include <OS.h>
|
||||
#include <string>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
std::string bytes_to_string(uint64 bytes);
|
||||
|
||||
class Statistics {
|
||||
public:
|
||||
Statistics();
|
||||
void Reset();
|
||||
|
||||
time_t StartTime() const { return fStartTime; }
|
||||
time_t ElapsedTime() const { return real_time_clock() - fStartTime; }
|
||||
std::string ElapsedTimeString() const;
|
||||
|
||||
void AddDirectory() { fDirectories++; }
|
||||
void AddFile() { fFiles++; }
|
||||
void AddSymlink() { fSymlinks++; }
|
||||
void AddAttribute() { fAttributes++; }
|
||||
|
||||
void AddDirectoryBytes(uint64 count) { fDirectoryBytes += count; }
|
||||
void AddFileBytes(uint64 count) { fFileBytes += count; }
|
||||
|
||||
void SetImageSize(uint64 size) { fImageSize = size; }
|
||||
|
||||
uint64 Directories() const { return fDirectories; }
|
||||
uint64 Files() const { return fFiles; }
|
||||
uint64 Symlinks() const { return fSymlinks; }
|
||||
uint64 Attributes() const { return fAttributes; }
|
||||
|
||||
uint64 DirectoryBytes() const { return fDirectoryBytes; }
|
||||
uint64 FileBytes() const { return fFileBytes; }
|
||||
std::string DirectoryBytesString() const;
|
||||
std::string FileBytesString() const;
|
||||
|
||||
uint64 ImageSize() const { return fImageSize; }
|
||||
std::string ImageSizeString() const;
|
||||
private:
|
||||
time_t fStartTime;
|
||||
uint64 fDirectories;
|
||||
uint64 fFiles;
|
||||
uint64 fSymlinks;
|
||||
uint64 fAttributes;
|
||||
uint64 fDirectoryBytes;
|
||||
uint64 fFileBytes;
|
||||
uint64 fImageSize;
|
||||
};
|
||||
|
||||
#endif // _STATISTICS_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,208 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file UdfBuilder.h
|
||||
|
||||
Main UDF image building class interface declarations.
|
||||
*/
|
||||
|
||||
#ifndef _UDF_BUILDER_H
|
||||
#define _UDF_BUILDER_H
|
||||
|
||||
#include <Entry.h>
|
||||
#include <list>
|
||||
#include <Node.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "Allocator.h"
|
||||
#include "FileStream.h"
|
||||
#include "MemoryStream.h"
|
||||
#include "PhysicalPartitionAllocator.h"
|
||||
#include "ProgressListener.h"
|
||||
#include "Statistics.h"
|
||||
#include "UdfString.h"
|
||||
|
||||
/*! \brief Handy struct into which all the interesting information about
|
||||
a processed directory, file, or whatever is placed by the corresponding
|
||||
UdfBuilder::_Process*() function.
|
||||
*/
|
||||
struct node_data {
|
||||
Udf::long_address icbAddress; //!< Udf icb address
|
||||
std::list<Udf::long_address> udfData; //!< Dataspace for node in Udf partition space
|
||||
std::list<Udf::extent_address> isoData; //!< Dataspace for node in physical space
|
||||
};
|
||||
|
||||
class UdfBuilder {
|
||||
public:
|
||||
UdfBuilder(const char *outputFile, uint32 blockSize, bool doUdf,
|
||||
const char *udfVolumeName, uint16 udfRevision, bool doIso,
|
||||
const char *isoVolumeName,
|
||||
const char *rootDirectory, const ProgressListener &listener,
|
||||
bool truncate);
|
||||
status_t InitCheck() const;
|
||||
status_t Build();
|
||||
private:
|
||||
//! Maximum length of string generated by calls to any _Print*() functions
|
||||
static const int kMaxUpdateStringLength = 1024;
|
||||
|
||||
FileStream& _OutputFile() { return fOutputFile; }
|
||||
uint32 _BlockSize() const { return fBlockSize; }
|
||||
uint32 _BlockShift() const { return fBlockShift; }
|
||||
bool _DoUdf() const { return fDoUdf; }
|
||||
Udf::String& _UdfVolumeName() { return fUdfVolumeName; }
|
||||
uint16 _UdfRevision() const { return fUdfRevision; }
|
||||
uint16 _UdfDescriptorVersion() const { return fUdfDescriptorVersion; }
|
||||
const Udf::entity_id& _UdfDomainId() const { return fUdfDomainId; }
|
||||
bool _DoIso() const { return fDoIso; }
|
||||
Udf::String& _IsoVolumeName() { return fIsoVolumeName; }
|
||||
BEntry& _RootDirectory() { return fRootDirectory; }
|
||||
Allocator& _Allocator() { return fAllocator; }
|
||||
PhysicalPartitionAllocator& _PartitionAllocator() { return fPartitionAllocator; }
|
||||
Statistics& _Stats() { return fStatistics; }
|
||||
time_t _BuildTime() const { return fBuildTime; }
|
||||
Udf::timestamp& _BuildTimeStamp() { return fBuildTimeStamp; }
|
||||
uint64 _NextUniqueId();
|
||||
bool _32BitIdsNoLongerUnique() const { return f32BitIdsNoLongerUnique; }
|
||||
|
||||
void _SetBuildTime(time_t time);
|
||||
|
||||
status_t _FormatString(char *message, const char *formatString, va_list arguments) const;
|
||||
void _PrintError(const char *formatString, ...) const;
|
||||
void _PrintWarning(const char *formatString, ...) const;
|
||||
void _PrintUpdate(VerbosityLevel level, const char *formatString, ...) const;
|
||||
|
||||
status_t _ProcessDirectory(BEntry &entry, const char *path, struct stat stats,
|
||||
node_data &node, Udf::long_address parentIcbAddress,
|
||||
bool isRootDirectory = false);
|
||||
status_t _ProcessFile(BEntry &entry, const char *path, struct stat stats,
|
||||
node_data &node);
|
||||
status_t _ProcessSymlink(BEntry &symlink);
|
||||
status_t _ProcessAttributes(BNode &node);
|
||||
|
||||
template <class FileEntry>
|
||||
status_t _WriteFileEntry(FileEntry *icb, uint8 fileType, uint16 linkCount,
|
||||
uint64 dataLength, uint64 objectSize, struct stat stats,
|
||||
uint64 uniqueId, uint32 allocationDescriptorsLength,
|
||||
Udf::tag_id fileEntryType, Udf::long_address icbAddress,
|
||||
Udf::extent_address icbExtent,
|
||||
std::list<Udf::long_address> dataAddresses);
|
||||
|
||||
status_t fInitStatus;
|
||||
FileStream fOutputFile;
|
||||
std::string fOutputFilename;
|
||||
uint32 fBlockSize;
|
||||
uint32 fBlockShift;
|
||||
bool fDoUdf;
|
||||
Udf::String fUdfVolumeName;
|
||||
uint16 fUdfRevision;
|
||||
uint16 fUdfDescriptorVersion;
|
||||
const Udf::entity_id &fUdfDomainId;
|
||||
bool fDoIso;
|
||||
Udf::String fIsoVolumeName;
|
||||
BEntry fRootDirectory;
|
||||
std::string fRootDirectoryName;
|
||||
const ProgressListener &fListener;
|
||||
Allocator fAllocator;
|
||||
PhysicalPartitionAllocator fPartitionAllocator;
|
||||
Statistics fStatistics;
|
||||
time_t fBuildTime;
|
||||
Udf::timestamp fBuildTimeStamp;
|
||||
uint64 fNextUniqueId;
|
||||
bool f32BitIdsNoLongerUnique;
|
||||
};
|
||||
|
||||
template <class FileEntry>
|
||||
status_t
|
||||
UdfBuilder::_WriteFileEntry(FileEntry *icb, uint8 fileType, uint16 linkCount,
|
||||
uint64 dataLength, uint64 objectSize, struct stat stats,
|
||||
uint64 uniqueId, uint32 allocationDescriptorsLength,
|
||||
Udf::tag_id fileEntryType, Udf::long_address icbAddress,
|
||||
Udf::extent_address icbExtent,
|
||||
std::list<Udf::long_address> dataAddresses)
|
||||
{
|
||||
DEBUG_INIT_ETC("UdfBuilder", ("type: %s", icb->descriptor_name()));
|
||||
status_t error = B_ERROR;
|
||||
Udf::icb_entry_tag &itag = icb->icb_tag();
|
||||
itag.set_prior_recorded_number_of_direct_entries(0);
|
||||
itag.set_strategy_type(Udf::ICB_STRATEGY_SINGLE);
|
||||
memset(itag.strategy_parameters().data, 0,
|
||||
itag.strategy_parameters().size());
|
||||
itag.set_entry_count(1);
|
||||
itag.reserved() = 0;
|
||||
itag.set_file_type(fileType);
|
||||
itag.parent_icb_location() = kNullLogicalBlock;
|
||||
Udf::icb_entry_tag::flags_accessor &iflags = itag.flags_access();
|
||||
// clear flags, then set those of interest
|
||||
iflags.all_flags = 0;
|
||||
iflags.flags.descriptor_flags = Udf::ICB_DESCRIPTOR_TYPE_LONG;
|
||||
iflags.flags.archive = 1;
|
||||
icb->set_uid(0xffffffff);
|
||||
icb->set_gid(0xffffffff);
|
||||
icb->set_permissions(Udf::OTHER_EXECUTE | Udf::OTHER_READ
|
||||
| Udf::GROUP_EXECUTE | Udf::GROUP_READ
|
||||
| Udf::USER_EXECUTE | Udf::USER_READ);
|
||||
icb->set_file_link_count(linkCount);
|
||||
icb->set_record_format(0);
|
||||
icb->set_record_display_attributes(0);
|
||||
icb->set_record_length(0);
|
||||
icb->set_information_length(dataLength);
|
||||
icb->set_object_size(objectSize); // EFE only
|
||||
icb->set_logical_blocks_recorded(_Allocator().BlocksFor(dataLength));
|
||||
icb->access_date_and_time() = Udf::timestamp(stats.st_atime);
|
||||
icb->modification_date_and_time() = Udf::timestamp(stats.st_mtime);
|
||||
icb->creation_date_and_time() = Udf::timestamp(stats.st_crtime); // EFE only
|
||||
icb->attribute_date_and_time() = icb->creation_date_and_time();
|
||||
icb->set_checkpoint(1);
|
||||
icb->set_reserved(0); // EFE only
|
||||
icb->extended_attribute_icb() = kNullAddress;
|
||||
icb->stream_directory_icb() = kNullAddress; // EFE only
|
||||
icb->implementation_id() = Udf::kImplementationId;
|
||||
icb->set_unique_id(uniqueId);
|
||||
icb->set_extended_attributes_length(0);
|
||||
icb->set_allocation_descriptors_length(allocationDescriptorsLength);
|
||||
icb->tag().set_id(fileEntryType);
|
||||
icb->tag().set_version(_UdfDescriptorVersion());
|
||||
icb->tag().set_serial_number(0);
|
||||
icb->tag().set_location(icbAddress.block());
|
||||
|
||||
// write allocation descriptors
|
||||
std::list<Udf::long_address>::iterator a;
|
||||
MemoryStream descriptorStream(icb->allocation_descriptors(),
|
||||
allocationDescriptorsLength);
|
||||
error = descriptorStream.InitCheck();
|
||||
if (!error) {
|
||||
for (a = dataAddresses.begin();
|
||||
a != dataAddresses.end() && error == B_OK;
|
||||
a++)
|
||||
{
|
||||
PRINT(("Dumping address:\n"));
|
||||
DUMP(*a);
|
||||
Udf::long_address &address = *a;
|
||||
ssize_t bytes = descriptorStream.Write(&address, sizeof(address));
|
||||
error = check_size_error(bytes, sizeof(address));
|
||||
}
|
||||
}
|
||||
icb->tag().set_checksums(*icb, icb->descriptor_size());
|
||||
PDUMP(icb);
|
||||
|
||||
// Write udf icb
|
||||
if (!error) {
|
||||
_PrintUpdate(VERBOSITY_MEDIUM, "udf: Writing icb");
|
||||
// write icb
|
||||
_OutputFile().Seek(off_t(icbExtent.location()) << _BlockShift(), SEEK_SET);
|
||||
PRINT(("position, icbsize: %Ld, %ld\n", _OutputFile().Position(), sizeof(icb)));
|
||||
ssize_t bytes = _OutputFile().Write(icb, _BlockSize());
|
||||
PRINT(("position: %Ld\n", _OutputFile().Position()));
|
||||
error = check_size_error(bytes, _BlockSize());
|
||||
PRINT(("position: %Ld\n", _OutputFile().Position()));
|
||||
}
|
||||
RETURN(error);
|
||||
}
|
||||
|
||||
#endif // _UDF_BUILDER_H
|
||||
@@ -1,20 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the MIT License.
|
||||
//
|
||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/*! \file makeudfimage.cpp
|
||||
|
||||
UDF image builder.
|
||||
*/
|
||||
|
||||
#include "Shell.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Shell shell;
|
||||
shell.Run(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
@@ -25,7 +25,6 @@ if $(TARGET_PLATFORM) = libbe_test {
|
||||
|
||||
SubInclude HAIKU_TOP src tests add-ons ;
|
||||
SubInclude HAIKU_TOP src tests apps ;
|
||||
SubInclude HAIKU_TOP src tests bin ;
|
||||
SubInclude HAIKU_TOP src tests system ;
|
||||
SubInclude HAIKU_TOP src tests kits ;
|
||||
SubInclude HAIKU_TOP src tests libs ;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
SubDir HAIKU_TOP src tests bin ;
|
||||
|
||||
SubInclude HAIKU_TOP src tests bin makeudfimage ;
|
||||
@@ -1,144 +0,0 @@
|
||||
#include <ThreadedTestCaller.h>
|
||||
#include <cppunit/Test.h>
|
||||
#include <cppunit/TestCaller.h>
|
||||
#include <cppunit/TestSuite.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <kernel/OS.h>
|
||||
#include <TestUtils.h>
|
||||
|
||||
#include "AllocatorTest.h"
|
||||
|
||||
#include "Allocator.h"
|
||||
#include "PhysicalPartitionAllocator.h"
|
||||
|
||||
AllocatorTest::AllocatorTest(std::string name)
|
||||
: BTestCase(name)
|
||||
{
|
||||
}
|
||||
|
||||
CppUnit::Test*
|
||||
AllocatorTest::Suite() {
|
||||
CppUnit::TestSuite *suite = new CppUnit::TestSuite("Yo");
|
||||
|
||||
// And our tests
|
||||
suite->addTest(new CppUnit::TestCaller<AllocatorTest>("Allocator::BlockSize Test", &AllocatorTest::BlockSizeTest));
|
||||
suite->addTest(new CppUnit::TestCaller<AllocatorTest>("Allocator::Partition Full Test", &AllocatorTest::PartitionFullTest));
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
void
|
||||
AllocatorTest::BlockSizeTest() {
|
||||
{
|
||||
Allocator allocator(0);
|
||||
CHK(allocator.InitCheck() != B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(1);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(2);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(3);
|
||||
CHK(allocator.InitCheck() != B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(256);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(512);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(1024);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(1025);
|
||||
CHK(allocator.InitCheck() != B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(2048);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
{
|
||||
Allocator allocator(4096);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
NextSubTest();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AllocatorTest::PartitionFullTest() {
|
||||
{
|
||||
extent_address extent;
|
||||
const uint32 blockSize = 2048;
|
||||
Allocator allocator(blockSize);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
CHK(allocator.GetNextExtent(blockSize*12, true, extent) == B_OK); // 0-11
|
||||
extent.set_location(14);
|
||||
extent.set_length(1);
|
||||
CHK(allocator.GetExtent(extent) == B_OK); // 14
|
||||
CHK(allocator.GetNextExtent(blockSize*3, true, extent) == B_OK); // 15-17
|
||||
CHK(allocator.GetNextExtent(1, true, extent) == B_OK); // 12
|
||||
CHK(allocator.GetBlock(12) != B_OK);
|
||||
CHK(allocator.GetBlock(13) == B_OK);
|
||||
}
|
||||
NextSubTest();
|
||||
{
|
||||
extent_address extent;
|
||||
Allocator allocator(2048);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
CHK(allocator.GetNextExtent(ULONG_MAX-1, true, extent) == B_OK);
|
||||
CHK(allocator.GetNextExtent(1, true, extent) != B_OK);
|
||||
extent.set_location(256);
|
||||
extent.set_length(1);
|
||||
CHK(allocator.GetExtent(extent) != B_OK);
|
||||
CHK(allocator.GetBlock(13) != B_OK);
|
||||
}
|
||||
NextSubTest();
|
||||
{
|
||||
extent_address extent;
|
||||
const uint32 blockSize = 2048;
|
||||
Allocator allocator(blockSize);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
CHK(allocator.GetNextExtent(ULONG_MAX-blockSize*2, true, extent) == B_OK);
|
||||
CHK(allocator.GetNextExtent(1, true, extent) == B_OK);
|
||||
extent.set_location(256);
|
||||
extent.set_length(1);
|
||||
CHK(allocator.GetExtent(extent) != B_OK);
|
||||
CHK(allocator.GetBlock(13) != B_OK);
|
||||
PhysicalPartitionAllocator partition(0, 0, allocator);
|
||||
std::list<long_address> extents;
|
||||
std::list<extent_address> physicalExtents;
|
||||
CHK(partition.GetNextExtents(1, extents, physicalExtents) == B_OK);
|
||||
}
|
||||
NextSubTest();
|
||||
{
|
||||
extent_address extent;
|
||||
const uint32 blockSize = 2048;
|
||||
Allocator allocator(blockSize);
|
||||
CHK(allocator.InitCheck() == B_OK);
|
||||
CHK(allocator.GetNextExtent(ULONG_MAX, true, extent) == B_OK);
|
||||
PhysicalPartitionAllocator partition(0, 0, allocator);
|
||||
std::list<long_address> extents;
|
||||
std::list<extent_address> physicalExtents;
|
||||
CHK(partition.GetNextExtents(1, extents, physicalExtents) != B_OK);
|
||||
}
|
||||
NextSubTest();
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef _udf_allocator_test_h_
|
||||
#define _udf_allocator_test_h_
|
||||
|
||||
#include <ThreadedTestCase.h>
|
||||
#include <Locker.h>
|
||||
|
||||
class AllocatorTest : public BTestCase {
|
||||
public:
|
||||
AllocatorTest(std::string name = "");
|
||||
|
||||
static CppUnit::Test* Suite();
|
||||
|
||||
void BlockSizeTest();
|
||||
void PartitionFullTest();
|
||||
};
|
||||
|
||||
#endif // _udf_allocator_test_h_
|
||||
@@ -1,32 +0,0 @@
|
||||
SubDir HAIKU_TOP src tests bin makeudfimage ;
|
||||
|
||||
AddSubDirSupportedPlatforms libbe_test ;
|
||||
|
||||
UsePublicHeaders add-ons/file_system ; # For fsproto.h
|
||||
UsePrivateHeaders [ FDirName kernel util ] ; # For kernel_cpp.h
|
||||
UsePrivateHeaders private shared ;
|
||||
SubDirHdrs [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems udf ] ;
|
||||
SubDirHdrs [ FDirName $(HAIKU_TOP) src bin makeudfimage ] ;
|
||||
|
||||
UnitTestLib libmakeudfimagetest.so
|
||||
: MakeudfimageTestAddon.cpp
|
||||
# test files
|
||||
AllocatorTest.cpp
|
||||
|
||||
# makeudfimage files
|
||||
Allocator.cpp
|
||||
PhysicalPartitionAllocator.cpp
|
||||
|
||||
# udf files
|
||||
UdfDebug.cpp
|
||||
UdfString.cpp
|
||||
UdfStructures.cpp
|
||||
Utils.cpp
|
||||
|
||||
: be [ TargetLibstdc++ ]
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles Allocator.cpp PhysicalPartitionAllocator.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src bin makeudfimage ] ;
|
||||
SEARCH on [ FGristFiles UdfDebug.cpp UdfString.cpp UdfStructures.cpp Utils.cpp ] #DString.cpp UdfDebug.cpp UdfString.cpp UdfStructures.cpp Utils.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems udf ] ;
|
||||
@@ -1,10 +0,0 @@
|
||||
#include <TestSuite.h>
|
||||
#include <TestSuiteAddon.h>
|
||||
|
||||
#include "AllocatorTest.h"
|
||||
|
||||
BTestSuite* getTestSuite() {
|
||||
BTestSuite *suite = new BTestSuite("makeudfimage");
|
||||
suite->addTest("Udf::Allocator", AllocatorTest::Suite());
|
||||
return suite;
|
||||
}
|
||||
Reference in New Issue
Block a user