sqlite-header-probe.dhover×250all
#!/usr/bin/env dub
/+ dub.sdl:
    name "autological_sqlite_header_probe"
    targetPath "build"
    dflags "-preview=in" "-preview=dip1000"
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
+/
/**
 * The 100-byte header that lets a database be an executable.
 *
 * SQLite reserves the first 100 bytes of every database file for a fixed-layout
 * header, and two of its fields are what make the SELF format possible at all:
 *
 *   - **`application_id`**, a 4-byte big-endian integer at **offset 68**. SQLite
 *     itself never interprets it; the documentation's stated purpose is to let
 *     `file(1)`-style tools identify *which application's* database this is. A
 *     `binfmt_misc` registration with `offset=68` and a 4-byte magic therefore
 *     dispatches on a field the storage engine has promised not to touch.
 *   - **`page_size`** at offset 16, big-endian, which decides whether segment
 *     BLOBs can ever be page-aligned — the crux of the lost-`mmap` problem.
 *
 * This program decodes the header of whatever files are passed on the command
 * line, and — with no arguments — of a synthesized SELF header plus the local
 * SQLite databases it can find, so it is useful with or without a corpus.
 *
 * The `Reserved space at end of each page` field (offset 20) is decoded too,
 * because it is the one the "segments in SQLite's reserved region" repair
 * candidate would have to use, and seeing it default to `0` makes the size of
 * that proposal concrete.
 *
 * Companions:
 *   docs/research/autological-artifacts/self-selfdb/index.md
 *   docs/research/autological-artifacts/sqlite-application-file-format.md
 *   docs/research/autological-artifacts/binfmt-misc.md
 *
 * Run with: `dub run --single sqlite-header-probe.d [FILE...]`
 *
 * Portability: pure `std`. Files that are not SQLite databases are reported as
 * such rather than treated as an error, so the program always exits 0.
 */
module 
(module) autological_sqlite_header_probe

The 100-byte header that lets a database be an executable.

SQLite reserves the first 100 bytes of every database file for a fixed-layout header, and two of its fields are what make the SELF format possible at all:

  • application_id, a 4-byte big-endian integer at offset 68. SQLite itself never interprets it; the documentation's stated purpose is to let file(1)-style tools identify which application's database this is. A binfmt_misc registration with offset=68 and a 4-byte magic therefore dispatches on a field the storage engine has promised not to touch.

  • page_size at offset 16, big-endian, which decides whether segment BLOBs can ever be page-aligned — the crux of the lost-mmap problem.

This program decodes the header of whatever files are passed on the command line, and — with no arguments — of a synthesized SELF header plus the local SQLite databases it can find, so it is useful with or without a corpus.

The Reserved space at end of each page field (offset 20) is decoded too, because it is the one the "segments in SQLite's reserved region" repair candidate would have to use, and seeing it default to 0 makes the size of that proposal concrete.

Companions

docs/research/autological-artifacts/self-selfdb/index.md docs/research/autological-artifacts/sqlite-application-file-format.md docs/research/autological-artifacts/binfmt-misc.md

Run with: dub run --single sqlite-header-probe.d [FILE...]

Portability

pure std. Files that are not SQLite databases are reported as such rather than treated as an error, so the program always exits 0.

autological_sqlite_header_probe
;
import
(package) std
std
.
(module) std.algorithm

This package implements generic algorithms oriented towards the processing of sequences. Sequences processed by these functions define range-based interfaces. See also Reference on ranges and tutorial on ranges.

Algorithms are categorized into the following submodules:

Submodule Functions

| Searching | all any balancedParens boyerMooreFinder canFind commonPrefix count countUntil endsWith find findAdjacent findAmong findSkip findSplit findSplitAfter findSplitBefore minCount maxCount minElement maxElement minIndex maxIndex minPos maxPos skipOver startsWith until |

| Comparison | among castSwitch clamp cmp either equal isPermutation isSameLength levenshteinDistance levenshteinDistanceAndPath max min mismatch predSwitch |

| Iteration | cache cacheBidirectional chunkBy cumulativeFold each filter filterBidirectional fold group joiner map mean permutations reduce splitWhen splitter substitute sum uniq |

