zip-eocd-scan.dhover×454all
#!/usr/bin/env dub
/+ dub.sdl:
    name "autological_zip_eocd_scan"
    targetPath "build"
    dflags "-preview=in" "-preview=dip1000"
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
+/
/**
 * Suffix parasitism from first principles: a ZIP archive with arbitrary bytes
 * glued to its front, still readable — and readable from the *tail alone*.
 *
 * This program builds a two-entry, `STORED` (uncompressed) ZIP archive by hand,
 * prefixes it with an unrelated payload (here a shell script, standing in for an
 * ELF/PE/Mach-O image), and then reads it back the way a conformant ZIP reader
 * must: scan backwards from EOF for the End Of Central Directory signature
 * `PK\x05\x06`, take the central-directory offset and size out of it, and parse
 * only those bytes.
 *
 * Two properties are demonstrated, and they are the ones the catalog's whole
 * argument rests on:
 *
 *   1. **The prefix is legal.** Nothing in the format says byte 0 is a local file
 *      header. Every internal pointer is an absolute offset from the start of the
 *      file, so a reader that finds the footer can find everything else. This is
 *      exactly why `redbean` can be a PE + ELF + Mach-O image *and* a ZIP.
 *   2. **Reading is sub-linear.** The program reports how many bytes it actually
 *      touched to enumerate the archive versus the file size. A footer-anchored
 *      index is what makes a ranged/partial read possible at all — the same
 *      property Parquet, ORC and `eStargz` monetize over HTTP range requests.
 *
 * The offsets written into the central directory deliberately *include* the
 * prefix length. Getting that wrong is the single most common way a hand-built
 * polyglot breaks, and it is precisely what `zip -A` ("adjust self-extracting
 * archive") exists to repair.
 *
 * Companions:
 *   docs/research/autological-artifacts/zip-parasitism.md
 *   docs/research/autological-artifacts/footer-indexed-formats.md
 *   docs/research/autological-artifacts/cosmopolitan-ape/index.md
 *
 * Run with: `dub run --single zip-eocd-scan.d`
 *
 * Portability: pure `std`, no syscalls beyond a temp file. If a system `unzip`
 * is on `PATH` the program additionally asks it to list the polyglot, proving an
 * independent implementation agrees; if not, it prints a `SKIP:` line for that
 * step and still exits 0.
 */
module 
(module) autological_zip_eocd_scan

Suffix parasitism from first principles: a ZIP archive with arbitrary bytes glued to its front, still readable — and readable from the tail alone.

This program builds a two-entry, STORED (uncompressed) ZIP archive by hand, prefixes it with an unrelated payload (here a shell script, standing in for an ELF/PE/Mach-O image), and then reads it back the way a conformant ZIP reader must: scan backwards from EOF for the End Of Central Directory signature PK\x05\x06, take the central-directory offset and size out of it, and parse only those bytes.

Two properties are demonstrated, and they are the ones the catalog's whole argument rests on:

  1. The prefix is legal. Nothing in the format says byte 0 is a local file header. Every internal pointer is an absolute offset from the start of the file, so a reader that finds the footer can find everything else. This is exactly why redbean can be a PE + ELF + Mach-O image and a ZIP.

  2. Reading is sub-linear. The program reports how many bytes it actually touched to enumerate the archive versus the file size. A footer-anchored index is what makes a ranged/partial read possible at all — the same property Parquet, ORC and eStargz monetize over HTTP range requests.

The offsets written into the central directory deliberately include the prefix length. Getting that wrong is the single most common way a hand-built polyglot breaks, and it is precisely what zip -A ("adjust self-extracting archive") exists to repair.

Companions

docs/research/autological-artifacts/zip-parasitism.md docs/research/autological-artifacts/footer-indexed-formats.md docs/research/autological-artifacts/cosmopolitan-ape/index.md

Run with: dub run --single zip-eocd-scan.d

Portability

pure std, no syscalls beyond a temp file. If a system unzip is on PATH the program additionally asks it to list the polyglot, proving an independent implementation agrees; if not, it prints a SKIP: line for that step and still exits 0.

autological_zip_eocd_scan
;
import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) autological_zip_eocd_scan.appender = std.array.appender(A)() if (isDynamicArray!A)

Convenience function that returns an Appender instance, optionally initialized with array.

appender
;
import
(package) std
std
.
(module) std.bitmanip

Bit-level manipulation facilities.

Category Functions
Bit constructs BitArray bitfields bitsSet
Endianness conversion bigEndianToNative littleEndianToNative nativeToBigEndian nativeToLittleEndian swapEndian
Integral ranges append peek read write
Floating-Point manipulation DoubleRep FloatRep
Tagging taggedClassRef taggedPointer

Source

std/bitmanip.d

@copyrightCopyright The D Language Foundation 2007 - 2011.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, Alex Rønne Petersen, Damian Ziemba, Amaury SECHET
bitmanip
:
(alias template) autological_zip_eocd_scan.littleEndianToNative = std.bitmanip.littleEndianToNative(T, ulong n)(ubyte[n] val) if (canSwapEndianness!T && (n == T.sizeof))

Converts the given value from little endian to the native endianness and returns it. The value is given as a ubyte[n] where n is the size of the target type. You must give the target type as a template argument, because there are multiple types with the same size and so the type of the argument is not enough to determine the return type.

Taking a ubyte[n] helps prevent accidentally using a swapped value as a regular one (and in the case of floating point values, it's necessary, because the FPU will mess up any swapped floating point values. So, you can't actually have swapped floating point values as floating point values).

real is not supported, because its size is implementation-dependent and therefore could vary from machine to machine (which could make it unusable if you tried to transfer it to another machine).

littleEndianToNative
,
(alias template) autological_zip_eocd_scan.nativeToLittleEndian = std.bitmanip.nativeToLittleEndian(T)(const T val) if (canSwapEndianness!T)

Converts the given value from the native endianness to little endian and returns it as a ubyte[n] where n is the size of the given type.

Returning a ubyte[n] helps prevent accidentally using a swapped value as a regular one (and in the case of floating point values, it's necessary, because the FPU will mess up any swapped floating point values. So, you can't actually have swapped floating point values as floating point values).

nativeToLittleEndian
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) autological_zip_eocd_scan.text = std.conv.text(T...)(T args) if (T.length > 0)

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
;
import
(package) std
std
.
(package) std.digest
digest
.
(module) std.digest.crc

Cyclic Redundancy Check (32-bit) implementation.

Category Functions

| Template API | CRC CRC32 CRC64ECMA CRC64ISO |

| OOP API | CRC32Digest CRC64ECMADigest CRC64ISODigest |

| Helpers | crcHexString crc32Of crc64ECMAOf crc64ISOOf |

This module conforms to the APIs defined in std.digest. To understand the differences between the template and the OOP API, see std.digest.

This module publicly imports std.digest and can be used as a stand-alone module.

Note

CRCs are usually printed with the MSB first. When using toHexString the result will be in an unexpected order. Use toHexString's optional order parameter to specify decreasing order for the correct result. The crcHexString alias can also be used for this purpose.

References

Wikipedia on CRC

Source

std/digest/crc.d

CTFE

Digests do not work in CTFE

Examples

//Template API
import std.digest.crc;

ubyte[4] hash = crc32Of("The quick brown fox jumps over the lazy dog");
assert(crcHexString(hash) == "414FA339");

//Feeding data
ubyte[1024] data;
CRC32 crc;
crc.put(data[]);
crc.start(); //Start again
crc.put(data[]);
hash = crc.finish();
//OOP API
import std.digest.crc;

auto crc = new CRC32Digest();
ubyte[] hash = crc.digest("The quick brown fox jumps over the lazy dog");
assert(crcHexString(hash) == "414FA339"); //352441c2

//Feeding data
ubyte[1024] data;
crc.put(data[]);
crc.reset(); //Start again
crc.put(data[]);
hash = crc.finish();
@licenseBoost License 1.0.@authorsPavel "EvilOne" Minayev, Alex Rønne Petersen, Johannes Pfau@standardsImplements the 'common' IEEE CRC32 variant (LSB-first order, Initial value uint.max, complement result)
crc
:
(alias template) autological_zip_eocd_scan.crc32Of = std.digest.crc.crc32Of(T...)(T data)

This is a convenience alias for digest using the CRC32 implementation.

