wpk

package module
v1.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 25, 2023 License: MIT Imports: 13 Imported by: 1

README

WPK

Library to build and use data files packages.

Go Go Reference Go Report Card Hits-of-Code

Preamble

Software often uses a lot of data files and needs effective method to manage them and get quick access. Stitch them to single package and then get access by mapped memory is a good resolution.

Package keeps all files together with warranty that no any file will be deleted, moved or changed separately from others during software is running, it's snapshot of entire development workflow. Package saves disk space due to except file system granulation, especially if many small files are packed together. Package allows to lock fragment of single file to get access to mapped memory.

Capabilities

  • Package read and write API.
  • Lua-scripting API.
  • Virtual file system.
  • Set of associated tags with each file.
  • No sensible limits for package size.
  • Access to package by file mapping, as to slice, as to file.
  • Package can be formed by several steps.
  • Package can be used as insert-read database.
  • Can be used union of packages as single file system.

Structure

Library have root wpk module that used by any code working with .wpk packages. And modules to build utilities for packing/unpacking data files to package:

  • wpk Places data files into single package, extracts them, and gives API for access to package.

  • wpk/bulk Wrapper for package to hold WPK-file whole content as a slice. Actual for small packages (size is much less than the amount of RAM).

  • wpk/mmap Wrapper for package to get access to nested files as to memory mapped blocks. Actual for medium size packages (size correlates with the RAM amount).

  • wpk/fsys Wrapper for package to get access to nested files by OS files. Actual for large packages (size is much exceeds the amount of RAM) or large nested files.

  • wpk/luawpk Package writer with package building process scripting using Lua 5.1. Typical script workflow is to create package for writing, setup some options, put group of files to package, and finalize it.

  • wpk/testdata Contains some Lua-scripts to test wpk/luawpk module and learn scripting API opportunities.

  • wpk/util/pack Small simple utility designed to pack a directory, or a list of directories into an package.

  • wpk/util/extract Small simple utility designed to extract all packed files from package, or list of packages to given directory.

  • wpk/util/build Utility for the packages programmable building, based on wpk/luawpk module.

Compiled binaries of utilities can be downloaded in Releases section.

How to use

At first, install Golang minimum 1.18 version for last version of this package, and get this package:

go get github.com/schwarzlichtbezirk/wpk

Then you can make simple package with files at testdata/media directory by command:

go run github.com/schwarzlichtbezirk/wpk/util/pack --src=${GOPATH}/src/github.com/schwarzlichtbezirk/wpk/testdata/media --dst=${GOPATH}/bin/media.wpk

It's runs utility that receives source directory full path and destination package full path. ${GOPATH} at command line directory path replaced by GOPATH environment variable value. To place any other environment variable VAR you can by ${VAR}. In this sample package placed into bin directory with other compiled golang binary files.

To extract files from this media.wpk package run command:

go run github.com/schwarzlichtbezirk/wpk/util/extract --md --src=${GOPATH}/bin/media.wpk --dst=${GOPATH}/bin/media

and see files in directory ${GOPATH}/bin/media.

To build package at development workflow you can by build utility. It can put files into package from any different paths with given names, and bind addition tags to each file, such as MIME types, keywords, CRC, MD5, SHA256 and others. Run this command to see how its work:

go run github.com/schwarzlichtbezirk/wpk/util/build ${GOPATH}/src/github.com/schwarzlichtbezirk/wpk/testdata/build.lua

and see build.wpk file in binary directory near compiled output.

WPK-format

Package consist of 3 sections:

  1. Header, constantly 64 bytes. Starts with signature (24 bytes), then follow 8 bytes with used at package types sizes, file tags table offset and table size (8+8 bytes), and bata block offset and size (8+8 bytes).

  2. Bare data files blocks.

  3. File tags set table. Contains list of tagset for each file alias. Each tagset must contain some requered fields: it's ID, file size, file offset in package, file name (path), creation time. Package can have common description stored as tagset with empty name. This tagset is placed as first record in file tags table.

Existing package can be opened to append new files, in this case new files blocks will be posted to tags sets old place.

Package can be splitted in two files: 1) file with header and tags table, .wpt-file, it's a short file in most common, and 2) file with data files block, typically .wpf-file. In this case package is able for reading during new files packing to package. If process of packing new files will be broken by any case, package remains accessible with information pointed at last header record.

Lua-scripting API

build utility receives one or more Lua-scripts that maneges package building workflow. Typical sequence is to create new package, setup common properties, put files and add aliases with some tags if it necessary, and complete package building. See whole script API documentation in header comment of api.lua script, and sample package building algorithm below.

step1.lua and step2.lua scripts shows sample how to create new package at step1:

go run github.com/schwarzlichtbezirk/wpk/util/build ${GOPATH}/src/github.com/schwarzlichtbezirk/wpk/testdata/step1.lua

and later append to exising package new files at step2 call:

go run github.com/schwarzlichtbezirk/wpk/util/build ${GOPATH}/src/github.com/schwarzlichtbezirk/wpk/testdata/step2.lua

packdir.lua script has function that can be used to put to package directory with original tree hierarchy.

WPK API usage

See godoc with API description, and wpk_test.go for usage samples.

On your program initialisation open prepared wpk-package by Package.OpenFile call. It reads tags sets of package at once, then you can get access to filenames and it's tags. TagsetRaw structure helps you to get tags associated to files, and also it provides file information by standard interfaces implementation. To get access to package nested files, create some Tagger object. Modules wpk/bulk, wpk/mmap and wpk/fsys provides this access by different ways. Package object have all io/fs file system interfaces implementations, and can be used by anyway where they needed.

Documentation

Index

Examples

Constants

View Source
const (
	SignSize   = 24 // signature field size.
	HeaderSize = 64 // package header size in bytes.

	SignReady = "Whirlwind 3.4 Package   " // package is ready for use
	SignBuild = "Whirlwind 3.4 Prebuild  " // package is in building progress
)
View Source
const (
	PTStidsz  = 2 // "tag ID" type size.
	PTStagsz  = 2 // "tag size" type size.
	PTStssize = 2 // "tagset size" type size.

)

Package types sizes.

View Source
const PackName = "@pack"

Special name for `Open` calls to get package content reference.

View Source
const PathSeparator = string(os.PathSeparator)

