@byteSwap em Zig — Referência e Exemplos

@byteSwap em Zig

O @byteSwap inverte a ordem dos bytes de um valor inteiro. É a operação fundamental para converter entre big-endian e little-endian, essencial para protocolos de rede, formatos de arquivo e interoperabilidade entre arquiteturas. Mapeia diretamente para instruções como BSWAP (x86).

Sintaxe

@byteSwap(value: T) T

Parâmetros

  • value (T): Valor inteiro cujos bytes serão invertidos. Deve ser um tipo inteiro com tamanho múltiplo de 8 bits.

Valor de retorno

Retorna T — o valor com a ordem dos bytes invertida.

Exemplos práticos

Exemplo 1: Inversão básica de bytes

const std = @import("std");

pub fn main() void {
    const valor: u32 = 0xAABBCCDD;
    const invertido = @byteSwap(valor);

    std.debug.print("Original:  0x{X:0>8}\n", .{valor});     // 0xAABBCCDD
    std.debug.print("Invertido: 0x{X:0>8}\n", .{invertido}); // 0xDDCCBBAA

    const v16: u16 = 0x1234;
    std.debug.print("u16: 0x{X:0>4} -> 0x{X:0>4}\n", .{ v16, @byteSwap(v16) });
    // u16: 0x1234 -> 0x3412
}

Exemplo 2: Conversão host para network byte order

const std = @import("std");
const builtin = @import("builtin");

fn hostToNetwork(valor: u32) u32 {
    // Network byte order é big-endian
    if (builtin.cpu.arch.endian() == .little) {
        return @byteSwap(valor);
    }
    return valor;
}

fn networkToHost(valor: u32) u32 {
    return hostToNetwork(valor); // A operação é simétrica
}

pub fn main() void {
    const ip = (192 << 24) | (168 << 16) | (1 << 8) | 1; // 192.168.1.1
    const rede = hostToNetwork(ip);

    std.debug.print("Host:    0x{X:0>8}\n", .{ip});
    std.debug.print("Network: 0x{X:0>8}\n", .{rede});
}

Exemplo 3: Ler inteiro de bytes em formato big-endian

const std = @import("std");

fn lerU32BigEndian(bytes: *const [4]u8) u32 {
    const valor = std.mem.bytesToValue(u32, bytes);
    // Se estamos em little-endian, inverter
    return std.mem.bigToNative(u32, valor);
}

pub fn main() void {
    const dados = [_]u8{ 0x00, 0x01, 0x00, 0x00 }; // 65536 em big-endian
    const valor = lerU32BigEndian(&dados);
    std.debug.print("Valor: {}\n", .{valor}); // 65536
}

Casos de uso comuns

  1. Protocolos de rede: Converter entre host byte order e network byte order (big-endian).
  2. Formatos de arquivo: Ler/escrever arquivos com endianness diferente do host.
  3. Serialização: Garantir formato consistente independente da plataforma.
  4. Interop entre arquiteturas: Comunicação entre sistemas big e little endian.

Builtins relacionados

Tutoriais relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.