diff --git a/internal/matchers/binary.go b/internal/matchers/binary.go index 0d625834..203a5093 100644 --- a/internal/matchers/binary.go +++ b/internal/matchers/binary.go @@ -121,3 +121,30 @@ func Dcm(in []byte) bool { func Nes(in []byte) bool { return bytes.HasPrefix(in, []byte{0x4E, 0x45, 0x53, 0x1A}) } + +// Marc matches a MARC21 (MAchine-Readable Cataloging) file. +func Marc(in []byte) bool { + // File is at least 24 bytes ("leader" field size) + if len(in) < 24 { + return false + } + + // Fixed bytes at offset 20 + if !bytes.Equal(in[20:24], []byte("4500")) { + return false + } + + // First 5 bytes are ASCII digits + for i := 0; i < 5; i++ { + if in[i] < '0' || in[i] > '9' { + return false + } + } + + // Field terminator is present + if !bytes.Contains(in, []byte{0x1E}) { + return false + } + + return true +} diff --git a/mime_test.go b/mime_test.go index ab984026..45d723aa 100644 --- a/mime_test.go +++ b/mime_test.go @@ -138,6 +138,7 @@ var files = map[string]*node{ "mach.o": macho, "sample32": macho, "sample64": macho, + "mrc.mrc": mrc, // fonts "woff.woff": woff, diff --git a/supported_mimes.md b/supported_mimes.md index 3557ec86..43f59655 100644 --- a/supported_mimes.md +++ b/supported_mimes.md @@ -1,4 +1,4 @@ -## 131 Supported MIME types +## 132 Supported MIME types This file is automatically generated when running tests. Do not edit manually. Extension | MIME type @@ -134,3 +134,4 @@ Extension | MIME type **.heic** | image/heic-sequence **.heif** | image/heif **.heif** | image/heif-sequence +**mrc** | application/marc diff --git a/testdata/mrc.mrc b/testdata/mrc.mrc new file mode 100644 index 00000000..6b997df9 --- /dev/null +++ b/testdata/mrc.mrc @@ -0,0 +1 @@ +00057 2200037 450024500190000001aTest MARC file \ No newline at end of file diff --git a/tree.go b/tree.go index 5171106f..9a85ed48 100644 --- a/tree.go +++ b/tree.go @@ -11,7 +11,7 @@ var root = newNode("application/octet-stream", "", matchers.True, wav, aiff, au, mpeg, quickTime, mqv, mp4, webM, threeGP, threeG2, avi, flv, mkv, asf, aac, voc, aMp4, m4a, txt, gzip, class, swf, crx, woff, woff2, otf, eot, wasm, shx, dbf, dcm, rar, djvu, mobi, lit, bpg, sqlite3, dwg, nes, macho, - qcp, icns, heic, heicSeq, heif, heifSeq, + qcp, icns, heic, heicSeq, heif, heifSeq, mrc, ) // The list of nodes appended to the root node @@ -146,4 +146,5 @@ var ( nes = newNode("application/vnd.nintendo.snes.rom", "nes", matchers.Nes) macho = newNode("application/x-mach-binary", "macho", matchers.MachO) qcp = newNode("audio/qcelp", "qcp", matchers.Qcp) + mrc = newNode("application/marc", "mrc", matchers.Marc) )