OS-specific path separator string

Variables

View Source
var (
	ErrBadIntLen = errors.New("unacceptable integer length")
	ErrTsiConst  = errors.New("content changes are disabled for iterator")
)
View Source
var (
	ErrSignPre = errors.New("package is not ready")
	ErrSignBad = errors.New("signature does not pass")
	ErrSignFTT = errors.New("header contains incorrect data")

	ErrRangeTSSize = errors.New("tagset size value is exceeds out of the type dimension")

	ErrNoTag    = errors.New("tag with given ID not found")
	ErrNoPath   = errors.New("file name is absent")
	ErrNoOffset = errors.New("file offset is absent")
	ErrNoSize   = errors.New("file size is absent")
	ErrOutOff   = errors.New("file offset is out of bounds")
	ErrOutSize  = errors.New("file size is out of bounds")

	ErrOtherSubdir = errors.New("directory refers to other workspace")
)

Errors on WPK-API.

View Source
var VarChar [256]bool = func() (a [256]bool) {
	a['_'] = true
	for c := 'A'; c <= 'Z'; c++ {
		a[c] = true
		a[c+32] = true
	}
	for c := '0'; c <= '9'; c++ {
		a[c] = true
	}
	return
}()

VarChar is table for fast check that ASCII code is acceptable symbol of variable.

View Source
var VarCharFirst [256]bool = func() (a [256]bool) {
	a['_'] = true
	for c := 'A'; c <= 'Z'; c++ {
		a[c] = true
		a[c+32] = true
	}
	return
}()

VarCharFirst is table for fast check that ASCII code is acceptable first symbol of variable.

Functions

func B2S added in v1.4.3

func B2S(b []byte) string

B2S converts bytes slice to string without memory allocation.

func DirExists added in v1.6.2

func DirExists(fpath string) (bool, error)

DirExists check up directory existence.

func Envfmt added in v1.1.0

func Envfmt(fpath string, envmap map[string]string) string

Envfmt replaces environment variables entries in file path to there values. Environment variables must be followed by those 3 patterns: $VAR, ${VAR}, %VAR%. Environment variables are looked at first in 'envmap' if it given, and then by os-call. This function works by two string passes, without superfluous memory allocations.

Example
package main

import (
	"fmt"
	"os"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	os.Setenv("VAR", "/go")
	// successful patterns
	fmt.Println(wpk.Envfmt("$VAR/bin/", nil))
	fmt.Println(wpk.Envfmt("${VAR}/bin/", nil))
	fmt.Println(wpk.Envfmt("%VAR%/bin/", nil))
	fmt.Println(wpk.Envfmt("/home$VAR", nil))
	fmt.Println(wpk.Envfmt("/home%VAR%", map[string]string{"VAR": "/any/path"}))
	fmt.Println(wpk.Envfmt("$VAR%VAR%${VAR}", nil))
	// patterns with unknown variable
	fmt.Println(wpk.Envfmt("$VYR/bin/", nil))
	fmt.Println(wpk.Envfmt("${VAR}/${_foo_}", nil))
	// patterns with errors
	fmt.Println(wpk.Envfmt("$VAR$/bin/", nil))
	fmt.Println(wpk.Envfmt("${VAR/bin/", nil))
	fmt.Println(wpk.Envfmt("%VAR/bin/", nil))
	fmt.Println(wpk.Envfmt("/home${VAR", nil))
}
Output:

/go/bin/
/go/bin/
/go/bin/
/home/go
/home/any/path
/go/go/go
$VYR/bin/
/go/${_foo_}
/go$/bin/
${VAR/bin/
%VAR/bin/
/home${VAR

func FileExists added in v1.6.2

func FileExists(fpath string) (bool, error)

FileExists check up file existence.

func GetF32 added in v1.5.0

func GetF32(b []byte) float32

func GetF64 added in v1.5.0

func GetF64(b []byte) float64

func GetPackageInfo added in v1.3.0

func GetPackageInfo(r io.ReadSeeker) (hdr Header, ts TagsetRaw, err error)

GetPackageInfo returns header and tagset with package information. It's a quick function to get info from the file without reading whole tags table.

Example
package main

import (
	"log"
	"os"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	// list of packages to get info
	var list = []string{
		"example1.wpk", "example2.wpk", "example3.wpk",
	}
	for _, fname := range list {
		func() {
			var err error

			// open package file
			var f wpk.RFile
			if f, err = os.Open(fname); err != nil {
				log.Printf("can not open package %s, %s", fname, err.Error())
				return
			}
			defer f.Close()

			// get quick package info
			var hdr wpk.Header
			var info wpk.TagsetRaw
			if hdr, info, err = wpk.GetPackageInfo(f); err != nil {
				log.Printf("can not get package info %s, %s", fname, err.Error())
				return
			}

			// print package info
			var label, _ = info.TagStr(wpk.TIDlabel)
			log.Printf("package %s info: %d records, %d data size, %d info notes, label '%s'",
				fname, hdr.Count(), hdr.DataSize(), info.Num(), label)
		}()
	}
}
Output:

func GetU16 added in v1.5.0

func GetU16(b []byte) uint16

func GetU32 added in v1.5.0

func GetU32(b []byte) uint32

func GetU64 added in v1.5.0

func GetU64(b []byte) uint64

func JoinFilePath added in v1.6.2

func JoinFilePath(dir, base string) string

JoinFilePath performs fast join of two file path chunks. In some cases concatenates with OS-specific separator.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	fmt.Println(wpk.JoinFilePath("dir/", "base.ext"))
	fmt.Println(wpk.JoinFilePath("dir", "/base.ext"))
	fmt.Println(wpk.JoinFilePath("dir/", "/base.ext"))
}
Output:

dir/base.ext
dir/base.ext
dir/base.ext

func JoinPath added in v1.6.2

func JoinPath(dir, base string) string

JoinPath performs fast join of two UNIX-like path chunks.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	fmt.Println(wpk.JoinPath("dir", "base.ext"))
	fmt.Println(wpk.JoinPath("dir/", "base.ext"))
	fmt.Println(wpk.JoinPath("dir", "/base.ext"))
	fmt.Println(wpk.JoinPath("dir/", "/base.ext"))
}
Output:

dir/base.ext
dir/base.ext
dir/base.ext
dir/base.ext

