From d5e966a0563e3f01c02c3cfb1f3a83fec852168b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 18 Sep 2024 13:29:18 -0700 Subject: Myriad tool is back, mostly works! --- src/tools/myriad.cpp | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 src/tools/myriad.cpp (limited to 'src/tools/myriad.cpp') diff --git a/src/tools/myriad.cpp b/src/tools/myriad.cpp new file mode 100644 index 0000000..1dc73ec --- /dev/null +++ b/src/tools/myriad.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2007-2023 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/sio.h" +#include "bu/file.h" +#include "bu/myriad.h" +#include "bu/myriadstream.h" +#include "bu/optparser.h" + +#include + +using namespace Bu; + +enum Mode +{ + modeCreate, + modeInfo, + modeStreamNew, + modeStreamDump, + modeStreamPut, + modeStreamGet, + modeBlockMap, + + modeNone +}; + +class Options : public OptParser +{ +public: + Options( int argc, char *argv[] ) : + eMode( modeNone ), + iBlockSize( 64 ), + iPreallocate( 0 ), + iStream( 0 ) + { + addHelpBanner("Mode of operation:"); + addOption( eMode, 'c', "create", + "Create a new Myriad file." ); + addOption( eMode, 'i', "info", + "Display some info about a Myriad file." ); + addOption( eMode, 'n', "new", + "Create a new sub-stream in a Myriad file."); + addOption( eMode, 'd', "dump", + "Display a hexdump of a stream from a Myriad file."); + addOption( eMode, "get", + "Get a file out of a Myriad stream (use --dst)."); + addOption( eMode, "put", + "Put a file into a Myriad stream (usr --src)."); + addOption( eMode, 'm', "block-map", + "Visualize block usage."); + addHelpOption(); + + addHelpBanner("\nGeneral options:"); + addOption( iBlockSize, 'b', "block-size", "Set the block size." ); + addOption( iPreallocate, 'p', "preallocate", + "Number of blocks to preallocate." ); + addOption( sFile, 'f', "file", "Set the Myriad filename." ); + addOption( iStream, 's', "stream", "Substream to work with."); + addOption( sSrc, "src", "Source file for copying into a Myriad file."); + addOption( sDst, "dst", + "Destination file for copying out of a Myriad file."); + + setOverride( "create", modeCreate ); + setOverride( "info", modeInfo ); + setOverride( "new", modeStreamNew ); + setOverride( "dump", modeStreamDump ); + setOverride( "put", modeStreamPut ); + setOverride( "get", modeStreamGet ); + setOverride( "block-map", modeBlockMap ); + + parse( argc, argv ); + } + + Mode eMode; + int iBlockSize; + int iPreallocate; + int iStream; + Bu::String sFile; + Bu::String sSrc; + Bu::String sDst; +}; + +Bu::Formatter &operator>>( Bu::Formatter &f, Mode & /*e*/ ) +{ + sio << "Uh oh, the formatter was called..." << sio.nl; + return f; +} + +int main( int argc, char *argv[] ) +{ + Options opts( argc, argv ); + + switch( opts.eMode ) + { + case modeCreate: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file to create." << sio.nl; + return 0; + } + else + { + File fOut( opts.sFile, File::WriteNew|File::Read ); + Myriad m( fOut, opts.iBlockSize, opts.iPreallocate ); + } + break; + + case modeInfo: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file to display info about." << sio.nl; + return 0; + } + else + { + File fIn( opts.sFile, File::Read ); + Myriad m( fIn ); + sio << "Myriad info:" << sio.nl + << " Block size: " << m.getBlockSize() << sio.nl + << " Block count: " << m.getTotalBlocks() << sio.nl + << " Blocks used: " << m.getUsedBlocks() << " (" + << m.getUsedBlocks()*100/m.getTotalBlocks() << "%)" + << sio.nl + << " Stream count: " << m.getTotalStreams() << sio.nl + << " Used space: " << m.getTotalUsedBytes() << sio.nl + << " Unused space: " << m.getTotalUnusedBytes() << sio.nl + << " % of files: " << (double)(m.getTotalBlocks()*m.getBlockSize())/(double)(m.getTotalUsedBytes() + m.getTotalUnusedBytes( 4096 ))*100.0 << sio.nl; +/* Bu::Array aStreams = m.getStreamIds(); + sio << " Stream info:" << sio.nl; + for( Bu::Array::iterator i = aStreams.begin(); i; i++ ) + { + sio << " " << Fmt(4) << *i << ") " + << m.getStreamSize( *i ) << "b" << sio.nl; + } */ + } + break; + + case modeStreamNew: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file manipulate." << sio.nl; + return 0; + } + else + { + File fOut( opts.sFile, File::Write|File::Read ); + Myriad m( fOut ); + m.create( Bu::Myriad::WriteNew, opts.iPreallocate ); + } + break; + + case modeStreamDump: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file to manipulate." << sio.nl; + return 0; + } + else + { + File fOut( opts.sFile, File::Read ); + Myriad m( fOut ); + MyriadStream s = m.open( opts.iStream, Bu::Myriad::Read ); + sio << "Stream " << opts.iStream << ":" << sio.nl; + char buf[8]; + int iPos = 0; + while( !s.isEos() ) + { + size_t sAmnt = s.read( buf, 8 ); + sio << Fmt(5) << iPos << ": "; + iPos += sAmnt; + for( size_t j = 0; j < sAmnt; j++ ) + { + sio << Fmt::hex(2) << (int)((unsigned char)buf[j]) + << " "; + } + for( size_t j = sAmnt; j < 8; j++ ) + { + sio << "-- "; + } + sio << "| "; + for( size_t j = 0; j < sAmnt; j++ ) + { + if( buf[j] >= 32 && buf[j] <= 126 ) + sio << buf[j] << " "; + else + sio << " "; + } + sio << sio.nl; + } + sio << "Position: " << s.tell() << ", isEos()=" << s.isEos() + << sio.nl; + } + break; + + case modeStreamPut: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file manipulate." << sio.nl; + return 0; + } + else if( !opts.sSrc.isSet() ) + { + sio << "Please specify a source file to read." << sio.nl; + } + else + { + File fOut( opts.sFile, File::Write|File::Read ); + Myriad m( fOut ); + MyriadStream sOut = m.create( + Bu::Myriad::WriteNew, opts.iPreallocate + ); + File fIn( opts.sSrc, File::Read ); + char buf[1024]; + while( !fIn.isEos() ) + { + sOut.write( buf, fIn.read( buf, 1024 ) ); + } + } + break; + + case modeStreamGet: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file manipulate." << sio.nl; + return 0; + } + else if( !opts.sDst.isSet() ) + { + sio << "Please specify a destination file to write." << sio.nl; + } + else + { + File fIn( opts.sFile, File::Write|File::Read ); + Myriad m( fIn ); + MyriadStream sIn = m.open( opts.iStream, Bu::Myriad::Read ); + File fOut( opts.sDst, File::Write|File::Create|File::Truncate ); + char buf[1024]; + while( !sIn.isEos() ) + { + fOut.write( buf, sIn.read( buf, 1024 ) ); + } + } + break; + + case modeBlockMap: + if( !opts.sFile.isSet() ) + { + sio << "Please specify a file manipulate." << sio.nl; + return 0; + } + { + File fIn( opts.sFile, File::Write|File::Read ); + Myriad m( fIn ); +/* Bu::BitString bs = m.getBlocksUsed(); + for( int j = 0; j < bs.getSize(); j++ ) + { + if( j>0 && (j%50) == 0 ) + Bu::println(""); + if( bs.getBit( j ) ) + Bu::print("#"); + else + Bu::print("-"); + }*/ + Bu::println("\n"); + } + break; + + case modeNone: + sio << "Please select a mode, for more info, try --help." + << sio.nl << sio.nl; + break; + } + + return 0; +} + -- cgit v1.2.3