Last active
August 29, 2015 14:28
-
-
Save asterite/8a7ac3f9e43075aee54f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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