func MakeDataPath added in v1.3.0

func MakeDataPath(fpath string) string

MakeDataPath receives file path and returns it with ".wpf" extension. It hepls to open splitted package.

func MakeTagsPath added in v1.3.0

func MakeTagsPath(fpath string) string

MakeTagsPath receives file path and returns it with ".wpt" extension. It hepls to open splitted package.

func PathName added in v1.6.2

func PathName(fpath string) string

PathName returns name of file in given file path without extension.

func ReadF32 added in v1.5.0

func ReadF32(r io.Reader) (f float32, err error)

func ReadF64 added in v1.5.0

func ReadF64(r io.Reader) (f float64, err error)

func ReadU16 added in v1.5.0

func ReadU16(r io.Reader) (u uint16, err error)

func ReadU32 added in v1.5.0

func ReadU32(r io.Reader) (u uint32, err error)

func ReadU64 added in v1.5.0

func ReadU64(r io.Reader) (u uint64, err error)

func S2B added in v1.4.3

func S2B(s string) (b []byte)

S2B converts string to bytes slice without memory allocation.

func SetF32 added in v1.5.0

func SetF32(b []byte, f float32)

func SetF64 added in v1.5.0

func SetF64(b []byte, f float64)

func SetU16 added in v1.5.0

func SetU16(b []byte, u uint16)

func SetU32 added in v1.5.0

func SetU32(b []byte, u uint32)

func SetU64 added in v1.5.0

func SetU64(b []byte, u uint64)

func TempPath added in v1.4.0

func TempPath(fname string) string

TempPath returns filename located at temporary directory.

func ToKey

func ToKey(s string) string

ToKey is high performance function to bring filenames to lower case in ASCII and true slashes at once without superfluous allocations if it possible.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	fmt.Println(wpk.ToKey("C:\\Windows\\Temp"))
}
Output:

c:/windows/temp

func ToLower added in v1.5.1

func ToLower(s string) string

ToLower is high performance function to bring filenames to lower case in ASCII without superfluous allocations if it possible.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	fmt.Println(wpk.ToLower("C:\\Windows\\Temp"))
}
Output:

c:\windows\temp

func ToSlash

func ToSlash(s string) string

ToSlash brings filenames to true slashes without superfluous allocations if it possible.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	fmt.Println(wpk.ToSlash("C:\\Windows\\Temp"))
}
Output:

C:/Windows/Temp

func ToUpper added in v1.5.1

func ToUpper(s string) string

ToUpper is high performance function to bring filenames to upper case in ASCII without superfluous allocations if it possible.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	fmt.Println(wpk.ToUpper("C:\\Windows\\Temp"))
}
Output:

C:\WINDOWS\TEMP

func WriteF32 added in v1.5.0

func WriteF32(w io.Writer, f float32) (err error)

func WriteF64 added in v1.5.0

func WriteF64(w io.Writer, f float64) (err error)

func WriteU16 added in v1.5.0

func WriteU16(w io.Writer, u uint16) (err error)

func WriteU32 added in v1.5.0

func WriteU32(w io.Writer, u uint32) (err error)

func WriteU64 added in v1.5.0

func WriteU64(w io.Writer, u uint64) (err error)

Types

type CompleteFS added in v1.4.0

type CompleteFS interface {
	fs.SubFS
	fs.StatFS
	fs.GlobFS
	fs.ReadDirFS
	fs.ReadFileFS
}

CompleteFS includes all FS interfaces.

type ErrTag

type ErrTag struct {
	What error  // error message
	Key  string // normalized file name
	TID  TID    // tag ID
}

ErrTag is error on some field of tags set.

func (*ErrTag) Error

func (e *ErrTag) Error() string

func (*ErrTag) Unwrap

func (e *ErrTag) Unwrap() error

type FTT added in v1.4.0

type FTT struct {
	// contains filtered or unexported fields
}

File tags table.

func (*FTT) Append added in v1.4.0

func (ftt *FTT) Append(wpt, wpf io.WriteSeeker) (err error)

Append writes prebuild header for previously opened package to append new files.

func (*FTT) Begin added in v1.4.0

func (ftt *FTT) Begin(wpt, wpf io.WriteSeeker) (err error)

Begin writes prebuild header for new empty package.

func (*FTT) CheckTagset added in v1.4.1

func (ftt *FTT) CheckTagset(ts TagsetRaw) (fkey string, err error)

CheckTagset tests path & offset & size tags existence and checks that size & offset is are in the bounds.

func (*FTT) DataSize added in v1.4.1

func (ftt *FTT) DataSize() uint

DataSize returns package data size from files tags table. This value changed on FTT open or sync operation.

func (*FTT) GetInfo added in v1.4.4

func (ftt *FTT) GetInfo() TagsetRaw

GetInfo returns package information tagset if it present.

Example
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	var err error

	// Open package files tags table
	var pkg = wpk.NewPackage()
	if err = pkg.OpenFile("example.wpk"); err != nil {
		log.Fatal(err)
	}

	// Format package information
	var items = []string{
		fmt.Sprintf("records: %d", pkg.TagsetNum()),
		fmt.Sprintf("datasize: %d", pkg.DataSize()),
	}
	if str, ok := pkg.GetInfo().TagStr(wpk.TIDlabel); ok {
		items = append(items, fmt.Sprintf("label: %s", str))
	}
	if str, ok := pkg.GetInfo().TagStr(wpk.TIDlink); ok {
		items = append(items, fmt.Sprintf("link: %s", str))
	}
	log.Println(strings.Join(items, ", "))
}
Output:

func (*FTT) Init added in v1.4.0

func (ftt *FTT) Init(hdr *Header)

Init performs initialization for given Package structure.

func (*FTT) IsSplitted added in v1.4.0

func (ftt *FTT) IsSplitted() bool

IsSplitted returns true if package is splitted on tags and data files.

func (*FTT) OpenDir added in v1.4.0

func (ftt *FTT) OpenDir(fulldir string) (fs.ReadDirFile, error)

OpenDir returns PackDirFile structure associated with group of files in package pooled with common directory prefix. Usable to implement fs.FileSystem interface.

func (*FTT) OpenFile added in v1.5.0

func (ftt *FTT) OpenFile(fpath string) (err error)

OpenFile opens package from the file with given name, it calls `OpenStream` method with file stream. Tagger should be set later if access to nested files is needed.

func (*FTT) OpenStream added in v1.5.0

func (ftt *FTT) OpenStream(r io.ReadSeeker) (err error)

OpenStream opens package. At first it checkups file signature, then reads records table, and reads file tagset table. Tags set for each file should contain at least file offset, file size, file ID and file name.

func (*FTT) Parse added in v1.4.4

func (ftt *FTT) Parse(buf []byte) (n int64, err error)

Parse makes table from given byte slice. It's high performance method without extra allocations calls.

func (*FTT) ReadDirN added in v1.4.0

func (ftt *FTT) ReadDirN(fulldir string, n int) (list []fs.DirEntry, err error)

ReadDirN returns fs.DirEntry array with nested into given package directory presentation. It's core function for ReadDirFile and ReadDirFS structures.

func (*FTT) ReadFrom added in v1.4.0

func (ftt *FTT) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom reads file tags table whole content from the given stream.

func (*FTT) SetInfo added in v1.4.0

func (ftt *FTT) SetInfo(ts TagsetRaw)

SetInfo puts given tagset as package information tagset.

Example
package main

import (
	"log"
	"os"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	var err error
	var f *os.File
	var pkg = wpk.NewPackage()

	const (
		label  = "empty-package"
		link   = "github.com/schwarzlichtbezirk/wpk"
		author = "schwarzlichtbezirk"
	)

	// open temporary file for read/write
	if f, err = os.OpenFile("example.wpk", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// starts new package
	if err = pkg.Begin(f, nil); err != nil {
		log.Fatal(err)
	}

	// put package info somewhere at the code before finalize
	pkg.SetInfo(wpk.TagsetRaw{}.
		Put(wpk.TIDlabel, wpk.StrTag(label)).
		Put(wpk.TIDlink, wpk.StrTag(link)).
		Put(wpk.TIDauthor, wpk.StrTag(author)))

	// finalize at the end
	if err = pkg.Sync(f, nil); err != nil {
		log.Fatal(err)
	}
}
Output:

func (*FTT) Sync added in v1.4.0

func (ftt *FTT) Sync(wpt, wpf io.WriteSeeker) (err error)

Sync writes actual file tags table and true signature with settings.

func (*FTT) TagsetNum added in v1.5.0

func (ftt *FTT) TagsetNum() int

TagsetNum returns actual number of entries at files tags table.

func (*FTT) WriteTo added in v1.4.0

func (ftt *FTT) WriteTo(w io.Writer) (n int64, err error)

WriteTo writes file tags table whole content to the given stream.

type Header struct {
	// contains filtered or unexported fields
}

Header - package header.

func (*Header) Count added in v1.5.0

func (hdr *Header) Count() int

Count returns package records count from header.

func (*Header) DataSize added in v1.1.0

func (hdr *Header) DataSize() uint

DataSize returns package data size from header.

func (*Header) FttSize added in v1.5.0

func (hdr *Header) FttSize() uint

FttSize returns package files tagset table size from header.

func (*Header) IsReady added in v1.3.0

func (hdr *Header) IsReady() error

IsReady determines that package is ready for read the data.

func (*Header) Parse added in v1.5.0

func (hdr *Header) Parse(buf []byte) (n int64, err error)

Parse fills header from given byte slice. It's high performance method without extra allocations calls.

func (*Header) ReadFrom added in v1.1.0

func (hdr *Header) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom reads header from stream as binary data of constant length.

func (*Header) WriteTo added in v1.1.0

func (hdr *Header) WriteTo(w io.Writer) (n int64, err error)

WriteTo writes header to stream as binary data of constant length.

type PackDirFile added in v1.4.0

type PackDirFile struct {
	TagsetRaw // has fs.FileInfo interface
	// contains filtered or unexported fields
}

PackDirFile is a directory file whose entries can be read with the ReadDir method. fs.ReadDirFile interface implementation.

func (*PackDirFile) Close added in v1.4.0

func (f *PackDirFile) Close() error

fs.ReadDirFile interface implementation.

func (*PackDirFile) Read added in v1.4.0

func (f *PackDirFile) Read(b []byte) (n int, err error)

fs.ReadDirFile interface implementation.

func (*PackDirFile) ReadDir added in v1.4.0

func (f *PackDirFile) ReadDir(n int) (matches []fs.DirEntry, err error)

fs.ReadDirFile interface implementation.

func (*PackDirFile) Stat added in v1.4.0

func (f *PackDirFile) Stat() (fs.FileInfo, error)

fs.ReadDirFile interface implementation.

type Package

type Package struct {
	*FTT
	Tagger
	Workspace string
}

Package structure contains file tags table, tagger object to get access to nested files, and subdirectory workspace.

func NewPackage added in v1.3.2

func NewPackage() *Package

NewPackage returns pointer to new initialized Package filesystem structure. Tagger should be set later if access to nested files is needed.

func (*Package) BaseTagset added in v1.3.3

func (pkg *Package) BaseTagset(offset, size uint, fkey string) TagsetRaw

BaseTagset returns new tagset based on predefined TID type size and tag size type, and puts file offset and file size into tagset with predefined sizes.

func (*Package) DelTagset added in v1.4.0

func (pkg *Package) DelTagset(fkey string) (TagsetRaw, bool)

GetDelTagset deletes the tagset for a key, returning the previous tagset if any.

func (*Package) Enum

func (pkg *Package) Enum(f func(string, TagsetRaw) bool)

Enum calls given closure for each tagset in package. Skips package info.

Example
package main

import (
	"log"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	var err error

	// Open package files tags table
	var pkg = wpk.NewPackage()
	if err = pkg.OpenFile("example.wpk"); err != nil {
		log.Fatal(err)
	}

	// How many unique records in package
	var m = map[uint]wpk.Void{}
	pkg.Enum(func(fkey string, ts wpk.TagsetRaw) bool {
		if offset, ok := ts.TagUint(wpk.TIDoffset); ok {
			m[offset] = wpk.Void{} // count unique offsets
		}
		return true
	})
	log.Printf("total %d unique files and %d aliases in package", len(m), pkg.TagsetNum()-len(m))
}
Output:

func (*Package) FullPath added in v1.4.0

func (pkg *Package) FullPath(fkey string) string

FullPath returns concatenation of workspace and relative path.

func (*Package) GetTagset added in v1.4.4

func (pkg *Package) GetTagset(fkey string) (TagsetRaw, bool)

GetTagset returns tagset with given filename key, if it found.

func (*Package) Glob

func (pkg *Package) Glob(pattern string) (res []string, err error)

Glob returns the names of all files in package matching pattern or nil if there is no matching file. fs.GlobFS interface implementation.

Example
package main

import (
	"log"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	var err error

	// Open package files tags table
	var pkg = wpk.NewPackage()
	if err = pkg.OpenFile("example.wpk"); err != nil {
		log.Fatal(err)
	}

	// Get all JPEG-files in subdirectories
	var res []string
	if res, err = pkg.Glob("*/*.jpg"); err != nil {
		log.Fatal(err)
	}
	// and print them
	for _, fname := range res {
		log.Println(fname)
	}
}
Output:

func (*Package) HasTagset added in v1.4.0

func (pkg *Package) HasTagset(fkey string) bool

HasTagset check up that tagset with given filename key is present.

func (*Package) Open added in v1.4.0

func (pkg *Package) Open(dir string) (fs.File, error)

Open implements access to nested into package file or directory by filename. fs.FS implementation.

func (*Package) PackData added in v1.3.0

func (pkg *Package) PackData(w io.WriteSeeker, r io.Reader, fkey string) (ts TagsetRaw, err error)

PackData puts data streamed by given reader into package as a file and associate keyname "fkey" with it.

func (*Package) PackFile added in v1.3.0

func (pkg *Package) PackFile(w io.WriteSeeker, file fs.File, fkey string) (ts TagsetRaw, err error)

PackFile puts file with given file handle into package and associate keyname "fkey" with it.

func (*Package) PutAlias added in v1.3.0

func (pkg *Package) PutAlias(fkey1, fkey2 string) error

PutAlias makes clone tagset with file name 'fkey1' and replace name tag in it to 'fkey2'. Keeps link to original file name.

func (*Package) ReadDir added in v1.4.0

func (pkg *Package) ReadDir(dir string) ([]fs.DirEntry, error)

ReadDir reads the named directory and returns a list of directory entries sorted by filename. fs.ReadDirFS interface implementation.

func (*Package) ReadFile added in v1.4.0

func (pkg *Package) ReadFile(fkey string) ([]byte, error)

ReadFile returns slice with nested into package file content. Makes content copy to prevent ambiguous access to closed mapped memory block. fs.ReadFileFS implementation.

func (*Package) Rename added in v1.3.0

func (pkg *Package) Rename(fkey1, fkey2 string) error

Rename tagset with file name 'fkey1' to 'fkey2'. Keeps link to original file name.

func (*Package) RenameDir added in v1.4.3

func (pkg *Package) RenameDir(olddir, newdir string, skipexist bool) (count int, err error)

RenameDir renames all files in package with 'olddir' path to 'newdir' path.

func (*Package) SetTagset added in v1.4.0

func (pkg *Package) SetTagset(fkey string, ts TagsetRaw)

SetTagset puts tagset with given filename key.

func (*Package) SetupTagset added in v1.4.4

func (pkg *Package) SetupTagset(ts TagsetRaw)

SetupTagset puts tagset with filename key stored at tagset.

func (*Package) Stat added in v1.4.0

func (pkg *Package) Stat(fkey string) (fs.FileInfo, error)

Stat returns a fs.FileInfo describing the file. fs.StatFS interface implementation.

func (*Package) Sub added in v1.4.0

func (pkg *Package) Sub(dir string) (sub fs.FS, err error)

Sub clones object and gives access to pointed subdirectory. fs.SubFS implementation.

func (*Package) TrimPath added in v1.4.3

func (pkg *Package) TrimPath(fkey string) string

TrimPath returns trimmed path without workspace prefix.

type PkgReader added in v1.6.1

type PkgReader interface {
	io.Reader
	io.ReaderAt
	io.Seeker
}

PkgReader is interface with readers for nested package files.

type RFile added in v1.6.1

type RFile interface {
	fs.File
	PkgReader
}

RFile is interface for acces on reading to nested package files.

type SeqMap added in v1.5.1

type SeqMap[K comparable, T any] struct {
	// contains filtered or unexported fields
}

SeqMap is thread-safe map with key-value pairs sequence in which they were placed into map.

func (*SeqMap[K, T]) Delete added in v1.5.1

func (m *SeqMap[K, T]) Delete(key K) (ret T, ok bool)

func (*SeqMap[K, T]) Has added in v1.5.1

func (m *SeqMap[K, T]) Has(key K) (ok bool)

func (*SeqMap[K, T]) Init added in v1.5.1

func (m *SeqMap[K, T]) Init(c int)

func (*SeqMap[K, T]) Len added in v1.5.1

func (m *SeqMap[K, T]) Len() int

func (*SeqMap[K, T]) Peek added in v1.5.1

func (m *SeqMap[K, T]) Peek(key K) (ret T, ok bool)

func (*SeqMap[K, T]) Poke added in v1.5.1

func (m *SeqMap[K, T]) Poke(key K, val T)

func (*SeqMap[K, T]) Pop added in v1.5.1

func (m *SeqMap[K, T]) Pop() (key K, val T, ok bool)

func (*SeqMap[K, T]) Push added in v1.5.1

func (m *SeqMap[K, T]) Push(key K, val T) (ok bool)

func (*SeqMap[K, T]) Range added in v1.5.1

func (m *SeqMap[K, T]) Range(f func(K, T) bool)

type TID

type TID = uint16
const (
	TIDnone TID = 0

	TIDoffset TID = 1  // required, uint
	TIDsize   TID = 2  // required, uint
	TIDpath   TID = 3  // required, unique, string
	TIDfid    TID = 4  // unique, uint
	TIDmtime  TID = 5  // required for files, 8/12 bytes (mod-time)
	TIDatime  TID = 6  // 8/12 bytes (access-time)
	TIDctime  TID = 7  // 8/12 bytes (change-time)
	TIDbtime  TID = 8  // 8/12 bytes (birth-time)
	TIDattr   TID = 9  // uint32
	TIDmime   TID = 10 // string

	TIDcrc32ieee TID = 11 // [4]byte, CRC-32-IEEE 802.3, poly = 0x04C11DB7, init = -1
	TIDcrc32c    TID = 12 // [4]byte, (Castagnoli), poly = 0x1EDC6F41, init = -1
	TIDcrc32k    TID = 13 // [4]byte, (Koopman), poly = 0x741B8CD7, init = -1
	TIDcrc64iso  TID = 14 // [8]byte, poly = 0xD800000000000000, init = -1

	TIDmd5    TID = 20 // [16]byte
	TIDsha1   TID = 21 // [20]byte
	TIDsha224 TID = 22 // [28]byte
	TIDsha256 TID = 23 // [32]byte
	TIDsha384 TID = 24 // [48]byte
	TIDsha512 TID = 25 // [64]byte

	TIDtmbjpeg  TID = 100 // []byte, thumbnail image (icon) in JPEG format
	TIDtmbwebp  TID = 101 // []byte, thumbnail image (icon) in WebP format
	TIDlabel    TID = 110 // string
	TIDlink     TID = 111 // string
	TIDkeywords TID = 112 // string
	TIDcategory TID = 113 // string
	TIDversion  TID = 114 // string
	TIDauthor   TID = 115 // string
	TIDcomment  TID = 116 // string
)

List of predefined tags IDs.

type TagRaw added in v1.4.0

type TagRaw []byte

TagRaw - file description item.

func BoolTag added in v1.4.0

func BoolTag(val bool) TagRaw

BoolTag is boolean tag constructor.

func ByteTag added in v1.4.0

func ByteTag(val byte) TagRaw

ByteTag is byte tag constructor.

func NumberTag added in v1.4.0

func NumberTag(val float64) TagRaw

NumberTag is 64-bit float tag constructor.

func StrTag added in v1.4.0

func StrTag(val string) TagRaw

StrTag is string tag constructor.

func TimeTag added in v1.4.0

func TimeTag(val time.Time) TagRaw

TimeTag is 12-bytes UNIX time tag constructor.

func Uint16Tag added in v1.4.0

func Uint16Tag(val uint16) TagRaw

Uint16Tag is 16-bit unsigned int tag constructor.

func Uint32Tag added in v1.4.0

func Uint32Tag(val uint32) TagRaw

Uint32Tag is 32-bit unsigned int tag constructor.

func Uint64Tag added in v1.4.0

func Uint64Tag(val uint64) TagRaw

Uint64Tag is 64-bit unsigned int tag constructor.

func UintLenTag added in v1.4.0

func UintLenTag(val uint, l int) TagRaw

UintLenTag is unsigned int tag constructor with specified length in bytes.

func UintTag added in v1.4.0

func UintTag(val uint) TagRaw

UintTag is unspecified size unsigned int tag constructor.

func UnixmsTag added in v1.5.1

func UnixmsTag(val time.Time) TagRaw

UnixmsTag is 8-bytes UNIX time in milliseconds tag constructor.

func (TagRaw) TagBool added in v1.4.0

func (t TagRaw) TagBool() (bool, bool)

TagBool is boolean tag converter.

func (TagRaw) TagByte added in v1.4.0

func (t TagRaw) TagByte() (byte, bool)

TagByte tag converter.

func (TagRaw) TagNumber added in v1.4.0

func (t TagRaw) TagNumber() (float64, bool)

TagNumber is 64-bit float tag converter.

func (TagRaw) TagStr added in v1.4.0

func (t TagRaw) TagStr() (string, bool)

TagStr tag converter.

func (TagRaw) TagTime added in v1.4.0

func (t TagRaw) TagTime() (time.Time, bool)

TagTime is 8/12-bytes time tag converter.

func (TagRaw) TagUint added in v1.4.0

func (t TagRaw) TagUint() (uint, bool)

TagUint is unspecified size unsigned int tag converter.

func (TagRaw) TagUint16 added in v1.4.0

func (t TagRaw) TagUint16() (uint16, bool)

TagUint16 is 16-bit unsigned int tag converter.

func (TagRaw) TagUint32 added in v1.4.0

func (t TagRaw) TagUint32() (uint32, bool)

TagUint32 is 32-bit unsigned int tag converter.

func (TagRaw) TagUint64 added in v1.4.0

func (t TagRaw) TagUint64() (uint64, bool)

TagUint64 is 64-bit unsigned int tag converter.

func (TagRaw) TagUnixms added in v1.6.0

func (t TagRaw) TagUnixms() (int64, bool)

TagUnixms is 8/12-bytes tag converter to UNIX time in milliseconds.

type Tagger

type Tagger interface {
	OpenTagset(TagsetRaw) (RFile, error)
	io.Closer
}

Tagger provides acces to nested files by given tagset of this package.

type TagsetIterator added in v1.3.0

type TagsetIterator struct {
	TagsetRaw
	// contains filtered or unexported fields
}

TagsetIterator helps to iterate through all tags.

func (*TagsetIterator) Add added in v1.6.0

func (tsi *TagsetIterator) Add(tid TID, tag TagRaw) TagsetRaw

Set is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) AddOk added in v1.6.0

