|
| 1 | +module Web.File.Blob |
| 2 | + ( Blob |
| 3 | + , type_ |
| 4 | + , size |
| 5 | + , StartByte(..) |
| 6 | + , EndByte(..) |
| 7 | + , ByteIdx |
| 8 | + , idxFromInt |
| 9 | + , idxFromNumber |
| 10 | + , slice |
| 11 | + , slice' |
| 12 | + ) where |
| 13 | + |
| 14 | +import Data.Int (toNumber) |
| 15 | +import Data.Maybe (Maybe(..)) |
| 16 | +import Data.MediaType (MediaType(..)) |
| 17 | +import Math (round) |
| 18 | +import Prelude ((==), (>>>)) |
| 19 | +import Unsafe.Coerce (unsafeCoerce) |
| 20 | + |
| 21 | +foreign import data Blob :: Type |
| 22 | + |
| 23 | +foreign import typeImpl :: Blob -> String |
| 24 | + |
| 25 | +-- | `MediaType` of the data contained in the `Blob`. |
| 26 | +-- | Returns `Nothing` if the `MediaType` is unknown. |
| 27 | +type_ :: Blob -> Maybe MediaType |
| 28 | +type_ blob = |
| 29 | + let |
| 30 | + blobType = typeImpl blob |
| 31 | + in |
| 32 | + if blobType == "" |
| 33 | + then Nothing |
| 34 | + else Just (MediaType blobType) |
| 35 | + |
| 36 | +-- | The size (in bytes) of the data contained in the `Blob`. |
| 37 | +foreign import size :: Blob -> Number |
| 38 | + |
| 39 | +-- | An index into the Blob indicating the first byte to include in the new Blob. |
| 40 | +-- | If you specify a negative value, it's treated as an offset from the end of the |
| 41 | +-- | string toward the beginning. For example, -10 would be the 10th from last byte |
| 42 | +-- | in the Blob. If you specify a value for start that is larger than the size |
| 43 | +-- | of the source Blob, the returned Blob has size 0 and contains no data. |
| 44 | +newtype StartByte = StartByte ByteIdx |
| 45 | + |
| 46 | +-- | An index into the Blob indicating the first byte that will *not* be included |
| 47 | +-- | in the new Blob (i.e. the byte exactly at this index is not included). |
| 48 | +-- | If you specify a negative value, it's treated as an offset from the end of |
| 49 | +-- | the string toward the beginning. For example, -10 would be the 10th from |
| 50 | +-- | last byte in the Blob. The default value is size. |
| 51 | +newtype EndByte = EndByte ByteIdx |
| 52 | + |
| 53 | +foreign import data ByteIdx :: Type |
| 54 | + |
| 55 | +-- | Creates `ByteIdx` from `Int` value |
| 56 | +idxFromInt :: Int -> ByteIdx |
| 57 | +idxFromInt = toNumber >>> unsafeCoerce |
| 58 | + |
| 59 | +-- | Creates `ByteIdx` from `Number` value using `Math.round`. |
| 60 | +idxFromNumber :: Number -> ByteIdx |
| 61 | +idxFromNumber = round >>> unsafeCoerce |
| 62 | + |
| 63 | +-- | Creates a new `Blob` object (with specified `MediaType`), containing the |
| 64 | +-- | data in the specified range of bytes of the source Blob, by setting . |
| 65 | +foreign import slice ∷ MediaType -> StartByte -> EndByte -> Blob -> Blob |
| 66 | + |
| 67 | +-- | Creates a new `Blob` object containing the data in the specified range |
| 68 | +-- | of bytes of the source Blob. |
| 69 | +slice' ∷ StartByte -> EndByte -> Blob -> Blob |
| 70 | +slice' = slice (MediaType "") |
0 commit comments