1- # using FileIO
2- # using ImageIO
3- # using LasIO
4- # using BSON
5- # using OrderedCollections
6-
7- # 2 types for now with MIME type
8- # 1. JSON - application/octet-stream/json
9- # 2. FileIO - application/octet-stream
10- # - application/bson
11- # - image/jpeg
12- # - image/png
13- # - application/vnd.apache.arrow.file
14-
15- const _MIMETypes = OrderedDict {MIME, DataType} ()
16- push! (_MIMETypes, MIME (" application/octet-stream/json" ) => format " JSON" )
17- push! (_MIMETypes, MIME (" application/bson" ) => format " BSON" )
18- push! (_MIMETypes, MIME (" image/png" ) => format " PNG" )
19- push! (_MIMETypes, MIME (" image/jpeg" ) => format " JPG" )
20- push! (_MIMETypes, MIME (" application/vnd.las" ) => format " LAS" )
21- push! (_MIMETypes, MIME (" application/vnd.apache.parque" ) => format " Parquet" ) # Provided by FileIO with ParquetFiles
1+ # #==============================================================================
2+ # # BlobPacking: format <-> MIME type bridging and blob serialization
3+ # #==============================================================================
4+
5+ # Override dictionary for formats not covered by MIMEs.jl + FileIO auto-detection.
6+ # Standard types (PNG, JPEG, CSV, etc.) are auto-detected and don't need entries here.
7+ const _MIMEOverrides = OrderedDict {DataType, MIME} (
8+ format " JSON" => MIME (" application/json" ),
9+ format " BSON" => MIME (" application/bson" ),
10+ format " LAS" => MIME (" application/vnd.las" ),
11+ format " Parquet" => MIME (" application/vnd.apache.parquet" ),
12+ )
13+
14+ """
15+ getMimetype(::Type{DataFormat{S}}) -> MIME
16+
17+ Get the MIME type for a FileIO `DataFormat`. Uses FileIO's extension registry
18+ and MIMEs.jl for standard types, falls back to `_MIMEOverrides` for
19+ domain-specific formats.
20+
21+ # Examples
22+ ```julia
23+ getMimetype(format"PNG") # MIME("image/png")
24+ getMimetype(format"JSON") # MIME("application/json")
25+ ```
26+ """
27+ function getMimetype (:: Type{DataFormat{S}} ) where {S}
28+ T = DataFormat{S}
29+ haskey (_MIMEOverrides, T) && return _MIMEOverrides[T]
30+ try
31+ finfo = FileIO. info (T)
32+ ext = finfo[2 ]
33+ ext = ext isa AbstractVector ? first (ext) : ext
34+ m = mime_from_extension (ext)
35+ ! isnothing (m) && return m
36+ catch
37+ end
38+ return MIME (" application/octet-stream" )
39+ end
40+
41+ """
42+ getDataFormat(::MIME) -> Union{Type{DataFormat{S}}, Nothing}
43+
44+ Get the FileIO `DataFormat` for a MIME type. Uses MIMEs.jl and FileIO's extension
45+ registry, falls back to `_MIMEOverrides`.
46+
47+ Returns `nothing` if no matching format is found.
48+
49+ # Examples
50+ ```julia
51+ getDataFormat(MIME("image/png")) # format"PNG"
52+ getDataFormat(MIME("application/json")) # format"JSON"
53+ ```
54+ """
55+ function getDataFormat (m:: MIME )
56+ for (fmt, mime) in _MIMEOverrides
57+ mime == m && return fmt
58+ end
59+ ext = extension_from_mime (m)
60+ sym = get (FileIO. ext2sym, ext, nothing )
61+ ! isnothing (sym) && return DataFormat{sym}
62+ return nothing
63+ end
2264
2365"""
2466 packBlob
25- Convert a file (JSON, JPG, PNG, BSON, LAS) to Vector{UInt8} for use as a Blob.
26- Returns the blob and MIME type .
67+ Convert data to ` Vector{UInt8}` for use as a Blob. Returns `(blob, mimetype)`.
68+ The MIME type is automatically determined from the DataFormat .
2769"""
2870function packBlob end
71+
2972"""
3073 unpackBlob
31- Convert a Blob back to the origanal typ using the MIME type or DataFormat type.
74+ Convert a Blob back to the original type using the MIME type or DataFormat type.
3275"""
3376function unpackBlob end
3477
3578unpackBlob (mime:: String , blob) = unpackBlob (MIME (mime), blob)
3679
3780function unpackBlob (T:: MIME , blob)
38- dataformat = get (_MIMETypes, T, nothing )
81+ dataformat = getDataFormat (T )
3982 isnothing (dataformat) && error (" Format not found for MIME type $(T) " )
4083 return unpackBlob (dataformat, blob)
4184end
4285
4386# 1. JSON strings are saved as is
4487function packBlob (:: Type{format"JSON"} , json_str:: String )
45- mimetype = findfirst (== (format " JSON" ), _MIMETypes)
46- # blob = codeunits(json_str)
88+ mimetype = getMimetype (format " JSON" )
4789 blob = Vector {UInt8} (json_str)
4890 return blob, mimetype
4991end
5597unpackBlob (entry:: Blobentry , blob:: Vector{UInt8} ) = unpackBlob (entry. mimetype, blob)
5698unpackBlob (eb:: Pair{<:Blobentry, Vector{UInt8}} ) = unpackBlob (eb[1 ], eb[2 ])
5799
58- # 2/ FileIO
100+ # 2. FileIO formats (PNG, JPEG, BSON, LAS, Parquet, etc.)
59101function packBlob (:: Type{T} , data:: Any ; kwargs... ) where {T <: DataFormat }
60102 io = IOBuffer ()
61103 save (Stream {T} (io), data; kwargs... )
62104 blob = take! (io)
63- mimetype = findfirst (== (T), _MIMETypes)
64- if isnothing (mimetype)
65- @warn " No MIME type found for format $T "
66- mimetype = MIME " application/octet-stream"
67- end
105+ mimetype = getMimetype (T)
68106 return blob, mimetype
69107end
70108
@@ -73,18 +111,13 @@ function unpackBlob(::Type{T}, blob::Vector{UInt8}) where {T <: DataFormat}
73111 return load (Stream {T} (io))
74112end
75113
76- # if false
77- # json_str = "{\"name\":\"John\"}"
78- # blob, mimetype = packBlob(format"JSON", json_str)
79- # @assert json_str == unpackBlob(format"JSON", blob)
80- # @assert json_str == unpackBlob(MIME("application/octet-stream/json"), blob)
81- # @assert json_str == unpackBlob("application/octet-stream/json", blob)
82-
83- # blob,mime = packBlob(format"PNG", img)
84- # up_img = unpackBlob(format"PNG", blob)
85-
86- # #TODO BSON does not work yet, can extend [un]packBlob(::Type{format"BSON"}, ...)
87- # packBlob(format"BSON", Dict("name"=>"John"))
88- # unpackBlob(format"BSON", Dict("name"=>"John"))
114+ """
115+ getMimetype(io::IO) -> MIME
89116
90- # end
117+ Detect the MIME type of data in an IO stream using FileIO's format detection.
118+ """
119+ function getMimetype (io:: IO )
120+ _getFormat (s:: FileIO.Stream{T} ) where {T} = T
121+ stream = FileIO. query (io)
122+ return getMimetype (_getFormat (stream))
123+ end
0 commit comments