bimime

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2026 License: MIT Imports: 10 Imported by: 1

README

bimime

bimime is a Go package for detecting Bi ecosystem file types by path hint, magic bytes, and lightweight text checks. It covers Real Virtuality and Enfusion engine formats, plus common modding files such as configs, scripts, assets, localization tables, project/workbench files, and diagnostics/crash artifacts.

Detection Profiles

  • fast: path/extension only, no content read.
  • normal: extension + magic when needed by plan/extension.
  • strict: normal + validation checks: extension/magic mismatch, text-likeness, content patterns.

Advanced Plans

  • Analyze supports per-extension AnalyzePlan overrides.
  • Use AnalyzeMatchExtensionMagic for targeted forced magic probing on selected extensions (for example wrp, p3d, rvmat, bisurf).
  • For batch processing, prefer Analyzer to reuse normalized config.

Usage

result, err := bimime.AnalyzeFile(
    bimime.BIAmbiguousRAPOptions("terrain.wrp", nil),
)
if err != nil {
    return err
}

fmt.Println(result.Probe.Resolved.ID)
analyzer := bimime.NewAnalyzer(bimime.AnalyzeOptions{
    DefaultPlan:      bimime.PlanFast(),
    PlansByExtension: bimime.BIAmbiguousRAPOverrides(),
})

result, err := analyzer.AnalyzeFile("terrain.wrp")
if err != nil {
    return err
}

fmt.Println(result.Probe.Resolved.ID)

Equivalent explicit options:

result, err := bimime.AnalyzeFile(bimime.AnalyzeOptions{
    Path: "terrain.wrp",
    DefaultPlan:      bimime.PlanFast(),
    PlansByExtension: bimime.BIAmbiguousRAPOverrides(),
})
if err != nil {
    return err
}

fmt.Println(result.Probe.Resolved.ID)
result, err := bimime.AnalyzeFile(bimime.AnalyzeOptions{
    Path: "x.png",
    DefaultPlan: bimime.PlanNormal(),
})
if err != nil {
    return err
}

result = bimime.Analyze(bimime.AnalyzeOptions{
    Path:   "script.sqf",
    Prefix: dataPrefix,
    DefaultPlan: bimime.PlanNormal(),
    PlansByExtension: map[string]bimime.AnalyzePlan{
        "sqf": {
            Match:    bimime.AnalyzeMatchExtensionMagicNeeded,
            Validate: bimime.AnalyzeValidateStrict,
        },
    },
})

Behavior Notes

  • NeedsContent decides whether prefix bytes are required.
  • AnalyzeReader reads only a prefix, not whole payload.
  • AnalyzeFile opens file and reads only required prefix bytes.
  • Probe resolves type by extension and magic bytes.
  • strict without payload prefix returns insufficient_content.

Documentation

Overview

Package bimime provides a unified registry of BI game file types with MIME names, descriptions, binary/text hints, extension/path matching, and magic-byte probing.

Use Analyze/AnalyzeReader/AnalyzeFile with AnalyzeOptions and AnalyzePlan:

  • extension-only matching for fast path.
  • extension+magic when content is needed.
  • strict validation when consistency checks are required.
  • extension-specific plan overrides for mixed corpora.
  • fast + forced magic for ambiguous RAP-like extensions via BIAmbiguousRAPOptions.
  • Analyzer for repeated calls with reused normalized config.

Magic-byte detection is considered more reliable than extension-only detection. Use Probe when both filename and payload prefix are available.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNilReader is returned when AnalyzeReader receives nil reader.
	ErrNilReader = errors.New("nil reader")
)

Functions

func BIAmbiguousRAPExtensions added in v0.2.0

func BIAmbiguousRAPExtensions() []string

BIAmbiguousRAPExtensions returns default extension set for fast mode with forced magic probing for BI formats that can appear as source or binarized.

func BIAmbiguousRAPOverrides added in v0.2.0

func BIAmbiguousRAPOverrides() map[string]AnalyzePlan

BIAmbiguousRAPOverrides returns extension overrides for the common "fast + forced magic for ambiguous BI formats" scenario.

func HasMagic

func HasMagic(typeID string) bool

HasMagic reports whether a registered type has at least one magic signature.

func IsRAP

func IsRAP(prefix []byte) bool

IsRAP reports whether payload starts with RAP magic bytes.

func NeedsContent

func NeedsContent(options AnalyzeOptions) bool

NeedsContent reports whether selected plan requires payload prefix bytes.

Types

type AnalyzeIssue

type AnalyzeIssue string

AnalyzeIssue describes a strict-mode validation problem.

