@@ -11,11 +11,13 @@ module Data.Yaml.Internal
11 , decodeHelper_
11 , decodeHelper_
12 , specialStrings
12 , specialStrings
13 , isNumeric
13 , isNumeric
16#if !MIN_VERSION_base(4,8,0)
17#if !MIN_VERSION_base(4,8,0)
17import Control.Applicative ((<$>), Applicative(..))
18import Control.Applicative ((<$>), Applicative(..))
20+import Control.Applicative ((<|>))
19import Control.Exception
21import Control.Exception
20import Control.Monad (liftM, ap, unless)
22import Control.Monad (liftM, ap, unless)
21import Control.Monad.IO.Class (MonadIO, liftIO)
23import Control.Monad.IO.Class (MonadIO, liftIO)
@@ -25,8 +27,9 @@ import Control.Monad.Trans.State
25import Data.Aeson
27import Data.Aeson
26import Data.Aeson.Types hiding (parse)
28import Data.Aeson.Types hiding (parse)
27import qualified Data.Attoparsec.Text as Atto
29import qualified Data.Attoparsec.Text as Atto
30+import Data.Bits (shiftL, (.|.))
28import Data.ByteString (ByteString)
31import Data.ByteString (ByteString)
29−import Data.Char (toUpper)
32+import Data.Char (toUpper, ord)
30import Data.Conduit ((.|), ConduitM, runConduit)
33import Data.Conduit ((.|), ConduitM, runConduit)
31import qualified Data.Conduit.List as CL
34import qualified Data.Conduit.List as CL
32import qualified Data.HashMap.Strict as M
35import qualified Data.HashMap.Strict as M
@@ -176,7 +179,16 @@ textToValue _ _ t
176 where titleCased = toUpper (T.head ref) `T.cons` T.tail ref
179 where titleCased = toUpper (T.head ref) `T.cons` T.tail ref
178textToScientific :: Text -> Either String Scientific
181textToScientific :: Text -> Either String Scientific
179−textToScientific = Atto.parseOnly (Atto.scientific <* Atto.endOfInput)
182+textToScientific = Atto.parseOnly (num <* Atto.endOfInput)
184+ num = (fromInteger <$> ("0x" *> Atto.hexadecimal))
185+ <|> (fromInteger <$> ("0o" *> octal))
188+ octal = T.foldl' step 0 <$> Atto.takeWhile1 isOctalDigit
190+ isOctalDigit c = (c >= '0' && c <= '7')
191+ step a c = (a `shiftL` 3) .|. fromIntegral (ord c - 48)
181parseO :: ConduitM Event o Parse Value
193parseO :: ConduitM Event o Parse Value
182parseO = do
194parseO = do
@@ -284,13 +296,4 @@ specialStrings = HashSet.fromList $ T.words
284 "y Y yes Yes YES n N no No NO true True TRUE false False FALSE on On ON off Off OFF null Null NULL ~ *"
296 "y Y yes Yes YES n N no No NO true True TRUE false False FALSE on On ON off Off OFF null Null NULL ~ *"
286isNumeric :: Text -> Bool
298isNumeric :: Text -> Bool
287−isNumeric t =
299+isNumeric = either (const False) (const True) . textToScientific
288− T.all isNumeric' t && T.any isNumber t
290− isNumber c = '0' <= c && c <= '9'
291− isNumeric' c = isNumber c