{-# LANGUAGE DeriveDataTypeable #-}
{- | This implements BootString en- and decoding, the foundation of Punycode
 -}
module Data.Encoding.BootString
	(BootString(..)
	,punycode) where

import Data.Encoding.Base
import Data.Encoding.Exception
import Data.Encoding.ByteSource
import Data.Encoding.ByteSink
import Control.Throws
import Data.Word
import Data.List (unfoldr,partition,find)
import Data.Char (ord,chr)
import Data.Typeable
import Control.Monad (when)

data BootString = BootString
	{BootString -> Int
base :: Int
	,BootString -> Int
tmin :: Int
	,BootString -> Int
tmax :: Int
	,BootString -> Int
skew :: Int
	,BootString -> Int
damp :: Int
	,BootString -> Int
init_bias :: Int
	,BootString -> Int
init_n    :: Int
	}
	deriving (Int -> BootString -> ShowS
[BootString] -> ShowS
BootString -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BootString] -> ShowS
$cshowList :: [BootString] -> ShowS
show :: BootString -> String
$cshow :: BootString -> String
showsPrec :: Int -> BootString -> ShowS
$cshowsPrec :: Int -> BootString -> ShowS
Show,BootString -> BootString -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BootString -> BootString -> Bool
$c/= :: BootString -> BootString -> Bool
== :: BootString -> BootString -> Bool
$c== :: BootString -> BootString -> Bool
Eq,Typeable)

punycode :: BootString
punycode :: BootString
punycode = BootString
	{base :: Int
base = Int
36
	,tmin :: Int
tmin = Int
1
	,tmax :: Int
tmax = Int
26
	,skew :: Int
skew = Int
38
	,damp :: Int
damp = Int
700
	,init_bias :: Int
init_bias = Int
72
	,init_n :: Int
init_n    = Int
0x80
	}

punyValue :: ByteSource m => Word8 -> m Int
punyValue :: forall (m :: * -> *). ByteSource m => Word8 -> m Int
punyValue Word8
c
	| Int
n forall a. Ord a => a -> a -> Bool
<  Int
0x30 = forall {a}. m a
norep
	| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0x39 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int
nforall a. Num a => a -> a -> a
-Int
0x30forall a. Num a => a -> a -> a
+Int
26
	| Int
n forall a. Ord a => a -> a -> Bool
<  Int
0x41 = forall {a}. m a
norep
	| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0x5A = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int
nforall a. Num a => a -> a -> a
-Int
0x41
	| Int
n forall a. Ord a => a -> a -> Bool
<  Int
0x61 = forall {a}. m a
norep
	| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0x7A = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int
nforall a. Num a => a -> a -> a
-Int
0x61
	| Bool
otherwise = forall {a}. m a
norep
	where
	n :: Int
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
c
	norep :: m a
norep = forall e (m :: * -> *) a. Throws e m => e -> m a
throwException (Word8 -> DecodingException
IllegalCharacter Word8
c)

punyChar :: ByteSink m => Int -> m Word8
punyChar :: forall (m :: * -> *). ByteSink m => Int -> m Word8
punyChar Int
c
	| Int
c forall a. Ord a => a -> a -> Bool
< Int
0  = forall {a}. m a
norep
	| Int
c forall a. Ord a => a -> a -> Bool
< Int
26 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Int
0x61forall a. Num a => a -> a -> a
+Int
c
	| Int
c forall a. Ord a => a -> a -> Bool
< Int
36 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Int
0x30forall a. Num a => a -> a -> a
+Int
cforall a. Num a => a -> a -> a
-Int
26
	| Bool
otherwise = forall {a}. m a
norep
	where
	norep :: m a
norep = forall e (m :: * -> *) a. Throws e m => e -> m a
throwException (Char -> EncodingException
HasNoRepresentation (Int -> Char
chr Int
c))