func (tsi *TagsetIterator) AddOk(tid TID, tag TagRaw) (TagsetRaw, bool)

Set is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) Del added in v1.3.0

func (tsi *TagsetIterator) Del(tid TID) TagsetRaw

Del is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) DelOk added in v1.6.0

func (tsi *TagsetIterator) DelOk(tid TID) (TagsetRaw, bool)

DelOk is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) Failed added in v1.3.0

func (tsi *TagsetIterator) Failed() bool

Failed points that iterator is finished by broken tagset state.

func (*TagsetIterator) Next added in v1.3.0

func (tsi *TagsetIterator) Next() (ok bool)

Next carries to the next tag position.

Example
package main

import (
	"fmt"
	"time"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	var ts = wpk.TagsetRaw{}.
		Put(wpk.TIDpath, wpk.StrTag("picture.jpg")).
		Put(wpk.TIDmtime, wpk.TimeTag(time.Now())).
		Put(wpk.TIDmime, wpk.StrTag("image/jpeg"))
	var tsi = ts.Iterator()
	for tsi.Next() {
		fmt.Printf("tid=%d, len=%d\n", tsi.TID(), tsi.TagLen())
	}
}
Output:

tid=3, len=11
tid=5, len=12
tid=10, len=10

func (*TagsetIterator) Passed added in v1.3.0

