mirror of
https://github.com/unclechu/gRPC-haskell.git
synced 2024-07-05 19:03:31 +02:00
* grpc_server_request_call * basic slice functionality * rename function to emphasize side effects * add docs * ByteBuffer function bindings * replace unsafeCoerce with more specific function, add docs, tests. * add newtypes for Tag and Reserved void pointers * manually fix request_registered_call binding * use nocode keyword to fix Ptr () problems * decouple copying Slice from freeing slice * Add time ops * remove nocode decls * Start Op module, fix c2hs preprocessing order * metadata manipulation operations * metadata free function, test * helper functions for constructing ops of each type * bindings for op creation functions * finish up Op creation functions, implement Op destruction, add docs. * tweak documentation * rework Op creation functions to work with an array of ops, for ease of use with grpc_call_start_batch * forgot to change return types * wrap hook lines, fix types to op creation functions * implement part of the payload test * hideous, but working, end to end test * bindings for connectivity state checks, split test into two threads * various cleanup * rename Core to Unsafe for emphasis, clean up tests more * begin safe low-level facilities * begin completion queue and server stuff * Finish server start/stop, cq start/stop, add tests * facilities for safely executing op batches * reorganize LowLevel modules, begin explicit export list * client functionality, stub payload test, various refactors * tweak cabal file, add test * add more documentation * doc tweaks * begin refactor to improve CompletionQueue safety * export only thread-safe CQ functions, add registered call creation and other CQ utilities * begin refactor to use GRPCIO monad, fix missing push semaphore, fix mem leak in server calls * switch to explicit Either where needed * add crashing tests, continue fleshing out serverHandleNormalCall * fix haddock error, finish first draft of request handling function * reduce GHC warnings * non-registered client request helpers * initial request/response test working * don't pass tags around; generate where needed * server call bracket functions * correct order of semaphore acquisition and shutdown check * simple debug flag logging, simplify Call type * fix various registered method issues (but still not working) * cleanup * delete old code * remove old todo * use MetadataMap synonym pervasively * more comments * update TODOs * tweak safety caveat * docs tweaks * improve haddocks * add casts to eliminate clang warnings, remove unused function * update options to eliminate cabal warnings * remove outdated todo * remove unneeded exports from CompletionQueue * rename to GRPCIOCallError, re-add create/shutdown exports (needed for Server module) * newtypes for hosts and method names * more newtypes * more debug logging * Fix flag name collision * instrument uses of free * more debug * switch to STM for completion queue stuff * reduce warnings * more debugging, create/destroy call tests * refactor, fix failure cleanup for server call creation. More tests passing. * formatting tweaks
52 lines
2.1 KiB
Plaintext
52 lines
2.1 KiB
Plaintext
module Network.GRPC.Unsafe.Slice where
|
|
|
|
#include <grpc/impl/codegen/slice.h>
|
|
#include <grpc_haskell.h>
|
|
|
|
import qualified Data.ByteString as B
|
|
import Foreign.C.String
|
|
import Foreign.C.Types
|
|
import Foreign.Ptr
|
|
|
|
-- | A 'Slice' is gRPC's string type. We can easily convert these to and from
|
|
-- ByteStrings. This type is a pointer to a C type.
|
|
{#pointer *gpr_slice as Slice newtype #}
|
|
|
|
-- TODO: we could also represent this type as 'Ptr Slice', by doing this:
|
|
-- newtype Slice = Slice {#type gpr_slice#}
|
|
-- This would have no practical effect, but it would communicate intent more
|
|
-- clearly by emphasizing that the type is indeed a pointer and that the data
|
|
-- it is pointing to might change/be destroyed after running IO actions. To make
|
|
-- the change, we would just need to change all occurrences of 'Slice' to
|
|
-- 'Ptr Slice' and add 'castPtr' in and out marshallers.
|
|
-- This seems like the right way to do it, but c2hs doesn't make it easy, so
|
|
-- maybe the established idiom is to do what c2hs does.
|
|
|
|
-- | Get the length of a slice.
|
|
{#fun gpr_slice_length_ as ^ {`Slice'} -> `CULong'#}
|
|
|
|
-- | Returns a pointer to the start of the character array contained by the
|
|
-- slice.
|
|
{#fun gpr_slice_start_ as ^ {`Slice'} -> `Ptr CChar' castPtr #}
|
|
|
|
{#fun gpr_slice_from_copied_string_ as ^ {`CString'} -> `Slice'#}
|
|
|
|
-- | Properly cleans up all memory used by a 'Slice'. Danger: the Slice should
|
|
-- not be used after this function is called on it.
|
|
{#fun free_slice as ^ {`Slice'} -> `()'#}
|
|
|
|
-- | Copies a 'Slice' to a ByteString.
|
|
-- TODO: there are also non-copying unsafe ByteString construction functions.
|
|
-- We could gain some speed by using them.
|
|
-- idea would be something :: (ByteString -> Response) -> IO () that handles
|
|
-- getting and freeing the slice behind the scenes.
|
|
sliceToByteString :: Slice -> IO B.ByteString
|
|
sliceToByteString slice = do
|
|
len <- fmap fromIntegral $ gprSliceLength slice
|
|
str <- gprSliceStart slice
|
|
B.packCStringLen (str, len)
|
|
|
|
-- | Copies a 'ByteString' to a 'Slice'.
|
|
byteStringToSlice :: B.ByteString -> IO Slice
|
|
byteStringToSlice bs = B.useAsCString bs gprSliceFromCopiedString
|