getT :: BootString -> Int -> Int -> Int
getT :: BootString -> Int -> Int -> Int
getT BootString
bs Int
k Int
bias
	| Int
k forall a. Ord a => a -> a -> Bool
<= Int
bias forall a. Num a => a -> a -> a
+ (BootString -> Int
tmin BootString
bs) = BootString -> Int
tmin BootString
bs
	| Int
k forall a. Ord a => a -> a -> Bool
>= Int
bias forall a. Num a => a -> a -> a
+ (BootString -> Int
tmax BootString
bs) = BootString -> Int
tmax BootString
bs
	| Bool
otherwise             = Int
kforall a. Num a => a -> a -> a
-Int
bias

adapt :: BootString -> Int -> Int -> Bool -> Int
adapt :: BootString -> Int -> Int -> Bool -> Int
adapt BootString
bs Int
delta Int
numpoints Bool
firsttime = let
	delta1 :: Int
delta1 = if Bool
firsttime
		then Int
delta forall a. Integral a => a -> a -> a
`div` (BootString -> Int
damp BootString
bs)
		else Int
delta forall a. Integral a => a -> a -> a
`div` Int
2
	delta2 :: Int
delta2 = Int
delta1 forall a. Num a => a -> a -> a
+ (Int
delta1 forall a. Integral a => a -> a -> a
`div` Int
numpoints)
	(Int
rd,Int
rk) = forall a. [a] -> a
head
		forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter ((forall a. Ord a => a -> a -> Bool
<=((BootString -> Int
base BootString
bs forall a. Num a => a -> a -> a
- BootString -> Int
tmin BootString
bs) forall a. Num a => a -> a -> a
* (BootString -> Int
tmax BootString
bs)) forall a. Integral a => a -> a -> a
`div` Int
2)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fst)
		forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> [a]
iterate (\(Int
d,Int
k) -> (Int
d forall a. Integral a => a -> a -> a
`div` (BootString -> Int
base BootString
bs forall a. Num a => a -> a -> a
- BootString -> Int
tmin BootString
bs),Int
kforall a. Num a => a -> a -> a
+(BootString -> Int
base BootString
bs))) (Int
delta2,Int
0)
	in Int
rk forall a. Num a => a -> a -> a
+ (((BootString -> Int
base BootString
bs forall a. Num a => a -> a -> a
- BootString -> Int
tmin BootString
bs forall a. Num a => a -> a -> a
+Int
1) forall a. Num a => a -> a -> a
* Int
rd) forall a. Integral a => a -> a -> a
`div` (Int
rd forall a. Num a => a -> a -> a
+ BootString -> Int
skew BootString
bs))

decodeValue :: ByteSource m => BootString -> Int -> Int -> Int -> Int -> [Int] -> m (Int,[Int])
decodeValue :: forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> Int -> Int -> Int -> [Int] -> m (Int, [Int])
decodeValue BootString
bs Int
bias Int
i Int
k Int
w (Int
x:[Int]
xs)
	| Int
x forall a. Ord a => a -> a -> Bool
>= BootString -> Int
base BootString
bs                     = forall e (m :: * -> *) a. Throws e m => e -> m a
throwException DecodingException
OutOfRange
	| Int
x forall a. Ord a => a -> a -> Bool
> (forall a. Bounded a => a
maxBound forall a. Num a => a -> a -> a
- Int
i) forall a. Integral a => a -> a -> a
`div` Int
w       = forall e (m :: * -> *) a. Throws e m => e -> m a
throwException DecodingException
OutOfRange
	| Int
x forall a. Ord a => a -> a -> Bool
<  Int
t                           = forall (m :: * -> *) a. Monad m => a -> m a
return (Int
ni,[Int]
xs)
	| Int
w forall a. Ord a => a -> a -> Bool
> forall a. Bounded a => a
maxBound forall a. Integral a => a -> a -> a
`div` (BootString -> Int
base BootString
bs forall a. Num a => a -> a -> a
- Int
t) = forall e (m :: * -> *) a. Throws e m => e -> m a
throwException DecodingException
OutOfRange
        | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
