blob

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 24, 2021 License: MIT Imports: 4 Imported by: 5

README

blob

Create Doom style blob files that combine multiple binary blobs into a single file.

The format is as simple as possible, first there is a header that gives each blob a string ID. Then comes the data.

You can create new blobs programmatically (blob.New) and save them to a file (Blob.Write) in a preprocessing step. Later in your program you can read the file (blob.Read) and access the data by their string ID (Blob.GetByID).

If creating a single file is not enough for you, check out bin2go which can take that file and make it into a Go file with a byte array that you can then compile and blob.Read. No more files to deploy, no filepath problems.

Documentation

See the GoDoc for this package for a reference of the API. It is kept minimal for ease of use.

Documentation

Index

Constants

View Source
const MaxIDLen = 65535

MaxIDLen is the maximum number of bytes in an ID if you want to be able to Write it. If any of the IDs is longer than MaxIDLen, Write will fail.

Variables

This section is empty.

Functions

This section is empty.

Types

type Blob

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

Blob is an in-memory data buffer, matching string IDs to byte slices (blobs).

func New

func New() *Blob

New creates an empty blob. You can add data to it using Append. After adding all resources, you can call Write to write it to a file for example.

func Read

func Read(r io.Reader) (*Blob, error)

Read reads a binary blob from the given reader, keeping all data in memory. If an error occurs, the returned blob will be nil. See Write for a description of the data format.

func (*Blob) Append

func (b *Blob) Append(id string, data []byte)

Append adds the given data at the end of the blob.

func (*Blob) GetByID

func (b *Blob) GetByID(id string) (data []byte, found bool)

GetByID searches the blob for an entry with the given ID and returns the first one found. If there is no entry with the given ID, data will be nil and found will be false.

func (*Blob) GetByIndex

func (b *Blob) GetByIndex(i int) (data []byte, found bool)

GetByIndex returns the data of the entry at index i. If the index is out of bounds, data will be nil and found will be false. Call ItemCount for the number of items.

func (Blob) GetIDAtIndex

func (h Blob) GetIDAtIndex(i int) string

GetIDAtIndex returns the ID of the entry at index i or the empty string if the given index is out of bounds. Call ItemCount for the number of items.

func (Blob) ItemCount

func (h Blob) ItemCount() int

ItemCount returns the number of blob items, i.e. pairs of string IDs and byte slices. When using GetIDAtIndex or GetByIndex, valid inidices range from 0 to ItemCount()-1.

func (*Blob) Write

func (b *Blob) Write(w io.Writer) (err error)

Write writes the whole binary blob to the given writer. The format is as follows, all numbers are encoded in little endian byte order:

uint32: Header length in bytes, of the header starting after this number
loop, this is the header data {
  uint16: ID length in bytes, length of the following ID
  string: ID, UTF-8 encoded
  uint64: data length in bytes, of the data associated with this ID
}
[]byte: after the header all data is stored back-to-back

Write will fail if any of the IDs has a length of more than MaxIDLen bytes, since this can not be represented in the above format (uint16 is used for the ID string's length).

Note that the header does not store offsets into the data explicitly, it only stores the length of each item so the offset can be computed from the cumulative sum of all data lengths of items that come before it.

type BlobReader

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

BlobReader is an out-of-memory data buffer, matching string IDs to byte slices (blobs).

func Open

func Open(r io.ReadSeeker) (*BlobReader, error)

Open opens a blob and reads the header without reading the data (unlike Read) which means that the data is not kept in memory. Calling GetByID or GetByIndex returns a io.ReadSeeker that can be used to read the data. Note that all data blob readers access the same underlying io.ReadSeeker r, the one that you pass to Open. Thus you must be careful not to read from two locations in r at the same time.

Example:

b, _ := blob.Open(file)
r1, _ := b.GetByIndex(0)
r2, _ := b.GetByIndex(1)

In this example it is safe to read consecutively from r1 and r2, e.g. reading one byte from r1, then one byte from r2, then again one byte from r1, etc. You can not, however, read from r1 and r2 in parallel, e.g. in two different Go routines since the underlying io.ReadSeeker is the same for both and in each Read on r1 and r2, the position of r is set before reading.

func (*BlobReader) GetByID

func (b *BlobReader) GetByID(id string) (r io.ReadSeeker, found bool)

GetByID searches the blob for an entry with the given ID and returns the first one found. If there is no entry with the given ID, r will be nil and found will be false.

func (*BlobReader) GetByIndex

func (b *BlobReader) GetByIndex(i int) (r io.ReadSeeker, found bool)

GetByIndex returns the data of the entry at index i. If the index is out of bounds, r will be nil and found will be false. See ItemCount for the number of items.

func (BlobReader) GetIDAtIndex

func (h BlobReader) GetIDAtIndex(i int) string

GetIDAtIndex returns the ID of the entry at index i or the empty string if the given index is out of bounds. Call ItemCount for the number of items.

func (BlobReader) ItemCount

func (h BlobReader) ItemCount() int

ItemCount returns the number of blob items, i.e. pairs of string IDs and byte slices. When using GetIDAtIndex or GetByIndex, valid inidices range from 0 to ItemCount()-1.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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