forked from chenxiaolong/DualBootPatcher
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libmbsparse: Refactor to use new mb::File classes
Signed-off-by: Andrew Gunnerson <[email protected]>
- Loading branch information
Andrew Gunnerson
committed
Jul 15, 2017
1 parent
29b8af4
commit 5345fc7
Showing
12 changed files
with
1,805 additions
and
1,313 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2016 Andrew Gunnerson <[email protected]> | ||
* Copyright (C) 2016-2017 Andrew Gunnerson <[email protected]> | ||
* | ||
* This file is part of DualBootPatcher | ||
* | ||
|
@@ -26,121 +26,71 @@ | |
#include "mbcommon/file/standard.h" | ||
#include "mbsparse/sparse.h" | ||
|
||
typedef std::unique_ptr<SparseCtx, bool (*)(SparseCtx *)> ScopedSparseCtx; | ||
|
||
struct Context | ||
{ | ||
std::string path; | ||
mb::StandardFile file; | ||
}; | ||
|
||
bool cbOpen(void *userData) | ||
{ | ||
Context *ctx = static_cast<Context *>(userData); | ||
if (ctx->file.open(ctx->path, mb::FileOpenMode::READ_ONLY) | ||
!= mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to open: %s\n", | ||
ctx->path.c_str(), ctx->file.error_string().c_str()); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool cbClose(void *userData) | ||
{ | ||
Context *ctx = static_cast<Context *>(userData); | ||
if (ctx->file.close() != mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to close: %s\n", | ||
ctx->path.c_str(), ctx->file.error_string().c_str()); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool cbRead(void *buf, uint64_t size, uint64_t *bytesRead, void *userData) | ||
{ | ||
Context *ctx = static_cast<Context *>(userData); | ||
size_t total = 0; | ||
while (size > 0) { | ||
size_t partial; | ||
if (ctx->file.read(buf, size, &partial) != mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to read: %s\n", | ||
ctx->path.c_str(), ctx->file.error_string().c_str()); | ||
return false; | ||
} | ||
size -= partial; | ||
total += partial; | ||
buf = static_cast<char *>(buf) + partial; | ||
} | ||
*bytesRead = total; | ||
return true; | ||
} | ||
|
||
bool cbSeek(int64_t offset, int whence, void *userData) | ||
{ | ||
Context *ctx = static_cast<Context *>(userData); | ||
if (ctx->file.seek(offset, whence, nullptr) != mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to seek: %s\n", | ||
ctx->path.c_str(), ctx->file.error_string().c_str()); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
if (argc != 3) { | ||
std::fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
const char *inputFile = argv[1]; | ||
const char *outputFile = argv[2]; | ||
const char *input_path = argv[1]; | ||
const char *output_path = argv[2]; | ||
|
||
Context ctx; | ||
ctx.path = inputFile; | ||
mb::StandardFile input_file; | ||
mb::StandardFile output_file; | ||
mb::sparse::SparseFile sparse_file; | ||
|
||
ScopedSparseCtx sparseCtx(sparseCtxNew(), &sparseCtxFree); | ||
if (!sparseCtx) { | ||
fprintf(stderr, "Out of memory\n"); | ||
if (input_file.open(input_path, mb::FileOpenMode::READ_ONLY) | ||
!= mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to open for reading: %s\n", | ||
input_path, input_file.error_string().c_str()); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
if (!sparseOpen(sparseCtx.get(), &cbOpen, &cbClose, &cbRead, &cbSeek, | ||
nullptr, &ctx)) { | ||
if (sparse_file.open(&input_file) != mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: %s\n", | ||
input_path, sparse_file.error_string().c_str()); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
mb::StandardFile file; | ||
|
||
if (file.open(outputFile, mb::FileOpenMode::WRITE_ONLY) | ||
if (output_file.open(output_path, mb::FileOpenMode::WRITE_ONLY) | ||
!= mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to open for writing: %s\n", | ||
outputFile, file.error_string().c_str()); | ||
output_path, output_file.error_string().c_str()); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
uint64_t bytesRead; | ||
size_t n_read; | ||
char buf[10240]; | ||
bool ret; | ||
while ((ret = sparseRead(sparseCtx.get(), buf, sizeof(buf), &bytesRead)) | ||
&& bytesRead > 0) { | ||
mb::FileStatus ret; | ||
while ((ret = sparse_file.read(buf, sizeof(buf), &n_read)) | ||
== mb::FileStatus::OK && n_read > 0) { | ||
char *ptr = buf; | ||
size_t bytesWritten; | ||
while (bytesRead > 0) { | ||
if (file.write(buf, bytesRead, &bytesWritten) | ||
size_t n_written; | ||
|
||
while (n_read > 0) { | ||
if (output_file.write(buf, n_read, &n_written) | ||
!= mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to write: %s\n", | ||
outputFile, file.error_string().c_str()); | ||
fprintf(stderr, "%s: Failed to write file: %s\n", | ||
output_path, output_file.error_string().c_str()); | ||
return EXIT_FAILURE; | ||
} | ||
bytesRead -= bytesWritten; | ||
ptr += bytesWritten; | ||
n_read -= n_written; | ||
ptr += n_written; | ||
} | ||
} | ||
if (!ret) { | ||
|
||
if (ret != mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to read file: %s\n", | ||
input_path, sparse_file.error_string().c_str()); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
if (output_file.close() != mb::FileStatus::OK) { | ||
fprintf(stderr, "%s: Failed to close file: %s\n", | ||
output_path, output_file.error_string().c_str()); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
return file.close() == mb::FileStatus::OK ? EXIT_SUCCESS : EXIT_FAILURE; | ||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright (C) 2017 Andrew Gunnerson <[email protected]> | ||
* | ||
* This file is part of DualBootPatcher | ||
* | ||
* DualBootPatcher is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* DualBootPatcher is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with DualBootPatcher. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <functional> | ||
|
||
namespace mb | ||
{ | ||
|
||
#if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304 | ||
|
||
template<class ForwardIt, class T, class Compare=std::less<>> | ||
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T &value, | ||
Compare comp={}) | ||
{ | ||
ForwardIt it = std::lower_bound(first, last, value, comp); | ||
return (it != last && !bool(comp(value, *it))) ? it : last; | ||
} | ||
|
||
#else | ||
|
||
template<class ForwardIt, class T> | ||
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T &value) | ||
{ | ||
ForwardIt it = std::lower_bound(first, last, value); | ||
return (it != last && !(value < *it)) ? it : last; | ||
} | ||
|
||
template<class ForwardIt, class T, class Compare> | ||
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T &value, | ||
Compare comp) | ||
{ | ||
ForwardIt it = std::lower_bound(first, last, value, comp); | ||
return (it != last && !bool(comp(value, *it))) ? it : last; | ||
} | ||
|
||
#endif | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright (C) 2017 Andrew Gunnerson <[email protected]> | ||
* | ||
* This file is part of DualBootPatcher | ||
* | ||
* DualBootPatcher is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* DualBootPatcher is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with DualBootPatcher. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifndef MBSPARSE_BUILD | ||
#error libmbsparse private headers cannot be used | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2015-2016 Andrew Gunnerson <[email protected]> | ||
* Copyright (C) 2015-2017 Andrew Gunnerson <[email protected]> | ||
* Copyright (C) 2010 The Android Open Source Project | ||
* | ||
* This file is part of DualBootPatcher | ||
|
@@ -20,43 +20,48 @@ | |
|
||
#pragma once | ||
|
||
#include "mbcommon/common.h" | ||
#include "mbsparse/sparse_header.h" | ||
|
||
#ifdef __cplusplus | ||
#include <cstdio> | ||
#else | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef bool (*SparseOpenCb)(void *userData); | ||
typedef bool (*SparseCloseCb)(void *userData); | ||
typedef bool (*SparseReadCb)(void *buf, uint64_t size, uint64_t *bytesRead, | ||
void *userData); | ||
typedef bool (*SparseSeekCb)(int64_t offset, int whence, void *userData); | ||
typedef bool (*SparseSkipCb)(uint64_t offset, void *userData); | ||
|
||
struct SparseCtx; | ||
|
||
MB_EXPORT struct SparseCtx * sparseCtxNew(); | ||
MB_EXPORT bool sparseCtxFree(struct SparseCtx *ctx); | ||
|
||
MB_EXPORT bool sparseOpen(struct SparseCtx *ctx, SparseOpenCb openCb, | ||
SparseCloseCb closeCb, SparseReadCb readCb, | ||
SparseSeekCb seekCb, SparseSkipCb skipCb, | ||
void *userData); | ||
MB_EXPORT bool sparseClose(struct SparseCtx *ctx); | ||
MB_EXPORT bool sparseRead(struct SparseCtx *ctx, void *buf, uint64_t size, | ||
uint64_t *bytesRead); | ||
MB_EXPORT bool sparseSeek(struct SparseCtx *ctx, int64_t offset, int whence); | ||
MB_EXPORT bool sparseTell(struct SparseCtx *ctx, uint64_t *offset); | ||
MB_EXPORT bool sparseSize(struct SparseCtx *ctx, uint64_t *size); | ||
|
||
#ifdef __cplusplus | ||
#include "mbcommon/file.h" | ||
|
||
namespace mb | ||
{ | ||
namespace sparse | ||
{ | ||
|
||
class SparseFilePrivate; | ||
class MB_EXPORT SparseFile : public File | ||
{ | ||
MB_DECLARE_PRIVATE(SparseFile) | ||
|
||
public: | ||
SparseFile(); | ||
SparseFile(File *file); | ||
virtual ~SparseFile(); | ||
|
||
MB_DISABLE_COPY_CONSTRUCT_AND_ASSIGN(SparseFile) | ||
MB_DEFAULT_MOVE_CONSTRUCT_AND_ASSIGN(SparseFile) | ||
|
||
// File open | ||
FileStatus open(File *file); | ||
|
||
// File size | ||
uint64_t size(); | ||
|
||
protected: | ||
/*! \cond INTERNAL */ | ||
SparseFile(SparseFilePrivate *priv); | ||
SparseFile(SparseFilePrivate *priv, File *file); | ||
/*! \endcond */ | ||
|
||
virtual FileStatus on_open() override; | ||
virtual FileStatus on_close() override; | ||
virtual FileStatus on_read(void *buf, size_t size, | ||
size_t *bytes_read) override; | ||
virtual FileStatus on_seek(int64_t offset, int whence, | ||
uint64_t *new_offset) override; | ||
|
||
private: | ||
std::unique_ptr<SparseFilePrivate> _priv_ptr; | ||
}; | ||
|
||
} | ||
} | ||
#endif |
Oops, something went wrong.