@paramdata InputRange of ElementType implicitly convertible to ubyte, ubyte[] or ubyte[num] or one or more arrays of any type.@returnsCRC32 of data
crc32Of
;
import
(package) std
std
.
(module) std.file

Utilities for manipulating files and scanning directories. Functions in this module handle files as a unit, e.g., read or write one file at a time. For opening files and manipulating them via handles refer to module std.stdio.

Category Functions
General exists isDir isFile isSymlink rename thisExePath
Directories chdir dirEntries getcwd mkdir mkdirRecurse rmdir rmdirRecurse tempDir
Files append copy read readText remove slurp write
Symlinks symlink readLink
Attributes attrIsDir attrIsFile attrIsSymlink getAttributes getLinkAttributes getSize setAttributes
Timestamp getTimes getTimesWin setTimes timeLastModified timeLastAccessed timeStatusChanged
Other DirEntry FileException PreserveAttributes SpanMode getAvailableDiskSpace

Source

std/file.d

@copyrightCopyright The D Language Foundation 2007 - 2011.@seeThe official tutorial for an introduction to working with files in D, module std.stdio for opening files and manipulating them via handles, and module std.path for manipulating path strings.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis
file
:
(alias template) autological_zip_eocd_scan.exists = std.file.exists(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
,
(alias template) autological_zip_eocd_scan.remove = std.file.remove(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Delete file name.

@paramname string or range of characters representing the file name@throwsFileException on error.
remove
,
(alias) autological_zip_eocd_scan.tempDir = string std.file.tempDir() @trusted

Returns the path to a directory for temporary files. On POSIX platforms, it searches through the following list of directories and returns the first one which is found to exist:

  1. The directory given by the TMPDIR environment variable.

  2. The directory given by the TEMP environment variable.

  3. The directory given by the TMP environment variable.

  4. /tmp/

  5. /var/tmp/

  6. /usr/tmp/

On all platforms, tempDir returns the current working directory on failure.

The return value of the function is cached, so the procedures described below will only be performed the first time the function is called. All subsequent runs will return the same string, regardless of whether environment variables and directory structures have changed in the meantime.

The POSIX tempDir algorithm is inspired by Python's tempfile.tempdir.

@returns

On Windows, this function returns the result of calling the Windows API function GetTempPath.

On POSIX platforms, it searches through the following list of directories and returns the first one which is found to exist:

  1. The directory given by the TMPDIR environment variable.

  2. The directory given by the TEMP environment variable.

  3. The directory given by the TMP environment variable.

  4. /tmp

  5. /var/tmp

  6. /usr/tmp

On all platforms, tempDir returns "." on failure, representing the current working directory.

tempDir
,
(alias template) autological_zip_eocd_scan.write = std.file.write(R)(R name, const void[] buffer) if ((isSomeFiniteCharInputRange!R || isSomeString!R) && !isConvertibleToString!R)

Write buffer to file name.

Creates the file if it does not already exist.

@paramname string or range of characters representing the file name@parambuffer data to be written to file@throwsFileException on error.@seetoFile
write
;
import
(package) std
std
.
(module) std.path

This module is used to manipulate path strings.

All functions, with the exception of expandTilde (and in some cases absolutePath and relativePath), are pure string manipulation functions; they don't depend on any state outside the program, nor do they perform any actual file system actions. This has the consequence that the module does not make any distinction between a path that points to a directory and a path that points to a file, and it does not know whether or not the object pointed to by the path actually exists in the file system. To differentiate between these cases, use isDir and exists.

Note that on Windows, both the backslash (\) and the slash (/) are in principle valid directory separators. This module treats them both on equal footing, but in cases where a new separator is added, a backslash will be used. Furthermore, the buildNormalizedPath function will replace all slashes with backslashes on that platform.

In general, the functions in this module assume that the input paths are well-formed. (That is, they should not contain invalid characters, they should follow the file system's path format, etc.) The result of calling a function on an ill-formed path is undefined. When there is a chance that a path or a file name is invalid (for instance, when it has been input by the user), it may sometimes be desirable to use the isValidFilename and isValidPath functions to check this.

Most functions do not perform any memory allocations, and if a string is returned, it is usually a slice of an input string. If a function allocates, this is explicitly mentioned in the documentation.

Category Functions
Normalization absolutePath asAbsolutePath asNormalizedPath asRelativePath buildNormalizedPath buildPath chainPath expandTilde
Partitioning baseName dirName dirSeparator driveName pathSeparator pathSplitter relativePath rootName stripDrive
Validation isAbsolute isDirSeparator isRooted isValidFilename isValidPath
Extension defaultExtension extension setExtension stripExtension withDefaultExtension withExtension
Other filenameCharCmp filenameCmp globMatch CaseSensitive

Source

std/path.d

@authorsLars Tandle Kyllingstad, Walter Bright, Grzegorz Adam Hankiewicz, Thomas Khne, Andrei Alexandrescu@copyrightCopyright (c) 2000-2014, the authors. All rights reserved.@licenseBoost License 1.0
path
:
(alias template) autological_zip_eocd_scan.buildPath = std.path.buildPath(Range)(scope Range segments) if (isInputRange!Range && !isInfinite!Range && isSomeString!(ElementType!Range))

Combines one or more path segments.

This function takes a set of path segments, given as an input range of string elements or as a set of string arguments, and concatenates them with each other. Directory separators are inserted between segments if necessary. If any of the path segments are absolute (as defined by isAbsolute), the preceding segments will be dropped.

On Windows, if one of the path segments are rooted, but not absolute (e.g. \foo), all preceding path segments down to the previous root will be dropped. (See below for an example.)

This function always allocates memory to hold the resulting path. The variadic overload is guaranteed to only perform a single allocation, as is the range version if paths is a forward range.

@paramsegments An input range of segments to assemble the path from.@returnsThe assembled path.
buildPath
;
import
(package) std
std
.
(module) std.process

Functions for starting and interacting with other processes, and for working with the current process' execution environment.

Process handling

  • `spawnProcess` spawns a new `process`, optionally assigning it an
        

    arbitrary set of standard input, output, and error streams. The function returns immediately, leaving the child process to execute in parallel with its parent. All other functions in this module that spawn processes are built around spawnProcess.

  • `wait` makes the parent `process` wait for a child `process` to
        

    terminate. In general one should always do this, to avoid child processes becoming "zombies" when the parent process exits. Scope guards are perfect for this – see the spawnProcess documentation for examples. tryWait is similar to wait, but does not block if the process has not yet terminated.

  • `pipeProcess` also spawns a child `process` which runs
        

    in parallel with its parent. However, instead of taking arbitrary streams, it automatically creates a set of pipes that allow the parent to communicate with the child through the child's standard input, output, and/or error streams. This function corresponds roughly to C's popen function.

  • `execute` starts a new `process` and waits for it
        

    to complete before returning. Additionally, it captures the process' standard output and error streams and returns the output of these as a string.

  • `spawnShell`, `pipeShell` and `executeShell` work like
        

    spawnProcess, pipeProcess and execute, respectively, except that they take a single command string and run it through the current user's default command interpreter. executeShell corresponds roughly to C's system function.

  • `kill` attempts to terminate a running `process`.
    
    

The following table compactly summarises the different process creation functions and how they relate to each other:

Runs program directly
Runs shell command
Low-level process creation
spawnProcess
spawnShell
Automatic input/output redirection using pipes
pipeProcess
pipeShell
Execute and wait for completion, collect output
execute
executeShell

Other functionality

  • `pipe` is used to create unidirectional pipes.
    
  • `environment` is an interface through which the current `process`'
        

    environment variables can be read and manipulated.

  • `escapeShellCommand` and `escapeShellFileName` are useful
        

    for constructing shell command lines in a portable way.

Source

std/process.d

Note

Most of the functionality in this module is not available on iOS, tvOS and watchOS. The only functions available on those platforms are: environment, thisProcessID and thisThreadID.

@authorsLars Tandle Kyllingstad, Steven Schveighoffer, Vladimir Panteleev@copyrightCopyright (c) 2013, the authors. All rights reserved.@licenseBoost License 1.0.
process
:
(alias) autological_zip_eocd_scan.execute = std.typecons.Tuple!(int, "status", string, "output") std.process.execute(scope const(char[])[] args, const(string[string]) env = cast(const(string[string]))null, std.process.Config config = Config(Flags.none, null, null), ulong maxOutput = 18446744073709551615LU, scope const(char)[] workDir = null) @safe

Executes the given program or shell command and returns its exit code and output.

execute and executeShell start a new process using spawnProcess and spawnShell, respectively, and wait for the process to complete before returning. The functions capture what the child process prints to both its standard output and standard error streams, and return this together with its exit code.

auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);

auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);

The args/program/command, env and config parameters are forwarded straight to the underlying spawn functions, and we refer to their documentation for details.

POSIX specific

If the process is terminated by a signal, the status field of the return value will contain a negative number whose absolute value is the signal number. (See wait for details.)

@paramargs An array which contains the program name as the zeroth element and any command-line arguments in the following elements. (See spawnProcess for details.)@paramprogram The program name, without command-line arguments. (See spawnProcess for details.)@paramcommand A shell command which is passed verbatim to the command interpreter. (See spawnShell for details.)@paramenv Additional environment variables for the child process. (See spawnProcess for details.)@paramconfig Flags that control process creation. See Config for an overview of available flags, and note that the retainStd... flags have no effect in this function.@parammaxOutput The maximum number of bytes of output that should be captured.@paramworkDir The working directory for the new process. By default the child process inherits the parent's working directory.@paramshellPath The path to the shell to use to run the specified program. By default this is nativeShell.@returnsAn std.typecons.Tuple!(int, "status", string, "output").@throws

ProcessException on failure to start the process.

StdioException on failure to capture output.

execute
,
(struct) std.process.Config

Options that control the behaviour of process creation functions in this module. Most options only apply to spawnProcess and spawnShell.

Example

auto logFile = File("myapp_error.log", "w");

// Start program, suppressing the console window (Windows only),
// redirect its error stream to logFile, and leave logFile open
// in the parent process as well.
auto pid = spawnProcess("myapp", stdin, stdout, logFile,
                        Config.retainStderr | Config.suppressConsole);
scope(exit)
{
    auto exitCode = wait(pid);
    logFile.writeln("myapp exited with code ", exitCode);
    logFile.close();
}
Config
;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(struct) std.stdio.File

Encapsulates a FILE*. Generally D does not attempt to provide thin wrappers over equivalent functions in the C standard library, but manipulating FILE* values directly is unsafe and error-prone in many ways. The File type ensures safe manipulation, automatic file closing, and a lot of convenience.

The underlying FILE* handle is maintained in a reference-counted manner, such that as soon as the last File variable bound to a given FILE* goes out of scope, the underlying FILE* is automatically closed.

Example

// test.d
import std.stdio;

void main(string[] args)
{
    auto f = File("test.txt", "w"); // open for writing
    f.write("Hello");
    if (args.length > 1)
    {
        auto g = f; // now g and f write to the same file
                    // internal reference count is 2
        g.write(", ", args[1]);
        // g exits scope, reference count decreases to 1
    }
    f.writeln("!");
    // f exits scope, reference count falls to zero,
    // underlying `FILE*` is closed.
}

% rdmd test.d Jimmy % cat test.txt Hello, Jimmy! % _

File
,
(alias template) autological_zip_eocd_scan.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to writef(fmt, args, '\n').

writefln
,
(alias template) autological_zip_eocd_scan.writeln = std.stdio.writeln(T...)(T args)

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
import
(package) std
std
.
(module) std.string

String handling functions.

Category Functions
Searching
column
indexOf
indexOfAny
indexOfNeither
lastIndexOf
lastIndexOfAny
lastIndexOfNeither
Comparison
isNumeric
Mutation
capitalize
Pruning and Filling
center
chomp
chompPrefix
chop
detabber
detab
entab
entabber
leftJustify
outdent
rightJustify
strip
stripLeft
stripRight
wrap
Substitution
abbrev
soundex
soundexer
succ
tr
translate
Miscellaneous
assumeUTF
fromStringz
lineSplitter
representation
splitLines
toStringz
Objects of types string, wstring, and dstring are value types
and cannot be mutated element-by-element. For using mutation during building
strings, use char[], wchar[], or dchar[]. The xxxstring
types are preferable because they don't exhibit undesired aliasing, thus
making code more robust.

The following functions are publicly imported:

Module Functions
Publicly imported functions
std.algorithm
cmp, std,algorithm,comparison
count, std,algorithm,searching
endsWith, std,algorithm,searching
startsWith, std,algorithm,searching
std.array
join, std,array
replace, std,array
replaceInPlace, std,array
split, std,array
empty, std,array
std.format
format, std,format
sformat, std,format
std.uni
icmp, std,uni
toLower, std,uni
toLowerInPlace, std,uni
toUpper, std,uni
toUpperInPlace, std,uni
There is a rich set of functions for string handling defined in other modules.
Functions related to Unicode and ASCII are found in std.uni
and std.ascii, respectively. Other functions that have a
wider generality than just strings can be found in std.algorithm
and std.range.

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) autological_zip_eocd_scan.representation = std.string.representation(Char)(Char[] s) if (isSomeChar!Char)

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
/// One member of the archive we are about to synthesize. struct
(struct) autological_zip_eocd_scan.Member