xs                          = forall e (m :: * -> *) a. Throws e m => e -> m a
throwException DecodingException
OutOfRange
	| Bool
otherwise = forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> Int -> Int -> Int -> [Int] -> m (Int, [Int])
decodeValue BootString
bs Int
bias Int
ni (Int
kforall a. Num a => a -> a -> a
+BootString -> Int
base BootString
bs) (Int
wforall a. Num a => a -> a -> a
*(BootString -> Int
base BootString
bs forall a. Num a => a -> a -> a
- Int
t)) [Int]
xs
	where
	ni :: Int
ni = Int
i forall a. Num a => a -> a -> a
+ Int
xforall a. Num a => a -> a -> a
*Int
w
	t :: Int
t  = BootString -> Int -> Int -> Int
getT BootString
bs Int
k Int
bias

decodeValues :: ByteSource m => BootString -> Int -> [Int] -> m [(Char,Int)]
decodeValues :: forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> [Int] -> m [(Char, Int)]
decodeValues BootString
bs Int
len [Int]
xs = forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> Int -> Int -> Int -> [Int] -> m [(Char, Int)]
decodeValues' BootString
bs (BootString -> Int
init_n BootString
bs) Int
0 (BootString -> Int
init_bias BootString
bs) Int
len [Int]
xs

decodeValues' :: ByteSource m => BootString -> Int -> Int -> Int -> Int -> [Int] -> m [(Char,Int)]
decodeValues' :: forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> Int -> Int -> Int -> [Int] -> m [(Char, Int)]
decodeValues' BootString
bs Int
n Int
i Int
bias Int
len [] = forall (m :: * -> *) a. Monad m => a -> m a
return []
decodeValues' BootString
bs Int
n Int
i Int
bias Int
len [Int]
xs = do
  (Int
ni,[Int]
rst) <- forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> Int -> Int -> Int -> [Int] -> m (Int, [Int])
decodeValue BootString
bs Int
bias Int
i (BootString -> Int
base BootString
bs) Int
1 [Int]
xs
  let (Int
dn,Int
nni) = Int
ni forall a. Integral a => a -> a -> (a, a)
`divMod` (Int
lenforall a. Num a => a -> a -> a
+Int
1)
  let nn :: Int
nn = Int
nforall a. Num a => a -> a -> a
+Int
dn
  if Int
dn forall a. Ord a => a -> a -> Bool
> forall a. Bounded a => a
maxBound forall a. Num a => a -> a -> a
- Int
n
     then forall e (m :: * -> *) a. Throws e m => e -> m a
throwException DecodingException
OutOfRange
     else (do
            [(Char, Int)]
rest <- forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> Int -> Int -> Int -> [Int] -> m [(Char, Int)]
decodeValues' BootString
bs Int
nn (Int
nniforall a. Num a => a -> a -> a
+Int
1) (BootString -> Int -> Int -> Bool -> Int
adapt BootString
bs (Int
niforall a. Num a => a -> a -> a
-Int
i) (Int
lenforall a. Num a => a -> a -> a
+Int
1) (Int
iforall a. Eq a => a -> a -> Bool
==Int
0)) (Int
lenforall a. Num a => a -> a -> a
+Int
1) [Int]
rst
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Int -> Char
chr forall a b. (a -> b) -> a -> b
$ Int
nn,Int
nni)forall a. a -> [a] -> [a]
:[(Char, Int)]
rest
          )
                                   
insertDeltas :: [(a,Int)] -> [a] -> [a]
insertDeltas :: forall a. [(a, Int)] -> [a] -> [a]
insertDeltas [] [a]
str     = [a]
str
insertDeltas ((a
c,Int
p):[(a, Int)]
xs) [a]
str = let
	([a]
l,[a]
r) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
p [a]
str
	in forall a. [(a, Int)] -> [a] -> [a]
insertDeltas [(a, Int)]
xs ([a]
lforall a. [a] -> [a] -> [a]
++[a
c]forall a. [a] -> [a] -> [a]
++[a]
r)

punyDecode :: ByteSource m => [Word8] -> [Word8] -> m String
punyDecode :: forall (m :: * -> *).
ByteSource m =>
[Word8] -> [Word8] -> m String
punyDecode [Word8]
base [Word8]
ext = do
  [Int]
pvals <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). ByteSource m => Word8 -> m Int
punyValue [Word8]
ext
  [(Char, Int)]
vals <- forall (m :: * -> *).
ByteSource m =>
BootString -> Int -> [Int] -> m [(Char, Int)]
decodeValues BootString
punycode (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Word8]
base) [Int]
pvals
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [(a, Int)] -> [a] -> [a]
insertDeltas [(Char, Int)]
vals (forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
chrforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (Integral a, Num b) => a -> b
fromIntegral) [Word8]
base)
  
encodeValue :: BootString -> Int -> Int -> Int -> Int -> [Int]
encodeValue :: BootString -> Int -> Int -> Int -> Int -> [Int]
encodeValue BootString
bs Int
bias Int
delta Int
n Int
c = forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr (\(Int
q,Int
k,Bool
out) -> let
		t :: Int
t = BootString -> Int -> Int -> Int
getT BootString
bs Int
k Int
bias
		(Int
nq,Int
dc) = (Int
qforall a. Num a => a -> a -> a
-Int
t) forall a. Integral a => a -> a -> (a, a)
`divMod` (BootString -> Int
base BootString
bs forall a. Num a => a -> a -> a
- Int
t)
		in if Bool
out
			then forall a. Maybe a
Nothing
			else (if Int
q forall a. Ord a => a -> a -> Bool
< Int
t
				then forall a. a -> Maybe a
Just (Int
q,(Int
q,Int
kforall a. Num a => a -> a -> a
+BootString -> Int
base BootString
bs,Bool
True))
				else forall a. a -> Maybe a
Just (Int
t forall a. Num a => a -> a -> a
+ Int
dc,(Int
nq,Int
kforall a. Num a => a -> a -> a
+BootString -> Int
base BootString
bs,Bool
False)))
		) (Int
delta,BootString -> Int
base BootString
bs,Bool
False)

encodeValues' :: BootString -> Int -> Int -> Int -> Int -> Int -> [Int] -> (Int,Int,Int,[Int])
encodeValues' :: BootString
-> Int
-> Int
-> Int
-> Int
-> Int
-> [Int]
-> (Int, Int, Int, [Int])
encodeValues' BootString
_  Int
_ Int
h Int
bias Int
delta Int
_ []     = (Int
delta,Int
h,Int
bias,[])
encodeValues' BootString
bs Int
b Int
h Int
bias Int
delta Int
n (Int
c:[Int]
cs) = case forall a. Ord a => a -> a -> Ordering
compare Int
c Int
n of
	Ordering
LT -> BootString
-> Int
-> Int
-> Int
-> Int
-> Int
-> [Int]
-> (Int, Int, Int, [Int])
encodeValues' BootString
bs Int
b Int
h Int
bias (Int
deltaforall a. Num a => a -> a -> a
+Int
1) Int
n [Int]
cs
	Ordering
GT -> BootString
-> Int
-> Int
-> Int
-> Int
-> Int
-> [Int]
-> (Int, Int, Int, [Int])
encodeValues' BootString
bs Int
b Int
h Int
bias Int
delta Int
n [Int]
cs
	Ordering
EQ -> let
		(Int
ndelta,Int
nh,Int
nbias,[Int]
rest) = BootString
-> Int
-> Int
-> Int
-> Int
-> Int
-> [Int]
-> (Int, Int, Int, [Int])
encodeValues' BootString
bs Int
b (Int
hforall a. Num a => a -> a -> a
+Int
1) (BootString -> Int -> Int -> Bool -> Int
adapt BootString
bs Int
delta (Int
hforall a. Num a => a -> a -> a
+Int
1) (Int
hforall a. Eq a => a -> a -> Bool
==Int
b)) Int
0 Int
n [Int]
cs
		xs :: [Int]
xs = BootString -> Int -> Int -> Int -> Int -> [Int]
encodeValue BootString
bs Int
bias Int
delta Int
n Int
c
		in (Int
ndelta,Int
nh,Int
nbias,[Int]
xsforall a. [a] -> [a] -> [a]
++[Int]
rest)

encodeValues :: BootString -> Int -> Int -> Int -> Int -> Int -> Int -> [Int] -> [Int]
encodeValues :: BootString
-> Int -> Int -> Int -> Int -> Int -> Int -> [Int] -> [Int]
encodeValues BootString
bs Int
b Int
l Int
h Int
bias Int
delta Int
n [Int]
cps
	| Int
h forall a. Eq a => a -> a -> Bool
== Int
l = []
	| Bool
otherwise = [Int]
outpforall a. [a] -> [a] -> [a]
++BootString
-> Int -> Int -> Int -> Int -> Int -> Int -> [Int] -> [Int]
encodeValues BootString
bs Int
b Int
l Int
nh Int
nbias (Int
ndeltaforall a. Num a => a -> a -> a
+Int
1) (Int
mforall a. Num a => a -> a -> a
+Int
1) [Int]
cps
	where
	m :: Int
m = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum (forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Ord a => a -> a -> Bool
>=Int
n) [Int]
cps)
	(Int
ndelta,Int
nh,Int
nbias,[Int]
outp) = BootString
-> Int
-> Int
-> Int
-> Int
-> Int
-> [Int]
-> (Int, Int, Int, [Int])
encodeValues' BootString
bs Int
b Int
h Int
bias (Int
delta forall a. Num a => a -> a -> a
+ (Int
m forall a. Num a => a -> a -> a
- Int
n)forall a. Num a => a -> a -> a
*(Int
h forall a. Num a => a -> a -> a
+ Int
1)) Int
m [Int]
cps

breakLast :: (a -> Bool) -> [a] -> Maybe ([a],[a])
breakLast :: forall a. (a -> Bool) -> [a] -> Maybe ([a], [a])
breakLast a -> Bool
p [a]
xs = do
  ([a]
bf,[a]
af,Integer
ind) <- forall {a} {a}.
(Ord a, Num a) =>
a -> Maybe a -> (a -> Bool) -> [a] -> Maybe ([a], [a], a)
breakLast' Integer
0 forall a. Maybe a
Nothing a -> Bool
p [a]
xs
  forall (m :: * -> *) a. Monad m => a -> m a
return ([a]
bf,[a]
af)
    where
      breakLast' :: a -> Maybe a -> (a -> Bool) -> [a] -> Maybe ([a], [a], a)
breakLast' a
n Maybe a
r a -> Bool
p [] = do
        a
v <- Maybe a
r
        forall (m :: * -> *) a. Monad m => a -> m a
return ([],[],a
v)
      breakLast' a
n Maybe a
r a -> Bool
p (a
x:[a]
xs) = let res :: Maybe ([a], [a], a)
res = if a -> Bool
p a
x
                                          then a -> Maybe a -> (a -> Bool) -> [a] -> Maybe ([a], [a], a)
breakLast' (a
nforall a. Num a => a -> a -> a
+a
1) (forall a. a -> Maybe a
Just a
n) a -> Bool
p [a]
xs
                                          else a -> Maybe a -> (a -> Bool) -> [a] -> Maybe ([a], [a], a)
breakLast' (a
nforall a. Num a => a -> a -> a
+a
1) Maybe a
r a -> Bool
p [a]
xs
                              in do
                                ([a]
bf,[a]
af,a
v) <- Maybe ([a], [a], a)
res
                                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if a
