Skip to content

Commit

Permalink
Add TarReader
Browse files Browse the repository at this point in the history
  • Loading branch information
Sainan committed Dec 4, 2024
1 parent 5e9dd6e commit c43288b
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 0 deletions.
9 changes: 9 additions & 0 deletions soup/Reader.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <cstring> // memset

#include "ioBase.hpp"

#include "fwd.hpp"
Expand Down Expand Up @@ -193,6 +195,13 @@ NAMESPACE_SOUP
return raw(v.data(), len);
}

// String with known length.
bool str(size_t len, char* v) SOUP_EXCAL
{
memset(v, 0, len);
return raw(v, len);
}

// std::vector<uint8_t> with u8 size prefix.
bool vec_u8_u8(std::vector<uint8_t>& v) SOUP_EXCAL
{
Expand Down
3 changes: 3 additions & 0 deletions soup/Soup.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,8 @@
<ClInclude Include="StringPool.hpp" />
<ClInclude Include="Sudoku.hpp" />
<ClInclude Include="T128.hpp" />
<ClInclude Include="TarIndexedFile.hpp" />
<ClInclude Include="TarReader.hpp" />
<ClInclude Include="textmate_grammar.hpp" />
<ClInclude Include="TlsSignatureScheme.hpp" />
<ClInclude Include="TransientToken.hpp" />
Expand Down Expand Up @@ -1367,6 +1369,7 @@
<ClCompile Include="spaceship.cpp" />
<ClCompile Include="Sudoku.cpp" />
<ClCompile Include="Svg.cpp" />
<ClCompile Include="TarReader.cpp" />
<ClCompile Include="Task.cpp" />
<ClCompile Include="textmate_grammar.cpp" />
<ClCompile Include="time.cpp" />
Expand Down
12 changes: 12 additions & 0 deletions soup/Soup.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,12 @@
<ClInclude Include="UnorderedMap.hpp">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="TarReader.hpp">
<Filter>io\tar</Filter>
</ClInclude>
<ClInclude Include="TarIndexedFile.hpp">
<Filter>io\tar</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Bytepatch.cpp">
Expand Down Expand Up @@ -2489,6 +2495,9 @@
<ClCompile Include="DetourHookBase.cpp">
<Filter>util\hooks</Filter>
</ClCompile>
<ClCompile Include="TarReader.cpp">
<Filter>io\tar</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="os">
Expand Down Expand Up @@ -2749,6 +2758,9 @@
<Filter Include="util\hooks">
<UniqueIdentifier>{a7f4aeee-77a2-4381-a5cb-7d9492511b79}</UniqueIdentifier>
</Filter>
<Filter Include="io\tar">
<UniqueIdentifier>{362041cb-1458-4b94-a12e-e5369f3ce84e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
Expand Down
13 changes: 13 additions & 0 deletions soup/TarIndexedFile.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "base.hpp"

NAMESPACE_SOUP
{
struct TarIndexedFile
{
char name[101];
size_t offset;
size_t size;
};
}
48 changes: 48 additions & 0 deletions soup/TarReader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "TarReader.hpp"

#include "string.hpp"

NAMESPACE_SOUP
{
std::vector<TarIndexedFile> TarReader::getFileList() const SOUP_EXCAL
{
r.seekEnd();
const size_t tarsize = r.getPosition();
SOUP_IF_UNLIKELY ((tarsize % 512) != 0)
{
return {}; // Not a valid tarball
}

std::vector<TarIndexedFile> res{};
for (size_t i = 0; i != tarsize; )
{
r.seek(i + 124);
char size_octal[13];
memset(size_octal, 0, sizeof(size_octal));
r.raw(size_octal, 12);
size_t size;
SOUP_IF_UNLIKELY (!string::toIntEx<size_t, 8>(size_octal, string::TI_FULL).consume(size))
{
break; // Tarball might end on a null block
}

r.seek(i + 156);
char type;
r.c(type);
if (type == '\0' || type == '0') // Regular file?
{
auto& file = res.emplace_back();

memset(file.name, 0, sizeof(file.name));
r.seek(i);
r.raw(file.name, 100);

file.offset = i + 512;
file.size = size;
}

i += ((1 + ((size + 511) / 512)) * 512);
}
return res;
}
}
27 changes: 27 additions & 0 deletions soup/TarReader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "Reader.hpp"
#include "TarIndexedFile.hpp"

NAMESPACE_SOUP
{
struct TarReader
{
Reader& r;

TarReader(Reader& r) noexcept
: r(r)
{
}

[[nodiscard]] std::vector<TarIndexedFile> getFileList() const SOUP_EXCAL;

[[nodiscard]] std::string getFileContents(const TarIndexedFile& file) const SOUP_EXCAL
{
r.seek(file.offset);
std::string res(file.size, '\0');
r.raw(res.data(), file.size);
return res;
}
};
}

0 comments on commit c43288b

Please sign in to comment.