reformatting code

pull/6/head
WooKyoung Noh 2017-02-17 22:45:59 +09:00
parent 9a607f4312
commit c7a349625c
2 changed files with 188 additions and 173 deletions

View File

@ -1,21 +1,22 @@
#OSC.jl # OSC.jl
#Copyright (c) 2014, Mark McCurry, All rights reserved. # Copyright (c) 2014, Mark McCurry, All rights reserved.
# #
#This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either # License as published by the Free Software Foundation; either
#version 3.0 of the License, or (at your option) any later version. # version 3.0 of the License, or (at your option) any later version.
# #
#This library is distributed in the hope that it will be useful, # This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#Lesser General Public License for more details. # Lesser General Public License for more details.
# #
#You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
#License along with this library. # License along with this library.
module OSC module OSC
import Base.show
import Base: show, getindex
export OscMsg, path export OscMsg, path
macro incfp(x) quote begin macro incfp(x) quote begin
@ -25,27 +26,27 @@ macro incfp(x) quote begin
end end end end end end
type OscMsg type OscMsg
data::Array{Uint8} data::Array{UInt8}
end end
path(msg::OscMsg) = stringify(msg.data) path(msg::OscMsg) = stringify(msg.data)
function stringify(data::Array{Uint8}) function stringify(data::Array{UInt8})
zeroInd = find(data.== 0) zeroInd = find(data.== 0)
if(length(zeroInd) == 0) if length(zeroInd) == 0
return string(map(Char, data)...) return string(map(Char, data)...)
elseif(zeroInd[1] == 0) elseif zeroInd[1] == 0
return nothing return nothing
else else
return string(map(Char, data[1:zeroInd[1]-1])...) return string(map(Char, data[1:zeroInd[1]-1])...)
end end
end end
function names(msg::OscMsg)#::ASCIIString function names(msg::OscMsg) #::String
pos = 1 pos = 1
while(msg.data[pos += 1] != 0) end #skip pattern while(msg.data[pos += 1] != 0) end #skip pattern
while(msg.data[pos += 1] == 0) end #skip null while(msg.data[pos += 1] == 0) end #skip null
return stringify(msg.data[pos+1:end]); #skip comma return stringify(msg.data[pos+1:end]) #skip comma
end end
strip_args(args::AbstractString) = replace(replace(args,"]",""),"[","") strip_args(args::AbstractString) = replace(replace(args,"]",""),"[","")
@ -55,267 +56,282 @@ function narguments(msg::OscMsg)
end end
has_reserved(typeChar::Char) = typeChar in "isbfhtdSrmc" has_reserved(typeChar::Char) = typeChar in "isbfhtdSrmc"
nreserved(args::ASCIIString) = sum(map(has_reserved, collect(args))) nreserved(args::String) = sum(map(has_reserved, collect(args)))
function argType(msg::OscMsg, nargument::Int)#::Char function argType(msg::OscMsg, nargument::Int) #::Char
@assert(nargument > 0 && nargument <= narguments(msg)); @assert(nargument > 0 && nargument <= narguments(msg))
return strip_args(names(msg))[nargument] return strip_args(names(msg))[nargument]
end end
align(pos) = pos+(4-(pos-1)%4) align(pos) = pos+(4-(pos-1)%4)
function arg_off(msg::OscMsg, idx::Int)#::Int function arg_off(msg::OscMsg, idx::Int) #::Int
if(!has_reserved(argType(msg,idx))) if(!has_reserved(argType(msg,idx)))
return 0; return 0
end end
#Iterate to the right position # Iterate to the right position
args::ASCIIString = names(msg); args::String = names(msg)
argc::Int = 1 argc::Int = 1
pos::Int = 1 pos::Int = 1
#Get past the Argument String # Get past the Argument String
while(msg.data[pos] != ',') pos += 1 end while(msg.data[pos] != UInt8(',')) pos += 1 end
while(msg.data[pos] != 0) pos += 1 end while(msg.data[pos] != 0) pos += 1 end
#Alignment # Alignment
pos = align(pos) pos = align(pos)
#ignore any leading '[' or ']' # ignore any leading '[' or ']'
while(args[argc] in "[]") argc += 1 end while(args[argc] in "[]") argc += 1 end
while(idx != 1) while(idx != 1)
bundle_length::Uint32 = 0; bundle_length::UInt32 = 0
arg = args[argc] arg = args[argc]
argc += 1 argc += 1
if(arg in "htd") if arg in "htd"
pos +=8; pos +=8
elseif(arg in "mrfci") elseif(arg in "mrfci")
pos += 4; pos += 4
elseif(arg in "Ss") elseif(arg in "Ss")
while(msg.data[pos += 1] != 0) end while(msg.data[pos += 1] != 0) end
pos = align(pos) pos = align(pos)
elseif(arg == 'b') elseif arg == 'b'
bundle_length |= (msg.data[@incfp(pos)] << 24); bundle_length |= (msg.data[@incfp(pos)] << 24)
bundle_length |= (msg.data[@incfp(pos)] << 16); bundle_length |= (msg.data[@incfp(pos)] << 16)
bundle_length |= (msg.data[@incfp(pos)] << 8); bundle_length |= (msg.data[@incfp(pos)] << 8)
bundle_length |= (msg.data[@incfp(pos)]); bundle_length |= (msg.data[@incfp(pos)])
bundle_length += 4-bundle_length%4; bundle_length += 4-bundle_length%4
pos += bundle_length; pos += bundle_length
elseif(arg in "[]")#completely ignore array chars elseif(arg in "[]") # completely ignore array chars
idx += 1; idx += 1
else #TFI else # TFI
end end
idx -= 1 idx -= 1
end end
pos; pos
end end
#Calculate the size of the message without writing to a buffer # Calculate the size of the message without writing to a buffer
function vsosc_null(address::ASCIIString, function vsosc_null(address::String,
arguments::ASCIIString, arguments::String,
args...) args...)
pos::Int = length(address)+1 pos::Int = length(address) + 1
pos = align(pos) pos = align(pos)
pos += 1+length(arguments) pos += 1+length(arguments)
pos = align(pos) pos = align(pos)
arg_pos = 1; arg_pos = 1
#Take care of varargs # Take care of varargs
for(arg = arguments) for arg in arguments
if(arg in "htd") if arg in "htd"
arg_pos += 1 arg_pos += 1
pos += 8; pos += 8
elseif(arg in "mrcfi") elseif arg in "mrcfi"
arg_pos += 1 arg_pos += 1
pos += 4; pos += 4
elseif(arg in "sS") elseif arg in "sS"
s::ASCIIString = args[@incfp(arg_pos)]; s::String = args[@incfp(arg_pos)]
pos += length(s); pos += length(s)
pos = align(pos) pos = align(pos)
elseif(arg in "b") elseif arg in "b"
i::Int32 = sizeof(args[@incfp(arg_pos)]) i::Int32 = sizeof(args[@incfp(arg_pos)])
pos += 4 + i; pos += 4 + i
pos = align(pos) pos = align(pos)
end #other args classes are ignored end # other args classes are ignored
end end
return pos-1; return pos - 1
end end
function rtosc_amessage(buffer::Array{Uint8}, function rtosc_amessage(buffer::Array{UInt8},
len::Int, len::Int,
address::ASCIIString, address::String,
arguments::ASCIIString, arguments::String,
args...) args...)
total_len::Int = vsosc_null(address, arguments, args...); total_len::Int = vsosc_null(address, arguments, args...)
for(i=1:total_len) for i=1:total_len
buffer[i] = 0 buffer[i] = 0
end end
#Abort if the message cannot fit # Abort if the message cannot fit
if(total_len>len) if total_len > len
return 0; return 0
end end
pos::Int = 1; pos::Int = 1
#Address #Address
for(C = address) buffer[@incfp(pos)] = C end for C in address
buffer[@incfp(pos)] = C
end
pos = align(pos) pos = align(pos)
#Arguments #Arguments
buffer[@incfp(pos)] = ','; buffer[@incfp(pos)] = UInt8(',')
for(A=arguments) buffer[@incfp(pos)] = A; end for A in arguments
buffer[@incfp(pos)] = A
end
pos = align(pos) pos = align(pos)
arg_pos::Int = 1; arg_pos::Int = 1
for(arg = arguments) for arg in arguments
@assert(arg != 0); @assert(UInt32(arg) != 0)
if(arg in "htd") if arg in "htd"
d::Uint64 = reinterpret(Uint64, args[@incfp(arg_pos)]); d::UInt64 = reinterpret(UInt64, args[@incfp(arg_pos)])
buffer[@incfp(pos)] = ((d>>56) & 0xff); buffer[@incfp(pos)] = ((d>>56) & 0xff)
buffer[@incfp(pos)] = ((d>>48) & 0xff); buffer[@incfp(pos)] = ((d>>48) & 0xff)
buffer[@incfp(pos)] = ((d>>40) & 0xff); buffer[@incfp(pos)] = ((d>>40) & 0xff)
buffer[@incfp(pos)] = ((d>>32) & 0xff); buffer[@incfp(pos)] = ((d>>32) & 0xff)
buffer[@incfp(pos)] = ((d>>24) & 0xff); buffer[@incfp(pos)] = ((d>>24) & 0xff)
buffer[@incfp(pos)] = ((d>>16) & 0xff); buffer[@incfp(pos)] = ((d>>16) & 0xff)
buffer[@incfp(pos)] = ((d>>8) & 0xff); buffer[@incfp(pos)] = ((d>>8) & 0xff)
buffer[@incfp(pos)] = (d & 0xff); buffer[@incfp(pos)] = (d & 0xff)
elseif(arg in "rfci") elseif arg in "rfci"
i::Int32 = reinterpret(Int32, args[@incfp(arg_pos)]); i::Int32 = reinterpret(Int32, args[@incfp(arg_pos)])
buffer[@incfp(pos)] = ((i>>24) & 0xff); buffer[@incfp(pos)] = ((i>>24) & 0xff)
buffer[@incfp(pos)] = ((i>>16) & 0xff); buffer[@incfp(pos)] = ((i>>16) & 0xff)
buffer[@incfp(pos)] = ((i>>8) & 0xff); buffer[@incfp(pos)] = ((i>>8) & 0xff)
buffer[@incfp(pos)] = (i & 0xff); buffer[@incfp(pos)] = (i & 0xff)
elseif(arg in "m") elseif arg in "m"
m = args[@incfp(arg_pos)]; m = args[@incfp(arg_pos)]
buffer[@incfp(pos)] = m[1]; buffer[@incfp(pos)] = m[1]
buffer[@incfp(pos)] = m[2]; buffer[@incfp(pos)] = m[2]
buffer[@incfp(pos)] = m[3]; buffer[@incfp(pos)] = m[3]
buffer[@incfp(pos)] = m[4]; buffer[@incfp(pos)] = m[4]
elseif(arg in "Ss") elseif arg in "Ss"
s = args[@incfp(arg_pos)]; s = args[@incfp(arg_pos)]
for(C = s) for C in s
buffer[@incfp(pos)] = C buffer[@incfp(pos)] = C
end end
pos = align(pos) pos = align(pos)
elseif(arg == 'b') elseif arg == 'b'
b = args[@incfp(arg_pos)]; b = args[@incfp(arg_pos)]
i = sizeof(b); i = sizeof(b)
buffer[@incfp(pos)] = ((i>>24) & 0xff); buffer[@incfp(pos)] = ((i>>24) & 0xff)
buffer[@incfp(pos)] = ((i>>16) & 0xff); buffer[@incfp(pos)] = ((i>>16) & 0xff)
buffer[@incfp(pos)] = ((i>>8) & 0xff); buffer[@incfp(pos)] = ((i>>8) & 0xff)
buffer[@incfp(pos)] = (i & 0xff); buffer[@incfp(pos)] = (i & 0xff)
for(U = b) for U in b
buffer[@incfp(pos)] = Uint8(U); buffer[@incfp(pos)] = UInt8(U)
end end
pos = align(pos) pos = align(pos)
end end
end end
return pos-1; return pos - 1
end end
OscMsg(address, arguments, args...) = message(address, arguments, args...) OscMsg(address, arguments, args...) = message(address, arguments, args...)
function message(address::ASCIIString, function message(address::String,
arguments::ASCIIString, arguments::String,
args...) args...)
len::Int = vsosc_null(address, arguments, args...); len::Int = vsosc_null(address, arguments, args...)
data::Vector{Uint8} = Array(Uint8, len); data::Vector{UInt8} = Array{UInt8}(len)
rtosc_amessage(data,len,address,arguments,args...); rtosc_amessage(data,len,address,arguments,args...)
return OscMsg(data) return OscMsg(data)
end end
function rtosc_argument(msg::OscMsg, idx::Int) function rtosc_argument(msg::OscMsg, idx::Int)
typeChar::Char = argType(msg, idx); typeChar::Char = argType(msg, idx)
#trivial case # trivial case
if(!has_reserved(typeChar)) if(!has_reserved(typeChar))
if(typeChar == 'T') if typeChar == 'T'
return true return true
elseif(typeChar == 'F') elseif typeChar == 'F'
return false; return false
end end
else else
arg_pos::Int = arg_off(msg, idx) arg_pos::Int = arg_off(msg, idx)
if(typeChar in "htd") if typeChar in "htd"
t::Uint64 = 0 t::UInt64 = 0
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 56); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 56)
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 48); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 48)
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 40); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 40)
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 32); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 32)
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 24); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 24)
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 16); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 16)
t |= (Uint64(msg.data[@incfp(arg_pos)]) << 8); t |= (UInt64(msg.data[@incfp(arg_pos)]) << 8)
t |= (Uint64(msg.data[@incfp(arg_pos)])); t |= (UInt64(msg.data[@incfp(arg_pos)]))
if(typeChar == 'h') if typeChar == 'h'
return reinterpret(Int64, t) return reinterpret(Int64, t)
elseif(typeChar == 'd') elseif typeChar == 'd'
return reinterpret(Float64, t); return reinterpret(Float64, t)
else else
return t; return t
end end
elseif(typeChar in "f") elseif typeChar in "f"
return reinterpret(Float32,msg.data[arg_pos+(3:-1:0)])[1] return reinterpret(Float32,msg.data[arg_pos+(3:-1:0)])[1]
elseif(typeChar in "rci") elseif typeChar in "rci"
i::Uint32 = 0 i::UInt32 = 0
i |= (Uint32(msg.data[@incfp(arg_pos)]) << 24); i |= (UInt32(msg.data[@incfp(arg_pos)]) << 24)
i |= (Uint32(msg.data[@incfp(arg_pos)]) << 16); i |= (UInt32(msg.data[@incfp(arg_pos)]) << 16)
i |= (Uint32(msg.data[@incfp(arg_pos)]) << 8); i |= (UInt32(msg.data[@incfp(arg_pos)]) << 8)
i |= (Uint32(msg.data[@incfp(arg_pos)])); i |= (UInt32(msg.data[@incfp(arg_pos)]))
if(typeChar == 'r') if typeChar == 'r'
return Uint32(i) return UInt32(i)
elseif(typeChar == 'c') elseif typeChar == 'c'
return Char(i) return Char(i)
else else
return reinterpret(Int32, i); return reinterpret(Int32, i)
end end
elseif(typeChar in "m") elseif typeChar in "m"
m = Array(Uint8, 4) m = Array{UInt8}(4)
m[1] = msg.data[@incfp(arg_pos)] m[1] = msg.data[@incfp(arg_pos)]
m[2] = msg.data[@incfp(arg_pos)] m[2] = msg.data[@incfp(arg_pos)]
m[3] = msg.data[@incfp(arg_pos)] m[3] = msg.data[@incfp(arg_pos)]
m[4] = msg.data[@incfp(arg_pos)] m[4] = msg.data[@incfp(arg_pos)]
return m return m
elseif(typeChar in "b") elseif typeChar in "b"
len::Int32 = 0 len::Int32 = 0
len |= (msg.data[@incfp(arg_pos)] << 24); len |= (msg.data[@incfp(arg_pos)] << 24)
len |= (msg.data[@incfp(arg_pos)] << 16); len |= (msg.data[@incfp(arg_pos)] << 16)
len |= (msg.data[@incfp(arg_pos)] << 8); len |= (msg.data[@incfp(arg_pos)] << 8)
len |= (msg.data[@incfp(arg_pos)]); len |= (msg.data[@incfp(arg_pos)])
return msg.data[arg_pos+(0:len-1)]; return msg.data[arg_pos+(0:len-1)]
elseif(typeChar in "Ss") elseif typeChar in "Ss"
return stringify(msg.data[arg_pos:end]); return stringify(msg.data[arg_pos:end])
end end
end end
return nothing; return nothing
end end
getindex(msg::OscMsg, idx::Int) = rtosc_argument(msg, idx) getindex(msg::OscMsg, idx::Int) = rtosc_argument(msg, idx)
function show(io::IO, msg::OscMsg) function show(io::IO, msg::OscMsg)
println(io, "OSC Message to ", stringify(msg.data)) println(io, "OSC Message to ", stringify(msg.data))
println(io, " Arguments:"); println(io, " Arguments:")
for i=1:narguments(msg) for i=1:narguments(msg)
showField(io, msg,i) showField(io, msg,i)
end end
end end
function showField(io::IO, msg::OscMsg, arg_id) function showField(io::IO, msg::OscMsg, arg_id)
map = ['i' Int32; 'f' Float32; 's' String; 'b' :Blob; 'h' Int32; 't' Uint64; map = ['i' Int32;
'd' Float64; 'S' Symbol; 'c' Char; 'r' :RBG; 'm' :Midi; 'T' true; 'f' Float32;
'F' false; 'N' Nothing] 's' String;
'b' :Blob;
'h' Int32;
't' UInt64;
'd' Float64;
'S' Symbol;
'c' Char;
'r' :RBG;
'm' :Midi;
'T' true;
'F' false;
'N' Void]
dict = Dict{Char, Any}(zip(Vector{Char}(map[:,1][:]),map[:,2][:])) dict = Dict{Char, Any}(zip(Vector{Char}(map[:,1][:]),map[:,2][:]))
dict['I'] = Inf dict['I'] = Inf
typeChar::Char = argType(msg, arg_id) typeChar::Char = argType(msg, arg_id)
value = msg[arg_id] value = msg[arg_id]
if(issubtype(typeof(value), Array)) if issubtype(typeof(value), Array)
value = value' value = value'
end end
@printf(io, " #%2d %c:", arg_id, typeChar); @printf(io, " #%2d %c:", arg_id, typeChar)
println(dict[typeChar]," - ", value) println(dict[typeChar]," - ", value)
end end

