Livt packages
Livt.Net
Version 1.4.1
Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.
Published files (163)
src/packet/ArrayPacketData.lvt
namespace Livt.Net
/**
* Array-backed packet storage with a contiguous initialized prefix.
* Publish freezes bytes; Release permits reuse and clears prefix metadata.
* Release only after all readers/regions have finished. Storage is not erased.
* Scheduled calls have no fixed-cycle or combinational-access guarantee.
*/
component ArrayPacketData<CAPACITY: int = 128> : IWritablePacketData<PacketDataGeometry<CAPACITY>>
{
static assert CAPACITY > 0, "Packet capacity must be positive"
// Owned bytes; only the contiguous initialized prefix may be published.
data: byte[CAPACITY]
// Prefix length and publication state; releasing does not erase storage.
const LENGTH_BITS: int = Bits.RequiredFor(CAPACITY)
written: logic[LENGTH_BITS]
published: bool
/**
* Creates owned storage with an empty, unpublished prefix; bytes need not be erased.
*/
new()
{
written = 0
published = false
}
/**
* Returns the fixed storage capacity in bytes; this does not reserve space.
*/
override fn GetCapacity() int
{
return CAPACITY
}
/**
* Returns the contiguous initialized prefix length, including unpublished bytes.
*/
override fn GetWrittenLength() int
{
return (written as uint) as int
}
/**
* Reports whether the initialized prefix is published for readers.
*/
override fn IsReady() bool
{
return published
}
/**
* Returns the published prefix length in bytes, or zero while unpublished.
*/
override fn GetAvailableLength() int
{
if (!published) {
return 0
}
return (written as uint) as int
}
/**
* Append the next byte or overwrite an initialized byte; holes are invalid.
*/
override fn TryWrite(index: int, value: byte) PacketDataResult
{
if (published) {
return PacketDataResult.Busy
}
if (index < 0 || index >= CAPACITY || index > ((written as uint) as int)) {
return PacketDataResult.Invalid
}
data[index] = value
if (index == ((written as uint) as int)) {
written++
}
return PacketDataResult.Success
}
/**
* An empty prefix is valid packet data, though not a valid Ethernet TX.
*/
override fn TryPublish() PacketDataResult
{
if (published) {
return PacketDataResult.Busy
}
published = true
return PacketDataResult.Success
}
/**
* Reads index in 0..written-1 from the published prefix. Returns NotReady
* while unpublished and Invalid outside the prefix; failure leaves output zero.
* The scheduled read must finish before the owner releases storage.
*/
override fn TryRead(index: int, value: out byte) PacketDataResult
{
value = 0x00
if (!published) {
return PacketDataResult.NotReady
}
if (index < 0 || index >= ((written as uint) as int)) {
return PacketDataResult.Invalid
}
value = data[index]
return PacketDataResult.Success
}
/**
* Releases a published prefix and resets its initialized length without erasing
* storage. Returns Invalid if unpublished. Finish all dependent reads first.
*/
override fn TryRelease() PacketDataResult
{
if (!published) {
return PacketDataResult.Invalid
}
published = false
written = 0
return PacketDataResult.Success
}
/**
* Abandon unpublished preparation; cannot discard a published source.
*/
override fn TryClear() PacketDataResult
{
if (published) {
return PacketDataResult.Busy
}
written = 0
return PacketDataResult.Success
}
}