summaryrefslogtreecommitdiff
path: root/StoneIsland/platforms/ios/Pods/GTMSessionFetcher/Source/GTMMIMEDocument.h
blob: 451e13239b2789431d03af16cf657fb14e135697 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This is a simple class to create or parse a MIME document.

// To create a MIME document, allocate a new GTMMIMEDocument and start adding parts.
// When you are done adding parts, call generateInputStream or generateDispatchData.
//
// A good reference for MIME is http://en.wikipedia.org/wiki/MIME

#import <Foundation/Foundation.h>

#ifndef GTM_NONNULL
  #if defined(__has_attribute)
    #if __has_attribute(nonnull)
      #define GTM_NONNULL(x) __attribute__((nonnull x))
    #else
      #define GTM_NONNULL(x)
    #endif
  #else
    #define GTM_NONNULL(x)
  #endif
#endif

#ifndef GTM_DECLARE_GENERICS
  #if __has_feature(objc_generics)
    #define GTM_DECLARE_GENERICS 1
  #else
    #define GTM_DECLARE_GENERICS 0
  #endif
#endif

#ifndef GTM_NSArrayOf
  #if GTM_DECLARE_GENERICS
    #define GTM_NSArrayOf(value) NSArray<value>
    #define GTM_NSDictionaryOf(key, value) NSDictionary<key, value>
  #else
    #define GTM_NSArrayOf(value) NSArray
    #define GTM_NSDictionaryOf(key, value) NSDictionary
  #endif // GTM_DECLARE_GENERICS
#endif  // GTM_NSArrayOf


// GTMMIMEDocumentPart represents a part of a MIME document.
//
// +[GTMMIMEDocument MIMEPartsWithBoundary:data:] returns an array of these.
@interface GTMMIMEDocumentPart : NSObject

@property(nonatomic, readonly) GTM_NSDictionaryOf(NSString *, NSString *) *headers;
@property(nonatomic, readonly) NSData *headerData;
@property(nonatomic, readonly) NSData *body;
@property(nonatomic, readonly) NSUInteger length;

+ (instancetype)partWithHeaders:(NSDictionary *)headers body:(NSData *)body;

@end

@interface GTMMIMEDocument : NSObject

// Get or set the unique boundary for the parts that have been added.
//
// When creating a MIME document from parts, this is typically calculated
// automatically after all parts have been added.
@property(nonatomic, copy) NSString *boundary;

#pragma mark - Methods for Creating a MIME Document

+ (instancetype)MIMEDocument;

// Adds a new part to this mime document with the given headers and body.
// The headers keys and values should be NSStrings.
// Adding a part may cause the boundary string to change.
- (void)addPartWithHeaders:(GTM_NSDictionaryOf(NSString *, NSString *) *)headers
                      body:(NSData *)body GTM_NONNULL((1,2));

// An inputstream that can be used to efficiently read the contents of the MIME document.
//
// Any parameter may be null if the result is not wanted.
- (void)generateInputStream:(NSInputStream **)outStream
                     length:(unsigned long long *)outLength
                   boundary:(NSString **)outBoundary;

// A dispatch_data_t with the contents of the MIME document.
//
// Note: dispatch_data_t is one-way toll-free bridged so the result
// may be cast directly to NSData *.
//
// Any parameter may be null if the result is not wanted.
- (void)generateDispatchData:(dispatch_data_t *)outDispatchData
                      length:(unsigned long long *)outLength
                    boundary:(NSString **)outBoundary;

// Utility method for making a header section, including trailing newlines.
+ (NSData *)dataWithHeaders:(GTM_NSDictionaryOf(NSString *, NSString *) *)headers;

#pragma mark - Methods for Parsing a MIME Document

// Method for parsing out an array of MIME parts from a MIME document.
//
// Returns an array of GTMMIMEDocumentParts.  Returns nil if no part can
// be found.
+ (GTM_NSArrayOf(GTMMIMEDocumentPart *) *)MIMEPartsWithBoundary:(NSString *)boundary
                                                           data:(NSData *)fullDocumentData;

// Utility method for efficiently searching possibly discontiguous NSData
// for occurrences of target byte. This method does not "flatten" an NSData
// that is composed of discontiguous blocks.
//
// The byte offsets of non-overlapping occurrences of the target are returned as
// NSNumbers in the array.
+ (void)searchData:(NSData *)data
       targetBytes:(const void *)targetBytes
      targetLength:(NSUInteger)targetLength
      foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets;

// Utility method to parse header bytes into an NSDictionary.
+ (GTM_NSDictionaryOf(NSString *, NSString *) *)headersWithData:(NSData *)data;

// ------ UNIT TESTING ONLY BELOW ------

// Internal methods, exposed for unit testing only.
- (void)seedRandomWith:(u_int32_t)seed;

+ (NSUInteger)findBytesWithNeedle:(const unsigned char *)needle
                     needleLength:(NSUInteger)needleLength
                         haystack:(const unsigned char *)haystack
                   haystackLength:(NSUInteger)haystackLength
                      foundOffset:(NSUInteger *)foundOffset;

+ (void)searchData:(NSData *)data
       targetBytes:(const void *)targetBytes
      targetLength:(NSUInteger)targetLength
      foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets
 foundBlockNumbers:(GTM_NSArrayOf(NSNumber *) **)outFoundBlockNumbers;

@end