Skip to content
This repository has been archived by the owner on Jan 30, 2021. It is now read-only.

Commit

Permalink
Fixed -p, -o and -i + finally added tests for them
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcin Kurczewski committed Jun 20, 2015
1 parent 99f86a3 commit 7ef4b34
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 16 deletions.
26 changes: 10 additions & 16 deletions cli/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "CRC/CRC16IBM.h"
#include "CRC/CRC32.h"
#include "File/File.h"
#include "util.h"

namespace
{
Expand Down Expand Up @@ -206,6 +207,7 @@ INFILE must be seekable stream. In other words, it cannot be a pipe

fa.automaticPosition = true;
fa.position = 0;
fa.overwrite = false;

for (size_t i = 3; i < args.size(); i++)
{
Expand Down Expand Up @@ -257,26 +259,18 @@ INFILE must be seekable stream. In other words, it cannot be a pipe
exit(EXIT_FAILURE);
}

auto totalSize = inputFile->getSize();
if (!fa.overwrite)
totalSize += fa.crc->getNumBytes();

if (fa.automaticPosition)
{
fa.position = fa.overwrite
? totalSize - fa.crc->getNumBytes()
: totalSize;
fa.position = computeAutoPosition(
inputFile->getSize(), fa.crc->getNumBytes(), fa.overwrite);
}

if (fa.position < 0)
fa.position += totalSize;

if (fa.position < 0 ||
fa.position + static_cast<File::OffsetType>(fa.crc->getNumBytes())
> totalSize)
else
{
std::cerr << "Patch position is located outside available input.\n";
exit(EXIT_FAILURE);
fa.position = shiftUserPosition(
fa.position,
inputFile->getSize(),
fa.crc->getNumBytes(),
fa.overwrite);
}

std::unique_ptr<File> outputFile;
Expand Down
55 changes: 55 additions & 0 deletions lib/util.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "util.h"

File::OffsetType computeAutoPosition(
File::OffsetType fileSize,
size_t crcSize,
bool overwrite)
{
auto totalSize = fileSize;
if (!overwrite)
totalSize += crcSize;

File::OffsetType targetPosition = crcSize
? totalSize - crcSize
: totalSize;

if (targetPosition < 0)
{
targetPosition += overwrite
? fileSize - crcSize
: fileSize;
}

if (targetPosition < 0 ||
targetPosition + static_cast<File::OffsetType>(crcSize) > totalSize)
{
throw std::invalid_argument(
"Patch position is located outside available input");
}

return targetPosition;
}

File::OffsetType shiftUserPosition(
File::OffsetType userPosition,
File::OffsetType fileSize,
size_t crcSize,
bool overwrite)
{
auto targetPosition = userPosition;
auto totalSize = fileSize;
if (!overwrite)
totalSize += crcSize;

while (targetPosition < 0)
targetPosition += fileSize;

if (targetPosition < 0 ||
targetPosition + static_cast<File::OffsetType>(crcSize) > totalSize)
{
throw std::invalid_argument(
"Patch position is located outside available input");
}

return targetPosition;
}
16 changes: 16 additions & 0 deletions lib/util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef CLI_UTIL_H
#define CLI_UTIL_H
#include "File/File.h"

File::OffsetType computeAutoPosition(
File::OffsetType fileSize,
size_t crcSize,
bool overwrite);

File::OffsetType shiftUserPosition(
File::OffsetType userPosition,
File::OffsetType fileSize,
size_t crcSize,
bool overwrite);

#endif
62 changes: 62 additions & 0 deletions tests/test_position.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "catch.hh"
#include "util.h"

TEST_CASE("Automatic patch insertion position works", "[pos]")
{
REQUIRE(computeAutoPosition(0, 4, false) == 0);
REQUIRE(computeAutoPosition(0, 2, false) == 0);
REQUIRE(computeAutoPosition(2, 4, false) == 2);
REQUIRE(computeAutoPosition(2, 2, false) == 2);
}

TEST_CASE("Automatic patch overwrite position works", "[pos]")
{
REQUIRE_THROWS(computeAutoPosition(0, 4, true));
REQUIRE_THROWS(computeAutoPosition(2, 4, true));
REQUIRE(computeAutoPosition(4, 4, true) == 0);
REQUIRE(computeAutoPosition(5, 4, true) == 1);
}

TEST_CASE("Manual patch insertion position works", "[pos]")
{
REQUIRE(shiftUserPosition(0, 4, 4, false) == 0);
REQUIRE(shiftUserPosition(1, 4, 4, false) == 1);
REQUIRE(shiftUserPosition(2, 4, 4, false) == 2);
REQUIRE(shiftUserPosition(3, 4, 4, false) == 3);
REQUIRE(shiftUserPosition(4, 4, 4, false) == 4);
REQUIRE_THROWS(shiftUserPosition(5, 4, 4, false));
}

TEST_CASE("Manual patch overwrite position works", "[pos]")
{
REQUIRE(shiftUserPosition(0, 4, 4, true) == 0);
REQUIRE_THROWS(shiftUserPosition(1, 4, 4, true));
REQUIRE_THROWS(shiftUserPosition(2, 4, 4, true));
REQUIRE_THROWS(shiftUserPosition(3, 4, 4, true));
REQUIRE_THROWS(shiftUserPosition(4, 4, 4, true));
REQUIRE_THROWS(shiftUserPosition(5, 4, 4, true));
REQUIRE(shiftUserPosition(0, 4, 2, true) == 0);
REQUIRE(shiftUserPosition(1, 4, 2, true) == 1);
REQUIRE(shiftUserPosition(2, 4, 2, true) == 2);
REQUIRE_THROWS(shiftUserPosition(3, 4, 2, true));
}

TEST_CASE("Manual negative patch insertion position works", "[pos]")
{
REQUIRE(shiftUserPosition(-0, 4, 4, false) == 0);
REQUIRE(shiftUserPosition(-1, 4, 4, false) == 3);
REQUIRE(shiftUserPosition(-2, 4, 4, false) == 2);
REQUIRE(shiftUserPosition(-3, 4, 4, false) == 1);
REQUIRE(shiftUserPosition(-4, 4, 4, false) == 0);
REQUIRE(shiftUserPosition(-5, 4, 4, false) == 3);
}

TEST_CASE("Manual negative patch overwrite position works", "[pos]")
{
REQUIRE(shiftUserPosition(-0, 4, 4, true) == 0);
REQUIRE_THROWS(shiftUserPosition(-1, 4, 4, true));
REQUIRE_THROWS(shiftUserPosition(-2, 4, 4, true));
REQUIRE_THROWS(shiftUserPosition(-3, 4, 4, true));
REQUIRE(shiftUserPosition(-4, 4, 4, true) == 0);
REQUIRE_THROWS(shiftUserPosition(-5, 4, 4, true));
}

0 comments on commit 7ef4b34

Please sign in to comment.