silk.git.pkt_line.
Read and write pkt-lines, the length-prefixed framing of the Git wire protocol.
When to use#
Use PktLine.read to walk the packets of a Git protocol message, such as the body of a
git-upload-pack response, and PktLine.appendData with PktLine.appendFlush and
PktLine.appendDelimiter to build a request body. Most programs use silk.git.remote, which
does this for you.
Details#
Each packet starts with four hexadecimal digits that give its length, the four digits included.
0000 is a flush packet, 0001 a delimiter, and 0002 a response end. A longer length is a
data packet of at most 65516 payload bytes. PktLine.read returns a Packet of offsets
into the input, so nothing is copied. PktLine.line returns the payload without its final
LF, the form in which most Git text lines are sent.
Errors#
PktLineErrorfor a length that is not four hexadecimal digits, is 3, or runs past the input, and for a payload that is too long to write.OutOfMemoryErrorfrom the append functions.
Examples#
Write two packets and read them back#
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.collections.bytes { Bytes }
import silk.core.effect { Effect }
import silk.core.result { Result }
import silk.git.pkt_line { Packet, PacketKind, PktLine, PktLineError }
effect fn roundTrip() -> bool ! PktLineError | OutOfMemoryError ? &mut Allocator {
let mut body = Bytes.make()
run PktLine.appendData(&mut body, b"command=ls-refs\n")
run PktLine.appendFlush(&mut body)
let input = Bytes.asSlice(&body)
let first = match PktLine.read(input, 0) {
Result<Packet, PktLineError>.Success { value } => value
Result<Packet, PktLineError>.Failure { error } => { fail move error }
}
let line = PktLine.line(input, &first)
let second = match PktLine.read(input, first.next) {
Result<Packet, PktLineError>.Success { value } => value
Result<Packet, PktLineError>.Failure { error } => { fail move error }
}
let flushed = match second.kind {
PacketKind.Flush => true
_ => false
}
return line.length == 15 && flushed && second.next == input.length
}
pub effect fn main() -> i32 ! PktLineError | OutOfMemoryError {
let mut allocator = Allocator.systemAllocatorProvider()
if run roundTrip() |> Effect.provideMut<Allocator>(&mut allocator) {
return 0
}
return 1
}Import as PktLine with import silk.git.pkt_line { PktLine }.
Public declarations: 5.
MAX_PAYLOAD#
pub const MAX_PAYLOAD: usizeThe largest payload of one data packet, in bytes: 65520 minus the four length digits.
PacketKind#
pub enum PacketKindWhat a Packet is.
Data#
DataA data packet, 0005 or longer. Its payload is from start to end.
Flush#
FlushThe flush packet 0000, which ends a message or a section.
Delimiter#
DelimiterThe delimiter packet 0001, which separates sections in protocol version 2.
ResponseEnd#
ResponseEndThe response-end packet 0002, which ends a stateless response in protocol version 2.
Implementation Debug for PacketKind#
impl Debug for PacketKindOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the name of the variant, such as Flush.
Packet#
pub struct PacketOne packet, as offsets into the input that PktLine.read read.
Details#
The payload is from start to end, after the four length digits. A packet that is not
Data has an empty payload. The next packet starts at next.
Field kind#
pub kind: PacketKindWhat the packet is.
Field start#
pub start: usizeThe offset of the first payload byte.
Field end#
pub end: usizeThe offset after the last payload byte.
Field next#
pub next: usizeThe offset after the packet, where the next one starts.
Implementation Copy for Packet#
impl Copy for PacketPktLineError#
pub union PktLineErrorThe reason that a PktLine function rejected its input.
Truncated#
TruncatedThe input ends inside the packet that starts at offset.
Field offset#
pub offset: usizeThe offset of the packet.
InvalidLength#
InvalidLengthThe length at offset is not four hexadecimal digits, or it is 3, which no packet has.
Field offset#
pub offset: usizeThe offset of the packet.
PayloadTooLong#
PayloadTooLongA payload to write is longer than MAX_PAYLOAD bytes.
Implementation Debug for PktLineError#
impl Debug for PktLineErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the variant and its offset, such as Truncated { offset: 4 }.
PktLine#
pub struct PktLineFunctions that read and write pkt-lines.
Implementation PktLine#
impl PktLineAssociated function read#
pub fn read(input: &[u8], offset: usize) -> Result<Packet, PktLineError>Returns the packet that starts at offset of input.
Details#
The four length digits can be upper or lower case. Nothing is copied: the Packet holds
offsets into input. Read the next packet at packet.next.
Errors#
Truncatedif fewer than four bytes start atoffset, or the payload runs past the end.InvalidLengthif the length is not four hexadecimal digits, or it is 3.
Associated function payload#
pub fn payload<'a>(input: &'a [u8], packet: &Packet) -> &'a [u8]Returns the payload of packet in input. It is empty for a packet that is not Data.
Associated function line#
pub fn line<'a>(input: &'a [u8], packet: &Packet) -> &'a [u8]Returns the payload of packet in input without its final LF, if it has one.
When to use#
Use it for the text lines of the protocol, which a sender may end with LF or not.
Associated function appendData#
pub effect fn appendData(output: &mut Bytes, payload: &[u8]) -> ()
! PktLineError | OutOfMemoryError
? &mut AllocatorAppends a data packet with payload to output: its four length digits in lower case, then
the payload.
Errors#
PayloadTooLongifpayloadhas more thanMAX_PAYLOADbytes.outputdoes not change.OutOfMemoryErrorif theAllocatorcannot growoutput.
Associated function appendFlush#
pub effect fn appendFlush(output: &mut Bytes) -> ()
! OutOfMemoryError
? &mut AllocatorAppends the flush packet 0000 to output.
Errors#
OutOfMemoryErrorif theAllocatorcannot growoutput.
Associated function appendDelimiter#
pub effect fn appendDelimiter(output: &mut Bytes) -> ()
! OutOfMemoryError
? &mut AllocatorAppends the delimiter packet 0001 to output.
Errors#
OutOfMemoryErrorif theAllocatorcannot growoutput.
Category: Version control.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.