rb_compression_options.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <ruby/ruby.h>
20 
21 #include "rb_compression_options.h"
22 
23 #include <string.h>
24 
25 #include "rb_byte_buffer.h"
26 #include "rb_grpc.h"
28 
29 #include <grpc/compression.h>
30 #include <grpc/grpc.h>
33 #include <grpc/support/alloc.h>
34 #include <grpc/support/log.h>
36 
37 static VALUE grpc_rb_cCompressionOptions = Qnil;
38 
39 /* Ruby Ids for the names of valid compression levels. */
40 static VALUE id_compress_level_none = Qnil;
41 static VALUE id_compress_level_low = Qnil;
42 static VALUE id_compress_level_medium = Qnil;
43 static VALUE id_compress_level_high = Qnil;
44 
45 /* grpc_rb_compression_options wraps a grpc_compression_options.
46  * It can be used to get the channel argument key-values for specific
47  * compression settings. */
48 
49 /* Note that ruby objects of this type don't carry any state in other
50  * Ruby objects and don't have a mark for GC. */
52  /* The actual compression options that's being wrapped */
55 
58  if (p == NULL) {
59  return;
60  };
62  if (wrapper->wrapped != NULL) {
64  wrapper->wrapped = NULL;
65  }
66  xfree(p);
67 }
68 
69 /* Destroys the compression options instances and free the
70  * wrapped grpc compression options. */
71 static void grpc_rb_compression_options_free(void* p) {
74 }
75 
76 /* Ruby recognized data type for the CompressionOptions class. */
77 static rb_data_type_t grpc_rb_compression_options_data_type = {
78  "grpc_compression_options",
79  {NULL,
82  {NULL, NULL}},
83  NULL,
84  NULL,
85 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
86  RUBY_TYPED_FREE_IMMEDIATELY
87 #endif
88 };
89 
90 /* Allocates CompressionOptions instances.
91  Allocate the wrapped grpc compression options and
92  initialize it here too. */
93 static VALUE grpc_rb_compression_options_alloc(VALUE cls) {
96 
98  wrapper->wrapped = NULL;
101 
102  return TypedData_Wrap_Struct(cls, &grpc_rb_compression_options_data_type,
103  wrapper);
104 }
105 
106 /* Disables a compression algorithm, given the GRPC core internal number of a
107  * compression algorithm. */
109  VALUE self, VALUE algorithm_to_disable) {
110  grpc_compression_algorithm compression_algorithm = 0;
112 
113  TypedData_Get_Struct(self, grpc_rb_compression_options,
115  compression_algorithm =
116  (grpc_compression_algorithm)NUM2INT(algorithm_to_disable);
117 
119  compression_algorithm);
120 
121  return Qnil;
122 }
123 
124 /* Gets the compression internal enum value of a compression level given its
125  * name. */
127  VALUE level_name) {
128  Check_Type(level_name, T_SYMBOL);
129 
130  /* Check the compression level of the name passed in, and see which macro
131  * from the GRPC core header files match. */
132  if (id_compress_level_none == SYM2ID(level_name)) {
134  } else if (id_compress_level_low == SYM2ID(level_name)) {
136  } else if (id_compress_level_medium == SYM2ID(level_name)) {
138  } else if (id_compress_level_high == SYM2ID(level_name)) {
140  }
141 
142  rb_raise(rb_eArgError,
143  "Unrecognized compression level name."
144  "Valid compression level names are none, low, medium, and high.");
145 
146  /* Phony return statement. */
148 }
149 
150 /* Sets the default compression level, given the name of a compression level.
151  * Throws an error if no algorithm matched. */
153  grpc_compression_options* options, VALUE new_level_name) {
154  options->default_level.level =
156  options->default_level.is_set = 1;
157 }
158 
159 /* Gets the internal value of a compression algorithm suitable as the value
160  * in a GRPC core channel arguments hash.
161  * algorithm_value is an out parameter.
162  * Raises an error if the name of the algorithm passed in is invalid. */
164  grpc_compression_algorithm* algorithm_value, VALUE algorithm_name) {
165  grpc_slice name_slice;
166  VALUE algorithm_name_as_string = Qnil;
167 
168  Check_Type(algorithm_name, T_SYMBOL);
169 
170  /* Convert the algorithm symbol to a ruby string, so that we can get the
171  * correct C string out of it. */
172  algorithm_name_as_string = rb_funcall(algorithm_name, rb_intern("to_s"), 0);
173 
174  name_slice =
175  grpc_slice_from_copied_buffer(RSTRING_PTR(algorithm_name_as_string),
176  RSTRING_LEN(algorithm_name_as_string));
177 
178  /* Raise an error if the name isn't recognized as a compression algorithm by
179  * the algorithm parse function
180  * in GRPC core. */
181  if (!grpc_compression_algorithm_parse(name_slice, algorithm_value)) {
182  char* name_slice_str = grpc_slice_to_c_string(name_slice);
183  char* error_message_str = NULL;
184  VALUE error_message_ruby_str = Qnil;
185  GPR_ASSERT(gpr_asprintf(&error_message_str,
186  "Invalid compression algorithm name: %s",
187  name_slice_str) != -1);
188  gpr_free(name_slice_str);
189  error_message_ruby_str =
190  rb_str_new(error_message_str, strlen(error_message_str));
191  gpr_free(error_message_str);
192  rb_raise(rb_eNameError, "%s", StringValueCStr(error_message_ruby_str));
193  }
194 
195  grpc_slice_unref(name_slice);
196 }
197 
198 /* Indicates whether a given algorithm is enabled on this instance, given the
199  * readable algorithm name. */
201  VALUE algorithm_name) {
203  grpc_compression_algorithm internal_algorithm_value;
204 
205  TypedData_Get_Struct(self, grpc_rb_compression_options,
208  &internal_algorithm_value, algorithm_name);
209 
211  internal_algorithm_value)) {
212  return Qtrue;
213  }
214  return Qfalse;
215 }
216 
217 /* Sets the default algorithm to the name of the algorithm passed in.
218  * Raises an error if the name is not a valid compression algorithm name. */
220  grpc_compression_options* options, VALUE algorithm_name) {
222  &options->default_algorithm.algorithm, algorithm_name);
223  options->default_algorithm.is_set = 1;
224 }
225 
226 /* Disables an algorithm on the current instance, given the name of an
227  * algorithm.
228  * Fails if the algorithm name is invalid. */
230  grpc_compression_options* compression_options, VALUE algorithm_name) {
231  grpc_compression_algorithm internal_algorithm_value;
232 
234  &internal_algorithm_value, algorithm_name);
235  grpc_compression_options_disable_algorithm(compression_options,
236  internal_algorithm_value);
237 }
238 
239 /* Provides a ruby hash of GRPC core channel argument key-values that
240  * correspond to the compression settings on this instance. */
243  grpc_compression_options* compression_options = NULL;
244  VALUE channel_arg_hash = rb_hash_new();
245  VALUE key = Qnil;
246  VALUE value = Qnil;
247 
248  TypedData_Get_Struct(self, grpc_rb_compression_options,
250  compression_options = wrapper->wrapped;
251 
252  /* Add key-value pairs to the new Ruby hash. It can be used
253  * as GRPC core channel arguments. */
254  if (compression_options->default_level.is_set) {
256  value = INT2NUM((int)compression_options->default_level.level);
257  rb_hash_aset(channel_arg_hash, key, value);
258  }
259 
260  if (compression_options->default_algorithm.is_set) {
262  value = INT2NUM((int)compression_options->default_algorithm.algorithm);
263  rb_hash_aset(channel_arg_hash, key, value);
264  }
265 
267  value = INT2NUM((int)compression_options->enabled_algorithms_bitset);
268  rb_hash_aset(channel_arg_hash, key, value);
269 
270  return channel_arg_hash;
271 }
272 
273 /* Converts an internal enum level value to a readable level name.
274  * Fails if the level value is invalid. */
276  grpc_compression_level compression_value) {
277  switch (compression_value) {
279  return ID2SYM(id_compress_level_none);
281  return ID2SYM(id_compress_level_low);
283  return ID2SYM(id_compress_level_medium);
285  return ID2SYM(id_compress_level_high);
286  default:
287  rb_raise(
288  rb_eArgError,
289  "Failed to convert compression level value to name for value: %d",
290  (int)compression_value);
291  /* return something to avoid compiler error about no return */
292  return Qnil;
293  }
294 }
295 
296 /* Converts an algorithm internal enum value to a readable name.
297  * Fails if the enum value is invalid. */
299  grpc_compression_algorithm internal_value) {
300  char* algorithm_name = NULL;
301 
302  if (!grpc_compression_algorithm_name(internal_value, &algorithm_name)) {
303  rb_raise(rb_eArgError, "Failed to convert algorithm value to name");
304  }
305 
306  return ID2SYM(rb_intern(algorithm_name));
307 }
308 
309 /* Gets the readable name of the default algorithm if one has been set.
310  * Returns nil if no algorithm has been set. */
312  grpc_compression_algorithm internal_value;
314 
315  TypedData_Get_Struct(self, grpc_rb_compression_options,
317 
318  if (wrapper->wrapped->default_algorithm.is_set) {
319  internal_value = wrapper->wrapped->default_algorithm.algorithm;
321  internal_value);
322  }
323 
324  return Qnil;
325 }
326 
327 /* Gets the internal value of the default compression level that is to be passed
328  * to the GRPC core as a channel argument value.
329  * A nil return value means that it hasn't been set. */
331  grpc_compression_level internal_value;
333 
334  TypedData_Get_Struct(self, grpc_rb_compression_options,
336 
337  if (wrapper->wrapped->default_level.is_set) {
338  internal_value = wrapper->wrapped->default_level.level;
340  internal_value);
341  }
342 
343  return Qnil;
344 }
345 
346 /* Gets a list of the disabled algorithms as readable names.
347  * Returns an empty list if no algorithms have been disabled. */
349  VALUE disabled_algorithms = rb_ary_new();
350  grpc_compression_algorithm internal_value;
352 
353  TypedData_Get_Struct(self, grpc_rb_compression_options,
355 
356  for (internal_value = GRPC_COMPRESS_NONE;
357  internal_value < GRPC_COMPRESS_ALGORITHMS_COUNT; internal_value++) {
359  internal_value)) {
360  rb_ary_push(disabled_algorithms,
362  internal_value));
363  }
364  }
365  return disabled_algorithms;
366 }
367 
368 /* Initializes the compression options wrapper.
369  * Takes an optional hash parameter.
370  *
371  * Example call-seq:
372  * options = CompressionOptions.new(
373  * default_level: :none,
374  * disabled_algorithms: [:gzip]
375  * )
376  * channel_arg hash = Hash.new[...]
377  * channel_arg_hash_with_compression_options = channel_arg_hash.merge(options)
378  */
379 VALUE grpc_rb_compression_options_init(int argc, VALUE* argv, VALUE self) {
381  VALUE default_algorithm = Qnil;
382  VALUE default_level = Qnil;
383  VALUE disabled_algorithms = Qnil;
384  VALUE algorithm_name = Qnil;
385  VALUE hash_arg = Qnil;
386 
387  rb_scan_args(argc, argv, "01", &hash_arg);
388 
389  /* Check if the hash parameter was passed, or if invalid arguments were
390  * passed. */
391  if (hash_arg == Qnil) {
392  return self;
393  } else if (TYPE(hash_arg) != T_HASH || argc > 1) {
394  rb_raise(rb_eArgError,
395  "Invalid arguments. Expecting optional hash parameter");
396  }
397 
398  TypedData_Get_Struct(self, grpc_rb_compression_options,
400 
401  /* Set the default algorithm if one was chosen. */
402  default_algorithm =
403  rb_hash_aref(hash_arg, ID2SYM(rb_intern("default_algorithm")));
404  if (default_algorithm != Qnil) {
406  default_algorithm);
407  }
408 
409  /* Set the default level if one was chosen. */
410  default_level = rb_hash_aref(hash_arg, ID2SYM(rb_intern("default_level")));
411  if (default_level != Qnil) {
413  default_level);
414  }
415 
416  /* Set the disabled algorithms if any were chosen. */
417  disabled_algorithms =
418  rb_hash_aref(hash_arg, ID2SYM(rb_intern("disabled_algorithms")));
419  if (disabled_algorithms != Qnil) {
420  Check_Type(disabled_algorithms, T_ARRAY);
421 
422  for (int i = 0; i < RARRAY_LEN(disabled_algorithms); i++) {
423  algorithm_name = rb_ary_entry(disabled_algorithms, i);
425  algorithm_name);
426  }
427  }
428 
429  return self;
430 }
431 
433  grpc_rb_cCompressionOptions = rb_define_class_under(
434  grpc_rb_mGrpcCore, "CompressionOptions", rb_cObject);
435 
436  /* Allocates an object managed by the ruby runtime. */
437  rb_define_alloc_func(grpc_rb_cCompressionOptions,
439 
440  /* Initializes the ruby wrapper. #new method takes an optional hash argument.
441  */
442  rb_define_method(grpc_rb_cCompressionOptions, "initialize",
444 
445  /* Methods for getting the default algorithm, default level, and disabled
446  * algorithms as readable names. */
447  rb_define_method(grpc_rb_cCompressionOptions, "default_algorithm",
449  rb_define_method(grpc_rb_cCompressionOptions, "default_level",
451  rb_define_method(grpc_rb_cCompressionOptions, "disabled_algorithms",
453 
454  /* Determines whether or not an algorithm is enabled, given a readable
455  * algorithm name.*/
456  rb_define_method(grpc_rb_cCompressionOptions, "algorithm_enabled?",
458 
459  /* Provides a hash of the compression settings suitable
460  * for passing to server or channel args. */
461  rb_define_method(grpc_rb_cCompressionOptions, "to_hash",
463  rb_define_alias(grpc_rb_cCompressionOptions, "to_channel_arg_hash",
464  "to_hash");
465 
466  /* Ruby ids for the names of the different compression levels. */
467  id_compress_level_none = rb_intern("none");
468  id_compress_level_low = rb_intern("low");
469  id_compress_level_medium = rb_intern("medium");
470  id_compress_level_high = rb_intern("high");
471 }
grpc_rb_compression_options
struct grpc_rb_compression_options grpc_rb_compression_options
grpc_slice_unref
GPRAPI void grpc_slice_unref(grpc_slice s)
Definition: slice_api.cc:32
compression.h
GRPC_COMPRESS_LEVEL_MED
@ GRPC_COMPRESS_LEVEL_MED
Definition: compression_types.h:75
grpc_compression_options::enabled_algorithms_bitset
uint32_t enabled_algorithms_bitset
Definition: compression_types.h:84
grpc_rb_cCompressionOptions
static VALUE grpc_rb_cCompressionOptions
Definition: rb_compression_options.c:37
log.h
rb_grpc_imports.generated.h
GRPC_RB_MEMSIZE_UNAVAILABLE
#define GRPC_RB_MEMSIZE_UNAVAILABLE
Definition: rb_grpc.h:57
grpc_rb_compression_options_alloc
static VALUE grpc_rb_compression_options_alloc(VALUE cls)
Definition: rb_compression_options.c:93
grpc_ruby_shutdown
void grpc_ruby_shutdown()
Definition: rb_grpc.c:296
grpc_rb_compression_options_init
VALUE grpc_rb_compression_options_init(int argc, VALUE *argv, VALUE self)
Definition: rb_compression_options.c:379
string.h
options
double_dict options[]
Definition: capstone_test.c:55
grpc_compression_algorithm
grpc_compression_algorithm
Definition: compression_types.h:60
grpc_rb_compression_options_data_type
static rb_data_type_t grpc_rb_compression_options_data_type
Definition: rb_compression_options.c:77
grpc_compression_options::grpc_compression_options_default_level::is_set
int is_set
Definition: compression_types.h:92
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
grpc_rb_compression_options_algorithm_name_to_value_internal
void grpc_rb_compression_options_algorithm_name_to_value_internal(grpc_compression_algorithm *algorithm_value, VALUE algorithm_name)
Definition: rb_compression_options.c:163
grpc_compression_options::grpc_compression_options_default_level::level
grpc_compression_level level
Definition: compression_types.h:93
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
grpc_rb_compression_options::wrapped
grpc_compression_options * wrapped
Definition: rb_compression_options.c:53
grpc_rb_compression_options_set_default_level
void grpc_rb_compression_options_set_default_level(grpc_compression_options *options, VALUE new_level_name)
Definition: rb_compression_options.c:152
grpc_compression_options
Definition: compression_types.h:80
GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL
Definition: compression_types.h:46
xds_manager.p
p
Definition: xds_manager.py:60
GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET
#define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET
Definition: compression_types.h:54
grpc_rb_compression_options_disable_algorithm
void grpc_rb_compression_options_disable_algorithm(grpc_compression_options *compression_options, VALUE algorithm_name)
Definition: rb_compression_options.c:229
GRPC_COMPRESS_NONE
@ GRPC_COMPRESS_NONE
Definition: compression_types.h:61
_grpc_channel_wrapper::wrapped
grpc_channel * wrapped
Definition: src/php/ext/grpc/channel.h:35
id_compress_level_none
static VALUE id_compress_level_none
Definition: rb_compression_options.c:40
grpc_types.h
grpc_rb_compression_options_level_name_to_value_internal
grpc_compression_level grpc_rb_compression_options_level_name_to_value_internal(VALUE level_name)
Definition: rb_compression_options.c:126
string_util.h
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc_compression_algorithm_name
GRPCAPI int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, const char **name)
Definition: compression.cc:56
grpc_rb_compression_options_free_internal
static void grpc_rb_compression_options_free_internal(void *p)
Definition: rb_compression_options.c:56
grpc_compression_options::default_level
struct grpc_compression_options::grpc_compression_options_default_level default_level
id_compress_level_low
static VALUE id_compress_level_low
Definition: rb_compression_options.c:41
grpc.h
GRPC_COMPRESS_LEVEL_NONE
@ GRPC_COMPRESS_LEVEL_NONE
Definition: compression_types.h:73
grpc_rb_compression_options_get_default_level
VALUE grpc_rb_compression_options_get_default_level(VALUE self)
Definition: rb_compression_options.c:330
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
id_compress_level_high
static VALUE id_compress_level_high
Definition: rb_compression_options.c:43
gpr_asprintf
GPRAPI int gpr_asprintf(char **strp, const char *format,...) GPR_PRINT_FORMAT_CHECK(2
grpc_rb_compression_options_disable_compression_algorithm_internal
VALUE grpc_rb_compression_options_disable_compression_algorithm_internal(VALUE self, VALUE algorithm_to_disable)
Definition: rb_compression_options.c:108
grpc_compression_options::default_algorithm
struct grpc_compression_options::grpc_compression_options_default_algorithm default_algorithm
wrapper
grpc_channel_wrapper * wrapper
Definition: src/php/ext/grpc/channel.h:48
GRPC_COMPRESS_LEVEL_HIGH
@ GRPC_COMPRESS_LEVEL_HIGH
Definition: compression_types.h:76
rb_byte_buffer.h
grpc_compression_algorithm_parse
GRPCAPI int grpc_compression_algorithm_parse(grpc_slice name, grpc_compression_algorithm *algorithm)
Definition: compression.cc:44
grpc_compression_options_disable_algorithm
GRPCAPI void grpc_compression_options_disable_algorithm(grpc_compression_options *opts, grpc_compression_algorithm algorithm)
Definition: compression.cc:85
compression_types.h
grpc_rb_compression_options_algorithm_value_to_name_internal
VALUE grpc_rb_compression_options_algorithm_value_to_name_internal(grpc_compression_algorithm internal_value)
Definition: rb_compression_options.c:298
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_slice_to_c_string
GPRAPI char * grpc_slice_to_c_string(grpc_slice s)
Definition: slice/slice.cc:35
rb_grpc.h
grpc_rb_mGrpcCore
VALUE grpc_rb_mGrpcCore
Definition: rb_grpc.c:252
grpc_slice_from_copied_buffer
GPRAPI grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t len)
Definition: slice/slice.cc:170
grpc_rb_compression_options_level_value_to_name_internal
VALUE grpc_rb_compression_options_level_value_to_name_internal(grpc_compression_level compression_value)
Definition: rb_compression_options.c:275
key
const char * key
Definition: hpack_parser_table.cc:164
rb_compression_options.h
grpc_compression_options_is_algorithm_enabled
GRPCAPI int grpc_compression_options_is_algorithm_enabled(const grpc_compression_options *opts, grpc_compression_algorithm algorithm)
Definition: compression.cc:90
GRPC_COMPRESS_LEVEL_LOW
@ GRPC_COMPRESS_LEVEL_LOW
Definition: compression_types.h:74
id_compress_level_medium
static VALUE id_compress_level_medium
Definition: rb_compression_options.c:42
grpc_compression_options_init
GRPCAPI void grpc_compression_options_init(grpc_compression_options *opts)
Definition: compression.cc:74
alloc.h
grpc_rb_compression_options_set_default_algorithm
void grpc_rb_compression_options_set_default_algorithm(grpc_compression_options *options, VALUE algorithm_name)
Definition: rb_compression_options.c:219
grpc_compression_level
grpc_compression_level
Definition: compression_types.h:72
GRPC_COMPRESS_ALGORITHMS_COUNT
@ GRPC_COMPRESS_ALGORITHMS_COUNT
Definition: compression_types.h:65
grpc_compression_options::grpc_compression_options_default_algorithm::is_set
int is_set
Definition: compression_types.h:100
grpc_rb_compression_options
Definition: rb_compression_options.c:51
grpc_rb_compression_options_get_disabled_algorithms
VALUE grpc_rb_compression_options_get_disabled_algorithms(VALUE self)
Definition: rb_compression_options.c:348
grpc_rb_compression_options_to_hash
VALUE grpc_rb_compression_options_to_hash(VALUE self)
Definition: rb_compression_options.c:241
grpc_rb_compression_options_get_default_algorithm
VALUE grpc_rb_compression_options_get_default_algorithm(VALUE self)
Definition: rb_compression_options.c:311
TYPE
#define TYPE(u, l)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8202
grpc_rb_compression_options_free
static void grpc_rb_compression_options_free(void *p)
Definition: rb_compression_options.c:71
Init_grpc_compression_options
void Init_grpc_compression_options()
Definition: rb_compression_options.c:432
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM
Definition: compression_types.h:42
grpc_compression_options::grpc_compression_options_default_algorithm::algorithm
grpc_compression_algorithm algorithm
Definition: compression_types.h:101
grpc_ruby_init
void grpc_ruby_init()
Definition: rb_grpc.c:286
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_rb_compression_options_is_algorithm_enabled
VALUE grpc_rb_compression_options_is_algorithm_enabled(VALUE self, VALUE algorithm_name)
Definition: rb_compression_options.c:200


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:59