Skip to content

Instantly share code, notes, and snippets.

@asterite
Last active August 29, 2015 14:28
Show Gist options
  • Save asterite/8a7ac3f9e43075aee54f to your computer and use it in GitHub Desktop.
Save asterite/8a7ac3f9e43075aee54f to your computer and use it in GitHub Desktop.
class TimeDecoderText
def initialize
super
@curr = Pointer(UInt8).new(0)
end
def decode(value_ptr)
@curr = value_ptr + 0
year = get_next_int
month = get_next_int
day = get_next_int
hour = get_next_int
minute = get_next_int
second = get_next_int
fraction = (@curr-1).value == '.'.ord ? get_next_int : 0
sign = (@curr-1).value == '-'.ord ? -1 : 1
offset = get_next_int * sign
milisecond = fraction_to_mili(fraction)
t = Time.new(year, month, day, hour, minute, second, milisecond, Time::Kind::Utc)
return apply_offset(t, offset)
end
private def get_next_int
return 0 if @curr.value == 0
int = 0
while @curr.value >= 48 && @curr.value <= 57
int = (int*10) + (@curr.value - 48)
@curr += 1
end
@curr += 1 unless @curr.value == 0
return int
end
private def fraction_to_mili(frac)
if frac < 10
frac * 100
elsif frac < 100
frac * 10
elsif frac > 1000
frac / 1000
else
frac
end
end
private def apply_offset(t, offset)
if offset == 0
t
else
t - TimeSpan.new(offset,0,0)
end
end
end
abstract class Decoder
def decode(value_ptr) end
private def swap32(ptr : UInt8*) : UInt32
(((((((( 0_u32
) | ptr[0] ) << 8
) | ptr[1] ) << 8
) | ptr[2] ) << 8
) | ptr[3] )
end
private def swap64(ptr : UInt8*) : UInt64
(((((((((((((((( 0_u64
) | ptr[0] ) << 8
) | ptr[1] ) << 8
) | ptr[2] ) << 8
) | ptr[3] ) << 8
) | ptr[4] ) << 8
) | ptr[5] ) << 8
) | ptr[6] ) << 8
) | ptr[7] )
end
end
class TimeDecoderSpan < Decoder
def decode(value_ptr)
v = swap64(value_ptr) / 1000
Time.new(2000,1,1, kind: Time::Kind::Utc) + TimeSpan.new(0,0,0,0,v)
end
end
class TimeDecoderInt < Decoder
def decode(value_ptr)
v = swap64(value_ptr) / 1000
Time.new(630822816000000000_i64 + (TimeSpan::TicksPerMillisecond * v), kind: Time::Kind::Utc)
end
end
ptr = "2015-05-01 13:10:01.23442-07".cstr
#bytes = {0_u8, 1_u8, 184_u8, 9_u8, 144_u8, 219_u8, 139_u8, 244_u8}
#bptr = pointerof(bytes) as UInt8*
pgdate = -825324695007526656_i64
bptr = pointerof(pgdate) as UInt8*
tdt = TimeDecoderText.new
tds = TimeDecoderSpan.new
tdi = TimeDecoderInt.new
p tdt.decode(ptr)
p tds.decode(bptr)
p tdi.decode(bptr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment