### Install Mimetype Go Library Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/README.md Use 'go get' to install the library. This command fetches and installs the specified package and its dependencies. ```bash go get github.com/gabriel-vasile/mimetype ``` -------------------------------- ### Example Usage of DetectFile Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-main.md Demonstrates how to use DetectFile to get the MIME type, extension, and parent type of a PDF file. ```go package main import ( "fmt" "github.com/gabriel-vasile/mimetype" ) func main() { mtype, err := mimetype.DetectFile("/path/to/document.pdf") if err != nil { fmt.Println("Error:", err) return } fmt.Println(mtype.String()) fmt.Println(mtype.Extension()) fmt.Println(mtype.Parent()) } ``` -------------------------------- ### Install Mimetype Package Source: https://github.com/gabriel-vasile/mimetype/blob/master/README.md Use this command to install the mimetype package for your Go project. ```bash go get github.com/gabriel-vasile/mimetype ``` -------------------------------- ### Example Usage of SetLimit Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/configuration.md Demonstrates detecting MIME types with default, increased, and unlimited read limits. Resets to default after use. ```go package main import ( "github.com/gabriel-vasile/mimetype" ) func main() { // Detect with default 4KB limit mtype, _ := mimetype.DetectFile("image.png") println(mtype.String()) // Increase limit to 1MB for Office documents mimetype.SetLimit(1024 * 1024) mtype, _ = mimetype.DetectFile("document.docx") println(mtype.String()) // Use entire file for detection (slower, more memory) mimetype.SetLimit(0) mtype, _ = mimetype.DetectFile("unknown.bin") println(mtype.String()) // Reset to default mimetype.SetLimit(4096) } ``` -------------------------------- ### Limited Search Example Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Searches for a specific byte pattern within the first 1KB of the input byte slice. ```go func(raw []byte, limit uint32) bool { // Search only in first 1KB searchLimit := min(len(raw), 1024) return bytes.Contains(raw[:searchLimit], []byte("pattern")) } ``` -------------------------------- ### Example Usage with Detection Limit Source: https://github.com/gabriel-vasile/mimetype/blob/master/README.md Demonstrates how to set a detection limit before attempting to detect a file's MIME type. This is useful for files with signatures located deep within the content. ```go mimetype.SetLimit(1024*1024) // Set limit to 1MB. // or mimetype.SetLimit(0) // No limit, whole file content used. mimetype.DetectFile("file.doc") ``` -------------------------------- ### Core Package-Level Functions Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/DOCUMENTATION-SUMMARY.txt Documentation for the 7 core package-level functions, including signatures, parameters, return values, and code examples. ```APIDOC ## Package Functions ### Detect() ### Description Detects the MIME type of a given byte slice. ### Function Signature `func Detect(data []byte) *MIME ` ### Parameters - `data` ([]byte) - The byte slice to analyze. ### Return Value - `*MIME` - A pointer to the detected MIME type. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" data := []byte{0x1f, 0x8b, 0x08, 0x00} mimeType := mimetype.Detect(data) ``` ### Response Example ```json { "type": "application/gzip", "extension": "gz", "parent": "application", "is": "gzip" } ``` --- ### DetectReader() ### Description Detects the MIME type of data from an `io.Reader`. ### Function Signature `func DetectReader(reader io.Reader) (*MIME, error) ` ### Parameters - `reader` (io.Reader) - The reader to analyze. ### Return Value - `*MIME` - A pointer to the detected MIME type. - `error` - An error if detection fails. ### Request Example ```go import ( "bytes" "github.com/gabriel-vasile/mimetype" ) reader := bytes.NewReader([]byte{0x89, 0x50, 0x4e, 0x47}) mimeType, err := mimetype.DetectReader(reader) ``` ### Response Example ```json { "type": "image/png", "extension": "png", "parent": "image", "is": "png" } ``` --- ### DetectFile() ### Description Detects the MIME type of a file. ### Function Signature `func DetectFile(filePath string) (*MIME, error) ` ### Parameters - `filePath` (string) - The path to the file. ### Return Value - `*MIME` - A pointer to the detected MIME type. - `error` - An error if detection fails. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" mimeType, err := mimetype.DetectFile("/path/to/your/file.jpg") ``` ### Response Example ```json { "type": "image/jpeg", "extension": "jpg", "parent": "image", "is": "jpeg" } ``` --- ### SetLimit() ### Description Sets the global read limit for detection. ### Function Signature `func SetLimit(limit int64) ` ### Parameters - `limit` (int64) - The maximum number of bytes to read for detection. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" mimetype.SetLimit(1024) ``` --- ### Extend() ### Description Extends the MIME type database with custom types. ### Function Signature `func Extend(customTypes ...*MIME) ` ### Parameters - `customTypes` ([]*MIME) - A variadic list of custom MIME types to add. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" customMime := &mimetype.MIME{ Type: "application/x-custom", Extension: "custom", Parent: "application", SubMime: []string{"x-custom"}, Signature: []byte{0x01, 0x02, 0x03}, } mimetype.Extend(customMime) ``` --- ### EqualsAny() ### Description Checks if a MIME type is equal to any of the provided types. ### Function Signature `func EqualsAny(mime *MIME, types ...string) bool ` ### Parameters - `mime` (*MIME) - The MIME type to check. - `types` ([]string) - A variadic list of MIME type strings to compare against. ### Return Value - `bool` - True if the MIME type matches any of the provided types, false otherwise. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" mime := mimetype.Detect([]byte("some data")) isImage := mimetype.EqualsAny(mime, "image/jpeg", "image/png") ``` --- ### Lookup() ### Description Looks up a MIME type by its string representation. ### Function Signature `func Lookup(mime string) *MIME ` ### Parameters - `mime` (string) - The MIME type string to look up. ### Return Value - `*MIME` - A pointer to the MIME type if found, otherwise nil. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" jpegMime := mimetype.Lookup("image/jpeg") ``` ``` -------------------------------- ### Example Usage of SetLimit Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-main.md Shows how to set the read limit for MIME type detection, including setting it to unlimited for specific file types like Office documents. ```go package main import ( "github.com/gabriel-vasile/mimetype" ) func main() { // Set limit to 1MB mimetype.SetLimit(1024 * 1024) // For Office documents, might need unlimited mimetype.SetLimit(0) // Detect files with the new limit mtype, err := mimetype.DetectFile("document.docx") if err != nil { panic(err) } println(mtype.String()) } ``` -------------------------------- ### Registering and Using a Custom MIME Type Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-main.md Example demonstrating how to define a custom detector function for a specific byte signature and register it using the Extend function. It then shows how to detect a file with this custom signature. ```go package main import ( "bytes" "github.com/gabriel-vasile/mimetype" ) func main() { // Define detector for custom format with "MYFORMAT" signature customDetector := func(raw []byte, limit uint32) bool { return bytes.HasPrefix(raw, []byte("MYFORMAT")) } // Register the custom type mimetype.Extend(customDetector, "application/x-myformat", ".myf") // Now detection works mtype := mimetype.Detect([]byte("MYFORMAT some data")) println(mtype.String()) // application/x-myformat println(mtype.Extension()) // .myf } ``` -------------------------------- ### Byte Count Validation Example Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Validates if the byte slice meets a minimum length and checks for the 'MZ' prefix, commonly found in executable files. ```go func(raw []byte, limit uint32) bool { if len(raw) < 4 { return false } return bytes.HasPrefix(raw, []byte("MZ")) } ``` -------------------------------- ### Example Usage of MIME Detection Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/types.md Demonstrates how to use the Detect function to identify a MIME type from byte input and access its properties like string representation, extension, and parent type. Also shows how to perform type checking. ```go package main import ( "fmt" "github.com/gabriel-vasile/mimetype" ) func main() { // Detect returns a *MIME detected := mimetype.Detect([]byte("")) // Access MIME properties fmt.Println(detected.String()) // text/xml fmt.Println(detected.Extension()) // .xml // Check parent hierarchy parent := detected.Parent() if parent != nil { fmt.Println(parent.String()) // text/plain } // Type checking if detected.Is("text/xml") { fmt.Println("Is XML") } } ``` -------------------------------- ### Check MIME Type with Is Method Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/usage-examples.md This example shows how to use the `Is` method to check if a detected MIME type matches a specific type or one of its ancestors. It's useful for conditional processing. ```go package main import ( "fmt" "github.com/gabriel-vasile/mimetype" ) func processFile(data []byte) { mtype := mimetype.Detect(data) if mtype.Is("application/json") { fmt.Println("Processing as JSON") } else if mtype.Is("text/xml") { fmt.Println("Processing as XML") } else if mtype.Is("text/plain") { fmt.Println("Processing as plain text") } else { fmt.Println("Unknown format:", mtype.String()) } } func main() { json := []byte("{\"key\": \"value\"}") processFile(json) } ``` -------------------------------- ### Add Custom Format Detection Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/usage-examples.md Register a new detector for a custom binary format. This example shows how to define a detector function and register it at the root level of the mimetype library. ```go package main import ( "bytes" "fmt" "github.com/gabriel-vasile/mimetype" ) func main() { // Define a detector for a custom binary format // Signature: "CUSTOMFMT" at start of file customDetector := func(raw []byte, limit uint32) bool { return bytes.HasPrefix(raw, []byte("CUSTOMFMT")) } // Register the custom format at root level mimetype.Extend(customDetector, "application/x-customfmt", ".cfmt") // Now detection works for custom format customData := []byte("CUSTOMFMT version 1.0") mtype := mimetype.Detect(customData) fmt.Println(mtype.String()) fmt.Println(mtype.Extension()) } ``` -------------------------------- ### Public MIME Type Methods Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/DOCUMENTATION-SUMMARY.txt Documentation for the 5 public methods available on the MIME type struct, including signatures and usage examples. ```APIDOC ## MIME Type Methods ### String() ### Description Returns the string representation of the MIME type. ### Method Signature `func (m *MIME) String() string ` ### Return Value - `string` - The MIME type string (e.g., "text/plain"). ### Request Example ```go import "github.com/gabriel-vasile/mimetype" data := []byte("Hello, World!") mime := mimetype.Detect(data) mimeString := mime.String() ``` --- ### Extension() ### Description Returns the primary file extension associated with the MIME type. ### Method Signature `func (m *MIME) Extension() string ` ### Return Value - `string` - The file extension (e.g., "txt"). ### Request Example ```go import "github.com/gabriel-vasile/mimetype" data := []byte("Some PNG data...") mime := mimetype.Detect(data) extension := mime.Extension() ``` --- ### Parent() ### Description Returns the parent type of the MIME type (e.g., "text" for "text/plain"). ### Method Signature `func (m *MIME) Parent() string ` ### Return Value - `string` - The parent type string. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" data := []byte("Some JSON data...") mime := mimetype.Detect(data) parent := mime.Parent() ``` --- ### Is() ### Description Checks if the MIME type matches a given type string or any of its aliases. ### Method Signature `func (m *MIME) Is(types ...string) bool ` ### Parameters - `types` ([]string) - A variadic list of MIME type strings or aliases to check against. ### Return Value - `bool` - True if the MIME type matches any of the provided types, false otherwise. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" data := []byte("Some XML data...") mime := mimetype.Detect(data) isXml := mime.Is("application/xml", "text/xml") ``` --- ### Extend() ### Description Extends the MIME type with additional sub-types or aliases. ### Method Signature `func (m *MIME) Extend(subMimes ...string) ` ### Parameters - `subMimes` ([]string) - A variadic list of sub-MIME type strings to add. ### Request Example ```go import "github.com/gabriel-vasile/mimetype" // Assuming 'customMime' is a previously defined *mimetype.MIME // customMime.Extend("x-custom-variant") ``` ``` -------------------------------- ### Detect JSON File Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Detects JSON files by checking if the trimmed byte slice starts with an opening brace '{' or bracket '[', common indicators of JSON structure. ```Go // Detects JSON by looking for opening brace/bracket JSON = func(raw []byte, limit uint32) bool { trimmed := bytes.TrimSpace(raw) return (bytes.HasPrefix(trimmed, []byte("{ ")) || bytes.HasPrefix(trimmed, []byte("["))) } ``` -------------------------------- ### Get MIME Type String Representation Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/INDEX.md Returns the string representation of the detected MIME type (e.g., 'application/json'). ```go mtype.String() ``` -------------------------------- ### Marker-Based Detection Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md An example detector function that searches for a specific byte marker within the input data, such as the MPEG frame sync marker for MP3 files. ```Go // MP3: search for MPEG frame sync marker MP3 := func(raw []byte, limit uint32) bool { return bytes.Contains(raw, []byte{0xFF, 0xFB}) } ``` -------------------------------- ### Extend Existing Format Detection Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/usage-examples.md Extend an existing format, like text/plain, to recognize a new custom text format. This example demonstrates adding a child type that inherits properties from its parent. ```go package main import ( "bytes" "fmt" "github.com/gabriel-vasile/mimetype" ) func main() { // Extend text/plain to recognize a custom text format customTextDetector := func(raw []byte, limit uint32) bool { return bytes.HasPrefix(raw, []byte("###MYFORMAT")) } // Add as child of text/plain textPlain := mimetype.Lookup("text/plain") textPlain.Extend(customTextDetector, "text/x-myformat", ".myf") // Detection will identify it as the custom type // with text/plain as parent data := []byte("###MYFORMAT custom text") mtype := mimetype.Detect(data) fmt.Println(mtype.String()) fmt.Println(mtype.Parent().String()) } ``` -------------------------------- ### Simple Magic Number Check Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md An example of a detector function that checks for the presence of a specific byte sequence (magic number) at the beginning of the input data, like the PNG signature. ```Go // Checks for PNG signature PNG := func(raw []byte, limit uint32) bool { return bytes.HasPrefix(raw, []byte("\x89PNG\r\n\x1a\n")) } ``` -------------------------------- ### Get Parent MIME Type Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/INDEX.md Retrieves the parent MIME type from the hierarchy, if one exists. This is useful for understanding type relationships (e.g., getting 'text/plain' from 'text/html'). ```go mtype.Parent() ``` -------------------------------- ### Get File Extension from MIME Type Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/INDEX.md Returns the common file extension associated with the detected MIME type (e.g., '.json'). ```go mtype.Extension() ``` -------------------------------- ### Programmatic Configuration Methods Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/configuration.md Shows the primary programmatic methods for configuring the mimetype library, including setting limits and extending MIME types. ```go // The only configuration method mimetype.SetLimit(uint32) // Custom formats are added via mimetype.Extend(detector, mime, extension, aliases...) // Or on specific MIME types via mimeType.Extend(detector, mime, extension, aliases...) ``` -------------------------------- ### Detect MIME type from byte slice and file Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/00-START-HERE.md Demonstrates how to detect the MIME type of data from a byte slice or a file path. Includes retrieving the string representation and file extension. ```go package main import ( "fmt" "github.com/gabriel-vasile/mimetype" ) func main() { // From byte slice mtype := mimetype.Detect([]byte("...")) fmt.Println(mtype.String()) // application/json fmt.Println(mtype.Extension()) // .json // From file mtype, err := mimetype.DetectFile("/path/to/file") if err == nil { fmt.Println(mtype.String()) } } ``` -------------------------------- ### Immediate Use After Import Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/configuration.md The mimetype library can be used immediately after importing, requiring no explicit initialization. ```go import "github.com/gabriel-vasile/mimetype" // Can be used immediately, no setup needed mtype := mimetype.Detect(data) ``` -------------------------------- ### Structure Validation Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md An example detector function that validates the structure of the input data by checking for specific headers or signatures, such as the ZIP file's central directory signature. ```Go // ZIP: validates central directory signature Zip := func(raw []byte, limit uint32) bool { // Check for PK\003\004 header if len(raw) < 4 { return false } return bytes.HasPrefix(raw, []byte("PK\003\004")) } ``` -------------------------------- ### Package Initialization: Root MIME Node Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Defines the root of the MIME type tree during package initialization. This node represents the default 'application/octet-stream' and includes all known child MIME types. ```go // In tree.go var root = newMIME( "application/octet-stream", "", func([]byte, uint32) bool { return true }, // Always matches xpm, sevenZ, zip, pdf, ... // All children ) ``` -------------------------------- ### Traverse MIME Type Hierarchy Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-mime-type.md Iterate through the parent MIME types starting from a detected type. Useful for understanding the fundamental nature of a file (e.g., text vs. binary). ```go mtype := mimetype.Detect([]byte("...")) for m := mtype; m != nil; m = m.Parent() { fmt.Println(m.String()) } ``` -------------------------------- ### Get MIME Type File Extension Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-mime-type.md The Extension method returns the file extension associated with the MIME type, including the leading dot. Returns an empty string if no extension is defined. ```go pdf := mimetype.Lookup("application/pdf") fmt.Println(pdf.Extension()) // .pdf jsonType := mimetype.Lookup("application/json") fmt.Println(jsonType.Extension()) // .json root := mimetype.Lookup("application/octet-stream") fmt.Println(root.Extension()) // (empty string) ``` -------------------------------- ### Add Simple Binary Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Register a custom detector for simple binary formats. The detector checks for a specific 8-byte signature at the beginning of the file. ```go myDetector := func(raw []byte, limit uint32) bool { // 1. Check minimum length if len(raw) < 8 { return false } // 2. Check signature return bytes.Equal(raw[:8], []byte("MYFORMAT")) } mimetype.Extend(myDetector, "application/x-myformat", ".myf") ``` -------------------------------- ### Atomic Operations for Read Limit Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Demonstrates atomic operations for loading and storing the read limit, ensuring lock-free access in concurrent scenarios. ```Go l := atomic.LoadUint32(&readLimit) ``` ```Go atomic.StoreUint32(&readLimit, limit) ``` -------------------------------- ### Print MIME Type and Extension Source: https://github.com/gabriel-vasile/mimetype/blob/master/README.md Prints the detected MIME type and its corresponding file extension. This is typically used after a successful detection. ```go fmt.Println(mtype.String(), mtype.Extension()) ``` -------------------------------- ### SetLimit with Concurrent Detections Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Shows how to safely update the detection limit while other goroutines are performing detection operations. This ensures consistency during concurrent access. ```Go // Safe: SetLimit with concurrent detections go func() { mimetype.SetLimit(1024*1024) }() go func() { mimetype.Detect(data) }() ``` -------------------------------- ### Concurrent Detection and Extension Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/configuration.md Demonstrates thread-safe operations for concurrent MIME type detection and extending the MIME type tree. ```go // All safe to call concurrently go func() { mimetype.Detect(data1) }() go func() { mimetype.Detect(data2) }() go func() { mtype := mimetype.Lookup("text/plain") mtype.Extend(customDetector, "text/custom", ".custom") }() ``` -------------------------------- ### Get MIME Type String Representation Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-mime-type.md The String method returns the full string representation of the MIME type, including optional parameters like charset. This implements the Go Stringer interface. ```go mtype := mimetype.Detect([]byte("plain text")) fmt.Println(mtype.String()) // text/plain; charset=utf-8 ``` -------------------------------- ### Extend Operation with Concurrent Detections Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Demonstrates the safe concurrent use of the Extend operation alongside detection operations. This allows adding new MIME types while the library is actively detecting others. ```Go // Safe: Extend while detecting go func() { mtype := mimetype.Lookup("text/plain") mtype.Extend(detector, "text/custom", ".custom") }() go func() { mimetype.Detect(data) }() ``` -------------------------------- ### Configure Detection Limit Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/INDEX.md Allows configuring the maximum number of bytes to read for detection. Use this to tune performance or memory usage. ```go mimetype.SetLimit(limit) ``` -------------------------------- ### Mimetype Detection Hierarchy Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Illustrates the hierarchical organization of MIME types, starting from the root 'application/octet-stream' and branching into more specific formats based on signature checks. This structure optimizes detection by narrowing down possibilities. ```plaintext application/octet-stream (root - always matches) ├── application/zip (ZIP signature check) │ ├── application/vnd.openxmlformats-officedocument.wordprocessingml.document (DOCX files in ZIP) │ ├── application/epub+zip (EPUB signature within ZIP) │ ├── application/java-archive (JAR signature within ZIP) │ └── ... (other ZIP-based formats) ├── application/pdf (PDF header check) ├── text/plain (Text detection) │ ├── text/html (HTML tag detection) │ ├── text/xml (XML tag detection) │ │ ├── application/rss+xml │ │ └── ... (other XML formats) │ └── ... (other text formats) ├── image/png (PNG magic number) ├── image/jpeg (JPEG marker check) └── ... (other formats) ``` -------------------------------- ### Goroutine-Safe SetLimit Usage Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/configuration.md Illustrates that SetLimit can be safely called from different goroutines concurrently with detection functions. ```go // Safe to use across goroutines go func() { mimetype.SetLimit(1024 * 1024) }() mtype, _ := mimetype.DetectFile("file.docx") ``` -------------------------------- ### Persistent MIME Tree Structure Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Illustrates the global variables used to maintain the MIME type tree. A single 'root' node is allocated at package init, and a mutex protects concurrent access. ```go var root *MIME // Allocated once at package init var mu sync.RWMutex // Protects access ``` -------------------------------- ### Core Package Functions Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/INDEX.md Public API entry points for MIME type detection and configuration. These functions allow detection from byte slices, readers, and files, as well as configuration of read limits and custom format extensions. ```APIDOC ## Core Package Functions ### Description Public API entry points for MIME type detection and configuration. These functions allow detection from byte slices, readers, and files, as well as configuration of read limits and custom format extensions. ### Functions - **Detect([]byte)** - Purpose: Detect MIME type from a byte slice. - Returns: `*MIME` - **DetectReader(io.Reader)** - Purpose: Detect MIME type from an io.Reader. - Returns: `(*MIME, error)` - **DetectFile(string)** - Purpose: Detect MIME type from a file path. - Returns: `(*MIME, error)` - **SetLimit(uint32)** - Purpose: Configure the read limit for detection. - Returns: `void` - **Extend(func, string, string, ...string)** - Purpose: Add a custom MIME type format. - Returns: `void` - **EqualsAny(string, ...string)** - Purpose: Compare a MIME type against a list of other MIME types. - Returns: `bool` - **Lookup(string)** - Purpose: Find a MIME type by its name. - Returns: `*MIME` ``` -------------------------------- ### Error Handling with Fallback Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/usage-examples.md Handles potential errors during file detection, such as file not found or permission issues. If an error occurs, it logs the error and returns 'application/octet-stream'. ```go package main import ( "fmt" "log" "os" "github.com/gabriel-vasile/mimetype" ) func detectWithFallback(path string) string { mtype, err := mimetype.DetectFile(path) if err != nil { if os.IsNotExist(err) { log.Printf("File not found: %s\n", path) } else if os.IsPermission(err) { log.Printf("Permission denied: %s\n", path) } else { log.Printf("Read error for %s: %v\n", path, err) } // Still return the MIME type (will be octet-stream) } return mtype.String() } func main() { mime := detectWithFallback("/nonexistent/file.bin") fmt.Println("Detected MIME:", mime) // application/octet-stream } ``` -------------------------------- ### File-Based MIME Type Detection with Error Logging Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/errors.md This pattern demonstrates detecting a file's MIME type and logging any detection errors without failing the program. It falls back to 'application/octet-stream' if an error occurs. ```go import ( "log" "os" "github.com/gabriel-vasile/mimetype" ) func detectFileType(path string) string { mtype, err := mimetype.DetectFile(path) if err != nil { // Log the error but don't fail log.Printf("Warning: detection error for %s: %v\n", path, err) // Fall back to the MIME type anyway (will be application/octet-stream) } return mtype.String() } ``` -------------------------------- ### Core Functions Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/DOCUMENTATION-SUMMARY.txt Reference for the 7 package-level functions that form the core API for MIME type detection. Includes function signatures, parameter details, and return type explanations. ```APIDOC ## Core Functions ### Description Documentation for the 7 package-level functions available for MIME type detection. ### API Reference This section details the signatures, parameters, and return types of the core functions. #### Function Signatures with Complete Type Information - **Detect(reader io.Reader, bufferSize int) (string, error)**: Detects the MIME type of the content from an io.Reader. - **DetectFile(filePath string) (string, error)**: Detects the MIME type of a file by its path. - **DetectBytes(data []byte) (string, error)**: Detects the MIME type of a byte slice. - **DetectExtension(extension string) (string, error)**: Detects the MIME type based on a file extension. - **DetectMagic(reader io.Reader, bufferSize int) (string, error)**: Detects the MIME type using magic number signatures. - **DetectPath(path string) (string, error)**: Detects the MIME type of a file path. - **DetectString(s string) (string, error)**: Detects the MIME type of a string. #### Parameter Tables - **reader** (io.Reader) - Required - The input stream to read data from. - **bufferSize** (int) - Optional - The size of the buffer to use for reading. - **filePath** (string) - Required - The path to the file. - **data** ([]byte) - Required - The byte slice containing the data. - **extension** (string) - Required - The file extension to look up. - **path** (string) - Required - The path to the file. - **s** (string) - Required - The string to analyze. #### Return Type Documentation - **string**: The detected MIME type. - **error**: An error if detection fails (though the library aims for graceful fallback). ``` -------------------------------- ### DetectFile Error Handling Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/errors.md DetectFile returns an error if the file cannot be opened or read. This pattern shows how to specifically check for file not found and permission errors, falling back to a general read error. The mtype will be application/octet-stream if an error occurs. ```Go mtype, err := mimetype.DetectFile(path) ``` ```Go mtype, err := mimetype.DetectFile("/path/to/file") if err != nil { if os.IsNotExist(err) { log.Println("File not found") } else if os.IsPermission(err) { log.Println("Permission denied") } else { log.Printf("Read error: %v\n", err) } // mtype will be application/octet-stream return } // File was successfully read and detected fmt.Println(mtype.String()) ``` -------------------------------- ### Handling Read Errors During File Detection Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/errors.md Shows how to handle read errors when detecting a file's MIME type. Even if an error occurs, a fallback MIME type is still provided. ```go mtype, err := mimetype.DetectFile("/nonexistent.bin") if err != nil { fmt.Printf("Read failed: %v\n", err) // But mtype is still valid! fmt.Println(mtype.String()) // application/octet-stream } ``` -------------------------------- ### Configure MIME Type Detection Limit Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Use `mimetype.SetLimit()` to configure the maximum number of bytes read for detection. Set to 0 for unlimited reading. ```go mimetype.SetLimit(1024 * 1024) // 1 MB ``` ```go mimetype.SetLimit(0) // Unlimited ``` -------------------------------- ### Fallback MIME Type for Unknown Formats Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/errors.md Demonstrates the fallback behavior when the format of the byte slice is unknown. It defaults to 'application/octet-stream'. ```go data := []byte("\xFF\xFE\xAD\xDE unknown format") mtype := mimetype.Detect(data) fmt.Println(mtype.String()) // application/octet-stream (fallback) fmt.Println(mtype.Is("application/octet-stream")) // true ``` -------------------------------- ### String() Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-mime-type.md Returns the string representation of the MIME type, including any optional parameters like charset. This method implements the Go Stringer interface. ```APIDOC ## String() ### Description Returns the string representation of the MIME type, including any optional parameters like charset. This implements the Go `Stringer` interface. ### Returns `string` - The MIME type string (e.g., `application/json`, `text/plain; charset=utf-8`). ### Example ```go mtype := mimetype.Detect([]byte("plain text")) fmt.Println(mtype.String()) // text/plain; charset=utf-8 ``` ``` -------------------------------- ### Add Format Aliases Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/usage-examples.md Register a custom detector with multiple aliases. This allows the same underlying MIME type to be looked up using different string identifiers. ```go package main import ( "fmt" "github.com/gabriel-vasile/mimetype" ) func main() { // Custom detector customDetector := func(raw []byte, limit uint32) bool { return len(raw) > 0 && raw[0] == '@' } // Register with multiple aliases mimetype.Extend( customDetector, "application/x-custom", ".custom", "application/x-mycustom", // Alias 1 "text/custom", // Alias 2 ) // Lookup works with any alias mtype1 := mimetype.Lookup("application/x-custom") mtype2 := mimetype.Lookup("application/x-mycustom") mtype3 := mimetype.Lookup("text/custom") fmt.Println(mtype1 == mtype2) fmt.Println(mtype1 == mtype3) } ``` -------------------------------- ### Concurrent Read Operations Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/architecture.md Illustrates safe concurrent reading operations using the mimetype detection functions. Multiple goroutines can safely call Detect and DetectFile simultaneously. ```Go // Safe: Multiple goroutines reading go func() { mimetype.Detect(data1) }() go func() { mimetype.Detect(data2) }() go func() { mimetype.DetectFile(path) }() ``` -------------------------------- ### Define a Custom Detector Function Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/types.md Implement a custom detector function that checks for a specific byte sequence at the beginning of the input data. Ensure the detector handles short inputs gracefully and uses the provided limit. ```go type Detector func(raw []byte, limit uint32) bool ``` ```go // Simple detector for a custom format starting with "MYHEADER" myDetector := func(raw []byte, limit uint32) bool { return len(raw) >= 8 && bytes.Equal(raw[:8], []byte("MYHEADER")) } ``` -------------------------------- ### Check if MIME Type Matches Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-mime-type.md Perform case-insensitive comparison of a detected MIME type against a target string. Ignores parameters, whitespace, and case, and checks registered aliases. ```go mtype := mimetype.Detect([]byte("plain text")) // Detected as: text/plain; charset=utf-8 if mtype.Is("text/plain") { fmt.Println("Is text/plain: true") } if mtype.Is("TEXT/PLAIN") { fmt.Println("Case-insensitive: true") } if mtype.Is("text/plain; charset=utf-8") { fmt.Println("With charset: true") } if mtype.Is("application/json") { fmt.Println("Different type: false") } ``` -------------------------------- ### Add Container-Based Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Register a custom detector for formats contained within other formats, like ZIP archives. This detector assumes the parent container check is already done and focuses on internal identifiers. ```go myZipDetector := func(raw []byte, limit uint32) bool { // Parent ZIP check is already done at this point // Just look for our identifying files/signatures return bytes.Contains(raw, []byte("myformat/manifest.xml")) } zipType := mimetype.Lookup("application/zip") zipType.Extend(myZipDetector, "application/x-myzipformat", ".myz") ``` -------------------------------- ### Add Text-Based Detector Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Register a custom detector for text-based formats. This detector first ensures the content is likely text (no null bytes) and then looks for a specific marker. ```go myTextDetector := func(raw []byte, limit uint32) bool { // 1. Check for text content if bytes.Contains(raw, []byte{0x00}) { return false // Has null bytes, probably binary } // 2. Look for characteristic markers return bytes.Contains(raw, []byte("###MYFORMAT")) } textPlain := mimetype.Lookup("text/plain") textPlain.Extend(myTextDetector, "text/x-myformat", ".myf") ``` -------------------------------- ### Extending Mimetype Detection Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/README.md Allows adding support for custom file formats at runtime by providing a detector function, MIME type string, and file extension. The Extend function registers this new detector with the library. ```go customDetector := func(raw []byte, limit uint32) bool { return bytes.HasPrefix(raw, []byte("MYHEADER")) } mimetype.Extend(customDetector, "application/x-custom", ".custom") ``` -------------------------------- ### mimetype.Extend Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-main.md Adds custom MIME type detection for unsupported file formats by registering a detector function, MIME type string, and file extension. ```APIDOC ## Extend Adds custom MIME type detection for unsupported file formats. ### Description `Extend` registers a custom detector function for a new file format. The detector function receives the raw input bytes and the read limit, and must return true if the bytes match the signature. This function is equivalent to calling `Extend()` on the root MIME type `application/octet-stream`. The custom detector will be checked after built-in detectors. The detector function should examine byte signatures (magic numbers) to identify the file format. ### Parameters #### Function Parameters - **detector** (func([]byte, uint32) bool) - Required - Function that returns true when input matches the signature. - **mime** (string) - Required - MIME type string (e.g., "text/custom"). - **extension** (string) - Required - File extension including dot (e.g., ".custom"). - **aliases** (...string) - Optional - Alternative MIME type names. ### Returns None (void function). ### Example ```go package main import ( "bytes" "github.com/gabriel-vasile/mimetype" ) func main() { // Define detector for custom format with "MYFORMAT" signature customDetector := func(raw []byte, limit uint32) bool { return bytes.HasPrefix(raw, []byte("MYFORMAT")) } // Register the custom type mimetype.Extend(customDetector, "application/x-myformat", ".myf") // Now detection works mtype := mimetype.Detect([]byte("MYFORMAT some data")) println(mtype.String()) // application/x-myformat println(mtype.Extension()) // .myf } ``` ``` -------------------------------- ### Internal MIME Hierarchy Function Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/api-reference-mime-type.md Returns a human-readable string of MIME type ancestors, showing the inheritance chain up to the root. ```go func (m *MIME) hierarchy() string ``` -------------------------------- ### Increase MIME Detection Accuracy with Larger Limit Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/README.md Configures the library to read a larger portion of a file for MIME type detection, improving accuracy for formats with late signatures like Office documents. Sets the detection limit to 1MB. ```go // For Office documents with late signatures mimetype.SetLimit(1024 * 1024) // 1MB limit mtype, err := mimetype.DetectFile("document.docx") ``` -------------------------------- ### Detect MIME Type from Bytes Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/INDEX.md Use this function for the fastest MIME type detection when you have the data as a byte slice. It always returns a *MIME type, defaulting to application/octet-stream if no match is found. ```go mtype := mimetype.Detect([]byte) ``` -------------------------------- ### Detect MP3 File Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Detects MP3 files by performing a linear search for MPEG frame sync bytes (0xFFF or 0xFFE) throughout the file. This check is positioned later in the detection sequence to minimize false positives. ```Go // MP3 uses linear search for MPEG frame sync (0xFFF or 0xFFE) // Different from most formats - checks throughout file MP3 = func(raw []byte, limit uint32) bool { // Positioned late in detection to avoid false positives return bytes.Contains(raw, []byte{0xFF, 0xFB}) || bytes.Contains(raw, []byte{0xFF, 0xFA}) } ``` -------------------------------- ### Detect DOCX File Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/detector-patterns.md Detects DOCX files by checking for the presence of 'word/document.xml' within the byte slice, as DOCX is a ZIP-based format. ```Go // Detects DOCX by looking for Word-specific file inside ZIP Docx = func(raw []byte, limit uint32) bool { return bytes.Contains(raw, []byte("word/document.xml")) } ``` -------------------------------- ### Process Directory for MIME Type Distribution Source: https://github.com/gabriel-vasile/mimetype/blob/master/_autodocs/usage-examples.md Walks through a specified directory, detects the MIME type of each file, and collects statistics on the distribution of MIME types. This is useful for analyzing the content of a directory. ```go package main import ( "fmt" "os" "path/filepath" "github.com/gabriel-vasile/mimetype" ) func processDirectory(dir string) error { // Map to collect statistics stats := make(map[string]int) // Walk directory err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } // Detect MIME type mtype, err := mimetype.DetectFile(path) if err != nil { // Still count even on error (will be octet-stream) } stats[mtype.String()]++ return nil }) if err != nil { return err } // Print statistics fmt.Println("MIME Type Distribution:") for mime, count := range stats { fmt.Printf(" %s: %d files\n", mime, count) } return nil } func main() { processDirectory("./documents") } ```