const (
	// AnalyzeIssueMagicMismatch means extension/path hint conflicts with magic.
	AnalyzeIssueMagicMismatch AnalyzeIssue = "magic_mismatch"
	// AnalyzeIssueTextExpected means detected text payload looks binary.
	AnalyzeIssueTextExpected AnalyzeIssue = "text_expected"
	// AnalyzeIssueInsufficientContent means strict checks require payload prefix.
	AnalyzeIssueInsufficientContent AnalyzeIssue = "insufficient_content"
	// AnalyzeIssueContentPatternMismatch means payload does not match expected
	// content markers for resolved type in strict mode.
	AnalyzeIssueContentPatternMismatch AnalyzeIssue = "content_pattern_mismatch"
)

Strict-mode issues.

type AnalyzeMatchMode added in v0.2.0

type AnalyzeMatchMode uint8

AnalyzeMatchMode controls how detection match is performed.

const (
	// AnalyzeMatchDefault falls back to extension+magic-as-needed behavior.
	AnalyzeMatchDefault AnalyzeMatchMode = iota
	// AnalyzeMatchExtension resolves only by path hint (filename/extension).
	AnalyzeMatchExtension
	// AnalyzeMatchExtensionMagicNeeded resolves by extension+magic, reading
	// content only when needed by extension heuristics.
	AnalyzeMatchExtensionMagicNeeded
	// AnalyzeMatchExtensionMagic resolves by extension+magic and expects magic
	// probing to be available for selected targets.
	AnalyzeMatchExtensionMagic
)

Analyze match modes.

type AnalyzeOptions

type AnalyzeOptions struct {
	// PlansByExtension maps extension (without dot) to per-extension plan.
	PlansByExtension map[string]AnalyzePlan `json:"plans_by_extension,omitempty" yaml:"plans_by_extension,omitempty"`
	// Path is filesystem path or filename hint used for extension matching.
	Path string `json:"path,omitempty" yaml:"path,omitempty"`
	// Prefix is optional payload prefix already available to caller.
	Prefix []byte `json:"prefix,omitempty" yaml:"prefix,omitempty"`
	// PrefixSize limits bytes read from reader/file for magic and text checks.
	// Zero or negative value uses the package default.
	PrefixSize int `json:"prefix_size,omitempty" yaml:"prefix_size,omitempty"`
	// DefaultPlan is used when no extension-specific override is configured.
	DefaultPlan AnalyzePlan `json:"default_plan" yaml:"default_plan"`
}

AnalyzeOptions controls Analyze/AnalyzeReader/AnalyzeFile behavior.

func BIAmbiguousRAPOptions added in v0.2.0

func BIAmbiguousRAPOptions(path string, prefix []byte) AnalyzeOptions

BIAmbiguousRAPOptions builds Analyze options for the common scenario: fast by default and forced magic probing for p3d/wrp/rvmat/bisurf.

type AnalyzePlan added in v0.2.0

type AnalyzePlan struct {
	// Match controls extension-only vs extension+magic probing behavior.
	Match AnalyzeMatchMode `json:"match,omitempty" yaml:"match,omitempty"`
	// Validate controls whether strict validation checks are applied.
	Validate AnalyzeValidateMode `json:"validate,omitempty" yaml:"validate,omitempty"`
}

AnalyzePlan describes how one file should be matched and validated.

func PlanFast added in v0.2.0

func PlanFast() AnalyzePlan

PlanFast returns extension-only matching with no strict validation.

func PlanNormal added in v0.2.0

func PlanNormal() AnalyzePlan

PlanNormal returns extension+magic-as-needed matching with no strict checks.

func PlanStrict added in v0.2.0

func PlanStrict() AnalyzePlan

PlanStrict returns extension+magic-as-needed matching with strict checks.

type AnalyzeResult

type AnalyzeResult struct {
	// Issues contains strict-mode validation issues.
	Issues []AnalyzeIssue `json:"issues,omitempty" yaml:"issues,omitempty"`
	// Probe contains extension/magic matches and resolved final type.
	Probe ProbeResult `json:"probe" yaml:"probe"`
	// Plan is effective plan after option normalization and extension overrides.
	Plan AnalyzePlan `json:"plan" yaml:"plan"`
	// Valid is true when strict validation passed or was not requested.
	Valid bool `json:"valid" yaml:"valid"`
	// CheckedMagic reports whether strict mode validated extension against magic.
	CheckedMagic bool `json:"checked_magic,omitempty" yaml:"checked_magic,omitempty"`
	// CheckedText reports whether strict mode validated text-like payload.
	CheckedText bool `json:"checked_text,omitempty" yaml:"checked_text,omitempty"`
	// CheckedContentPattern reports whether strict mode validated type-specific
	// content regex markers.
	CheckedContentPattern bool `json:"checked_content_pattern,omitempty" yaml:"checked_content_pattern,omitempty"`
	// LooksText reports quick text-likeness heuristic result when CheckedText is true.
	LooksText bool `json:"looks_text,omitempty" yaml:"looks_text,omitempty"`
}

AnalyzeResult stores classification and validation outcome.

func Analyze

func Analyze(options AnalyzeOptions) AnalyzeResult

