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:
Kyle Ambroff-Kao
2020-03-09 12:18:06 +00:00
committed by waddlesplash
parent ddb8a39005
commit 2a0d1eb890
37 changed files with 0 additions and 4206 deletions
-1
View File
@@ -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 ;
-272
View File
@@ -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;
}
}
-53
View File
@@ -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
-31
View File
@@ -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;
}
-30
View File
@@ -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
-111
View File
@@ -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");
}
}
}
-34
View File
@@ -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
-38
View File
@@ -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
-51
View File
@@ -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;
}
-32
View File
@@ -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
-77
View File
@@ -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;
}
-36
View File
@@ -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
-30
View File
@@ -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;
}
-30
View File
@@ -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
-42
View File
@@ -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 ] ;
-31
View File
@@ -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;
}
-30
View File
@@ -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
-207
View File
@@ -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);
}
-47
View File
@@ -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
-36
View File
@@ -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
-173
View File
@@ -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");
}
-41
View File
@@ -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
-297
View File
@@ -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;
}
-77
View File
@@ -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
-158
View File
@@ -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());
}
-64
View File
@@ -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
-208
View File
@@ -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
-20
View File
@@ -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;
}
-1
View File
@@ -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 ;
-3
View File
@@ -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_
-32
View File
@@ -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;
}