| Sorting | completeSort isPartitioned isSorted isStrictlyMonotonic ordered strictlyOrdered makeIndex merge multiSort nextEvenPermutation nextPermutation nthPermutation partialSort partition partition3 schwartzSort sort topN topNCopy topNIndex |

| Set operations (setops) | cartesianProduct largestPartialIntersection largestPartialIntersectionWeighted multiwayMerge multiwayUnion setDifference setIntersection setSymmetricDifference |

| Mutation | bringToFront copy fill initializeAll move moveAll moveSome moveEmplace moveEmplaceAll moveEmplaceSome remove reverse strip stripLeft stripRight swap swapRanges uninitializedFill |

Many functions in this package are parameterized with a predicate. The predicate may be any suitable callable type (a function, a delegate, a functor, or a lambda), or a compile-time string. The string may consist of any legal D expression that uses the symbol a (for unary functions) or the symbols a and b (for binary functions). These names will NOT interfere with other homonym symbols in user code because they are evaluated in a different context. The default for all binary comparison predicates is "a == b" for unordered operations and "a < b" for ordered operations.

Example

int[] a = ...;
static bool greater(int a, int b)
{
    return a > b;
}
sort!greater(a);           // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a);           // predicate as string
                           // (no ambiguity with array name)
sort(a);                   // no predicate, "a < b" is implicit

Source

std/algorithm/package.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
algorithm
:
(alias template) autological_sqlite_header_probe.filter = std.algorithm.iteration.filter(alias predicate) if (is(typeof(unaryFun!predicate)))

``filter!(predicate)(range) returns a new range containing only elements x in range for which predicate(x) returns true.

The predicate is passed to unaryFun, and can be either a string, or any callable that can be executed via pred(element).

@parampredicate Function to apply to each element of range@returnsAn input range that contains the filtered elements. If range is at least a forward range, the return value of filter will also be a forward range.@seeFilter (higher-order function), filterBidirectional
filter
,
(alias template) autological_sqlite_header_probe.map = std.algorithm.iteration.map(fun...) if (fun.length >= 1)

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