One member of the archive we are about to synthesize.

Member
{
(alias) object.string = string
string
(field) string autological_zip_eocd_scan.Member.name
name
;
(alias) object.string = string
string
(field) string autological_zip_eocd_scan.Member.contents
contents
;
} /// Where a member's local header ended up, so the central directory can point at it. struct
(struct) autological_zip_eocd_scan.Placed

Where a member's local header ended up, so the central directory can point at it.

Placed
{
(struct) autological_zip_eocd_scan.Member

One member of the archive we are about to synthesize.

Member
(field) autological_zip_eocd_scan.Member autological_zip_eocd_scan.Placed.member
member
;
uint
(field) uint autological_zip_eocd_scan.Placed.localHeaderOffset
localHeaderOffset
;
uint
(field) uint autological_zip_eocd_scan.Placed.crc
crc
;
} private enum uint
(constant) uint autological_zip_eocd_scan.sigLocal = 67324752u
sigLocal
= 0x0403_4b50; // "PK\x03\x04"
private enum uint
(constant) uint autological_zip_eocd_scan.sigCentral = 33639248u
sigCentral
= 0x0201_4b50; // "PK\x01\x02"
private enum uint
(constant) uint autological_zip_eocd_scan.sigEocd = 101010256u
sigEocd
= 0x0605_4b50; // "PK\x05\x06"
/// Appends `value` to `w` in little-endian order, the only byte order ZIP uses. void
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(T, W)(ref
(alias) W = std.array.Appender!(ubyte[])
W
(parameter) std.array.Appender!(ubyte[]) w
w
,
(alias) T = ushort
T
(parameter) ushort value
value
)
{
(parameter) std.array.Appender!(ubyte[]) w
w
~=
ubyte[2] std.bitmanip.nativeToLittleEndian!ushort(const(ushort) val) pure nothrow @nogc @trusted

Converts the given value from the native endianness to little endian and returns it as a ubyte[n] where n is the size of the given type.

Returning a ubyte[n] helps prevent accidentally using a swapped value as a regular one (and in the case of floating point values, it's necessary, because the FPU will mess up any swapped floating point values. So, you can't actually have swapped floating point values as floating point values).

Examples

int i = 12345;
ubyte[4] swappedI = nativeToLittleEndian(i);
assert(i == littleEndianToNative!int(swappedI));

float f = 123.45f;
ubyte[4] swappedF = nativeToLittleEndian(f);
assert(f == littleEndianToNative!float(swappedF));

const float cf = 123.45f;
ubyte[4] swappedCF = nativeToLittleEndian(cf);
assert(cf == littleEndianToNative!float(swappedCF));

double d = 123.45;
ubyte[8] swappedD = nativeToLittleEndian(d);
assert(d == littleEndianToNative!double(swappedD));

const double cd = 123.45;
ubyte[8] swappedCD = nativeToLittleEndian(cd);
assert(cd == littleEndianToNative!double(swappedCD));
nativeToLittleEndian
(
(parameter) ushort value
value
)[];
} /// Reads a little-endian `T` at `offset` from `bytes`.
(alias) T = uint
T
uint autological_zip_eocd_scan.readLE!uint(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
(T)(in ubyte[]
(parameter) const(ubyte[]) bytes
bytes
,
(alias) object.size_t = ulong
size_t
(parameter) ulong offset
offset
)
in (
(parameter) ulong offset
offset
+
(uint) uint
T
.
(constant) ulong uint.sizeof = 4LU
sizeof
<=
(parameter) const(ubyte[]) bytes
bytes
.
(field) ulong const(ubyte[]).length
length
, "read past end of buffer")
{ ubyte[
(alias) T = uint
T
.sizeof]
(local variable) ubyte[4] raw
raw
=
(parameter) const(ubyte[]) bytes
bytes
[
(parameter) ulong offset
offset
..
(parameter) ulong offset
offset
+
(uint) uint
T
.
(constant) ulong uint.sizeof = 4LU
sizeof
];
return
uint std.bitmanip.littleEndianToNative!(uint, 4LU)(ubyte[4] val) pure nothrow @nogc @trusted

Converts the given value from little endian to the native endianness and returns it. The value is given as a ubyte[n] where n is the size of the target type. You must give the target type as a template argument, because there are multiple types with the same size and so the type of the argument is not enough to determine the return type.

Taking a ubyte[n] helps prevent accidentally using a swapped value as a regular one (and in the case of floating point values, it's necessary, because the FPU will mess up any swapped floating point values. So, you can't actually have swapped floating point values as floating point values).

real is not supported, because its size is implementation-dependent and therefore could vary from machine to machine (which could make it unusable if you tried to transfer it to another machine).

Examples

ushort i = 12345;
ubyte[2] swappedI = nativeToLittleEndian(i);
assert(i == littleEndianToNative!ushort(swappedI));

dchar c = 'D';
ubyte[4] swappedC = nativeToLittleEndian(c);
assert(c == littleEndianToNative!dchar(swappedC));
littleEndianToNative
!
(alias) T = uint
T
(
(local variable) ubyte[4] raw
raw
);
} /++ Builds a `STORED` ZIP whose internal offsets are biased by `prefixLength`. Passing a non-zero `prefixLength` is the whole trick: the archive is written as if it already began that many bytes into the file, so gluing it after an unrelated payload of exactly that size produces a file both readers accept. +/ ubyte[]
ubyte[] autological_zip_eocd_scan.buildZip(in autological_zip_eocd_scan.Member[] members, uint prefixLength) @safe

Builds a STORED ZIP whose internal offsets are biased by prefixLength.

Passing a non-zero prefixLength is the whole trick: the archive is written as if it already began that many bytes into the file, so gluing it after an unrelated payload of exactly that size produces a file both readers accept.

buildZip
(in
(struct) autological_zip_eocd_scan.Member

One member of the archive we are about to synthesize.

Member
[]
(parameter) const(autological_zip_eocd_scan.Member[]) members
members
, uint
(parameter) uint prefixLength
prefixLength
) @safe
{ auto
(local variable) std.array.Appender!(ubyte[]) body_
body_
=
std.array.Appender!(ubyte[]) std.array.appender!(ubyte[])() pure nothrow @safe

Convenience function that returns an Appender instance, optionally initialized with array.

appender
!(ubyte[]);
(struct) autological_zip_eocd_scan.Placed

Where a member's local header ended up, so the central directory can point at it.

Placed
[]
(local variable) autological_zip_eocd_scan.Placed[] placed
placed
;
foreach (
(parameter) const(autological_zip_eocd_scan.Member) m
m
;
(parameter) const(autological_zip_eocd_scan.Member[]) members
members
)
{ const
(local variable) const(immutable(ubyte)[]) data
data
=
(local variable) const(autological_zip_eocd_scan.Member) m
m
.
(field) string autological_zip_eocd_scan.Member.contents
contents
.
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
const
(local variable) const(uint) crc
crc
= () @trusted { return
uint std.bitmanip.littleEndianToNative!(uint, 4LU)(ubyte[4] val) pure nothrow @nogc @trusted

Converts the given value from little endian to the native endianness and returns it. The value is given as a ubyte[n] where n is the size of the target type. You must give the target type as a template argument, because there are multiple types with the same size and so the type of the argument is not enough to determine the return type.

Taking a ubyte[n] helps prevent accidentally using a swapped value as a regular one (and in the case of floating point values, it's necessary, because the FPU will mess up any swapped floating point values. So, you can't actually have swapped floating point values as floating point values).

real is not supported, because its size is implementation-dependent and therefore could vary from machine to machine (which could make it unusable if you tried to transfer it to another machine).

Examples

ushort i = 12345;
ubyte[2] swappedI = nativeToLittleEndian(i);
assert(i == littleEndianToNative!ushort(swappedI));

dchar c = 'D';
ubyte[4] swappedC = nativeToLittleEndian(c);
assert(c == littleEndianToNative!dchar(swappedC));
littleEndianToNative
!uint(
ubyte[4] std.digest.crc.crc32Of!(immutable(ubyte)[])(immutable(ubyte)[] __param_0) pure nothrow @nogc @safe

This is a convenience alias for digest using the CRC32 implementation.

Examples

ubyte[] data = [4,5,7,25];
assert(data.crc32Of == [167, 180, 199, 131]);

import std.utf : byChar;
assert("hello"d.byChar.crc32Of == [134, 166, 16, 54]);

ubyte[4] hash = "abc".crc32Of();
assert(hash == digest!CRC32("ab", "c"));

import std.range : iota;
enum ubyte S = 5, F = 66;
assert(iota(S, F).crc32Of == [59, 140, 234, 154]);
@paramdata InputRange of ElementType implicitly convertible to ubyte, ubyte[] or ubyte[num] or one or more arrays of any type.@returnsCRC32 of data
crc32Of
(
(local variable) const(immutable(ubyte)[]) data
data
)); }();
(local variable) autological_zip_eocd_scan.Placed[] placed
placed
~=
(struct) autological_zip_eocd_scan.Placed

Where a member's local header ended up, so the central directory can point at it.

Placed
(
(local variable) const(autological_zip_eocd_scan.Member) m
m
,
(parameter) uint prefixLength
prefixLength
+ cast(uint)
(local variable) std.array.Appender!(ubyte[]) body_
body_
[].
(field) ulong ubyte[].length
length
,
(local variable) const(uint) crc
crc
);
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
,
(constant) uint autological_zip_eocd_scan.sigLocal = 67324752u
sigLocal
);
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, ushort(20)); // version needed to extract: 2.0
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, ushort(0)); // general purpose bit flag
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, ushort(0)); // compression method: 0 = STORED
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, ushort(0)); // last mod time (fixed, for reproducibility)
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, ushort(0x21)); // last mod date: 1980-01-01
void autological_zip_eocd_scan.putLE!(const(uint), std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, const(uint) value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
,
(local variable) const(uint) crc
crc
);
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, cast(uint)
(local variable) const(immutable(ubyte)[]) data
data
.
(field) ulong const(immutable(ubyte)[]).length
length
); // compressed size
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, cast(uint)
(local variable) const(immutable(ubyte)[]) data
data
.
(field) ulong const(immutable(ubyte)[]).length
length
); // uncompressed size
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, cast(ushort)
(local variable) const(autological_zip_eocd_scan.Member) m
m
.
(field) string autological_zip_eocd_scan.Member.name
name
.
(field) ulong const(string).length
length
);
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) body_
body_
, ushort(0)); // extra field length
(local variable) std.array.Appender!(ubyte[]) body_
body_
~=
(local variable) const(autological_zip_eocd_scan.Member) m
m
.
(field) string autological_zip_eocd_scan.Member.name
name
.
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
(local variable) std.array.Appender!(ubyte[]) body_
body_
~=
(local variable) const(immutable(ubyte)[]) data
data
;
} const
(local variable) const(uint) centralOffset
centralOffset
=
(parameter) uint prefixLength
prefixLength
+ cast(uint)
(local variable) std.array.Appender!(ubyte[]) body_
body_
[].
(field) ulong ubyte[].length
length
;
auto
(local variable) std.array.Appender!(ubyte[]) central
central
=
std.array.Appender!(ubyte[]) std.array.appender!(ubyte[])() pure nothrow @safe