func (tsi *TagsetIterator) Passed() bool

Passed returns true if the end of iterations is successfully reached.

Example
package main

import (
	"fmt"

	"github.com/schwarzlichtbezirk/wpk"
)

func main() {
	var slice = []byte{
		3, 0, 4, 0, 10, 0, 0, 0,
		4, 0, 12, 0, 115, 111, 109, 101, 102, 105, 108, 101, 46, 100, 97, 116,
	}
	var tsi = wpk.TagsetRaw(slice).Iterator()
	for tsi.Next() {
		// place some handler code here
	}
	fmt.Println(tsi.Passed())
}
Output:

true

func (*TagsetIterator) Put added in v1.3.0

func (tsi *TagsetIterator) Put(tid TID, tag TagRaw) TagsetRaw

Put is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) Reset added in v1.3.0

func (tsi *TagsetIterator) Reset()

Reset restarts iterator for new iterations loop.

func (*TagsetIterator) Set added in v1.3.0

func (tsi *TagsetIterator) Set(tid TID, tag TagRaw) TagsetRaw

Set is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) SetOk added in v1.6.0

func (tsi *TagsetIterator) SetOk(tid TID, tag TagRaw) (TagsetRaw, bool)

Set is the stub to disable any changes to data content of iterator.

func (*TagsetIterator) TID added in v1.3.0