nforall a. Ord a => a -> a -> Bool
<a
v then (a
xforall a. a -> [a] -> [a]
:[a]
bf,[a]
af,a
v) else ([a]
bf,a
xforall a. a -> [a] -> [a]
:[a]
af,a
v)
                          

instance Encoding BootString where
    encodeChar :: forall (m :: * -> *). ByteSink m => BootString -> Char -> m ()
encodeChar BootString
_ Char
c = forall a. HasCallStack => String -> a
error String
"Data.Encoding.BootString.encodeChar: Please use 'encode' for encoding BootStrings"
    decodeChar :: forall (m :: * -> *). ByteSource m => BootString -> m Char
decodeChar BootString
_ = forall a. HasCallStack => String -> a
error String
"Data.Encoding.BootString.decodeChar: Please use 'decode' for decoding BootStrings"
    encode :: forall (m :: * -> *). ByteSink m => BootString -> String -> m ()
encode BootString
bs String
str = let (String
base,String
nbase) = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\Char
c -> Char -> Int
ord Char
c forall a. Ord a => a -> a -> Bool
< BootString -> Int
init_n BootString
bs) String
str
	                b :: Int
b = forall (t :: * -> *) a. Foldable t => t a -> Int
length String
base
                    in do
                      [Word8]
res <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). ByteSink m => Int -> m Word8
punyChar forall a b. (a -> b) -> a -> b
$ BootString
-> Int -> Int -> Int -> Int -> Int -> Int -> [Int] -> [Int]
encodeValues BootString
bs Int
b (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str) Int
b (BootString -> Int
init_bias BootString
bs) Int
0 (BootString -> Int
init_n BootString
bs) (forall a b. (a -> b) -> [a] -> [b]
map Char -> Int
ord String
str)
                      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
base) forall a b. (a -> b) -> a -> b
$ do
                               forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (Integral a, Num b) => a -> b
fromIntegralforall b c a. (b -> c) -> (a -> b) -> a -> c
.Char -> Int
ord) String
base
                               forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8 (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'-')
                      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8 [Word8]
res
    decode :: forall (m :: * -> *). ByteSource m => BootString -> m String
decode BootString
bs = do
      [Word8]
wrds <- forall (m :: * -> *) a. Monad m => m Bool -> m a -> m [a]
untilM forall (m :: * -> *). ByteSource m => m Bool
sourceEmpty forall (m :: * -> *). ByteSource m => m Word8
fetchWord8
      let m :: Word8
m = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'-'
      case forall a. (a -> Bool) -> [a] -> Maybe ([a], [a])
breakLast (forall a. Eq a => a -> a -> Bool
==Word8
m) [Word8]
wrds of
        Just ([],[Word8]
_) -> forall e (m :: * -> *) a. Throws e m => e -> m a
throwException (Word8 -> DecodingException
IllegalCharacter Word8
m)
	Just ([Word8]
base,Word8
_:[Word8]
nbase) -> case forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\Word8
w -> forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w forall a. Ord a => a -> a -> Bool
> BootString -> Int
init_n BootString
bs) [Word8]
base of
                                Maybe Word8
Nothing -> forall (m :: * -> *).
ByteSource m =>
[Word8] -> [Word8] -> m String
punyDecode [Word8]
base [Word8]
nbase
                                Just Word8
ww -> forall e (m :: * -> *) a. Throws e m => e -> m a
throwException (Word8 -> DecodingException
IllegalCharacter Word8
ww)
	Maybe ([Word8], [Word8])
Nothing -> forall (m :: * -> *).
ByteSource m =>
[Word8] -> [Word8] -> m String
punyDecode [] [Word8]
wrds
    encodeable :: BootString -> Char -> Bool
encodeable BootString
bs Char
c = Bool
True -- XXX: hm, really?