gRPC 1.2.0 compatibility (#12)

* update for reorganized headers in gRPC v1.1: https://github.com/grpc/grpc/pull/7559

* update nix files

* rename all gpr_slice to grpc_slice since we can't be backwards compatible anyway

* use gRPC 1.1.4

* now compatible with gRPC 1.2.0

* use nixpkgs 17.03 to get protobuf3_2, newer proto3-* deps, fix some warnings

* another warning
This commit is contained in:
Connor Clark 2017-04-14 19:28:01 -07:00 committed by GitHub
parent 4ab231c1d9
commit b550607f60
15 changed files with 147 additions and 137 deletions

View file

@ -4,6 +4,7 @@
#include <grpc/grpc_security.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/slice.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -38,32 +39,47 @@ grpc_call *grpc_channel_create_call_(grpc_channel *channel,
grpc_completion_queue *completion_queue,
const char *method, const char *host,
gpr_timespec *deadline, void *reserved) {
grpc_slice method_slice = grpc_slice_from_copied_string(method);
grpc_slice host_slice = grpc_slice_from_copied_string(host);
return grpc_channel_create_call(channel, parent_call, propagation_mask,
completion_queue, method, host,
*deadline, reserved);
completion_queue, method_slice,
&host_slice, *deadline, reserved);
}
size_t gpr_slice_length_(gpr_slice *slice){
return GPR_SLICE_LENGTH(*slice);
}
uint8_t *gpr_slice_start_(gpr_slice *slice){
return GPR_SLICE_START_PTR(*slice);
}
gpr_slice* gpr_slice_from_copied_buffer_(const char *source, size_t len){
gpr_slice* retval = malloc(sizeof(gpr_slice));
//note: 'gpr_slice_from_copied_string' handles allocating space for 'source'.
*retval = gpr_slice_from_copied_buffer(source, len);
grpc_slice* grpc_slice_malloc_(size_t len){
grpc_slice* retval = malloc(sizeof(grpc_slice));
*retval = grpc_slice_malloc(len);
return retval;
}
void gpr_slice_unref_(gpr_slice* slice){
gpr_slice_unref(*slice);
size_t grpc_slice_length_(grpc_slice *slice){
return GRPC_SLICE_LENGTH(*slice);
}
void free_slice(gpr_slice *slice){
gpr_slice_unref(*slice);
uint8_t *grpc_slice_start_(grpc_slice *slice){
return GRPC_SLICE_START_PTR(*slice);
}
grpc_slice* grpc_slice_from_copied_string_(const char* source){
grpc_slice* retval = malloc(sizeof(grpc_slice));
*retval = grpc_slice_from_copied_string(source);
return retval;
}
grpc_slice* grpc_slice_from_copied_buffer_(const char *source, size_t len){
grpc_slice* retval = malloc(sizeof(grpc_slice));
//note: 'grpc_slice_from_copied_string' handles allocating space for 'source'.
*retval = grpc_slice_from_copied_buffer(source, len);
return retval;
}
void grpc_slice_unref_(grpc_slice* slice){
grpc_slice_unref(*slice);
}
void free_slice(grpc_slice *slice){
grpc_slice_unref(*slice);
grpc_haskell_free("free_slice", slice);
}
@ -89,8 +105,8 @@ void byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader){
grpc_haskell_free("byte_buffer_reader_destroy", reader);
}
gpr_slice *grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader){
gpr_slice *retval = malloc(sizeof(gpr_slice));
grpc_slice *grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader){
grpc_slice *retval = malloc(sizeof(grpc_slice));
*retval = grpc_byte_buffer_reader_readall(reader);
return retval;
}
@ -170,24 +186,18 @@ void metadata_free(grpc_metadata* m){
void set_metadata_key_val(char *key, char *val, size_t val_len,
grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i;
p->key = key;
p->value = val;
p->value_length = val_len;
p->key = grpc_slice_from_copied_string(key);
p->value = grpc_slice_from_copied_buffer(val,val_len);
}
const char* get_metadata_key(grpc_metadata *arr, size_t i){
grpc_slice* get_metadata_key(grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i;
return p->key;
return &p->key;
}
const char* get_metadata_val(grpc_metadata *arr, size_t i){
grpc_slice* get_metadata_val(grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i;
return p->value;
}
size_t get_metadata_val_len(grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i;
return p->value_length;
return &(p->value);
}
grpc_op* op_array_create(size_t n){
@ -207,7 +217,7 @@ void op_array_destroy(grpc_op* op_array, size_t n){
metadata_free(op->data.send_initial_metadata.metadata);
break;
case GRPC_OP_SEND_MESSAGE:
grpc_byte_buffer_destroy(op->data.send_message);
grpc_byte_buffer_destroy(op->data.send_message.send_message);
break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
break;
@ -256,7 +266,7 @@ void op_send_message(grpc_op *op_array, size_t i,
grpc_byte_buffer *payload){
grpc_op *op = op_array + i;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = grpc_byte_buffer_copy(payload);
op->data.send_message.send_message = grpc_byte_buffer_copy(payload);
op->flags = 0;
op->reserved = NULL;
}
@ -272,7 +282,7 @@ void op_recv_initial_metadata(grpc_op *op_array, size_t i,
grpc_metadata_array** arr){
grpc_op *op = op_array + i;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = *arr;
op->data.recv_initial_metadata.recv_initial_metadata = *arr;
op->flags = 0;
op->reserved = NULL;
}
@ -281,7 +291,7 @@ void op_recv_message(grpc_op *op_array, size_t i,
grpc_byte_buffer **payload_recv){
grpc_op *op = op_array + i;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = payload_recv;
op->data.recv_message.recv_message = payload_recv;
op->flags = 0;
op->reserved = NULL;
}
@ -289,13 +299,12 @@ void op_recv_message(grpc_op *op_array, size_t i,
void op_recv_status_client(grpc_op *op_array, size_t i,
grpc_metadata_array** arr,
grpc_status_code* status,
char **details, size_t* details_capacity){
grpc_slice* details){
grpc_op *op = op_array + i;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = *arr;
op->data.recv_status_on_client.status = status;
op->data.recv_status_on_client.status_details = details;
op->data.recv_status_on_client.status_details_capacity = details_capacity;
op->flags = 0;
op->reserved = NULL;
}
@ -310,7 +319,7 @@ void op_recv_close_server(grpc_op *op_array, size_t i, int *was_cancelled){
void op_send_status_server(grpc_op *op_array, size_t i,
size_t metadata_count, grpc_metadata* m,
grpc_status_code status, char *details){
grpc_status_code status, grpc_slice *details){
grpc_op *op = op_array + i;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = metadata_count;
@ -319,9 +328,7 @@ void op_send_status_server(grpc_op *op_array, size_t i,
memcpy(op->data.send_status_from_server.trailing_metadata, m,
metadata_count*sizeof(grpc_metadata));
op->data.send_status_from_server.status = status;
op->data.send_status_from_server.status_details
= malloc(sizeof(char)*(strlen(details) + 1));
strcpy((char*)(op->data.send_status_from_server.status_details), details);
op->data.send_status_from_server.status_details = details;
op->flags = 0;
op->reserved = NULL;
}
@ -398,12 +405,12 @@ grpc_call* grpc_channel_create_registered_call_(
*deadline, reserved);
}
char* call_details_get_method(grpc_call_details* details){
return details->method;
grpc_slice* call_details_get_method(grpc_call_details* details){
return &details->method;
}
char* call_details_get_host(grpc_call_details* details){
return details->host;
grpc_slice* call_details_get_host(grpc_call_details* details){
return &details->host;
}
gpr_timespec* call_details_get_deadline(grpc_call_details* details){

View file

@ -19,7 +19,7 @@ Flag Debug
flag with-examples
description: Also build example executables.
manual: True
default: True
default: False
library
build-depends:
@ -29,7 +29,7 @@ library
, stm == 2.4.*
, containers ==0.5.*
, managed >= 1.0.0 && < 1.1
, pipes ==4.1.*
, pipes >=4.1 && <=4.4
, transformers
, proto3-suite
, proto3-wire
@ -79,8 +79,8 @@ library
, grpc/status.h
, grpc/support/time.h
, grpc/impl/codegen/compression_types.h
, grpc/impl/codegen/slice_buffer.h
, grpc/impl/codegen/slice.h
, grpc/slice_buffer.h
, grpc/slice.h
build-tools: c2hs
default-language: Haskell2010
ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind
@ -206,14 +206,14 @@ test-suite test
, tasty-quickcheck ==0.8.*
, containers ==0.5.*
, managed >= 1.0.0 && < 1.1
, pipes ==4.1.*
, pipes >=4.1 && <=4.4
, proto3-suite
, transformers
, safe
, clock >=0.6.0 && <0.8.0
, turtle >= 1.2.0
, text
, QuickCheck ==2.8.*
, QuickCheck >=2.8 && <3.0
other-modules:
LowLevelTests,
LowLevelTests.Op,

View file

@ -4,7 +4,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/time.h>
#include <grpc/support/time.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
@ -23,13 +23,17 @@ grpc_call *grpc_channel_create_call_(grpc_channel *channel,
const char *method, const char *host,
gpr_timespec *deadline, void *reserved);
size_t gpr_slice_length_(gpr_slice *slice);
grpc_slice* grpc_slice_malloc_(size_t len);
uint8_t *gpr_slice_start_(gpr_slice *slice);
size_t grpc_slice_length_(grpc_slice *slice);
gpr_slice* gpr_slice_from_copied_buffer_(const char *source, size_t len);
uint8_t *grpc_slice_start_(grpc_slice *slice);
void free_slice(gpr_slice *slice);
grpc_slice* grpc_slice_from_copied_string_(const char* source);
grpc_slice* grpc_slice_from_copied_buffer_(const char *source, size_t len);
void free_slice(grpc_slice *slice);
grpc_byte_buffer **create_receiving_byte_buffer();
@ -39,7 +43,7 @@ grpc_byte_buffer_reader *byte_buffer_reader_create(grpc_byte_buffer *buffer);
void byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
gpr_slice* grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader);
grpc_slice* grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader);
void timespec_destroy(gpr_timespec* t);
@ -68,11 +72,9 @@ void metadata_free(grpc_metadata* m);
void set_metadata_key_val(char *key, char *val, size_t val_len,
grpc_metadata *arr, size_t i);
const char* get_metadata_key(grpc_metadata *arr, size_t i);
grpc_slice* get_metadata_key(grpc_metadata *arr, size_t i);
const char* get_metadata_val(grpc_metadata *arr, size_t i);
size_t get_metadata_val_len(grpc_metadata *arr, size_t i);
grpc_slice* get_metadata_val(grpc_metadata *arr, size_t i);
grpc_op* op_array_create(size_t n);
@ -95,15 +97,15 @@ void op_recv_message(grpc_op *op_array, size_t i,
grpc_byte_buffer **payload_recv);
void op_recv_status_client(grpc_op *op_array, size_t i,
grpc_metadata_array** arr,
grpc_status_code* status,
char **details, size_t* details_capacity);
grpc_metadata_array** arr,
grpc_status_code* status,
grpc_slice* details);
void op_recv_close_server(grpc_op *op_array, size_t i, int *was_cancelled);
void op_send_status_server(grpc_op *op_array, size_t i,
size_t metadata_count, grpc_metadata* m,
grpc_status_code status, char *details);
grpc_status_code status, grpc_slice *details);
grpc_status_code* create_status_code_ptr();
@ -135,9 +137,9 @@ grpc_call* grpc_channel_create_registered_call_(
grpc_completion_queue *completion_queue, void *registered_call_handle,
gpr_timespec *deadline, void *reserved);
char* call_details_get_method(grpc_call_details* details);
grpc_slice* call_details_get_method(grpc_call_details* details);
char* call_details_get_host(grpc_call_details* details);
grpc_slice* call_details_get_host(grpc_call_details* details);
gpr_timespec* call_details_get_deadline(grpc_call_details* details);

View file

@ -3,12 +3,12 @@
stdenv.mkDerivation rec {
name = "grpc-${version}";
version = "1.0.1-${lib.strings.substring 0 7 rev}";
rev = "6040b471bcd1d6bb05b25c126b6545180a1d3528";
version = "1.2.0-${lib.strings.substring 0 7 rev}";
rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
src = fetchgit {
inherit rev;
url = "https://github.com/grpc/grpc.git";
sha256 = "1kx6jkx2dnnfnjfyc50ravfk7mfdszj988vndrlzs1zkd6627k4z";
sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
};
preInstall = "export prefix";
buildInputs =

View file

@ -8,8 +8,8 @@ mkDerivation {
version = "0.1.0.0";
src = fetchgit {
url = "https://github.com/awakenetworks/proto3-suite.git";
sha256 = "1g6w4ddqybgwnj3143bkl7sp9f5ch6d8qpb242fi4m396585bpq9";
rev = "8db2ceb8c48a3f8dc2cbdc492d1e8cbaf8b62a15";
sha256 = "1w5qwwlivrxkd6943rxsw3znk9jjpf7ad11gm0zl4lzq6k3kdinp";
rev = "46f40d38c4db8a6320bab010ae30e75c83fab6ee";
};
libraryHaskellDepends = [
base bytestring cereal containers deepseq filepath haskell-src mtl

View file

@ -7,8 +7,8 @@ mkDerivation {
version = "1.0.0";
src = fetchgit {
url = "https://github.com/awakenetworks/proto3-wire.git";
sha256 = "1v1jsgsdrhaz3ddbil09yqimnps3svgqbjvdk7hil4irpgqkfs98";
rev = "1b88bf24aad15db1f59a00d201d609fa308157f7";
sha256 = "10z1sirmiz29r2nx5dza1y1p3kp83wsq80pz4msxqmaykpyh5iaa";
rev = "62b50ea460847dde5bc8e63d2f93360d9bfcae9d";
};
libraryHaskellDepends = [
base bytestring cereal containers deepseq QuickCheck safe text

View file

@ -1,6 +1,6 @@
{
"url": "https://github.com/NixOS/nixpkgs.git",
"rev": "7ae9da426924537755ce9164fd5b5f81ce16a1c3",
"date": "2017-01-31T10:35:58-06:00",
"sha256": "1fcvc066c270dd2yfir8cpj0gcslsbvw7grnk2fayb06rkppjxrf"
"rev": "1849e695b00a54cda86cb75202240d949c10c7ce",
"date": "2017-03-30T18:32:09+02:00",
"sha256": "1fw9ryrz1qzbaxnjqqf91yxk1pb9hgci0z0pzw53f675almmv9q2"
}

View file

@ -62,7 +62,12 @@ let
nixpkgs = import ./nixpkgs.nix;
config = {
packageOverrides = pkgs: rec {
cython = pkgs.buildPythonPackage rec {
protobuf3_2NoCheck =
pkgs.stdenv.lib.overrideDerivation
pkgs.pythonPackages.protobuf3_2
(oldAttrs : {doCheck = false; doInstallCheck = false;});
cython = pkgs.pythonPackages.buildPythonPackage rec {
name = "Cython-${version}";
version = "0.24.1";
@ -106,8 +111,8 @@ let
src = pkgs.fetchgit {
url = "https://github.com/grpc/grpc.git";
rev = "c204647295437b01337ad8e6c17c4296609c7a13";
sha256 = "0ifg5acwcb0qyf5g5mrja8ab4x3f1fxdw80rkmhn3kyjkhjzm9ik";
rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
};
preConfigure = ''
@ -127,7 +132,7 @@ let
propagatedBuildInputs = [
cython
pkgs.pythonPackages.futures
pkgs.pythonPackages.protobuf3_0
protobuf3_2NoCheck
pkgs.pythonPackages.enum34
];
};
@ -139,8 +144,8 @@ let
src = pkgs.fetchgit {
url = "https://github.com/grpc/grpc.git";
rev = "c204647295437b01337ad8e6c17c4296609c7a13";
sha256 = "0ifg5acwcb0qyf5g5mrja8ab4x3f1fxdw80rkmhn3kyjkhjzm9ik";
rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
};
preConfigure = ''
@ -162,7 +167,7 @@ let
propagatedBuildInputs = [
cython
pkgs.pythonPackages.futures
pkgs.pythonPackages.protobuf3_0
protobuf3_2NoCheck
pkgs.pythonPackages.enum34
grpcio
];

View file

@ -12,19 +12,18 @@ import Control.Monad.Trans.Except
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Maybe (catMaybes)
import Foreign.C.String (CString)
import Foreign.C.Types (CInt)
import Foreign.Marshal.Alloc (free, malloc,
mallocBytes)
import Foreign.Marshal.Alloc (free, malloc)
import Foreign.Ptr (Ptr, nullPtr)
import Foreign.Storable (peek, poke)
import Foreign.Storable (peek)
import Network.GRPC.LowLevel.CompletionQueue
import Network.GRPC.LowLevel.GRPC
import qualified Network.GRPC.Unsafe as C (Call)
import qualified Network.GRPC.Unsafe.ByteBuffer as C
import qualified Network.GRPC.Unsafe.Metadata as C
import qualified Network.GRPC.Unsafe.Op as C
import qualified Network.GRPC.Unsafe.Slice as C (Slice, freeSlice)
import qualified Network.GRPC.Unsafe.Slice as C
import Network.GRPC.Unsafe.Slice (Slice)
-- | Sum describing all possible send and receive operations that can be batched
-- and executed by gRPC. Usually these are processed in a handful of
@ -46,12 +45,10 @@ data OpContext =
OpSendInitialMetadataContext C.MetadataKeyValPtr Int
| OpSendMessageContext (C.ByteBuffer, C.Slice)
| OpSendCloseFromClientContext
| OpSendStatusFromServerContext C.MetadataKeyValPtr Int C.StatusCode
B.ByteString
| OpSendStatusFromServerContext C.MetadataKeyValPtr Int C.StatusCode Slice
| OpRecvInitialMetadataContext (Ptr C.MetadataArray)
| OpRecvMessageContext (Ptr C.ByteBuffer)
| OpRecvStatusOnClientContext (Ptr C.MetadataArray) (Ptr C.StatusCode)
(Ptr CString)
| OpRecvStatusOnClientContext (Ptr C.MetadataArray) (Ptr C.StatusCode) Slice
| OpRecvCloseOnServerContext (Ptr CInt)
deriving Show
@ -72,7 +69,7 @@ createOpContext (OpSendStatusFromServer m code (StatusDetails str)) =
uncurry OpSendStatusFromServerContext
<$> C.createMetadata m
<*> return code
<*> return str
<*> C.byteStringToSlice str
createOpContext OpRecvInitialMetadata =
fmap OpRecvInitialMetadataContext C.metadataArrayCreate
createOpContext OpRecvMessage =
@ -80,10 +77,8 @@ createOpContext OpRecvMessage =
createOpContext OpRecvStatusOnClient = do
pmetadata <- C.metadataArrayCreate
pstatus <- C.createStatusCodePtr
pstr <- malloc
cstring <- mallocBytes defaultStatusStringLen
poke pstr cstring
return $ OpRecvStatusOnClientContext pmetadata pstatus pstr
slice <- C.grpcSliceMalloc defaultStatusStringLen
return $ OpRecvStatusOnClientContext pmetadata pstatus slice
createOpContext OpRecvCloseOnServer =
fmap OpRecvCloseOnServerContext $ malloc
@ -97,14 +92,13 @@ setOpArray arr i (OpSendMessageContext (bb,_)) =
setOpArray arr i OpSendCloseFromClientContext =
C.opSendCloseClient arr i
setOpArray arr i (OpSendStatusFromServerContext kvs l code details) =
B.useAsCString details $ \cstr ->
C.opSendStatusServer arr i l kvs code cstr
C.opSendStatusServer arr i l kvs code details
setOpArray arr i (OpRecvInitialMetadataContext pmetadata) =
C.opRecvInitialMetadata arr i pmetadata
setOpArray arr i (OpRecvMessageContext pbb) =
C.opRecvMessage arr i pbb
setOpArray arr i (OpRecvStatusOnClientContext pmetadata pstatus pstr) = do
C.opRecvStatusClient arr i pmetadata pstatus pstr defaultStatusStringLen
setOpArray arr i (OpRecvStatusOnClientContext pmetadata pstatus slice) =
C.opRecvStatusClient arr i pmetadata pstatus slice
setOpArray arr i (OpRecvCloseOnServerContext pcancelled) = do
C.opRecvCloseServer arr i pcancelled
@ -120,12 +114,10 @@ freeOpContext (OpRecvInitialMetadataContext metadata) =
C.metadataArrayDestroy metadata
freeOpContext (OpRecvMessageContext pbb) =
C.destroyReceivingByteBuffer pbb
freeOpContext (OpRecvStatusOnClientContext metadata pcode pstr) = do
freeOpContext (OpRecvStatusOnClientContext metadata pcode slice) = do
C.metadataArrayDestroy metadata
C.destroyStatusCodePtr pcode
str <- peek pstr
free str
free pstr
C.freeSlice slice
freeOpContext (OpRecvCloseOnServerContext pcancelled) =
grpcDebug ("freeOpContext: freeing pcancelled: " ++ show pcancelled)
>> free pcancelled
@ -176,8 +168,7 @@ resultFromOpContext (OpRecvStatusOnClientContext pmetadata pcode pstr) = do
metadata <- peek pmetadata
metadataMap <- C.getAllMetadataArray metadata
code <- C.derefStatusCodePtr pcode
cstr <- peek pstr
statusInfo <- B.packCString cstr
statusInfo <- C.sliceToByteString pstr
return $ Just $ OpRecvStatusOnClientResult metadataMap code statusInfo
resultFromOpContext (OpRecvCloseOnServerContext pcancelled) = do
grpcDebug "resultFromOpContext: OpRecvCloseOnServerContext"

View file

@ -6,7 +6,7 @@ module Network.GRPC.Unsafe where
import Control.Exception (bracket)
import Control.Monad
import Data.ByteString (ByteString, useAsCString, packCString)
import Data.ByteString (ByteString, useAsCString)
import Foreign.C.String (CString, peekCString)
import Foreign.Marshal.Alloc (free)
@ -20,10 +20,11 @@ import Network.GRPC.Unsafe.Constants
{#import Network.GRPC.Unsafe.Op#}
{#import Network.GRPC.Unsafe.Metadata#}
{#import Network.GRPC.Unsafe.ChannelArgs#}
{#import Network.GRPC.Unsafe.Slice#}
#include <grpc/grpc.h>
#include <grpc/status.h>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/support/alloc.h>
#include <grpc_haskell.h>
{#context prefix = "grpc" #}
@ -286,8 +287,8 @@ getPeerPeek cstr = do
`CompletionQueue',unTag `Tag'}
-> `CallError'#}
{#fun unsafe call_details_get_method as ^ {`CallDetails'} -> `ByteString' packCString* #}
{#fun unsafe call_details_get_method as ^ {`CallDetails'} -> `ByteString' sliceToByteString* #}
{#fun unsafe call_details_get_host as ^ {`CallDetails'} -> `ByteString' packCString* #}
{#fun unsafe call_details_get_host as ^ {`CallDetails'} -> `ByteString' sliceToByteString* #}
{#fun call_details_get_deadline as ^ {`CallDetails'} -> `CTimeSpec' peek* #}

View file

@ -3,9 +3,9 @@
module Network.GRPC.Unsafe.ByteBuffer where
#include <grpc/grpc.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/slice.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/slice_buffer.h>
#include <grpc/slice_buffer.h>
#include <grpc_haskell.h>

View file

@ -9,7 +9,7 @@ import Foreign.Storable
#include <grpc/grpc.h>
#include <grpc/status.h>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/support/alloc.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc_haskell.h>

View file

@ -4,11 +4,13 @@
module Network.GRPC.Unsafe.Metadata where
{#import Network.GRPC.Unsafe.Slice#}
import Control.Exception
import Control.Monad
import Data.Function (on)
import Data.ByteString (ByteString, useAsCString,
useAsCStringLen, packCString, packCStringLen)
useAsCStringLen)
import Data.List (sortBy, groupBy)
import qualified Data.SortedList as SL
import qualified Data.Map.Strict as M
@ -111,13 +113,10 @@ setMetadataKeyVal k v m i =
useAsCStringLen v $ \(vStr, vLen) -> setMetadataKeyVal' k vStr vLen m i
{#fun unsafe get_metadata_key as getMetadataKey'
{`MetadataKeyValPtr', `Int'} -> `CString'#}
{`MetadataKeyValPtr', `Int'} -> `Slice'#}
{#fun unsafe get_metadata_val as getMetadataVal'
{`MetadataKeyValPtr', `Int'} -> `CString'#}
{#fun unsafe get_metadata_val_len as getMetadataValLen
{`MetadataKeyValPtr', `Int'} -> `Int'#}
{`MetadataKeyValPtr', `Int'} -> `Slice'#}
withMetadataArrayPtr :: (Ptr MetadataArray -> IO a) -> IO a
withMetadataArrayPtr = bracket metadataArrayCreate metadataArrayDestroy
@ -126,12 +125,11 @@ withMetadataKeyValPtr :: Int -> (MetadataKeyValPtr -> IO a) -> IO a
withMetadataKeyValPtr i f = bracket (metadataAlloc i) metadataFree f
getMetadataKey :: MetadataKeyValPtr -> Int -> IO ByteString
getMetadataKey m = getMetadataKey' m >=> packCString
getMetadataKey m = getMetadataKey' m >=> sliceToByteString
getMetadataVal :: MetadataKeyValPtr -> Int -> IO ByteString
getMetadataVal m i = do vStr <- getMetadataVal' m i
vLen <- getMetadataValLen m i
packCStringLen (vStr, vLen)
sliceToByteString vStr
createMetadata :: MetadataMap -> IO (MetadataKeyValPtr, Int)
createMetadata m = do

View file

@ -2,8 +2,9 @@
module Network.GRPC.Unsafe.Op where
{#import Network.GRPC.Unsafe.Slice#}
import Control.Exception
import Foreign.C.String
import Foreign.C.Types
import Foreign.Ptr
{#import Network.GRPC.Unsafe.ByteBuffer#}
@ -90,7 +91,7 @@ withOpArray n f = bracket (opArrayCreate n) (flip opArrayDestroy n) f
-- this call.
{#fun unsafe op_recv_status_client as ^
{`OpArray', `Int',id `Ptr MetadataArray', castPtr `Ptr StatusCode',
castPtr `Ptr CString', `Int'}
`Slice'}
-> `()'#}
-- | Creates an op of type GRPC_OP_RECV_CLOSE_ON_SERVER at the specified index
@ -104,5 +105,5 @@ withOpArray n f = bracket (opArrayCreate n) (flip opArrayDestroy n) f
-- Metadata and string are copied when creating the op, and can be safely
-- destroyed immediately after calling this function.
{#fun unsafe op_send_status_server as ^
{`OpArray', `Int', `Int', `MetadataKeyValPtr', `StatusCode', `CString'}
{`OpArray', `Int', `Int', `MetadataKeyValPtr', `StatusCode', `Slice'}
-> `()'#}

View file

@ -2,7 +2,7 @@
module Network.GRPC.Unsafe.Slice where
#include <grpc/impl/codegen/slice.h>
#include <grpc/slice.h>
#include <grpc_haskell.h>
import qualified Data.ByteString as B
@ -12,12 +12,12 @@ 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 #}
{#pointer *grpc_slice as Slice newtype #}
deriving instance Show Slice
-- TODO: we could also represent this type as 'Ptr Slice', by doing this:
-- newtype Slice = Slice {#type gpr_slice#}
-- newtype Slice = Slice {#type grpc_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
@ -27,13 +27,18 @@ deriving instance Show Slice
-- maybe the established idiom is to do what c2hs does.
-- | Get the length of a slice.
{#fun unsafe gpr_slice_length_ as ^ {`Slice'} -> `CULong'#}
{#fun unsafe grpc_slice_length_ as ^ {`Slice'} -> `CULong'#}
-- | Slices allocated using this function must be freed by
-- 'freeSlice'
{#fun unsafe grpc_slice_malloc_ as ^ {`Int'} -> `Slice'#}
-- | Returns a pointer to the start of the character array contained by the
-- slice.
{#fun unsafe gpr_slice_start_ as ^ {`Slice'} -> `Ptr CChar' castPtr #}
{#fun unsafe grpc_slice_start_ as ^ {`Slice'} -> `Ptr CChar' castPtr #}
{#fun unsafe gpr_slice_from_copied_buffer_ as ^ {`CString', `Int'} -> `Slice'#}
-- | Slices must be freed using 'freeSlice'.
{#fun unsafe grpc_slice_from_copied_buffer_ as ^ {`CString', `Int'} -> `Slice'#}
-- | Properly cleans up all memory used by a 'Slice'. Danger: the Slice should
-- not be used after this function is called on it.
@ -46,10 +51,10 @@ deriving instance Show Slice
-- getting and freeing the slice behind the scenes.
sliceToByteString :: Slice -> IO B.ByteString
sliceToByteString slice = do
len <- fmap fromIntegral $ gprSliceLength slice
str <- gprSliceStart slice
len <- fmap fromIntegral $ grpcSliceLength slice
str <- grpcSliceStart slice
B.packCStringLen (str, len)
-- | Copies a 'ByteString' to a 'Slice'.
byteStringToSlice :: B.ByteString -> IO Slice
byteStringToSlice bs = B.useAsCStringLen bs $ uncurry gprSliceFromCopiedBuffer
byteStringToSlice bs = B.useAsCStringLen bs $ uncurry grpcSliceFromCopiedBuffer