@paramfun one or more transformation functions@seeMap (higher-order function)
map
;
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_sqlite_header_probe.array = std.array.array(Range)(Range r) if (isIterable!Range && !isAutodecodableString!Range && !isInfinite!Range)

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
;
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_sqlite_header_probe.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
.
(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_sqlite_header_probe.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_sqlite_header_probe.isFile = std.file.isFile(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Returns whether the given file (or directory) is a file.

On Windows, if a file is not a directory, then it's a file. So, either isFile or isDir will return true for any given file.

On POSIX systems, if isFile is true, that indicates that the file is a regular file (e.g. not a block not device). So, on POSIX systems, it's possible for both isFile and isDir to be false for a particular file (in which case, it's a special file). You can use getAttributes to get the attributes to figure out what type of special it is, or you can use DirEntry to get at its statBuf, which is the result from stat. In either case, see the man page for stat for more information.

@paramname The path to the file.@returnstrue if name specifies a file@throwsFileException if the given file does not exist.
isFile
,
(alias template) autological_sqlite_header_probe.read = std.file.read(R)(R name, size_t upTo = size_t.max) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Read entire contents of file name and returns it as an untyped array. If the file size is larger than upTo, only upTo bytes are read.

@paramname string or range of characters representing the file name@paramupTo if present, the maximum number of bytes to read@returnsUntyped array of bytes read.@throwsFileException on error.@seereadText for reading and validating a text file.
read
;
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
:
(alias template) autological_sqlite_header_probe.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

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

writefln
,
(alias template) autological_sqlite_header_probe.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_sqlite_header_probe.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
;
/// The header magic every SQLite 3 database opens with, `NUL` included. enum
(alias) object.string = string
string
(constant) string autological_sqlite_header_probe.sqliteMagic = "SQLite format 3\0"

The header magic every SQLite 3 database opens with, NUL included.

sqliteMagic
= "SQLite format 3\0";
/++ The subset of the 100-byte header this catalog cares about. Offsets are from the SQLite file-format documentation; every multi-byte integer in the header is **big-endian**, which is worth stating because the rest of the formats in this tree (ZIP, ELF, PE) are little-endian, and a polyglot has to keep both straight. +/ struct
(struct) autological_sqlite_header_probe.SqliteHeader

The subset of the 100-byte header this catalog cares about.

Offsets are from the SQLite file-format documentation; every multi-byte integer in the header is big-endian, which is worth stating because the rest of the formats in this tree (ZIP, ELF, PE) are little-endian, and a polyglot has to keep both straight.

SqliteHeader
{ ushort
(field) ushort autological_sqlite_header_probe.SqliteHeader.pageSizeRaw
pageSizeRaw
; // offset 16; 1 means 65536
ubyte
(field) ubyte autological_sqlite_header_probe.SqliteHeader.writeVersion
writeVersion
; // offset 18; 1 = legacy, 2 = WAL
ubyte
(field) ubyte autological_sqlite_header_probe.SqliteHeader.readVersion
readVersion
; // offset 19
ubyte
(field) ubyte autological_sqlite_header_probe.SqliteHeader.reservedPerPage
reservedPerPage
; // offset 20
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.changeCounter
changeCounter
; // offset 24
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.sizeInPages
sizeInPages
; // offset 28
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.schemaCookie
schemaCookie
; // offset 40
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.textEncoding
textEncoding
; // offset 56; 1 = UTF-8, 2 = UTF-16le, 3 = UTF-16be
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.userVersion
userVersion
; // offset 60
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.applicationId
applicationId
; // offset 68
uint
(field) uint autological_sqlite_header_probe.SqliteHeader.sqliteVersionNumber
sqliteVersionNumber
; // offset 96
/// The real page size, resolving the documented `1 == 65536` escape. uint
uint autological_sqlite_header_probe.SqliteHeader.pageSize() const pure nothrow @nogc @safe

The real page size, resolving the documented 1 == 65536 escape.

pageSize
() const @safe pure nothrow @nogc
=>
(field) ushort autological_sqlite_header_probe.SqliteHeader.pageSizeRaw
pageSizeRaw
== 1 ? 65_536 :
(field) ushort autological_sqlite_header_probe.SqliteHeader.pageSizeRaw
pageSizeRaw
;
/// `application_id` rendered as the four ASCII bytes tools usually put there.
(alias) object.string = string
string
string autological_sqlite_header_probe.SqliteHeader.applicationTag() const pure @safe

application_id rendered as the four ASCII bytes tools usually put there.

applicationTag
() const @safe pure
{ char[4]
(local variable) char[4] tag
tag
;
foreach (
(local variable) int i
i
; 0 .. 4)
{ const
(local variable) const(ubyte) b
b
= cast(ubyte)(
(field) uint autological_sqlite_header_probe.SqliteHeader.applicationId
applicationId
>> (8 * (3 -
(local variable) int i
i
)));
(local variable) char[4] tag
tag
[
(local variable) int i
i
] = (
(local variable) const(ubyte) b
b
>= 0x20 &&
(local variable) const(ubyte) b
b
< 0x7f) ? cast(char)
(local variable) const(ubyte) b
b
: '.';
} return
(local variable) char[4] tag
tag
.
string object.idup!char(char[] a) pure nothrow @property @safe

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

idup
;
} } /// Reads a big-endian `uint` at `offset`. uint
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(in ubyte[]
(parameter) const(ubyte[]) b
b
,
(alias) object.size_t = ulong
size_t
(parameter) ulong offset
offset
) @safe pure nothrow @nogc
in (
(parameter) ulong offset
offset
+ 4 <=
(parameter) const(ubyte[]) b
b
.
(field) ulong const(ubyte[]).length
length
)
=> (uint(
(parameter) const(ubyte[]) b
b
[
(parameter) ulong offset
offset
]) << 24) | (uint(
(parameter) const(ubyte[]) b
b
[
(parameter) ulong offset
offset
+ 1]) << 16)
| (uint(
(parameter) const(ubyte[]) b
b
[
(parameter) ulong offset
offset
+ 2]) << 8) | uint(
(parameter) const(ubyte[]) b
b
[
(parameter) ulong offset
offset
+ 3]);
/// Reads a big-endian `ushort` at `offset`. ushort
ushort autological_sqlite_header_probe.beU16(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian ushort at offset.

beU16
(in ubyte[]
(parameter) const(ubyte[]) b
b
,
(alias) object.size_t = ulong
size_t
(parameter) ulong offset
offset
) @safe pure nothrow @nogc
in (
(parameter) ulong offset
offset
+ 2 <=
(parameter) const(ubyte[]) b
b
.
(field) ulong const(ubyte[]).length
length
)
=> cast(ushort)((ushort(
(parameter) const(ubyte[]) b
b
[
(parameter) ulong offset
offset
]) << 8) |
(parameter) const(ubyte[]) b
b
[
(parameter) ulong offset
offset
+ 1]);
/// True when `b` opens with the SQLite 3 header magic. bool
bool autological_sqlite_header_probe.isSqlite(in ubyte[] b) pure nothrow @nogc @safe

True when b opens with the SQLite 3 header magic.

isSqlite
(in ubyte[]
(parameter) const(ubyte[]) b
b
) @safe pure nothrow @nogc
=>
(parameter) const(ubyte[]) b
b
.
(field) ulong const(ubyte[]).length
length
>= 100 &&
(parameter) const(ubyte[]) b
b
[0 .. 16] ==
(constant) string autological_sqlite_header_probe.sqliteMagic = "SQLite format 3\0"

The header magic every SQLite 3 database opens with, NUL included.

sqliteMagic
.
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
;
/// Decodes the header fields this catalog reads.
(struct) autological_sqlite_header_probe.SqliteHeader

The subset of the 100-byte header this catalog cares about.

Offsets are from the SQLite file-format documentation; every multi-byte integer in the header is big-endian, which is worth stating because the rest of the formats in this tree (ZIP, ELF, PE) are little-endian, and a polyglot has to keep both straight.

SqliteHeader
autological_sqlite_header_probe.SqliteHeader autological_sqlite_header_probe.decode(in ubyte[] b) pure nothrow @nogc @safe

Decodes the header fields this catalog reads.

decode
(in ubyte[]
(parameter) const(ubyte[]) b
b
) @safe pure nothrow @nogc
in (
bool autological_sqlite_header_probe.isSqlite(in ubyte[] b) pure nothrow @nogc @safe

True when b opens with the SQLite 3 header magic.

isSqlite
(
(parameter) const(ubyte[]) b
b
))
{
(struct) autological_sqlite_header_probe.SqliteHeader

The subset of the 100-byte header this catalog cares about.

Offsets are from the SQLite file-format documentation; every multi-byte integer in the header is big-endian, which is worth stating because the rest of the formats in this tree (ZIP, ELF, PE) are little-endian, and a polyglot has to keep both straight.

SqliteHeader
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
;
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) ushort autological_sqlite_header_probe.SqliteHeader.pageSizeRaw
pageSizeRaw
=
ushort autological_sqlite_header_probe.beU16(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian ushort at offset.

beU16
(
(parameter) const(ubyte[]) b
b
, 16);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.writeVersion
writeVersion
=
(parameter) const(ubyte[]) b
b
[18];
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.readVersion
readVersion
=
(parameter) const(ubyte[]) b
b
[19];
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.reservedPerPage
reservedPerPage
=
(parameter) const(ubyte[]) b
b
[20];
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.changeCounter
changeCounter
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 24);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.sizeInPages
sizeInPages
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 28);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.schemaCookie
schemaCookie
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 40);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.textEncoding
textEncoding
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 56);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.userVersion
userVersion
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 60);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.applicationId
applicationId
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 68);
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.sqliteVersionNumber
sqliteVersionNumber
=
uint autological_sqlite_header_probe.beU32(in ubyte[] b, ulong offset) pure nothrow @nogc @safe