Convenience function that returns an Appender instance, optionally initialized with array.

appender
!(ubyte[]);
foreach (
(parameter) autological_zip_eocd_scan.Placed p
p
;
(local variable) autological_zip_eocd_scan.Placed[] placed
placed
)
{ const
(local variable) const(immutable(ubyte)[]) data
data
=
(local variable) autological_zip_eocd_scan.Placed p
p
.
(field) autological_zip_eocd_scan.Member autological_zip_eocd_scan.Placed.member
member
.
(field) string autological_zip_eocd_scan.Member.contents
contents
.
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
,
(constant) uint autological_zip_eocd_scan.sigCentral = 33639248u
sigCentral
);
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(20)); // version made by
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(20)); // version needed to extract
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // flags
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // method: STORED
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // time
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0x21)); // date
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
,
(local variable) autological_zip_eocd_scan.Placed p
p
.
(field) uint autological_zip_eocd_scan.Placed.crc
crc
);
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, cast(uint)
(local variable) const(immutable(ubyte)[]) data
data
.
(field) ulong const(immutable(ubyte)[]).length
length
);
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, cast(uint)
(local variable) const(immutable(ubyte)[]) data
data
.
(field) ulong const(immutable(ubyte)[]).length
length
);
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, cast(ushort)
(local variable) autological_zip_eocd_scan.Placed p
p
.
(field) autological_zip_eocd_scan.Member autological_zip_eocd_scan.Placed.member
member
.
(field) string autological_zip_eocd_scan.Member.name
name
.
(field) ulong string.length
length
);
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // extra length
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // comment length
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // disk number start
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, ushort(0)); // internal attributes
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
, uint(0)); // external attributes
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) central
central
,
(local variable) autological_zip_eocd_scan.Placed p
p
.
(field) uint autological_zip_eocd_scan.Placed.localHeaderOffset
localHeaderOffset
); // <-- biased by the prefix
(local variable) std.array.Appender!(ubyte[]) central
central
~=
(local variable) autological_zip_eocd_scan.Placed p
p
.
(field) autological_zip_eocd_scan.Member autological_zip_eocd_scan.Placed.member
member
.
(field) string autological_zip_eocd_scan.Member.name
name
.
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
} auto
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
=
std.array.Appender!(ubyte[]) std.array.appender!(ubyte[])() pure nothrow @safe