View File

@ -16,13 +16,12 @@
using Base.Test using Base.Test
require("OSC")
using OSC using OSC
test_type = length(ARGS) == 1 ? ARGS[1] : "ALL" test_type = length(ARGS) == 1 ? ARGS[1] : "ALL"
#buffer = Array(Uint8,1024) #buffer = Array(UInt8,1024)
#buf_size = rtosc_amessage(buffer, 1024, "/random/address", "sif", #buf_size = rtosc_amessage(buffer, 1024, "/random/address", "sif",
# "string", 0xdeadbeef, float32(12.0)) # "string", 0xdeadbeef, float32(12.0))
#println() #println()
@ -39,15 +38,15 @@ test_type = length(ARGS) == 1 ? ARGS[1] : "ALL"
function test_it_fat() function test_it_fat()
i::Int32 = 42; #integer i::Int32 = 42; #integer
f::Float32 = 0.25; #float f::Float32 = 0.25; #float
s::ASCIIString = "string"; #string s::String = "string"; #string
b = s; #blob b = s; #blob
h::Int64 = -125; #long integer h::Int64 = -125; #long integer
t::Uint64 = 22412; #timetag t::UInt64 = 22412; #timetag
d::Float64 = 0.125; #double d::Float64 = 0.125; #double
S::ASCIIString = "Symbol"; #symbol S::String = "Symbol"; #symbol
c::Char = 'J'; #character c::Char = 'J'; #character
r::Int32 = 0x12345678; #RGBA r::Int32 = 0x12345678; #RGBA
m::Array{Uint8,1} = [0x12,0x23, #midi m::Array{UInt8,1} = [0x12,0x23, #midi
0x34,0x45]; 0x34,0x45];
#true #true
#false #false
@ -80,7 +79,7 @@ end
function test_it_osc_spec() function test_it_osc_spec()
println("Starting OSC Spec...") println("Starting OSC Spec...")
message_one::Array{Uint8} = [ message_one::Array{UInt8} = [
0x2f, 0x6f, 0x73, 0x63, 0x2f, 0x6f, 0x73, 0x63,
0x69, 0x6c, 0x6c, 0x61, 0x69, 0x6c, 0x6c, 0x61,
0x74, 0x6f, 0x72, 0x2f, 0x74, 0x6f, 0x72, 0x2f,
@ -91,7 +90,7 @@ function test_it_osc_spec()
0x43, 0xdc, 0x00, 0x00, 0x43, 0xdc, 0x00, 0x00,
]; ];
message_two::Array{Uint8} = [ message_two::Array{UInt8} = [
0x2f, 0x66, 0x6f, 0x6f, #4 0x2f, 0x66, 0x6f, 0x6f, #4
0x00, 0x00, 0x00, 0x00, #8 0x00, 0x00, 0x00, 0x00, #8
0x2c, 0x69, 0x69, 0x73, 0x2c, 0x69, 0x69, 0x73,