func (tsi *TagsetIterator) TID() TID

TID returns the tag ID of the last readed tag.

func (*TagsetIterator) Tag added in v1.3.0

func (tsi *TagsetIterator) Tag() TagRaw

Tag returns tag slice of the last readed tag content.

func (*TagsetIterator) TagLen added in v1.3.0

func (tsi *TagsetIterator) TagLen() int

TagLen returns length of last readed tag content.

type TagsetRaw added in v1.4.0

type TagsetRaw []byte

TagsetRaw is slice of bytes with tags set. Each tag should be with unique ID. fs.FileInfo interface implementation.

func CopyTagset added in v1.6.0

func CopyTagset(ts TagsetRaw) TagsetRaw

CopyTagset makes copy of given tagset to new space. It prevents rewriting data at solid slice with FTT when tagset modify.

func (TagsetRaw) AccessTime added in v1.4.0

func (ts TagsetRaw) AccessTime() time.Time

AccessTime returns file access timestamp of nested into package file. times.Timespec implementation.

func (TagsetRaw) Add added in v1.6.0

func (ts TagsetRaw) Add(tid TID, tag TagRaw) TagsetRaw

AddOk appends tag with given ID only if tagset does not have same yet. Signature helps to build the call chain.

func (TagsetRaw) AddOk added in v1.6.0

func (ts TagsetRaw) AddOk(tid TID, tag TagRaw) (TagsetRaw, bool)

AddOk appends tag with given ID only if tagset does not have same yet. Returns true if it added.

func (TagsetRaw) BirthTime added in v1.4.0

func (ts TagsetRaw) BirthTime() time.Time

BirthTime returns file access timestamp of nested into package file. times.Timespec implementation.

func (TagsetRaw) ChangeTime added in v1.4.0

func (ts TagsetRaw) ChangeTime() time.Time

ChangeTime returns file change timestamp of nested into package file. times.Timespec implementation.

func (TagsetRaw) Del added in v1.4.0

func (ts TagsetRaw) Del(tid TID) TagsetRaw

Del deletes tag with given ID. Signature helps to build the call chain.

func (TagsetRaw) DelOk added in v1.6.0

func (ts TagsetRaw) DelOk(tid TID) (TagsetRaw, bool)

DelOk deletes tag with given ID. Returns true if tagset was modified.

func (TagsetRaw) Get added in v1.4.0

func (ts TagsetRaw) Get(tid TID) (TagRaw, bool)

GetTag returns TagRaw with given identifier. If tag is not found, slice content is broken, returns false.

func (TagsetRaw) Has added in v1.4.0

func (ts TagsetRaw) Has(tid TID) bool

Has checks existence of tag with given ID.

func (TagsetRaw) HasBirthTime added in v1.4.0

func (ts TagsetRaw) HasBirthTime() bool

HasBirthTime is times.Timespec interface implementation. Returns whether birth timestamp is present.

func (TagsetRaw) HasChangeTime added in v1.4.0

func (ts TagsetRaw) HasChangeTime() bool

HasChangeTime is times.Timespec interface implementation. Returns whether change timestamp is present.

func (TagsetRaw) Info added in v1.4.0

func (ts TagsetRaw) Info() (fs.FileInfo, error)

Info returns the FileInfo for the file or subdirectory described by the entry. fs.DirEntry interface implementation.

func (TagsetRaw) IsDir added in v1.4.0

func (ts TagsetRaw) IsDir() bool

IsDir detects that object presents a directory. Directory can not have file ID. fs.FileInfo implementation.

func (TagsetRaw) Iterator added in v1.4.0

func (ts TagsetRaw) Iterator() TagsetIterator

Iterator clones this tagset to iterate through all tags.

func (TagsetRaw) ModTime added in v1.4.0

func (ts TagsetRaw) ModTime() time.Time

ModTime returns file modification timestamp of nested into package file. fs.FileInfo & times.Timespec implementation.

func (TagsetRaw) Mode added in v1.4.0

func (ts TagsetRaw) Mode() fs.FileMode

Mode is for fs.FileInfo interface compatibility.

func (TagsetRaw) Name added in v1.4.0

func (ts TagsetRaw) Name() string

Name returns base name of nested into package file. fs.FileInfo implementation.

func (TagsetRaw) Num added in v1.4.0

func (ts TagsetRaw) Num() (n int)

Num returns number of tags in tagset.

func (TagsetRaw) Path added in v1.4.0

func (ts TagsetRaw) Path() string

Path returns path of nested into package file. Path required to be present in any tagset.

func (TagsetRaw) Pos added in v1.4.0

func (ts TagsetRaw) Pos() (offset, size uint)

Pos returns file offset and file size in package. Those values required to be present in any tagset.

func (TagsetRaw) Put added in v1.4.0

func (ts TagsetRaw) Put(tid TID, tag TagRaw) TagsetRaw

