module Sound.OSC.Type.JSON where
import qualified Data.Aeson as A
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy as B.L
import qualified Data.ByteString.Lazy.UTF8 as U
import Sound.OSC as O
import Sound.OSC.Type.JSON.Aeson
type Value = A.Value
encode_json_str :: Value -> String
encode_json_str = U.toString . encode_json
decode_json_str :: String -> Maybe Value
decode_json_str = decode_json . U.fromString
type Number = Either Integer Double
encode_number :: Number -> Value
encode_number = either encode_integral encode_floating
encode_timestamp :: Time -> Value
encode_timestamp n = encode_assoc ("timestamp",encode_floating n)
encode_blob :: B.L.ByteString -> Value
encode_blob b =
let a = encode_list (map encode_integral (B.L.unpack b))
in encode_assoc ("blob",a)
encode_midi :: MIDI -> A.Value
encode_midi (MIDI p q r s) =
let a = encode_list (map encode_integral [p,q,r,s])
in encode_assoc ("midi",a)
encode_datum :: Datum -> Value
encode_datum d =
case d of
Int32 n -> encode_integral n
Int64 n -> encode_integral n
Float n -> encode_floating n
Double n -> encode_floating n
ASCII_String s -> encode_string (C.unpack s)
Blob b -> encode_blob b
TimeStamp n -> encode_timestamp n
Midi m -> encode_midi m
encode_message :: Message -> Value
encode_message (Message a d) =
let a' = encode_string a
d' = map encode_datum d
in encode_list (a' : d')
encode_bundle :: Bundle -> Value
encode_bundle (Bundle t m) =
let b = encode_string "#bundle"
t' = encode_timestamp t
m' = map encode_message m
in encode_list (b : t' : m')
encode_packet :: Packet -> Value
encode_packet p =
case p of
Packet_Message m -> encode_message m
Packet_Bundle b -> encode_bundle b
decode_message :: Value -> Maybe Message
decode_message j =
case decode_list j of
Just (m : d) ->
case decode_datum m of
Just (ASCII_String m') -> mapM decode_datum d >>=
Just . message (C.unpack m')
_ -> Nothing
_ -> Nothing
decode_bundle :: Value -> Maybe Bundle
decode_bundle j =
case decode_list j of
Just (b : t : m) ->
case (datum_string =<< decode_datum b,decode_datum t) of
(Just "#bundle",Just (TimeStamp t')) ->
mapM decode_message m >>= Just . Bundle t'
_ -> Nothing
_ -> Nothing
decode_packet :: Value -> Maybe Packet
decode_packet v =
case decode_bundle v of
Just b -> Just (Packet_Bundle b)
Nothing -> case decode_message v of
Just m -> Just (Packet_Message m)
Nothing -> Nothing