Convenience function that returns an Appender instance, optionally initialized with array.

appender
!(ubyte[]);
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
,
(constant) uint autological_zip_eocd_scan.sigEocd = 101010256u
sigEocd
);
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
, ushort(0)); // this disk
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
, ushort(0)); // disk with central directory
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
, cast(ushort)
(local variable) autological_zip_eocd_scan.Placed[] placed
placed
.
(field) ulong autological_zip_eocd_scan.Placed[].length
length
); // entries on this disk
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
, cast(ushort)
(local variable) autological_zip_eocd_scan.Placed[] placed
placed
.
(field) ulong autological_zip_eocd_scan.Placed[].length
length
); // entries total
void autological_zip_eocd_scan.putLE!(uint, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, uint value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
, cast(uint)
(local variable) std.array.Appender!(ubyte[]) central
central
[].
(field) ulong ubyte[].length
length
); // central directory size
void autological_zip_eocd_scan.putLE!(const(uint), std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, const(uint) value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
,
(local variable) const(uint) centralOffset
centralOffset
); // <-- biased by the prefix
void autological_zip_eocd_scan.putLE!(ushort, std.array.Appender!(ubyte[]))(ref std.array.Appender!(ubyte[]) w, ushort value) pure nothrow @safe

Appends value to w in little-endian order, the only byte order ZIP uses.

putLE
(
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
, ushort(0)); // comment length
return
(local variable) std.array.Appender!(ubyte[]) body_
body_
[] ~
(local variable) std.array.Appender!(ubyte[]) central
central
[] ~
(local variable) std.array.Appender!(ubyte[]) eocd
eocd
[];
} /// What a tail-only read recovered, plus what it cost. struct
(struct) autological_zip_eocd_scan.Enumerated

What a tail-only read recovered, plus what it cost.

Enumerated
{
(alias) object.string = string
string
[]
(field) string[] autological_zip_eocd_scan.Enumerated.names
names
;
uint
(field) uint autological_zip_eocd_scan.Enumerated.centralOffset
centralOffset
;
uint
(field) uint autological_zip_eocd_scan.Enumerated.centralSize
centralSize
;
uint
(field) uint autological_zip_eocd_scan.Enumerated.firstLocalHeaderOffset
firstLocalHeaderOffset
;
(alias) object.size_t = ulong
size_t
(field) ulong autological_zip_eocd_scan.Enumerated.bytesRead
bytesRead
;
} /++ Enumerates an archive by doing what a real reader does: seek to the end, scan backwards for the EOCD signature, then read only the central directory. Never reads a local file header, and never reads a byte of file data — which is why the returned `bytesRead` is a small constant plus the directory size, independent of how large the members (or the parasitic prefix) are. +/
(struct) autological_zip_eocd_scan.Enumerated

What a tail-only read recovered, plus what it cost.

Enumerated
autological_zip_eocd_scan.Enumerated autological_zip_eocd_scan.enumerateFromTail(string path, ulong tailWindow = 512LU)

Enumerates an archive by doing what a real reader does: seek to the end, scan backwards for the EOCD signature, then read only the central directory.

Never reads a local file header, and never reads a byte of file data — which is why the returned bytesRead is a small constant plus the directory size, independent of how large the members (or the parasitic prefix) are.