Reads a big-endian uint at offset.

beU32
(
(parameter) const(ubyte[]) b
b
, 96);
return
(local variable) autological_sqlite_header_probe.SqliteHeader h
h
;
} /// Renders one decoded header as the catalog wants to read it. void
void autological_sqlite_header_probe.report(string label, in autological_sqlite_header_probe.SqliteHeader h) @safe

Renders one decoded header as the catalog wants to read it.

report
(
(alias) object.string = string
string
(parameter) string label
label
, in
(struct) autological_sqlite_header_probe.SqliteHeader

The subset of the 100-byte header this catalog cares about.

Offsets are from the SQLite file-format documentation; every multi-byte integer in the header is big-endian, which is worth stating because the rest of the formats in this tree (ZIP, ELF, PE) are little-endian, and a polyglot has to keep both straight.

SqliteHeader
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
) @safe
{
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

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

writefln
("%s",
(parameter) string label
label
);
void std.stdio.writefln!(char, uint, string)(in char[] fmt, uint __param_1, string __param_2) @safe

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

writefln
(" page size (off 16) %s bytes%s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
uint autological_sqlite_header_probe.SqliteHeader.pageSize() const pure nothrow @nogc @safe

The real page size, resolving the documented 1 == 65536 escape.

pageSize
,
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
uint autological_sqlite_header_probe.SqliteHeader.pageSize() const pure nothrow @nogc @safe

The real page size, resolving the documented 1 == 65536 escape.

pageSize
>= 4096 ? " (>= a 4 KiB VM page — alignment is at least possible)"
: " (< a 4 KiB VM page — a page-aligned BLOB cannot fit one VM page)");
void std.stdio.writefln!(char, const(ubyte), const(ubyte), string)(in char[] fmt, const(ubyte) __param_1, const(ubyte) __param_2, string __param_3) @safe

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

writefln
(" write/read version (18/19) %s / %s%s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.writeVersion
writeVersion
,
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.readVersion
readVersion
,
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.writeVersion
writeVersion
== 2 ? " (WAL)" : " (rollback journal)");
void std.stdio.writefln!(char, const(ubyte), string)(in char[] fmt, const(ubyte) __param_1, string __param_2) @safe

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

writefln
(" reserved per page (off 20) %s bytes%s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.reservedPerPage
reservedPerPage
,
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) ubyte autological_sqlite_header_probe.SqliteHeader.reservedPerPage
reservedPerPage
== 0 ? " (the region a 'segments in reserved space' design would claim)" : "");
void std.stdio.writefln!(char, const(uint))(in char[] fmt, const(uint) __param_1) @safe

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

writefln
(" change counter (off 24) %s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.changeCounter
changeCounter
);
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
(" size in pages (off 28) %s => %s bytes of database",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.sizeInPages
sizeInPages
, ulong(
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.sizeInPages
sizeInPages
) *
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
uint autological_sqlite_header_probe.SqliteHeader.pageSize() const pure nothrow @nogc @safe

The real page size, resolving the documented 1 == 65536 escape.

pageSize
);
void std.stdio.writefln!(char, const(uint), string)(in char[] fmt, const(uint) __param_1, string __param_2) @safe

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

writefln
(" text encoding (off 56) %s (%s)",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.textEncoding
textEncoding
,
string autological_sqlite_header_probe.encodingName(uint e) pure nothrow @nogc @safe

Maps the documented text-encoding constants to names.

encodingName
(
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.textEncoding
textEncoding
));
void std.stdio.writefln!(char, const(uint))(in char[] fmt, const(uint) __param_1) @safe

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

writefln
(" user_version (off 60) %s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.userVersion
userVersion
);
void std.stdio.writefln!(char, const(uint), string, string)(in char[] fmt, const(uint) __param_1, string __param_2, string __param_3) @safe

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

writefln
(" application_id (off 68) 0x%08x '%s'%s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.applicationId
applicationId
,
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
string autological_sqlite_header_probe.SqliteHeader.applicationTag() const pure @safe

application_id rendered as the four ASCII bytes tools usually put there.

applicationTag
,
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.applicationId
applicationId
== 0 ? " (unset — no binfmt_misc handle)"
: " <-- the 4 bytes binfmt_misc can match on at offset 68");
void std.stdio.writefln!(char, const(uint))(in char[] fmt, const(uint) __param_1) @safe

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

writefln
(" sqlite_version (off 96) %s",
(parameter) const(autological_sqlite_header_probe.SqliteHeader) h
h
.
(field) uint autological_sqlite_header_probe.SqliteHeader.sqliteVersionNumber
sqliteVersionNumber
);
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
;
} /// Maps the documented text-encoding constants to names.
(alias) object.string = string
string
string autological_sqlite_header_probe.encodingName(uint e) pure nothrow @nogc @safe

Maps the documented text-encoding constants to names.

encodingName
(uint
(parameter) uint e
e
) @safe pure nothrow @nogc
{ switch (
(parameter) uint e
e
)
{ case 0: return "unset"; case 1: return "UTF-8"; case 2: return "UTF-16le"; case 3: return "UTF-16be"; default: return "invalid"; } } /++ Synthesizes the header a SELF-style artifact would carry. Nothing here is guesswork about SELF's internals: it is the *minimum* a file needs so that (a) SQLite opens it and (b) a `binfmt_misc` rule keyed on `offset=68, magic=SELF` selects an interpreter for it. +/ immutable(ubyte)[]
immutable(ubyte)[] autological_sqlite_header_probe.synthesize() pure @safe

Synthesizes the header a SELF-style artifact would carry.

Nothing here is guesswork about SELF's internals: it is the minimum a file needs so that (a) SQLite opens it and (b) a binfmt_misc rule keyed on offset=68, magic=SELF selects an interpreter for it.

synthesize
() @safe pure
{ auto
(local variable) ubyte[] h
h
= new ubyte[100];
(local variable) ubyte[] h
h
[0 .. 16] =
(constant) string autological_sqlite_header_probe.sqliteMagic = "SQLite format 3\0"

The header magic every SQLite 3 database opens with, NUL included.

sqliteMagic
.
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) ubyte[] h
h
[16] = 0x10;
(local variable) ubyte[] h
h
[17] = 0x00; // page_size = 4096
(local variable) ubyte[] h
h
[18] = 1; // write version: legacy rollback journal
(local variable) ubyte[] h
h
[19] = 1; // read version
(local variable) ubyte[] h
h
[20] = 0; // reserved space per page
(local variable) ubyte[] h
h
[28] = 0;
(local variable) ubyte[] h
h
[31] = 4; // size in pages = 4
(local variable) ubyte[] h
h
[56 + 3] = 1; // text encoding = UTF-8
(local variable) ubyte[] h
h
[68 .. 72] = "SELF".
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
; // application_id
return
(local variable) ubyte[] h
h
.
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

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

idup
;
} int
int D main(string[] args)
main
(
(alias) object.string = string
string
[]
(parameter) string[] args
args
)
{
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
("SQLite header probe — offset 68 is the byte that makes a database dispatchable.");
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 autological_sqlite_header_probe.report(string label, in autological_sqlite_header_probe.SqliteHeader h) @safe

Renders one decoded header as the catalog wants to read it.

report
("synthesized SELF-style header (not read from disk)",
autological_sqlite_header_probe.SqliteHeader autological_sqlite_header_probe.decode(in ubyte[] b) pure nothrow @nogc @safe

Decodes the header fields this catalog reads.

decode
(
immutable(ubyte)[] autological_sqlite_header_probe.synthesize() pure @safe

Synthesizes the header a SELF-style artifact would carry.

Nothing here is guesswork about SELF's internals: it is the minimum a file needs so that (a) SQLite opens it and (b) a binfmt_misc rule keyed on offset=68, magic=SELF selects an interpreter for it.

synthesize
()));
auto
(local variable) string[] candidates
candidates
=
(parameter) string[] args
args
.
(field) ulong string[].length
length
> 1
?
(parameter) string[] args
args
[1 .. $]
: ["/var/lib/dbus/machine-id.sqlite", "test.db"].
std.algorithm.iteration.FilterResult!(exists, string[]) std.algorithm.iteration.filter!(exists).filter!(string[])(string[] range) pure nothrow @nogc @safe

filter`!(predicate)(`range`)` returns a new `range` containing only elements `x` in range`` for which predicate(x) returns true.

The predicate is passed to unaryFun, and can be either a string, or any callable that can be executed via pred(element).

Examples

import std.algorithm.comparison : equal;
import std.math.operations : isClose;
import std.range;

int[] arr = [ 1, 2, 3, 4, 5 ];

// Filter below 3
auto small = filter!(a => a < 3)(arr);
assert(equal(small, [ 1, 2 ]));

// Filter again, but with Uniform Function Call Syntax (UFCS)
auto sum = arr.filter!(a => a < 3);
assert(equal(sum, [ 1, 2 ]));

// In combination with chain() to span multiple ranges
int[] a = [ 3, -2, 400 ];
int[] b = [ 100, -101, 102 ];
auto r = chain(a, b).filter!(a => a > 0);
assert(equal(r, [ 3, 400, 100, 102 ]));

// Mixing convertible types is fair game, too
double[] c = [ 2.5, 3.0 ];
auto r1 = chain(c, a, b).filter!(a => cast(int) a != a);
assert(isClose(r1, [ 2.5 ]));
@parampredicate Function to apply to each element of range@returnsAn input range that contains the filtered elements. If range is at least a forward range, the return value of filter will also be a forward range.@seeFilter (higher-order function), filterBidirectional@paramrange An input range of elements@returnsA range containing only elements x in range for which predicate(x) returns true.
filter
!
(template) 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
.
string[] std.array.array!(std.algorithm.iteration.FilterResult!(exists, string[]))(std.algorithm.iteration.FilterResult!(exists, string[]) r) nothrow @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
;
if (
(local variable) string[] candidates
candidates
.
(field) ulong string[].length
length
== 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
("SKIP: no database files given or found locally — pass paths as arguments");
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
(" to decode real headers (e.g. any *.sqlite / *.db on this machine).");
return 0; } foreach (
(parameter) string path
path
;
(local variable) string[] candidates
candidates
)
{ if (!
(local variable) 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
|| !
(local variable) string path
path
.
bool std.file.isFile!string(string name) @property @safe

Returns whether the given file (or directory) is a file.

On Windows, if a file is not a directory, then it's a file. So, either isFile or isDir will return true for any given file.

On POSIX systems, if isFile is true, that indicates that the file is a regular file (e.g. not a block not device). So, on POSIX systems, it's possible for both isFile and isDir to be false for a particular file (in which case, it's a special file). You can use getAttributes to get the attributes to figure out what type of special it is, or you can use DirEntry to get at its statBuf, which is the result from stat. In either case, see the man page for stat for more information.

@paramname The path to the file.@returnstrue if name specifies a file@throwsFileException if the given file does not exist.
isFile
)
{
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

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

writefln
("%s: not a readable file — skipped",
(local variable) string path
path
);
continue; } const
(local variable) const(ubyte[]) bytes
bytes
= cast(ubyte[])
void[] std.file.read!string(string name, ulong upTo = 18446744073709551615LU) @safe

Read entire contents of file name and returns it as an untyped array. If the file size is larger than upTo, only upTo bytes are read.

Examples

import std.utf : byChar;
scope(exit)
{
    assert(exists(deleteme));
    remove(deleteme);
}

std.file.write(deleteme, "1234"); // deleteme is the name of a temporary file
assert(read(deleteme, 2) == "12");
assert(read(deleteme.byChar) == "1234");
assert((cast(const(ubyte)[])read(deleteme)).length == 4);
@paramname string or range of characters representing the file name@paramupTo if present, the maximum number of bytes to read@returnsUntyped array of bytes read.@throwsFileException on error.@seereadText for reading and validating a text file.
read
(
(local variable) string path
path
, 100);
if (!
bool autological_sqlite_header_probe.isSqlite(in ubyte[] b) pure nothrow @nogc @safe

True when b opens with the SQLite 3 header magic.

isSqlite
(
(local variable) const(ubyte[]) bytes
bytes
))
{
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

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

writefln
("%s: not a SQLite database (first 16 bytes are not the header magic)",
(local variable) string path
path
);
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
;
continue; }
void autological_sqlite_header_probe.report(string label, in autological_sqlite_header_probe.SqliteHeader h) @safe

Renders one decoded header as the catalog wants to read it.

report
(
(local variable) string path
path
,
autological_sqlite_header_probe.SqliteHeader autological_sqlite_header_probe.decode(in ubyte[] b) pure nothrow @nogc @safe

Decodes the header fields this catalog reads.

decode
(
(local variable) const(ubyte[]) bytes
bytes
));
} return 0; }