Analyze classifies path/prefix pair according to extension-aware plans.

func AnalyzeFile

func AnalyzeFile(options AnalyzeOptions) (AnalyzeResult, error)

AnalyzeFile classifies file path and reads only required prefix bytes.

func AnalyzeReader

func AnalyzeReader(reader io.Reader, options AnalyzeOptions) (AnalyzeResult, error)

AnalyzeReader classifies path using selected plans and optional reader.

type AnalyzeValidateMode added in v0.2.0

type AnalyzeValidateMode uint8

AnalyzeValidateMode controls whether strict validations are applied.

const (
	// AnalyzeValidateDefault falls back to no strict validation.
	AnalyzeValidateDefault AnalyzeValidateMode = iota
	// AnalyzeValidateNone disables strict validation checks.
	AnalyzeValidateNone
	// AnalyzeValidateStrict enables strict consistency and text checks.
	AnalyzeValidateStrict
)

Analyze validation modes.

type Analyzer added in v0.2.0

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

Analyzer stores normalized analyze configuration for repeated calls.

func NewAnalyzer added in v0.2.0

func NewAnalyzer(options AnalyzeOptions) Analyzer

NewAnalyzer builds analyzer from options and normalizes plan declarations.

func (Analyzer) Analyze added in v0.2.0

func (analyzer Analyzer) Analyze(path string, prefix []byte) AnalyzeResult

Analyze classifies path/prefix pair according to analyzer plan.

func (Analyzer) AnalyzeFile added in v0.2.0

func (analyzer Analyzer) AnalyzeFile(path string) (AnalyzeResult, error)

AnalyzeFile classifies file path and reads only required prefix bytes.

func (Analyzer) AnalyzeReader added in v0.2.0

func (analyzer Analyzer) AnalyzeReader(path string, reader io.Reader) (AnalyzeResult, error)

AnalyzeReader classifies path using analyzer and optional reader.

func (Analyzer) NeedsContent added in v0.2.0

func (analyzer Analyzer) NeedsContent(path string) bool

NeedsContent reports whether payload prefix is required for this path.

type ProbeResult

type ProbeResult struct {
	// Source shows which signals produced the result.
	Source Source `json:"source" yaml:"source"`
	// Extension is normalized extension used for extension lookup.
	Extension string `json:"extension,omitempty" yaml:"extension,omitempty"`
	// Resolved is final selected type (magic has priority over extension).
	Resolved Type `json:"resolved" yaml:"resolved"`
	// ByMagic is magic-based type when matched.
	ByMagic Type `json:"by_magic" yaml:"by_magic"`
	// ByExtension is path-hint type when matched (well-known filename or extension).
	ByExtension Type `json:"by_extension" yaml:"by_extension"`
}

ProbeResult contains extension and magic matches with resolved final type.

func Probe

func Probe(path string, prefix []byte) ProbeResult

Probe resolves by both path hint and magic; magic match has priority.

type Source

type Source string

Source describes how detection result was obtained.

const (
	// SourceUnknown means no known extension/magic was matched.
	SourceUnknown Source = "unknown"
	// SourceExtension means only path hint matched (well-known filename or extension).
	SourceExtension Source = "extension"
	// SourceMagic means only magic bytes matched.
	SourceMagic Source = "magic"
	// SourceMagicAndExtension means both extension and magic matched.
	SourceMagicAndExtension Source = "magic+extension"
)

Detection sources.

type Type

type Type struct {
	// ID is stable internal identifier (e.g. "bi.rap").
	ID string `json:"id" yaml:"id"`
	// MIME is canonical MIME value for the type.
	MIME string `json:"mime" yaml:"mime"`
	// Description is detailed human-readable type description.
	Description string `json:"description" yaml:"description"`
	// ShortDescription is compact description for UIs with narrow columns.
	ShortDescription string `json:"short_description,omitempty" yaml:"short_description,omitempty"`
	// Extensions lists mapped extensions without a leading dot.
	Extensions []string `json:"extensions,omitempty" yaml:"extensions,omitempty"`
	// Binary reports whether payload should be treated as binary by default.
	Binary bool `json:"binary" yaml:"binary"`
}

Type describes one known file type from registry.

func Detect

func Detect(path string, prefix []byte) Type

Detect returns final resolved type for given filename and payload prefix.

func DetectByExtension

func DetectByExtension(path string) (Type, bool)

DetectByExtension resolves type by path hint only (well-known filename/extension).

func DetectByMagic

func DetectByMagic(prefix []byte) (Type, bool)

DetectByMagic resolves type only by payload magic bytes.

func Lookup

func Lookup(id string) (Type, bool)

Lookup finds one type by stable id.

func Registry

func Registry() []Type

Registry returns all registered game types.

func UnknownType

func UnknownType() Type

UnknownType returns a copy of fallback type used for no-match cases.

Jump to

Keyboard shortcuts

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