enumerateFromTail
(
(alias) object.string = string
string
(parameter) string path
path
,
(alias) object.size_t = ulong
size_t
(parameter) ulong tailWindow
tailWindow
= 512)
{ auto
(local variable) std.stdio.File f
f
=
(struct) std.stdio.File

Encapsulates a FILE*. Generally D does not attempt to provide thin wrappers over equivalent functions in the C standard library, but manipulating FILE* values directly is unsafe and error-prone in many ways. The File type ensures safe manipulation, automatic file closing, and a lot of convenience.

The underlying FILE* handle is maintained in a reference-counted manner, such that as soon as the last File variable bound to a given FILE* goes out of scope, the underlying FILE* is automatically closed.

Example

// test.d
import std.stdio;

void main(string[] args)
{
    auto f = File("test.txt", "w"); // open for writing
    f.write("Hello");
    if (args.length > 1)
    {
        auto g = f; // now g and f write to the same file
                    // internal reference count is 2
        g.write(", ", args[1]);
        // g exits scope, reference count decreases to 1
    }
    f.writeln("!");
    // f exits scope, reference count falls to zero,
    // underlying `FILE*` is closed.
}

% rdmd test.d Jimmy % cat test.txt Hello, Jimmy! % _

File
(
std.stdio.File std.stdio.File.this(string name, scope const(char)[] stdioOpenmode = "rb") ref @safe

Constructor taking the name of the file to open and the open mode.

Copying one File object to another results in the two File objects referring to the same underlying file.

The destructor automatically closes the file as soon as no File object refers to it anymore.

@paramname range or string representing the file name@paramstdioOpenmode range or string represting the open mode (with the same semantics as in the C standard library fopen function)@throwsErrnoException if the file could not be opened.
path
, "rb");
const
(local variable) const(ulong) size
size
=
(local variable) std.stdio.File f
f
.
ulong std.stdio.File.size() @property @safe

Returns the size of the file in bytes, ulong.max if file is not searchable or throws if the operation fails.

Example

import std.stdio, std.file;

void main()
{
    string deleteme = "delete.me";
    auto file_handle = File(deleteme, "w");
    file_handle.write("abc"); //create temporary file
    scope(exit) deleteme.remove; //remove temporary file at scope exit

    assert(file_handle.size() == 3); //check if file size is 3 bytes
}
size
;
(alias) object.size_t = ulong
size_t
(local variable) ulong bytesRead
bytesRead
;
const
(local variable) const(ulong) window
window
=
(local variable) const(ulong) size
size
<
(parameter) ulong tailWindow
tailWindow
? cast(
(alias) object.size_t = ulong
size_t
)
(local variable) const(ulong) size
size
:
(parameter) ulong tailWindow
tailWindow
;
(local variable) std.stdio.File f
f
.
void std.stdio.File.seek(long offset, int origin = 0) @trusted

Calls fseek for the file handle to move its position indicator.

@paramoffset Binary files: Number of bytes to offset from origin. Text files: Either zero, or a value returned by tell.@paramorigin Binary files: Position used as reference for the offset, must be one of SEEK_SET, SEEK_CUR or SEEK_END. Text files: Shall necessarily be SEEK_SET.@throwsException if the file is not opened. ErrnoException if the call to fseek fails.
seek
(cast(long)(
(local variable) const(ulong) size
size
-
(local variable) const(ulong) window
window
));
auto
(local variable) ubyte[] tail
tail
= new ubyte[
(local variable) const(ulong) window
window
];
(local variable) ubyte[] tail
tail
=
(local variable) std.stdio.File f
f
.
ubyte[] std.stdio.File.rawRead!ubyte(ubyte[] buffer) @safe

Calls fread for the file handle. The number of items to read and the size of each item is inferred from the size and type of the input array, respectively.

Examples

static import std.file;

auto testFile = std.file.deleteme();
std.file.write(testFile, "\r\n\n\r\n");
scope(exit) std.file.remove(testFile);

auto f = File(testFile, "r");
auto buf = f.rawRead(new char[5]);
f.close();
assert(buf == "\r\n\n\r\n");
@returnsThe slice of buffer containing the data that was actually read. This will be shorter than buffer if EOF was reached before the buffer could be filled. If the buffer is empty, it will be returned.@throws

ErrnoException if the file is not opened or the call to fread fails.

rawRead always reads in binary mode on Windows.

rawRead
(
(local variable) ubyte[] tail
tail
);
(local variable) ulong bytesRead
bytesRead
+=
(local variable) ubyte[] tail
tail
.
(field) ulong ubyte[].length
length
;
// Backwards scan: the EOCD is last, but a trailing comment may follow it, // so the signature — not the file end — is the anchor.
(alias) object.ptrdiff_t = long
ptrdiff_t
(local variable) long eocd
eocd
= -1;
for (
(alias) object.ptrdiff_t = long
ptrdiff_t
(local variable) long i
i
= cast(
(alias) object.ptrdiff_t = long
ptrdiff_t
)
(local variable) ubyte[] tail
tail
.
(field) ulong ubyte[].length
length
- 22; i >= 0; i--)
{ if (
uint autological_zip_eocd_scan.readLE!uint(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!uint(
(local variable) ubyte[] tail
tail
,
(local variable) long i
i
) ==
(constant) uint autological_zip_eocd_scan.sigEocd = 101010256u
sigEocd
)
{
(local variable) long eocd
eocd
=
(local variable) long i
i
;
break; } } if (
(local variable) long eocd
eocd
< 0)
throw new
(class) object.Exception

The base class of all errors that are safe to catch and handle.

In principle, only thrown objects derived from this class are safe to catch inside a catch block. Thrown objects not derived from Exception represent runtime errors that should not be caught, as certain runtime guarantees may not hold, making it unsafe to continue program execution.

Examples

bool gotCaught;
try
{
    throw new Exception("msg");
}
catch (Exception e)
{
    gotCaught = true;
    assert(e.msg == "msg");
}
assert(gotCaught);
Exception
("no End Of Central Directory record in the last " ~
(local variable) const(ulong) window
window
.
string std.conv.text!(const(ulong))(const(ulong) __param_0) pure nothrow @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
~ " bytes");
const
(local variable) const(ushort) total
total
=
ushort autological_zip_eocd_scan.readLE!ushort(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!ushort(
(local variable) ubyte[] tail
tail
,
(local variable) long eocd
eocd
+ 10);
const
(local variable) const(uint) centralSize
centralSize
=
uint autological_zip_eocd_scan.readLE!uint(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!uint(
(local variable) ubyte[] tail
tail
,
(local variable) long eocd
eocd
+ 12);
const
(local variable) const(uint) centralOffset
centralOffset
=
uint autological_zip_eocd_scan.readLE!uint(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!uint(
(local variable) ubyte[] tail
tail
,
(local variable) long eocd
eocd
+ 16);
(local variable) std.stdio.File f
f
.
void std.stdio.File.seek(long offset, int origin = 0) @trusted

Calls fseek for the file handle to move its position indicator.

@paramoffset Binary files: Number of bytes to offset from origin. Text files: Either zero, or a value returned by tell.@paramorigin Binary files: Position used as reference for the offset, must be one of SEEK_SET, SEEK_CUR or SEEK_END. Text files: Shall necessarily be SEEK_SET.@throwsException if the file is not opened. ErrnoException if the call to fseek fails.
seek
(
(local variable) const(uint) centralOffset
centralOffset
);
auto
(local variable) ubyte[] central
central
= new ubyte[
(local variable) const(uint) centralSize
centralSize
];
(local variable) ubyte[] central
central
=
(local variable) std.stdio.File f
f
.
ubyte[] std.stdio.File.rawRead!ubyte(ubyte[] buffer) @safe

Calls fread for the file handle. The number of items to read and the size of each item is inferred from the size and type of the input array, respectively.

Examples

static import std.file;

auto testFile = std.file.deleteme();
std.file.write(testFile, "\r\n\n\r\n");
scope(exit) std.file.remove(testFile);

auto f = File(testFile, "r");
auto buf = f.rawRead(new char[5]);
f.close();
assert(buf == "\r\n\n\r\n");
@returnsThe slice of buffer containing the data that was actually read. This will be shorter than buffer if EOF was reached before the buffer could be filled. If the buffer is empty, it will be returned.@throws

ErrnoException if the file is not opened or the call to fread fails.

rawRead always reads in binary mode on Windows.

rawRead
(
(local variable) ubyte[] central
central
);
(local variable) ulong bytesRead
bytesRead
+=
(local variable) ubyte[] central
central
.
(field) ulong ubyte[].length
length
;
(alias) object.string = string
string
[]
(local variable) string[] names
names
;
uint
(local variable) uint firstLocal
firstLocal
;
(alias) object.size_t = ulong
size_t
(local variable) ulong cursor
cursor
;
foreach (
(local variable) int i
i
; 0 ..
(local variable) const(ushort) total
total
)
{ if (
uint autological_zip_eocd_scan.readLE!uint(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!uint(
(local variable) ubyte[] central
central
,
(local variable) ulong cursor
cursor
) !=
(constant) uint autological_zip_eocd_scan.sigCentral = 33639248u
sigCentral
)
throw new
(class) object.Exception

The base class of all errors that are safe to catch and handle.

In principle, only thrown objects derived from this class are safe to catch inside a catch block. Thrown objects not derived from Exception represent runtime errors that should not be caught, as certain runtime guarantees may not hold, making it unsafe to continue program execution.

Examples

bool gotCaught;
try
{
    throw new Exception("msg");
}
catch (Exception e)
{
    gotCaught = true;
    assert(e.msg == "msg");
}
assert(gotCaught);
Exception
("central directory entry has a bad signature");
const
(local variable) const(ushort) nameLen
nameLen
=
ushort autological_zip_eocd_scan.readLE!ushort(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!ushort(
(local variable) ubyte[] central
central
,
(local variable) ulong cursor
cursor
+ 28);
const
(local variable) const(ushort) extraLen
extraLen
=
ushort autological_zip_eocd_scan.readLE!ushort(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!ushort(
(local variable) ubyte[] central
central
,
(local variable) ulong cursor
cursor
+ 30);
const
(local variable) const(ushort) commentLen
commentLen
=
ushort autological_zip_eocd_scan.readLE!ushort(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!ushort(
(local variable) ubyte[] central
central
,
(local variable) ulong cursor
cursor
+ 32);
if (
(local variable) int i
i
== 0)
(local variable) uint firstLocal
firstLocal
=
uint autological_zip_eocd_scan.readLE!uint(in ubyte[] bytes, ulong offset) pure nothrow @nogc @safe

Reads a little-endian T at offset from bytes.

readLE
!uint(
(local variable) ubyte[] central
central
,
(local variable) ulong cursor
cursor
+ 42);
(local variable) string[] names
names
~= cast(
(alias) object.string = string
string
)
(local variable) ubyte[] central
central
[
(local variable) ulong cursor
cursor
+ 46 ..
(local variable) ulong cursor
cursor
+ 46 +
(local variable) const(ushort) nameLen
nameLen
].
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
(local variable) ulong cursor
cursor
+= 46 +
(local variable) const(ushort) nameLen
nameLen
+
(local variable) const(ushort) extraLen
extraLen
+
(local variable) const(ushort) commentLen
commentLen
;
} return
(struct) autological_zip_eocd_scan.Enumerated

What a tail-only read recovered, plus what it cost.

Enumerated
(
(local variable) string[] names
names
,
(local variable) const(uint) centralOffset
centralOffset
,
(local variable) const(uint) centralSize
centralSize
,
(local variable) uint firstLocal
firstLocal
,
(local variable) ulong bytesRead
bytesRead
);
} int
int D main()
main
()
{ // The parasitic prefix. In redbean this is a real PE/ELF/Mach-O image; the // ZIP format cannot tell the difference and does not try to. const
(local variable) const(string) prefix
prefix
= "#!/bin/sh\n" ~
"# Everything above the archive is opaque to a ZIP reader.\n" ~ "echo 'this file is also a shell script'; exit 0\n"; // One member is deliberately bulky. Enumeration must not touch it: that is // the difference between an index you can range-request and one you cannot. import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) replicate = std.array.replicate(S)(S s, size_t n) if (isDynamicArray!S)

Params: s = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) or a dynamic array n = number of times to repeat s

Returns: An array that consists of s repeated n times. This function allocates, fills, and returns a new array.

See_Also: For a lazy version, refer to $(REF repeat, std,range).

replicate
;
const
(local variable) const(autological_zip_eocd_scan.Member[]) members
members
= [
(struct) autological_zip_eocd_scan.Member

One member of the archive we are about to synthesize.

Member
("greeting.txt", "the container is a tax\n"),
(struct) autological_zip_eocd_scan.Member

One member of the archive we are about to synthesize.

Member
("assets/note.md", "# footer-anchored\n\nThe index is at the end, so the front is free.\n"),
(struct) autological_zip_eocd_scan.Member

One member of the archive we are about to synthesize.

Member
("assets/bulk.bin",
string std.array.replicate!string(string s, ulong n) pure nothrow @safe
@params an input range or a dynamic array@paramn number of times to repeat s@returnsAn array that consists of s repeated n times. This function allocates, fills, and returns a new array.@seeFor a lazy version, refer to repeat.
replicate
("payload ", 32 * 1024)),
]; const
(local variable) const(ubyte[]) zip
zip
=
ubyte[] autological_zip_eocd_scan.buildZip(in autological_zip_eocd_scan.Member[] members, uint prefixLength) @safe

Builds a STORED ZIP whose internal offsets are biased by prefixLength.

Passing a non-zero prefixLength is the whole trick: the archive is written as if it already began that many bytes into the file, so gluing it after an unrelated payload of exactly that size produces a file both readers accept.

buildZip
(
(local variable) const(autological_zip_eocd_scan.Member[]) members
members
, cast(uint)
(local variable) const(string) prefix
prefix
.
(field) ulong const(string).length
length
);
const
(local variable) const(string) path
path
=
string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safe

Combines one or more path segments.

This function takes a set of path segments, given as an input range of string elements or as a set of string arguments, and concatenates them with each other. Directory separators are inserted between segments if necessary. If any of the path segments are absolute (as defined by isAbsolute), the preceding segments will be dropped.

On Windows, if one of the path segments are rooted, but not absolute (e.g. \foo), all preceding path segments down to the previous root will be dropped. (See below for an example.)

This function always allocates memory to hold the resulting path. The variadic overload is guaranteed to only perform a single allocation, as is the range version if paths is a forward range.

Examples

version (Posix)
{
    assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
    assert(buildPath("/foo/", "bar/baz")  == "/foo/bar/baz");
    assert(buildPath("/foo", "/bar")      == "/bar");
}

version (Windows)
{
    assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
    assert(buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
    assert(buildPath("foo", `d:\bar`)     == `d:\bar`);
    assert(buildPath("foo", `\bar`)       == `\bar`);
    assert(buildPath(`c:\foo`, `\bar`)    == `c:\bar`);
}
@paramsegments An input range of segments to assemble the path from.@returnsThe assembled path.
buildPath
(
string std.file.tempDir() @trusted

Returns the path to a directory for temporary files. On POSIX platforms, it searches through the following list of directories and returns the first one which is found to exist:

  1. The directory given by the TMPDIR environment variable.

  2. The directory given by the TEMP environment variable.

  3. The directory given by the TMP environment variable.

  4. /tmp/

  5. /var/tmp/

  6. /usr/tmp/

On all platforms, tempDir returns the current working directory on failure.

The return value of the function is cached, so the procedures described below will only be performed the first time the function is called. All subsequent runs will return the same string, regardless of whether environment variables and directory structures have changed in the meantime.

The POSIX tempDir algorithm is inspired by Python's tempfile.tempdir.

Examples

import std.ascii : letters;
import std.conv : to;
import std.path : buildPath;
import std.random : randomSample;
import std.utf : byCodeUnit;

// random id with 20 letters
auto id = letters.byCodeUnit.randomSample(20).to!string;
auto myFile = tempDir.buildPath(id ~ "my_tmp_file");
scope(exit) myFile.remove;

myFile.write("hello");
assert(myFile.readText == "hello");
@returns

On Windows, this function returns the result of calling the Windows API function GetTempPath.

On POSIX platforms, it searches through the following list of directories and returns the first one which is found to exist:

  1. The directory given by the TMPDIR environment variable.

  2. The directory given by the TEMP environment variable.

  3. The directory given by the TMP environment variable.

  4. /tmp

  5. /var/tmp

  6. /usr/tmp

On all platforms, tempDir returns "." on failure, representing the current working directory.

tempDir
, "autological-polyglot.zip");
void std.file.write!string(string name, const(void[]) buffer) @safe

Write buffer to file name.

Creates the file if it does not already exist.

Examples

scope(exit)
{
    assert(exists(deleteme));
    remove(deleteme);
}

int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];
write(deleteme, a); // deleteme is the name of a temporary file
const bytes = read(deleteme);
const fileInts = () @trusted { return cast(int[]) bytes; }();
assert(fileInts == a);
@paramname string or range of characters representing the file name@parambuffer data to be written to file@throwsFileException on error.@seetoFile
write
(
(local variable) const(string) path
path
,
(local variable) const(string) prefix
prefix
.
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
~
(local variable) const(ubyte[]) zip
zip
);
scope (exit) if (
(local variable) const(string) path
path
.
bool std.file.exists!string(string name) nothrow @nogc @safe

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
)
void std.file.remove!string(string name) @safe

Delete file name.

@paramname string or range of characters representing the file name@throwsFileException on error.
remove
(
(local variable) const(string) path
path
);
const
(local variable) const(ulong) total
total
=
(local variable) const(string) prefix
prefix
.
(field) ulong const(string).length
length
+
(local variable) const(ubyte[]) zip
zip
.
(field) ulong const(ubyte[]).length
length
;
void std.stdio.writefln!(char, const(ulong), ulong, ulong)(in char[] fmt, const(ulong) __param_1, ulong __param_2, ulong __param_3) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("Built a %s-byte polyglot: %s bytes of shell script, then a %s-byte ZIP.",
(local variable) const(ulong) total
total
,
(local variable) const(string) prefix
prefix
.
(field) ulong const(string).length
length
,
(local variable) const(ubyte[]) zip
zip
.
(field) ulong const(ubyte[]).length
length
);
void std.stdio.writefln!(char, char)(in char[] fmt, char __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" byte 0 is '%s' — a ZIP reader never looks there.", cast(char)
(local variable) const(string) prefix
prefix
[0]);
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
const
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
=
autological_zip_eocd_scan.Enumerated autological_zip_eocd_scan.enumerateFromTail(string path, ulong tailWindow = 512LU)

Enumerates an archive by doing what a real reader does: seek to the end, scan backwards for the EOCD signature, then read only the central directory.

Never reads a local file header, and never reads a byte of file data — which is why the returned bytesRead is a small constant plus the directory size, independent of how large the members (or the parasitic prefix) are.

enumerateFromTail
(
(local variable) const(string) path
path
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("Enumerated by scanning backwards from EOF:");
void std.stdio.writefln!(char, const(uint), const(uint))(in char[] fmt, const(uint) __param_1, const(uint) __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" central directory at absolute offset %s, %s bytes",
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
.
(field) uint autological_zip_eocd_scan.Enumerated.centralOffset
centralOffset
,
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
.
(field) uint autological_zip_eocd_scan.Enumerated.centralSize
centralSize
);
foreach (
(parameter) const(string) n
n
;
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
.
(field) string[] autological_zip_eocd_scan.Enumerated.names
names
)
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" entry: %s",
(local variable) const(string) n
n
);
void std.stdio.writefln!(char, const(uint), ulong)(in char[] fmt, const(uint) __param_1, ulong __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" first member's local header sits at absolute offset %s == the prefix length (%s):",
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
.
(field) uint autological_zip_eocd_scan.Enumerated.firstLocalHeaderOffset
firstLocalHeaderOffset
,
(local variable) const(string) prefix
prefix
.
(field) ulong const(string).length
length
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" every internal pointer is biased by the prefix, which is what `zip -A` repairs");
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
void std.stdio.writefln!(char, const(ulong), const(ulong), double)(in char[] fmt, const(ulong) __param_1, const(ulong) __param_2, double __param_3) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("Cost of enumeration: %s of %s bytes read (%.1f%%).",
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
.
(field) ulong autological_zip_eocd_scan.Enumerated.bytesRead
bytesRead
,
(local variable) const(ulong) total
total
, 100.0 *
(local variable) const(autological_zip_eocd_scan.Enumerated) found
found
.
(field) ulong autological_zip_eocd_scan.Enumerated.bytesRead
bytesRead
/
(local variable) const(ulong) total
total
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" A header-anchored format would have had to start at byte 0 —");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" which is the byte the prefix is already using.");
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
// An independent implementation is the real proof. `unzip -l` refuses // nothing here: it performs the same backwards scan. const
(local variable) const(std.typecons.Tuple!(int, "status", string, "output")) probe
probe
=
std.typecons.Tuple!(int, "status", string, "output") std.process.execute(scope const(char[])[] args, const(string[string]) env = cast(const(string[string]))null, std.process.Config config = Config(Flags.none, null, null), ulong maxOutput = 18446744073709551615LU, scope const(char)[] workDir = null) @safe

Executes the given program or shell command and returns its exit code and output.

execute and executeShell start a new process using spawnProcess and spawnShell, respectively, and wait for the process to complete before returning. The functions capture what the child process prints to both its standard output and standard error streams, and return this together with its exit code.

auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);

auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);

The args/program/command, env and config parameters are forwarded straight to the underlying spawn functions, and we refer to their documentation for details.

POSIX specific

If the process is terminated by a signal, the status field of the return value will contain a negative number whose absolute value is the signal number. (See wait for details.)

@paramargs An array which contains the program name as the zeroth element and any command-line arguments in the following elements. (See spawnProcess for details.)@paramprogram The program name, without command-line arguments. (See spawnProcess for details.)@paramcommand A shell command which is passed verbatim to the command interpreter. (See spawnShell for details.)@paramenv Additional environment variables for the child process. (See spawnProcess for details.)@paramconfig Flags that control process creation. See Config for an overview of available flags, and note that the retainStd... flags have no effect in this function.@parammaxOutput The maximum number of bytes of output that should be captured.@paramworkDir The working directory for the new process. By default the child process inherits the parent's working directory.@paramshellPath The path to the shell to use to run the specified program. By default this is nativeShell.@returnsAn std.typecons.Tuple!(int, "status", string, "output").@throws

ProcessException on failure to start the process.

StdioException on failure to capture output.

execute
(["unzip", "-l",
(local variable) const(string) path
path
], null,
(struct) std.process.Config

Options that control the behaviour of process creation functions in this module. Most options only apply to spawnProcess and spawnShell.

Example

auto logFile = File("myapp_error.log", "w");

// Start program, suppressing the console window (Windows only),
// redirect its error stream to logFile, and leave logFile open
// in the parent process as well.
auto pid = spawnProcess("myapp", stdin, stdout, logFile,
                        Config.retainStderr | Config.suppressConsole);
scope(exit)
{
    auto exitCode = wait(pid);
    logFile.writeln("myapp exited with code ", exitCode);
    logFile.close();
}
Config
.
(constant) std.process.Config std.process.Config.suppressConsole = Config(Flags.suppressConsole, null, null)

For backwards compatibility, and cases when only flags need to be specified in the Config, these allow building Config instances using flag names only.

suppressConsole
);
if (
(local variable) const(std.typecons.Tuple!(int, "status", string, "output")) probe
probe
.status == 0)
{
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("System `unzip -l` agrees:");
foreach (
(local variable) string line
line
;
(local variable) const(std.typecons.Tuple!(int, "status", string, "output")) probe
probe
.output.
std.string.LineSplitter!(Flag.no, string) autological_zip_eocd_scan.lineSplitterRange(string s) pure nothrow @nogc @safe

lineSplitter wrapped so the call site above reads as one pipeline.

lineSplitterRange
)
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" | %s",
(local variable) string line
line
);
} else {
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("SKIP: no working `unzip` on PATH — the independent cross-check was not run.");
} return 0; } /// `lineSplitter` wrapped so the call site above reads as one pipeline. private auto
std.string.LineSplitter!(Flag.no, string) autological_zip_eocd_scan.lineSplitterRange(string s) pure nothrow @nogc @safe

lineSplitter wrapped so the call site above reads as one pipeline.

lineSplitterRange
(
(alias) object.string = string
string
(parameter) string s
s
) @safe pure nothrow
{ import
(package) std
std
.
(module) std.string

String handling functions.

Category Functions
Searching
column
indexOf
indexOfAny
indexOfNeither
lastIndexOf
lastIndexOfAny
lastIndexOfNeither
Comparison
isNumeric
Mutation
capitalize
Pruning and Filling
center
chomp
chompPrefix
chop
detabber
detab
entab
entabber
leftJustify
outdent
rightJustify
strip
stripLeft
stripRight
wrap
Substitution
abbrev
soundex
soundexer
succ
tr
translate
Miscellaneous
assumeUTF
fromStringz
lineSplitter
representation
splitLines
toStringz
Objects of types string, wstring, and dstring are value types
and cannot be mutated element-by-element. For using mutation during building
strings, use char[], wchar[], or dchar[]. The xxxstring
types are preferable because they don't exhibit undesired aliasing, thus
making code more robust.

The following functions are publicly imported:

Module Functions
Publicly imported functions
std.algorithm
cmp, std,algorithm,comparison
count, std,algorithm,searching
endsWith, std,algorithm,searching
startsWith, std,algorithm,searching
std.array
join, std,array
replace, std,array
replaceInPlace, std,array
split, std,array
empty, std,array
std.format
format, std,format
sformat, std,format
std.uni
icmp, std,uni
toLower, std,uni
toLowerInPlace, std,uni
toUpper, std,uni
toUpperInPlace, std,uni
There is a rich set of functions for string handling defined in other modules.
Functions related to Unicode and ASCII are found in std.uni
and std.ascii, respectively. Other functions that have a
wider generality than just strings can be found in std.algorithm
and std.range.

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) lineSplitter = std.string.lineSplitter(Flag keepTerm = No.keepTerminator, Range)(Range r) if (hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)

Split an array or slicable range of characters into a range of lines using '\r', '\n', '\v', '\f', "\r\n", $(REF lineSep, std,uni), $(REF paraSep, std,uni) and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.

    Does not throw on invalid UTF; such is simply passed unchanged
    to the output.

    Adheres to $(HTTP www.unicode.org/versions/Unicode7.0.0/ch05.pdf, Unicode 7.0).

    Does not allocate memory.

Params: r = array of chars, wchars, or dchars or a slicable range keepTerm = whether delimiter is included or not in the results Returns: range of slices of the input range r

See_Also: $(LREF splitLines) $(REF splitter, std,algorithm) $(REF splitter, std,regex)

lineSplitter
;
return
(parameter) string s
s
.
std.string.LineSplitter!(Flag.no, string) std.string.lineSplitter!(Flag.no, immutable(char))(string r) pure nothrow @nogc @safe

Split an array or slicable range of characters into a range of lines using '\r', '\n', '\v', '\f', "\r\n", lineSep, paraSep and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.

Does not throw on invalid UTF; such is simply passed unchanged to the output.

Adheres to Unicode 7.0.

Does not allocate memory.

Examples

import std.array : array;

string s = "Hello\nmy\rname\nis";

/* notice the call to 'array' to turn the lazy range created by
lineSplitter comparable to the string[] created by splitLines.
*/
assert(lineSplitter(s).array == splitLines(s));
auto s = "\rpeter\n\rpaul\r\njerry\u2028ice\u2029cream\n\nsunday\nmon\u2030day\n";
auto lines = s.lineSplitter();
static immutable witness = ["", "peter", "", "paul", "jerry", "ice", "cream", "", "sunday", "mon\u2030day"];
uint i;
foreach (line; lines)
{
    assert(line == witness[i++]);
}
assert(i == witness.length);
@paramr array of chars, wchars, or dchars or a slicable range@paramkeepTerm whether delimiter is included or not in the results@returnsrange of slices of the input range r@seesplitLines splitter splitter
lineSplitter
;
}