mirror of
https://github.com/h2non/filetype.git
synced 2025-12-24 11:52:08 +08:00
feat: 🎸 support concurrent map writes
This commit is contained in:
47
filetype.go
47
filetype.go
@@ -29,8 +29,8 @@ func AddType(ext, mime string) types.Type {
|
||||
|
||||
// Is checks if a given buffer matches with the given file type extension
|
||||
func Is(buf []byte, ext string) bool {
|
||||
kind, ok := types.Types[ext]
|
||||
if ok {
|
||||
kind := types.Get(ext)
|
||||
if kind != types.Unknown {
|
||||
return IsType(buf, kind)
|
||||
}
|
||||
return false
|
||||
@@ -52,33 +52,48 @@ func IsType(buf []byte, kind types.Type) bool {
|
||||
|
||||
// IsMIME checks if a given buffer matches with the given MIME type
|
||||
func IsMIME(buf []byte, mime string) bool {
|
||||
for _, kind := range types.Types {
|
||||
result := false
|
||||
types.Types.Range(func(k, v interface{}) bool {
|
||||
kind := v.(types.Type)
|
||||
if kind.MIME.Value == mime {
|
||||
matcher := matchers.Matchers[kind]
|
||||
return matcher(buf) != types.Unknown
|
||||
result = matcher(buf) != types.Unknown
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
return true
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSupported checks if a given file extension is supported
|
||||
func IsSupported(ext string) bool {
|
||||
for name := range Types {
|
||||
if name == ext {
|
||||
return true
|
||||
result := false
|
||||
types.Types.Range(func(k, v interface{}) bool {
|
||||
key := k.(string)
|
||||
if key == ext {
|
||||
result = true
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
return true
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// IsMIMESupported checks if a given MIME type is supported
|
||||
func IsMIMESupported(mime string) bool {
|
||||
for _, m := range Types {
|
||||
if m.MIME.Value == mime {
|
||||
return true
|
||||
result := false
|
||||
types.Types.Range(func(k, v interface{}) bool {
|
||||
kind := v.(types.Type)
|
||||
if kind.MIME.Value == mime {
|
||||
result = true
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
return true
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// GetType retrieves a Type by file extension
|
||||
|
||||
@@ -2,10 +2,26 @@ package filetype
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/h2non/filetype/types"
|
||||
)
|
||||
|
||||
func TestConcurrent(t *testing.T) {
|
||||
go func() {
|
||||
for i := 0; i < 10000; i++ {
|
||||
types.NewType("xml", "text/xml")
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for i := 0; i < 10000; i++ {
|
||||
types.NewType("xml", "text/xml")
|
||||
}
|
||||
}()
|
||||
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
|
||||
func TestIs(t *testing.T) {
|
||||
cases := []struct {
|
||||
buf []byte
|
||||
@@ -22,6 +38,7 @@ func TestIs(t *testing.T) {
|
||||
t.Fatalf("Invalid match: %s", test.ext)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsType(t *testing.T) {
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
package types
|
||||
|
||||
var Types = make(map[string]Type)
|
||||
import "sync"
|
||||
|
||||
// Types Support concurrent map writes
|
||||
var Types sync.Map
|
||||
|
||||
// Add registers a new type in the package
|
||||
func Add(t Type) Type {
|
||||
Types[t.Extension] = t
|
||||
Types.Store(t.Extension, t)
|
||||
return t
|
||||
}
|
||||
|
||||
// Get retrieves a Type by extension
|
||||
func Get(ext string) Type {
|
||||
kind := Types[ext]
|
||||
if kind.Extension != "" {
|
||||
return kind
|
||||
if tmp, ok := Types.Load(ext); ok {
|
||||
kind := tmp.(Type)
|
||||
if kind.Extension != "" {
|
||||
return kind
|
||||
}
|
||||
}
|
||||
return Unknown
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user