Skip to content

Commit

Permalink
Merge pull request #19 from rtbo/tar_gnulong
Browse files Browse the repository at this point in the history
Rewrite Tar module and implement gnulong
  • Loading branch information
rtbo authored Aug 9, 2023
2 parents a962211 + ae3c907 commit c1d1581
Show file tree
Hide file tree
Showing 12 changed files with 1,689 additions and 432 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
os: [ ubuntu-latest, windows-latest ]
dc: [ dmd-latest ]
bt: [ debug ]
meson: [ '0.62.0' ]
meson: [ '0.62.2' ]

runs-on: ${{ matrix.os }}

Expand Down
19 changes: 17 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,31 @@ if get_option('enable_test')
'test/archive.d',
'test/compress.d',
'test/main.d',
'test/tar.d',
'test/util.d',
])

squiz_test_exe = executable('squiz-test', squiz_test_src,
stupid_gen_exe = executable('stupid_gen', 'tools/stupid_gen.d',
d_import_dirs: include_directories('tools'),
)
squiz_stupid = custom_target('dop_stupid',
capture: true,
output: 'stupid.d',
input: squiz_test_src,
command: [
stupid_gen_exe, '@INPUT@',
],
)

squiz_test_exe = executable('squiz-test', squiz_stupid, squiz_test_src,
d_unittest: true,
install: false,
include_directories: squiz_inc,
dependencies: squiz_deps,
d_module_versions: squiz_ver,
)

test('unit tests', squiz_test_exe)
test('unit tests', squiz_test_exe,
timeout: 120,
)
endif
126 changes: 125 additions & 1 deletion src/squiz_box/box/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ interface ArchiveEntry
import std.path : buildNormalizedPath, isAbsolute;
import std.string : startsWith;

if (allowedSz != ulong.max && size > allowedSz)
if (size > allowedSz)
return true;

const p = path;
Expand Down Expand Up @@ -571,3 +571,127 @@ class FileBoxEntry : BoxEntry
return inputRangeObject(ByChunkImpl(File(filePath, "rb"), chunkSize));
}
}

struct BoxEntryInfo
{
/// The archive mode this entry is for.
/// The path of the entry within the archive.
/// Should always be a relative path, and never go backward (..)
/// The directory separations are always '/' (forward slash) even on Windows
string path;

/// The type of entry (directory, file, symlink)
EntryType type;

/// If symlink, this is the path pointed to by the link (relative to the symlink).
/// Should be null for directories and regular file.
string linkname;

/// The size of the entry in bytes (should be zero for directories and symlink)
/// This is the size of uncompressed data.
ulong size;

/// The timeLastModified of the entry
SysTime timeLastModified;

/// The file attributes (as returned std.file.getLinkAttributes)
uint attributes;

version (Posix)
{
/// The owner id of the entry
int ownerId;
/// The group id of the entry
int groupId;
}
}

class InfoBoxEntry : BoxEntry
{
BoxEntryInfo info;
ByteRange data;

this(BoxEntryInfo info, ByteRange data)
in (data is null || data.empty || info.type == EntryType.regular, "data can only be supplied for regular files")
{
this.info = info;
this.data = data;
}

override @property EntryMode mode()
{
return EntryMode.creation;
}

override @property string path()
{
return info.path;
}

override @property EntryType type()
{
return info.type;
}

override @property string linkname()
{
return info.linkname;
}

override @property ulong size()
{
return info.size;
}

override @property SysTime timeLastModified()
{
return info.timeLastModified;
}

override @property uint attributes()
{
return info.attributes;
}

version (Posix)
{
override @property int ownerId()
{
return info.ownerId;
}

override @property int groupId()
{
return info.groupId;
}
}

/// Return the data passed in the ctor.
/// chunkSize has no effect here
ByteRange byChunk(size_t chunkSize = 0)
{
if (data)
return data;
return inputRangeObject(emptyByteRange);
}
}

/// Create a BoxEntry from the provided info.
/// This allows to create archives out of generated data, without any backing file on disk.
InfoBoxEntry infoEntry(I)(BoxEntryInfo info, I data)
if (isByteRange!I)
in (info.type == EntryType.regular || data.empty, "symlinks and directories can't have data")
{
import std.datetime : Clock;

if (info.timeLastModified == SysTime.init)
info.timeLastModified = Clock.currTime;

return new InfoBoxEntry(info, inputRangeObject(data));
}

/// ditto
InfoBoxEntry infoEntry(BoxEntryInfo info)
{
return infoEntry(info, inputRangeObject(emptyByteRange));
}
2 changes: 1 addition & 1 deletion src/squiz_box/box/seven_z/header.d
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ struct Header
auto unpacked = cursorByteRange(mainCursor, packSize)
.squizMaxOut(algo, unpackSize)
.join();
assert(unpacked.length = unpackSize);
assert(unpacked.length == unpackSize);

static if (false)
{
Expand Down
Loading

0 comments on commit c1d1581

Please sign in to comment.