Put appends new tag to tagset. Can be used in chain calls at initialization.

func (TagsetRaw) Set added in v1.4.0

func (ts TagsetRaw) Set(tid TID, tag TagRaw) TagsetRaw

Set replaces tag with given ID and equal size, or appends it to tagset. Signature helps to build the call chain.

func (TagsetRaw) SetOk added in v1.6.0

func (ts TagsetRaw) SetOk(tid TID, tag TagRaw) (TagsetRaw, bool)

SetOk replaces tag with given ID and equal size, or appends it to tagset. Returns true if new one added.

func (TagsetRaw) Size added in v1.4.0

func (ts TagsetRaw) Size() int64

Size returns size of nested into package file. fs.FileInfo implementation.

func (TagsetRaw) Sys added in v1.4.0

func (ts TagsetRaw) Sys() interface{}

Sys is for fs.FileInfo interface compatibility.

func (TagsetRaw) TagBool added in v1.4.0

func (ts TagsetRaw) TagBool(tid TID) (bool, bool)

TagBool is boolean tag getter.

func (TagsetRaw) TagByte added in v1.4.0

func (ts TagsetRaw) TagByte(tid TID) (byte, bool)

TagByte tag getter.

func (TagsetRaw) TagNumber added in v1.4.0

func (ts TagsetRaw) TagNumber(tid TID) (float64, bool)

TagNumber is 64-bit float tag getter.

func (TagsetRaw) TagStr added in v1.4.0

func (ts TagsetRaw) TagStr(tid TID) (string, bool)

TagStr tag getter.

func (TagsetRaw) TagTime added in v1.4.0

func (ts TagsetRaw) TagTime(tid TID) (time.Time, bool)

TagTime is time tag getter.

func (TagsetRaw) TagUint added in v1.4.0

func (ts TagsetRaw) TagUint(tid TID) (uint, bool)

TagUint is unspecified size unsigned int tag getter.

func (TagsetRaw) TagUint16 added in v1.4.0

func (ts TagsetRaw) TagUint16(tid TID) (uint16, bool)

TagUint16 is 16-bit unsigned int tag getter. Conversion can be used to get signed 16-bit integers.

func (TagsetRaw) TagUint32 added in v1.4.0

func (ts TagsetRaw) TagUint32(tid TID) (uint32, bool)

TagUint32 is 32-bit unsigned int tag getter. Conversion can be used to get signed 32-bit integers.

func (TagsetRaw) TagUint64 added in v1.4.0

func (ts TagsetRaw) TagUint64(tid TID) (uint64, bool)

TagUint64 is 64-bit unsigned int tag getter. Conversion can be used to get signed 64-bit integers.

func (TagsetRaw) TagUnixms added in v1.6.0

func (ts TagsetRaw) TagUnixms(tid TID) (int64, bool)

TagUnixms is UNIX time in milliseconds tag getter.

func (TagsetRaw) Type added in v1.4.0

func (ts TagsetRaw) Type() fs.FileMode

Type is for fs.DirEntry interface compatibility.

type Union added in v1.4.0

type Union struct {
	List []*Package
}

Union glues list of packages into single filesystem.

func (*Union) AllKeys added in v1.4.0

func (u *Union) AllKeys() (res []string)

AllKeys returns list of all accessible files in union of packages. If union have more than one file with the same name, only first entry will be included to result.

func (*Union) Close added in v1.4.0

func (u *Union) Close() (err error)

Close call Close-function for all included into the union packages. io.Closer implementation.

func (*Union) Glob added in v1.4.0

func (u *Union) Glob(pattern string) (res []string, err error)

Glob returns the names of all files in union matching pattern or nil if there is no matching file.

func (*Union) Open added in v1.4.0

func (u *Union) Open(dir string) (fs.File, error)

Open implements access to nested into union of packages file or directory by keyname. If union have more than one file with the same name, first will be returned. fs.FS implementation.

func (*Union) ReadDir added in v1.4.0

func (u *Union) ReadDir(dir string) ([]fs.DirEntry, error)

ReadDir reads the named directory and returns a list of directory entries sorted by filename. fs.ReadDirFS interface implementation.

func (*Union) ReadDirN added in v1.4.0

func (u *Union) ReadDirN(dir string, n int) (list []fs.DirEntry, err error)

ReadDir reads the named directory and returns a list of directory entries sorted by filename.

func (*Union) ReadFile added in v1.4.0

func (u *Union) ReadFile(fpath string) ([]byte, error)

ReadFile returns slice with nested into union of packages file content. If union have more than one file with the same name, first will be returned. fs.ReadFileFS implementation.

func (*Union) Stat added in v1.4.0

func (u *Union) Stat(fpath string) (fs.FileInfo, error)

Stat returns a fs.FileInfo describing the file. If union have more than one file with the same name, info of the first will be returned. fs.StatFS implementation.

func (*Union) Sub added in v1.4.0

func (u *Union) Sub(dir string) (fs.FS, error)

Sub clones object and gives access to pointed subdirectory. fs.SubFS implementation.

type UnionDir added in v1.4.0

type UnionDir struct {
	TagsetRaw
	*Union
}

UnionDir is helper to get access to union directories, that contains files from all packages with same dir if it present.

func (*UnionDir) Close added in v1.4.0

func (f *UnionDir) Close() error

fs.ReadDirFile interface implementation.

func (*UnionDir) Read added in v1.4.0

func (f *UnionDir) Read([]byte) (int, error)

fs.ReadDirFile interface implementation.

func (*UnionDir) ReadDir added in v1.4.0

func (f *UnionDir) ReadDir(n int) ([]fs.DirEntry, error)

fs.ReadDirFile interface implementation.

func (*UnionDir) Stat added in v1.4.0

func (f *UnionDir) Stat() (fs.FileInfo, error)

fs.ReadDirFile interface implementation.

type Void added in v1.4.0

type Void = struct{}

Void is empty structure to release of the set of keys.

type WriteSeekCloser added in v1.3.0

type WriteSeekCloser interface {
	io.Writer
	io.Seeker
	io.Closer
}

WriteSeekCloser is typical useful interface for package writing.

Directories

Path Synopsis
This code prints current time in ISO 8601 format.
This code prints current time in ISO 8601 format.
util

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL