DoxigAlpha

readSourceFileToEndAlloc

If the source can be UTF-16LE encoded, this function asserts that gpa will align a byte-sized allocation to at least 2. Allocators that don't do this are rare.

Function parameters

Parameters

#
file_reader:*std.fs.File.Reader

Type definitions in this namespace

Types

#
EnvVar
Collects all the environment variables that Zig could possibly inspect, so
EmitArtifact
Every kind of artifact which the compiler can emit.

Functions in this namespace

Functions

#
binNameAlloc
Returns the standard file system basename of a binary generated by the Zig compiler.
serializeCpu
Renders a `std.Target.Cpu` value into a textual representation that can be parsed
fmtId
Return a Formatter for a Zig identifier, escaping it with `@""` syntax if needed.
fmtIdFlags
Return a Formatter for a Zig identifier, escaping it with `@""` syntax if needed.
fmtString
Return a formatter for escaping a double quoted Zig string.
fmtChar
Return a formatter for escaping a single quoted Zig string.
stringEscape
Print the string as escaped contents of a double quoted string.
charEscape
Print as escaped contents of a single-quoted string.
readSourceFileToEndAlloc
If the source can be UTF-16LE encoded, this function asserts that `gpa`

There are many assumptions in the entire codebase that Zig source files can

Values

#
max_src_size
There are many assumptions in the entire codebase that Zig source files can

Source

Implementation

#
pub fn readSourceFileToEndAlloc(gpa: Allocator, file_reader: *std.fs.File.Reader) ![:0]u8 {
    var buffer: std.ArrayList(u8) = .empty;
    defer buffer.deinit(gpa);

    if (file_reader.getSize()) |size| {
        const casted_size = std.math.cast(u32, size) orelse return error.StreamTooLong;
        // +1 to avoid resizing for the null byte added in toOwnedSliceSentinel below.
        try buffer.ensureTotalCapacityPrecise(gpa, casted_size + 1);
    } else |_| {}

    try file_reader.interface.appendRemaining(gpa, &buffer, .limited(max_src_size));

    // Detect unsupported file types with their Byte Order Mark
    const unsupported_boms = [_][]const u8{
        "\xff\xfe\x00\x00", // UTF-32 little endian
        "\xfe\xff\x00\x00", // UTF-32 big endian
        "\xfe\xff", // UTF-16 big endian
    };
    for (unsupported_boms) |bom| {
        if (std.mem.startsWith(u8, buffer.items, bom)) {
            return error.UnsupportedEncoding;
        }
    }

    // If the file starts with a UTF-16 little endian BOM, translate it to UTF-8
    if (std.mem.startsWith(u8, buffer.items, "\xff\xfe")) {
        if (buffer.items.len % 2 != 0) return error.InvalidEncoding;
        return std.unicode.utf16LeToUtf8AllocZ(gpa, @ptrCast(@alignCast(buffer.items))) catch |err| switch (err) {
            error.DanglingSurrogateHalf => error.UnsupportedEncoding,
            error.ExpectedSecondSurrogateHalf => error.UnsupportedEncoding,
            error.UnexpectedSecondSurrogateHalf => error.UnsupportedEncoding,
            else => |e| return e,
        };
    }

    return buffer.toOwnedSliceSentinel(gpa, 0);
}