1-- | Primitive parsers for decoding Google Protocol Buffers.
3-- | You almost never need to import this module.
4-- | See package README for explanation.
21, module Protobuf.Decode32
22, module Protobuf.Decode64
27import Control.Monad.Trans.Class (lift)
28import Data.ArrayBuffer.ArrayBuffer as AB
29import Data.ArrayBuffer.DataView as DV
30import Data.ArrayBuffer.Typed as AT
31import Data.ArrayBuffer.Types (DataView, Uint8Array)
32import Data.Either (Either(..))
33import Data.Float32 (Float32)
34import Data.Int (Radix, radix, toStringAs)
35import Data.Long.Internal (Long, Signed, Unsigned, fromLowHighBits, highBits, lowBits, unsignedToSigned)
36import Data.Long.Internal as Long
37import Data.Maybe (Maybe(..), fromJust)
38import Data.TextDecoding (decodeUtf8)
39import Data.UInt (UInt)
40import Data.UInt as UInt
42import Effect.Class (class MonadEffect, liftEffect)
43import Partial.Unsafe (unsafePartial)
44import Protobuf.Common (Bytes(..))
45import Protobuf.Decode32 (varint32, zigzag32, tag32)
46import Protobuf.Decode64 (varint64, zigzag64)
47import Text.Parsing.Parser (ParserT, fail)
48import Text.Parsing.Parser.DataView as Parse
51-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
52double :: forall m. MonadEffect m => ParserT DataView m Number
53double = Parse.anyFloat64le
56-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
57float :: forall m. MonadEffect m => ParserT DataView m Float32
58float = Parse.anyFloat32le
61-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
62int32 :: forall m. MonadEffect m => ParserT DataView m Int
66 -- But this is a problem with the Protobuf spec?
67 -- “If you use int32 or int64 as the type for a negative number, the resulting
68 -- varint is always ten bytes long”
69 -- https://developers.google.com/protocol-buffers/docs/encoding#signed_integers
70 -- So what are we supposed to do if the field type is int32 but the
71 -- decoded varint is too big? There is no guarantee that either negative
72 -- or positive numbers encoded as varints will be in range.
73 -- I suppose we could check that the high bits are all 0
74 -- for positive or all 1 for negative.
75 -- The conformance tests seem to like it if we just throw away
76 -- the hight bits. So that's what we'll do.
78 -- conformance checker hates this:
79 -- case Long.toInt n of
80 -- Nothing -> fail "int32 value out of range."
84-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
85int64 :: forall m. MonadEffect m => ParserT DataView m (Long Signed)
86int64 = unsignedToSigned <$> varint64
89-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
90uint32 :: forall m. MonadEffect m => ParserT DataView m UInt
93 pure $ UInt.fromInt $ lowBits n
96-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
97uint64 :: forall m. MonadEffect m => ParserT DataView m (Long Unsigned)
101-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
102sint32 :: forall m. MonadEffect m => ParserT DataView m Int
104 n <- zigzag32 <$> varint32
106 -- n <- zigzag64 <$> varint64
107 -- -- pure $ lowBits n
108 -- case Long.toInt n of
109 -- -- Nothing -> fail "sint32 value out of range."
110 -- Nothing -> fail $ "\nsint32 value out of range.\n lowBits " <> toStringAs (unsafePartial $ fromJust $ radix 16) (lowBits n) <> "\n highBits " <> toStringAs (unsafePartial $ fromJust $ radix 16) (highBits n)
114-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
115sint64 :: forall m. MonadEffect m => ParserT DataView m (Long Signed)
116sint64 = zigzag64 <$> varint64
119-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
120fixed32 :: forall m. MonadEffect m => ParserT DataView m UInt
121fixed32 = Parse.anyUint32le
124-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
125fixed64 :: forall m. MonadEffect m => ParserT DataView m (Long Unsigned)
126fixed64 = fromLowHighBits <$> Parse.anyInt32le <*> Parse.anyInt32le
129-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
130sfixed32 :: forall m. MonadEffect m => ParserT DataView m Int
131sfixed32 = Parse.anyInt32le
134-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
135sfixed64 :: forall m. MonadEffect m => ParserT DataView m (Long Signed)
136sfixed64 = fromLowHighBits <$> Parse.anyInt32le <*> Parse.anyInt32le
139-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
140bool :: forall m. MonadEffect m => ParserT DataView m Boolean
143 if lowBits x == 0 && highBits x == 0
148-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
149string :: forall m. MonadEffect m => ParserT DataView m String
151 stringview <- varint32 >>= UInt.toInt >>> Parse.takeN
152 stringarray <- lift $ liftEffect $ mkTypedArray stringview
153 case decodeUtf8 stringarray of
154 Left err -> fail $ "string decodeUtf8 failed. " <> show err
157 mkTypedArray :: DataView -> Effect Uint8Array
159 let buffer = DV.buffer dv
160 byteOffset = DV.byteOffset dv
161 byteLength = DV.byteLength dv
162 AT.part buffer byteOffset byteLength
165-- | [Scalar Value Type](https://developers.google.com/protocol-buffers/docs/proto3#scalar)
166bytes :: forall m. MonadEffect m => ParserT DataView m Bytes
168 len <- UInt.toInt <$> varint32
169 dv <- Parse.takeN len
170 let ab = DV.buffer dv
171 let begin = DV.byteOffset dv
172 pure $ Bytes $ AB.slice begin (begin + len) ab
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list