libMeatloaf/lib/meatloaf/archive/archive_ml.cpp
2024-01-24 13:43:53 -05:00

365 lines
12 KiB
C++

// #include "archive_ml.h"
// #include <archive.h>
// #include <archive_entry.h>
// #include "meat_io.h"
// /* Returns pointer and size of next block of data from archive. */
// // The read callback returns the number of bytes read, zero for end-of-file, or a negative failure code as above.
// // It also returns a pointer to the block of data read.
// // https://github.com/libarchive/libarchive/wiki/LibarchiveIO
// //
// // This callback is just a way to get bytes from srcStream into libarchive for processing
// ssize_t cb_read(struct archive *a, void *userData, const void **buff)
// {
// ArchiveStreamData *streamData = (ArchiveStreamData *)userData;
// // 1. we have to call srcStr.read(...)
// ssize_t bc = streamData->srcStream->read(streamData->srcBuffer, ArchiveStream::buffSize);
// //std::string dump((char*)streamData->srcBuffer, bc);
// //Debug_printv("Libarch pulling data from src MStream, got bytes:%d", bc);
// //Debug_printv("Dumping bytes: %s", dump.c_str());
// // 2. set *buff to the bufer read in 1.
// *buff = streamData->srcBuffer;
// // 3. return read bytes count
// return bc;
// }
// /*
// It must return the number of bytes actually skipped, or a negative failure code if skipping cannot be done.
// It can skip fewer bytes than requested but must never skip more.
// Only positive/forward skips will ever be requested.
// If skipping is not provided or fails, libarchive will call the read() function and simply ignore any data that it does not need.
// * Skips at most request bytes from archive and returns the skipped amount.
// * This may skip fewer bytes than requested; it may even skip zero bytes.
// * If you do skip fewer bytes than requested, libarchive will invoke your
// * read callback and discard data as necessary to make up the full skip.
// */
// // https://github.com/libarchive/libarchive/wiki/LibarchiveIO
// int64_t cb_skip(struct archive *a, void *userData, int64_t request)
// {
// Debug_printv("bytes[%d]", request);
// ArchiveStreamData *streamData = (ArchiveStreamData *)userData;
// if (streamData->srcStream->isOpen())
// {
// bool rc = streamData->srcStream->seek(request, SEEK_CUR);
// return (rc) ? request : ARCHIVE_WARN;
// }
// else
// {
// Debug_printv("ERROR! skip failed");
// return ARCHIVE_FATAL;
// }
// }
// int64_t cb_seek(struct archive *a, void *userData, int64_t offset, int whence)
// {
// Debug_printv("offset[%d] whence[%d] (0=begin, 1=curr, 2=end)", offset, whence);
// ArchiveStreamData *streamData = (ArchiveStreamData *)userData;
// if (streamData->srcStream->isOpen())
// {
// bool rc = streamData->srcStream->seek(offset, whence);
// return (rc) ? offset : ARCHIVE_WARN;
// }
// else
// {
// Debug_printv("ERROR! seek failed");
// return ARCHIVE_FATAL;
// }
// }
// int cb_close(struct archive *a, void *userData)
// {
// ArchiveStreamData *src_str = (ArchiveStreamData *)userData;
// Debug_printv("Libarch wants to close, but we do nothing here...");
// // do we want to close srcStream here???
// return (ARCHIVE_OK);
// }
// int cb_open(struct a *arch, void *userData)
// {
// // maybe we can use open for something? Check if stream is open?
// return (ARCHIVE_OK);
// }
// /********************************************************
// * Streams implementations
// ********************************************************/
// ArchiveStream::ArchiveStream(std::shared_ptr<MStream> srcStr)
// {
// // it should be possible to to pass a password parameter here and somehow
// // call archive_passphrase_callback(password) from here, right?
// streamData.srcStream = srcStr;
// a = archive_read_new();
// archive_read_support_filter_all(a);
// archive_read_support_format_all(a);
// streamData.srcBuffer = new uint8_t[buffSize];
// open();
// }
// ArchiveStream::~ArchiveStream()
// {
// close();
// if (streamData.srcBuffer != nullptr)
// delete[] streamData.srcBuffer;
// Debug_printv("Stream destructor OK!");
// }
// bool ArchiveStream::open()
// {
// if (!is_open)
// {
// // TODO enable seek only if the stream is random access
// archive_read_set_read_callback(a, cb_read);
// archive_read_set_skip_callback(a, cb_skip);
// archive_read_set_seek_callback(a, cb_seek);
// archive_read_set_close_callback(a, cb_close);
// // archive_read_set_open_callback(mpa->arch, cb_open); - what does it do?
// archive_read_set_callback_data(a, &streamData);
// Debug_printv("== BEGIN Calling open1 on archive instance ==========================");
// int r = archive_read_open1(a);
// Debug_printv("== END opening archive result=%d! (OK should be 0!) =======================================", r);
// //int r = archive_read_open2(a, &streamData, NULL, myRead, myskip, myclose);
// if (r == ARCHIVE_OK)
// is_open = true;
// }
// return is_open;
// };
// void ArchiveStream::close()
// {
// if (is_open)
// {
// archive_read_close(a);
// archive_read_free(a);
// is_open = false;
// }
// Debug_printv("Close called");
// }
// bool ArchiveStream::isOpen()
// {
// return is_open;
// };
// std::vector<uint8_t> leftovers;
// uint32_t ArchiveStream::read(uint8_t *buf, uint32_t size)
// {
// Debug_printv("calling read size[%d]", size);
// const void *incomingBuffer;
// size_t incomingSize;
// int64_t offset;
// int r = archive_read_data_block(a, &incomingBuffer, &incomingSize, &offset);
// Debug_printv("r[%d]", r);
// if ( r == ARCHIVE_EOF )
// return 0;
// if ( r < ARCHIVE_OK )
// return 0;
// // 'buff' contains the data of the current block
// // 'size' is the size of the current block
// std::vector<uint8_t> incomingVector((uint8_t*)incomingBuffer, (uint8_t*)incomingBuffer + incomingSize);
// // concatenate intermediate buffer with incomingVector
// leftovers.insert(leftovers.end(), incomingVector.begin(), incomingVector.end());
// if(leftovers.size() <= size) {
// // ok, we can fit everything that was left and new data to our buffer
// auto size = leftovers.size();
// _position += size;
// leftovers.clear();
// }
// else {
// // ok, so we can only write up to size and we have to keep leftovers for next time
// std::copy(leftovers.begin(), leftovers.begin() + size, buf);
// std::vector<uint8_t> leftovers2(leftovers.begin() + size, leftovers.end());
// leftovers = leftovers2;
// _position += size;
// }
// _position += size;
// Debug_printv("size[%d] position[%d]", size, _position);
// return size;
// }
// uint32_t ArchiveStream::write(const uint8_t *buf, uint32_t size)
// {
// return -1;
// }
// // For files with a browsable random access directory structure
// // d64, d74, d81, dnp, etc.
// bool ArchiveStream::seekPath(std::string path)
// {
// Debug_printv("seekPath called for path: %s", path.c_str());
// if ( seekEntry( path ) )
// {
// Debug_printv("entry[%s]", archive_entry_pathname(entry));
// return true;
// }
// return false;
// }
// bool ArchiveStream::seekEntry( std::string filename )
// {
// Debug_printv( "filename[%s] size[%d]", filename.c_str(), filename.size());
// // Read Directory Entries
// if ( filename.size() > 0 )
// {
// bool found = false;
// bool wildcard = ( mstr::contains(filename, "*") || mstr::contains(filename, "?") );
// while ( archive_read_next_header(a, &entry) == ARCHIVE_OK )
// {
// std::string entryPath = ""; //archive_entry_sourcepath(entry);
// std::string entryFilename = archive_entry_pathname(entry);
// Debug_printv("path[%s] filename[%s] entry.filename[%.16s]", entryPath.c_str(), filename.c_str(), entryFilename.c_str());
// // Check filetype
// if ( archive_entry_filetype(entry) != AE_IFDIR )
// {
// // Read Entry From Stream
// if (filename == "*") // Match first entry
// {
// filename = entryFilename;
// found = true;
// }
// else if ( filename == entryFilename ) // Match exact
// {
// found = true;
// }
// else if ( wildcard )
// {
// if ( mstr::compare(filename, entryFilename) ) // X?XX?X* Wildcard match
// {
// // Set filename to this filename
// Debug_printv( "Found! file[%s] -> entry[%s]", filename.c_str(), entryFilename.c_str() );
// found = true;
// }
// }
// if ( found )
// {
// _size = archive_entry_size(entry);
// return true;
// }
// }
// }
// Debug_printv( "Not Found! file[%s]", filename.c_str() );
// }
// return false;
// }
// // // For files with no directory structure
// // // tap, crt, tar
// // std::string ArchiveStream::seekNextEntry()
// // {
// // struct archive_entry *entry;
// // if (archive_read_next_header(a, &entry) == ARCHIVE_OK)
// // return archive_entry_pathname(entry);
// // else
// // return "";
// // };
// bool ArchiveStream::seek(uint32_t pos)
// {
// return streamData.srcStream->seek(pos);
// }
// /********************************************************
// * Files implementations
// ********************************************************/
// MStream *ArchiveContainerFile::getDecodedStream(std::shared_ptr<MStream> containerIstream)
// {
// // TODO - we can get password from this URL and pass it as a parameter to this constructor
// Debug_printv("calling getDecodedStream for ArchiveContainerFile, we should return open stream");
// auto stream = new ArchiveStream(containerIstream);
// return stream;
// }
// // archive file is always a directory
// bool ArchiveContainerFile::isDirectory()
// {
// //Debug_printv("pathInStream[%s]", pathInStream.c_str());
// if ( pathInStream == "" )
// return true;
// else
// return false;
// };
// bool ArchiveContainerFile::rewindDirectory()
// {
// dirIsOpen = true;
// return prepareDirListing();
// }
// MFile *ArchiveContainerFile::getNextFileInDir()
// {
// if(!dirIsOpen)
// rewindDirectory();
// struct archive_entry *entry;
// Debug_printv("getNextFileInDir calling archive_read_next_header");
// if (archive_read_next_header(getArchive(), &entry) == ARCHIVE_OK)
// {
// std::string fileName = archive_entry_pathname(entry);
// auto file = MFSOwner::File(streamFile->url + "/" + fileName);
// file->_size = archive_entry_size(entry);
// file->_exists = true;
// return file;
// }
// else
// {
// //Debug_printv( "END OF DIRECTORY");
// dirStream->close();
// dirIsOpen = false;
// return nullptr;
// }
// }
// bool ArchiveContainerFile::prepareDirListing()
// {
// if (dirStream.get() != nullptr)
// {
// dirStream->close();
// }
// Debug_printv("w prepare dir listing");
// dirStream = std::shared_ptr<MStream>(this->getSourceStream());
// if(dirStream->isOpen())
// {
// return true;
// }
// else
// {
// Debug_printv("opening Archive for dir nok");
// return false;
// }
// }