• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#import "NSDictionary+GRPC.h"
20
21#include <grpc/support/alloc.h>
22
23#pragma mark Category for binary metadata elements
24
25@interface NSData (GRPCMetadata)
26+ (instancetype)grpc_dataFromMetadataValue:(grpc_metadata *)metadata;
27
28// Fill a metadata object with the binary value in this NSData.
29- (void)grpc_initMetadata:(grpc_metadata *)metadata;
30@end
31
32@implementation NSData (GRPCMetadata)
33+ (instancetype)grpc_dataFromMetadataValue:(grpc_metadata *)metadata {
34  // TODO(jcanizales): Should we use a non-copy constructor?
35  return [self dataWithBytes:GRPC_SLICE_START_PTR(metadata->value)
36                      length:GRPC_SLICE_LENGTH(metadata->value)];
37}
38
39- (void)grpc_initMetadata:(grpc_metadata *)metadata {
40  metadata->value = grpc_slice_from_copied_buffer(self.bytes, self.length);
41}
42@end
43
44#pragma mark Category for textual metadata elements
45
46@interface NSString (GRPCMetadata)
47+ (instancetype)grpc_stringFromMetadataValue:(grpc_metadata *)metadata;
48
49// Fill a metadata object with the textual value in this NSString.
50- (void)grpc_initMetadata:(grpc_metadata *)metadata;
51@end
52
53@implementation NSString (GRPCMetadata)
54+ (instancetype)grpc_stringFromMetadataValue:(grpc_metadata *)metadata {
55  return [[self alloc] initWithBytes:GRPC_SLICE_START_PTR(metadata->value)
56                              length:GRPC_SLICE_LENGTH(metadata->value)
57                            encoding:NSUTF8StringEncoding];
58}
59
60// Precondition: This object contains only ASCII characters.
61- (void)grpc_initMetadata:(grpc_metadata *)metadata {
62  metadata->value = grpc_slice_from_copied_string(self.UTF8String);
63}
64@end
65
66#pragma mark Category for metadata arrays
67
68@implementation NSDictionary (GRPC)
69+ (instancetype)grpc_dictionaryFromMetadataArray:(grpc_metadata_array)array {
70  return [self grpc_dictionaryFromMetadata:array.metadata count:array.count];
71}
72
73+ (instancetype)grpc_dictionaryFromMetadata:(grpc_metadata *)entries count:(size_t)count {
74  NSMutableDictionary *metadata = [NSMutableDictionary dictionaryWithCapacity:count];
75  for (grpc_metadata *entry = entries; entry < entries + count; entry++) {
76    char *key = grpc_slice_to_c_string(entry->key);
77    NSString *name = [NSString stringWithCString:key encoding:NSASCIIStringEncoding];
78    gpr_free(key);
79    if (!name || metadata[name]) {
80      // Log if name is nil?
81      continue;
82    }
83    id value;
84    if ([name hasSuffix:@"-bin"]) {
85      value = [NSData grpc_dataFromMetadataValue:entry];
86    } else {
87      value = [NSString grpc_stringFromMetadataValue:entry];
88    }
89    metadata[name] = value;
90  }
91  return metadata;
92}
93
94// Preconditions: All keys are ASCII strings. Keys ending in -bin have NSData values; the others
95// have NSString values.
96- (grpc_metadata *)grpc_metadataArray {
97  grpc_metadata *metadata = gpr_malloc([self count] * sizeof(grpc_metadata));
98  grpc_metadata *current = metadata;
99  for (NSString *key in self) {
100    id value = self[key];
101    current->key = grpc_slice_from_copied_string(key.UTF8String);
102    if ([value respondsToSelector:@selector(grpc_initMetadata:)]) {
103      [value grpc_initMetadata:current];
104    } else {
105      [NSException raise:NSInvalidArgumentException
106                  format:@"Metadata values must be NSString or NSData."];
107    }
108    ++current;
109  }
110  return metadata;
111}
112@end
113