{-# LANGUAGE CPP #-}
module Data.Repa.Scalar.Date32
        ( Date32

        -- * Projections
        , year, month, day

        -- * Packing and Unpacking
        , pack
        , unpack

        -- * Operators
        , next
        , diffDays

        -- * Loading
        , loadYYYYsMMsDD
        , loadDDsMMsYYYY)
where
import Data.Word
import Data.Bits
import GHC.Exts
import GHC.Word
import Foreign.Storable
import Foreign.Ptr
import Control.Monad
import Data.Repa.Scalar.Int
import qualified Data.Time.Calendar     as Time
import qualified Foreign.Ptr            as F
import qualified Foreign.Storable       as F
import Prelude                          as P


-- | A date packed into a 32-bit word.
--
--   The bitwise format is:
--
--   @
--   32             16       8      0 
--   | year          | month | day  |
--   @
--
--   Pros: Packing and unpacking a Date32 is simpler than using other formats
--   that represent dates as a number of days from some epoch. We can also
--   avoid worrying about what the epoch should be, and the representation
--   will not overflow until year 65536. 
--
--   Cons: Computing a range of dates is slower than with representations
--   using an epoch, as we cannot simply add one to get to the next valid date.
--
newtype Date32 
        = Date32 Word32
        deriving (Date32 -> Date32 -> Bool
(Date32 -> Date32 -> Bool)
-> (Date32 -> Date32 -> Bool) -> Eq Date32
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Date32 -> Date32 -> Bool
== :: Date32 -> Date32 -> Bool
$c/= :: Date32 -> Date32 -> Bool
/= :: Date32 -> Date32 -> Bool
Eq, Eq Date32
Eq Date32 =>
(Date32 -> Date32 -> Ordering)
-> (Date32 -> Date32 -> Bool)
-> (Date32 -> Date32 -> Bool)
-> (Date32 -> Date32 -> Bool)
-> (Date32 -> Date32 -> Bool)
-> (Date32 -> Date32 -> Date32)
-> (Date32 -> Date32 -> Date32)
-> Ord Date32
Date32 -> Date32 -> Bool
Date32 -> Date32 -> Ordering
Date32 -> Date32 -> Date32
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Date32 -> Date32 -> Ordering
compare :: Date32 -> Date32 -> Ordering
$c< :: Date32 -> Date32 -> Bool
< :: Date32 -> Date32 -> Bool
$c<= :: Date32 -> Date32 -> Bool
<= :: Date32 -> Date32 -> Bool
$c> :: Date32 -> Date32 -> Bool
> :: Date32 -> Date32 -> Bool
$c>= :: Date32 -> Date32 -> Bool
>= :: Date32 -> Date32 -> Bool
$cmax :: Date32 -> Date32 -> Date32
max :: Date32 -> Date32 -> Date32
$cmin :: Date32 -> Date32 -> Date32
min :: Date32 -> Date32 -> Date32
Ord, Int -> Date32 -> ShowS
[Date32] -> ShowS
Date32 -> String
(Int -> Date32 -> ShowS)
-> (Date32 -> String) -> ([Date32] -> ShowS) -> Show Date32
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Date32 -> ShowS
showsPrec :: Int -> Date32 -> ShowS
$cshow :: Date32 -> String
show :: Date32 -> String
$cshowList :: [Date32] -> ShowS
showList :: [Date32] -> ShowS
Show)


instance Storable Date32 where
 sizeOf :: Date32 -> Int
sizeOf (Date32 Word32
w)      = Word32 -> Int
forall a. Storable a => a -> Int
sizeOf Word32
w
 alignment :: Date32 -> Int
alignment (Date32 Word32
w)   = Word32 -> Int
forall a. Storable a => a -> Int
alignment Word32
w
 peek :: Ptr Date32 -> IO Date32
peek Ptr Date32
ptr               = (Word32 -> Date32) -> IO Word32 -> IO Date32
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Word32 -> Date32
Date32 (Ptr Word32 -> IO Word32
forall a. Storable a => Ptr a -> IO a
peek (Ptr Date32 -> Ptr Word32
forall a b. Ptr a -> Ptr b
castPtr Ptr Date32
ptr))
 poke :: Ptr Date32 -> Date32 -> IO ()
poke Ptr Date32
ptr (Date32 Word32
w)    = Ptr Word32 -> Word32 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Date32 -> Ptr Word32
forall a b. Ptr a -> Ptr b
castPtr Ptr Date32
ptr) Word32
w
 {-# INLINE sizeOf    #-}
 {-# INLINE alignment #-}
 {-# INLINE peek      #-}
 {-# INLINE poke      #-}


---------------------------------------------------------------------------------------------------
-- | Pack a year, month and day into a `Word32`. 
--
--   If any components of the date are out-of-range then they will be bit-wise
--   truncated so they fit in their destination fields.
--
pack   :: (Int, Int, Int) -> Date32
pack :: (Int, Int, Int) -> Date32
pack (Int
yy, Int
mm, Int
dd) 
        = Word32 -> Date32
Date32
        (Word32 -> Date32) -> Word32 -> Date32
forall a b. (a -> b) -> a -> b
$   ((Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
yy Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0ffff) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
16) 
        Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. ((Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
mm Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0ff)   Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
        Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|.  (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dd Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0ff)
{-# INLINE pack #-}


-- | Inverse of `pack`.
--
--   This function does a simple bit-wise unpacking of the given `Word32`, 
--   and does not guarantee that the returned fields are within a valid 
--   range for the given calendar date.
--
unpack  :: Date32 -> (Int, Int, Int)
unpack :: Date32 -> (Int, Int, Int)
unpack (Date32 Word32
date)
        = ( Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> Word32 -> Int
forall a b. (a -> b) -> a -> b
$ (Word32
date Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0ffff
          , Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> Word32 -> Int
forall a b. (a -> b) -> a -> b
$ (Word32
date Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)  Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0ff
          , Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> Word32 -> Int
forall a b. (a -> b) -> a -> b
$ Word32
date               Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0ff)
{-# INLINE unpack #-}


-- | Take the year number of a `Date32`.
year :: Date32 -> Int
year :: Date32 -> Int
year Date32
date
 = case Date32 -> (Int, Int, Int)
unpack Date32
date of
        (Int
yy, Int
_, Int
_)      -> Int
yy
{-# INLINE year #-}


-- | Take the month number of a `Date32`.
month :: Date32 -> Int
month :: Date32 -> Int
month Date32
date
 = case Date32 -> (Int, Int, Int)
unpack Date32
date of
        (Int
_, Int
mm, Int
_)      -> Int
mm
{-# INLINE month #-}


-- | Take the day number of a `Date32`.
day :: Date32 -> Int
day :: Date32 -> Int
day Date32
date
 = case Date32 -> (Int, Int, Int)
unpack Date32
date of
        (Int
_, Int
_, Int
dd)      -> Int
dd
{-# INLINE day #-}


---------------------------------------------------------------------------------------------------
-- | Yield the next date in the series.
--
--   This assumes leap years occur every four years, 
--   which is valid after year 1900 and before year 2100.
--
next  :: Date32 -> Date32
next :: Date32 -> Date32
next (Date32 (W32# Word32#
date))
          = Word32 -> Date32
Date32 (Word32# -> Word32
W32# (Word32# -> Word32#
next' Word32#
date))
{-# INLINE next #-}

-- Word32# used to wrap a Word# rather than Word32#
-- before base 4.16 (i.e. GHC 9.0 and older)
#if MIN_VERSION_base(4,16,0)
next' :: Word32# -> Word32#
#else
next' :: Word# -> Word#
#endif
next' :: Word32# -> Word32#
next' !Word32#
date
 | (Int
yy,  Int
mm, Int
dd) <- Date32 -> (Int, Int, Int)
unpack (Word32 -> Date32
Date32 (Word32# -> Word32
W32# Word32#
date))
 , (Int
yy', Int
mm', Int
dd') 
     <- case Int
mm of
        Int
1       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31  then (Int
yy,     Int
2, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Jan

        Int
2       -> if Int
yy Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
4 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0                                      -- Feb
                        then if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
29
                                then (Int
yy,     Int
3,      Int
1) 
                                else (Int
yy,    Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
                        else if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
28
                                then (Int
yy,     Int
3,      Int
1)
                                else (Int
yy,    Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

        Int
3       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31 then (Int
yy,     Int
4, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Mar
        Int
4       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
30 then (Int
yy,     Int
5, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Apr
        Int
5       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31 then (Int
yy,     Int
6, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- May
        Int
6       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
30 then (Int
yy,     Int
7, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Jun
        Int
7       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31 then (Int
yy,     Int
8, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Jul
        Int
8       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31 then (Int
yy,     Int
9, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Aug
        Int
9       -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
30 then (Int
yy,    Int
10, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Sep
        Int
10      -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31 then (Int
yy,    Int
11, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Oct
        Int
11      -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
30 then (Int
yy,    Int
12, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Nov
        Int
12      -> if Int
dd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
31 then (Int
yy Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
1, Int
1) else (Int
yy, Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)  -- Dec
        Int
_       -> (Int
0, Int
0, Int
0)
 = case (Int, Int, Int) -> Date32
pack (Int
yy', Int
mm', Int
dd') of
        Date32 (W32# Word32#
w)  -> Word32#
w
{-# NOINLINE next' #-}


-- | Take the number of days between two `Date32`s
diffDays :: Date32 -> Date32 -> Integer
diffDays :: Date32 -> Date32 -> Year
diffDays Date32
date1 Date32
date2
 | (Int
y1, Int
m1, Int
d1)  <- Date32 -> (Int, Int, Int)
unpack Date32
date1
 , (Int
y2, Int
m2, Int
d2)  <- Date32 -> (Int, Int, Int)
unpack Date32
date2
 = Day -> Day -> Year
Time.diffDays
        (Year -> Int -> Int -> Day
Time.fromGregorian (Int -> Year
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y1) Int
m1 Int
d1)
        (Year -> Int -> Int -> Day
Time.fromGregorian (Int -> Year
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y2) Int
m2 Int
d2)


---------------------------------------------------------------------------------------------------
-- | Read a date in YYYYsMMsDD format from the given buffer.
loadYYYYsMMsDD 
        :: Word8                        -- ^ Separating character.
        -> Ptr Word8                    -- ^ Buffer.
        -> Int                          -- ^ Length of buffer.
        -> IO (Maybe (Date32, Int))     -- ^ Result.

loadYYYYsMMsDD :: Word8 -> Ptr Word8 -> Int -> IO (Maybe (Date32, Int))
loadYYYYsMMsDD !Word8
sep !Ptr Word8
buf (I# Int#
len_)
 = IO (Maybe (Date32, Int))
loadYear
 where  loadYear :: IO (Maybe (Date32, Int))
loadYear 
         | Int#
1# <- Int#
4# Int# -> Int# -> Int#
<=# Int#
len_
         , (# Int#
1#, Int#
yy, Int#
ix' #)    <- Ptr Word8 -> Int# -> (# Int#, Int#, Int# #)
forall {a}. Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' Ptr Word8
buf Int#
4#
         = Int# -> Int# -> IO (Maybe (Date32, Int))
sep1 Int#
ix' Int#
yy
         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        sep1 :: Int# -> Int# -> IO (Maybe (Date32, Int))
sep1 Int#
ix Int#
yy
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int# -> Int# -> Int#
<=# Int#
len_    
         = Ptr Word8 -> Int -> IO Word8
forall b. Ptr b -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
F.peekByteOff Ptr Word8
buf (Int# -> Int
I# Int#
ix) IO Word8
-> (Word8 -> IO (Maybe (Date32, Int))) -> IO (Maybe (Date32, Int))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(Word8
r :: Word8)
         -> if Word8
r Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
sep
                then Int# -> Int# -> IO (Maybe (Date32, Int))
loadMonth (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int#
yy 
                else Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        loadMonth :: Int# -> Int# -> IO (Maybe (Date32, Int))
loadMonth Int#
ix Int#
yy
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
2#) Int# -> Int# -> Int#
<=# Int#
len_    
         , (# Int#
1#, Int#
mm, Int#
o #)    <- Ptr Any -> Int# -> (# Int#, Int#, Int# #)
forall {a}. Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' (Ptr Word8
buf Ptr Word8 -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`F.plusPtr` (Int# -> Int
I# Int#
ix)) Int#
2#
         = Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
sep2 (Int#
ix Int# -> Int# -> Int#
+# Int#
o) Int#
yy Int#
mm
         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        sep2 :: Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
sep2 Int#
ix Int#
yy Int#
mm
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int# -> Int# -> Int#
<=# Int#
len_
         =  Ptr Word8 -> Int -> IO Word8
forall b. Ptr b -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
F.peekByteOff Ptr Word8
buf (Int# -> Int
I# Int#
ix) IO Word8
-> (Word8 -> IO (Maybe (Date32, Int))) -> IO (Maybe (Date32, Int))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(Word8
r :: Word8)
         -> if Word8
r Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
sep
                then Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
loadDay (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int#
yy Int#
mm 
                else Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        loadDay :: Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
loadDay Int#
ix Int#
yy Int#
mm
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
2#) Int# -> Int# -> Int#
<=# Int#
len_
         , (# Int#
1#, Int#
dd, Int#
o #)    <- Ptr Any -> Int# -> (# Int#, Int#, Int# #)
forall {a}. Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' (Ptr Word8
buf Ptr Word8 -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`F.plusPtr` (Int# -> Int
I# Int#
ix)) Int#
2#
         = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return 
         (Maybe (Date32, Int) -> IO (Maybe (Date32, Int)))
-> Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a b. (a -> b) -> a -> b
$ (Date32, Int) -> Maybe (Date32, Int)
forall a. a -> Maybe a
Just ((Int, Int, Int) -> Date32
pack   ( Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# Int#
yy)
                        , Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# Int#
mm)
                        , Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# Int#
dd))
                , Int# -> Int
I# (Int#
ix Int# -> Int# -> Int#
+# Int#
o))

         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing
{-# NOINLINE loadYYYYsMMsDD #-}


---------------------------------------------------------------------------------------------------
-- | Read a date in YYYYsMMsDD format from the given buffer.
loadDDsMMsYYYY
        :: Word8                        -- ^ Separating character.
        -> Ptr Word8                    -- ^ Buffer.
        -> Int                          -- ^ Length of buffer.
        -> IO (Maybe (Date32, Int))     -- ^ Result.

loadDDsMMsYYYY :: Word8 -> Ptr Word8 -> Int -> IO (Maybe (Date32, Int))
loadDDsMMsYYYY !Word8
sep !Ptr Word8
buf (I# Int#
len_)
 = IO (Maybe (Date32, Int))
loadDay
 where  loadDay :: IO (Maybe (Date32, Int))
loadDay 
         | Int#
1# <- Int#
2#          Int# -> Int# -> Int#
<=# Int#
len_
         , (# Int#
1#, Int#
dd, Int#
o #)      <- Ptr Word8 -> Int# -> (# Int#, Int#, Int# #)
forall {a}. Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' Ptr Word8
buf Int#
2#
         = Int# -> Int# -> IO (Maybe (Date32, Int))
sep1 Int#
o Int#
dd
         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        sep1 :: Int# -> Int# -> IO (Maybe (Date32, Int))
sep1 Int#
ix Int#
dd
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
1#)  Int# -> Int# -> Int#
<=# Int#
len_    
         = Ptr Word8 -> Int -> IO Word8
forall b. Ptr b -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
F.peekByteOff Ptr Word8
buf (Int# -> Int
I# Int#
ix) IO Word8
-> (Word8 -> IO (Maybe (Date32, Int))) -> IO (Maybe (Date32, Int))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(Word8
r :: Word8)
         -> if Word8
r Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
sep
                then Int# -> Int# -> IO (Maybe (Date32, Int))
loadMonth (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int#
dd
                else Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        loadMonth :: Int# -> Int# -> IO (Maybe (Date32, Int))
loadMonth Int#
ix Int#
dd
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
2#)   Int# -> Int# -> Int#
<=# Int#
len_    
         , (# Int#
1#, Int#
mm, Int#
o #)    <- Ptr Any -> Int# -> (# Int#, Int#, Int# #)
forall {a}. Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' (Ptr Word8
buf Ptr Word8 -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`F.plusPtr` (Int# -> Int
I# Int#
ix)) Int#
2#
         = Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
sep2 (Int#
ix Int# -> Int# -> Int#
+# Int#
o) Int#
dd Int#
mm
         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        sep2 :: Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
sep2 Int#
ix Int#
dd Int#
mm
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int# -> Int# -> Int#
<=# Int#
len_
         = Ptr Word8 -> Int -> IO Word8
forall b. Ptr b -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
F.peekByteOff Ptr Word8
buf (Int# -> Int
I# Int#
ix) IO Word8
-> (Word8 -> IO (Maybe (Date32, Int))) -> IO (Maybe (Date32, Int))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(Word8
r :: Word8)
         -> if Word8
r Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
sep
                then Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
loadYear (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int#
dd Int#
mm
                else Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing

        loadYear :: Int# -> Int# -> Int# -> IO (Maybe (Date32, Int))
loadYear Int#
ix Int#
dd Int#
mm 
         | Int#
1# <- (Int#
ix Int# -> Int# -> Int#
+# Int#
4#) Int# -> Int# -> Int#
<=# Int#
len_
         , (# Int#
1#, Int#
yy, Int#
o #)    <- Ptr Any -> Int# -> (# Int#, Int#, Int# #)
forall {a}. Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' (Ptr Word8
buf Ptr Word8 -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`F.plusPtr` (Int# -> Int
I# Int#
ix)) Int#
4#
         = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return 
         (Maybe (Date32, Int) -> IO (Maybe (Date32, Int)))
-> Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a b. (a -> b) -> a -> b
$ (Date32, Int) -> Maybe (Date32, Int)
forall a. a -> Maybe a
Just ((Int, Int, Int) -> Date32
pack   ( Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# Int#
yy)
                        , Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# Int#
mm)
                        , Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# Int#
dd))
                , Int# -> Int
I# (Int#
ix Int# -> Int# -> Int#
+# Int#
o))

         | Bool
otherwise    = Maybe (Date32, Int) -> IO (Maybe (Date32, Int))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Date32, Int)
forall a. Maybe a
Nothing
{-# NOINLINE loadDDsMMsYYYY #-}


loadInt' :: Ptr a -> Int# -> (# Int#, Int#, Int# #)
loadInt' (Ptr Addr#
addr) Int#
len
 = Addr# -> Int# -> (# Int#, Int#, Int# #)
loadInt# Addr#
addr Int#
len
{-# INLINE loadInt' #-}