Documentation
¶
Index ¶
- func ParseHexUint(b []byte) (uint64, bool)
- func ParseUint(b []byte) (uint64, bool)
- func ReadDir(name string) iter.Seq[DirEntry]
- func ReadFile(name string, buffer []byte) ([]byte, bool)
- type Bytestring
- func (b *Bytestring) EOL() (eol bool)
- func (b *Bytestring) HexUint64() (num uint64, ok bool)
- func (b *Bytestring) Next() (ch byte, ok bool)
- func (b *Bytestring) NumFields() (num int)
- func (b *Bytestring) SkipSpace() (eol bool)
- func (b *Bytestring) SkipText(s string) (ok bool)
- func (b *Bytestring) Uint64() (num uint64, ok bool)
- type DirEntry
- type DirEntryType
- type RawDirEntry64
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseHexUint ¶ added in v0.2.1
ParseHexUint parses the given byte slice with a hexadecimal number, returning its uint64 value and ok, or a zero value and false in case of error. It is an error for the given decimal number overflows the uint64 range or if there bytes for characters other than "0" to "9", “a” to “f”, or “A” to “F” are encountered.
func ParseUint ¶
ParseUint parses the given byte slice with a decimal number, returning its uint64 value and ok, or a zero value and false in case of error. It is an error for the given decimal number overflows the uint64 range or if there bytes for characters other than "0" to "9" are encountered.
Compared with strconv.ParseUint, this version is around 50% faster, albeit that is moaning at high level. Both versions do not allocate on the heap in case of non-errors, and as our ParseUint does returns a bool instead of an error message, it is without heap allocation also in case of error.
Please note that Go's strconv.ParseUint has been optimized so that the compiler sees that while the input string escapes to the error value, ParseUint copies the input string to the error message so that in turn the compiler can now use optimized []byte to string conversions.
func ReadDir ¶
ReadDir returns an iterator over entries of the specified directory. In case the specified directory does not exist, the iterator does not produce any entries.
Please note that ReadDir produces DirEntry directory entries where their Name fields are stored as []byte, referencing the underlying raw directory entry. The lifetime of the Name field is thus limited to the body of the iteration loop. This design avoids heap allocations and puts the need, if any, into the hands of the loop body.
Due to its Go iterator design, ReadDir needs only a single allocation per full iteration, as opposed to O(n) for os.File.ReadDir. A second allocation only happens for the first run or if there are concurrent directory reads going on and a new directory entries read buffer needs to be allocated. This directory entries buffer allocation behavior mimics the one exhibited by os.File.ReadDir.
ReadDir is roughly 25% faster compared to os.File.ReadDir and only needs a constant(!) 24 B/op heap allocation, as opposed to O(n) heap allocations for the stdlib's ReadDir.
func ReadFile ¶
ReadFile reads the contents of the named file into the supplied buffer, growing the buffer as necessary, returning the contents and true. Only the capacity of the passed buffer matters, the buffer's current length gets ignored. If the file cannot be read for whatever reason, ReadFile returns false. Please note that if the read problem appears in midstream, the buffer might have been already reallocated and thus the most recent buffer is returned even in case of error.
The buffer underlying the returned contents can be same buffer if the capacity was sufficient, otherwise it will be a new backing buffer.
As with os.ReadFile, reaching the end of the file is not considered to be an error but normal operation, and thus not reported.
Types ¶
type Bytestring ¶
type Bytestring struct {
// contains filtered or unexported fields
}
Bytestring provides efficient parsing of text lines in form of byte slices, assuming contents to be in ASCII and treating UTF-8 as individual byte-sized characters.
We rely on the compiler emitting efficient machine code for determining len(b), so we don't need to store it explicitly, but use the length already stored as part of the byte slice anyway. Looking at the generated x86-64 machine code using a tools like the “Compiler Explorer” confirms efficient code where len(bs.b) results in a single MOVQ instruction. For arm64 “all we get” is also a single MOVD instruction.
func NewBytestring ¶
func NewBytestring(b []byte) *Bytestring
NewBytestring returns a new Bytestring object for parsing the supplied text line as a byte slice. It is small enough to be allocated on the stack, avoiding heap allocations.
func (*Bytestring) EOL ¶
func (b *Bytestring) EOL() (eol bool)
EOL returns true if the parsing has reached the end of the byte string, otherwise false.
func (*Bytestring) HexUint64 ¶ added in v0.2.1
func (b *Bytestring) HexUint64() (num uint64, ok bool)
HexUint64 parses the hexadecimal number starting in the buffer at the current position until a character other than 0-9, a-f, or A-F is encountered, or EOL. The number must consist of at least a single hex digit. If successful, HexUint64 returns the number and true; otherwise zero and false. Overflowing HexUint64 is also considered to be an error, returning zero and false in this case.
func (*Bytestring) Next ¶
func (b *Bytestring) Next() (ch byte, ok bool)
Next returns the next byte from the bytestring and ok true, otherwise ok false.
func (*Bytestring) NumFields ¶
func (b *Bytestring) NumFields() (num int)
NumFields returns the number of fields found in the line, starting from the current position. NumFields does not change the current position. Fields are made of sequences of characters excluding the space character. Fields are separated by one or more spaces.
func (*Bytestring) SkipSpace ¶
func (b *Bytestring) SkipSpace() (eol bool)
SkipSpace skips over any space 0x20 characters until either reaching the first non-space character, or EOF. When reaching EOL, it returns true.
func (*Bytestring) SkipText ¶
func (b *Bytestring) SkipText(s string) (ok bool)
SkipText skips the text s in the buffer at the current position if present, returning ok true. Otherwise, returns ok false and the buffer's parsing position is left unchanged.
func (*Bytestring) Uint64 ¶
func (b *Bytestring) Uint64() (num uint64, ok bool)
Uint64 parses the decimal number starting in the buffer at the current position until a character other than 0-9 is encountered, or EOL. The number must consist of at least a single digit. If successful, Uint64 returns the number and true; otherwise zero and false. Overflowing Uint64 is also considered to be an error, returning zero and false in this case.
type DirEntry ¶
type DirEntry struct {
Ino uint64
Name []byte
Type DirEntryType
}
DirEntry represents a single directory entry with only name, type and inode number.
Please note that in order to avoid heap escaping allocations, DirEntry represents the name in the directory entry as a slice of bytes with its backing comes from the underlying raw getdents64 syscall. This allows us to defer converting the name to a string to user code, where there is a much better chance of compiler optimizations for conversions between strings and byte slices.
See also getdents(2) for background details.
func (DirEntry) IsBlockDev ¶
IsBlockDev returns true if this directory entry is about a block device.
func (DirEntry) IsCharDev ¶
IsCharDev returns true if this directory entry is about a character device.
func (DirEntry) IsPipe ¶
IsPipe returns true if this directory entry is about a pipe, also known as “FIFO”.
type DirEntryType ¶
type DirEntryType uint8
const ( DirEntryFIFO DirEntryType = unix.DT_FIFO DirEntryChar DirEntryType = unix.DT_CHR DirEntryBlock DirEntryType = unix.DT_BLK DirEntryDir DirEntryType = unix.DT_DIR DirEntryRegular DirEntryType = unix.DT_REG DirEntrySymlink DirEntryType = unix.DT_LNK DirEntrySocket DirEntryType = unix.DT_SOCK )
func (DirEntryType) String ¶
func (t DirEntryType) String() string
type RawDirEntry64 ¶
type RawDirEntry64 []byte
RawDirEntry64 provides convenient access to a directory entry within a byte slice, as returned by the getdents64() syscall.
See also getdents(2) for background details.
func (RawDirEntry64) Ino ¶
func (d RawDirEntry64) Ino() (uint64, bool)
Ino returns the inode number of this directory entry and ok; otherwise, it returns false.
func (RawDirEntry64) Len ¶
func (d RawDirEntry64) Len() (uint64, bool)
Len returns the length of this directory entry, or false.
func (RawDirEntry64) Name ¶
func (d RawDirEntry64) Name() ([]byte, bool)
Name returns the name of the directory entry, or false. The name returned references the underlying directory entry and thus becomes invalid as soon as the underlying directory entry gets overwritten.
func (RawDirEntry64) Type ¶
func (d RawDirEntry64) Type() (DirEntryType, bool)
Type returns the type of this directory entry, or false.