GTMMIMEDocument.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* Copyright 2014 Google Inc. All rights reserved.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. // This is a simple class to create or parse a MIME document.
  16. // To create a MIME document, allocate a new GTMMIMEDocument and start adding parts.
  17. // When you are done adding parts, call generateInputStream or generateDispatchData.
  18. //
  19. // A good reference for MIME is http://en.wikipedia.org/wiki/MIME
  20. #import <Foundation/Foundation.h>
  21. #ifndef GTM_NONNULL
  22. #if defined(__has_attribute)
  23. #if __has_attribute(nonnull)
  24. #define GTM_NONNULL(x) __attribute__((nonnull x))
  25. #else
  26. #define GTM_NONNULL(x)
  27. #endif
  28. #else
  29. #define GTM_NONNULL(x)
  30. #endif
  31. #endif
  32. #ifndef GTM_DECLARE_GENERICS
  33. #if __has_feature(objc_generics)
  34. #define GTM_DECLARE_GENERICS 1
  35. #else
  36. #define GTM_DECLARE_GENERICS 0
  37. #endif
  38. #endif
  39. #ifndef GTM_NSArrayOf
  40. #if GTM_DECLARE_GENERICS
  41. #define GTM_NSArrayOf(value) NSArray<value>
  42. #define GTM_NSDictionaryOf(key, value) NSDictionary<key, value>
  43. #else
  44. #define GTM_NSArrayOf(value) NSArray
  45. #define GTM_NSDictionaryOf(key, value) NSDictionary
  46. #endif // GTM_DECLARE_GENERICS
  47. #endif // GTM_NSArrayOf
  48. // GTMMIMEDocumentPart represents a part of a MIME document.
  49. //
  50. // +[GTMMIMEDocument MIMEPartsWithBoundary:data:] returns an array of these.
  51. @interface GTMMIMEDocumentPart : NSObject
  52. @property(nonatomic, readonly) GTM_NSDictionaryOf(NSString *, NSString *) *headers;
  53. @property(nonatomic, readonly) NSData *headerData;
  54. @property(nonatomic, readonly) NSData *body;
  55. @property(nonatomic, readonly) NSUInteger length;
  56. + (instancetype)partWithHeaders:(NSDictionary *)headers body:(NSData *)body;
  57. @end
  58. @interface GTMMIMEDocument : NSObject
  59. // Get or set the unique boundary for the parts that have been added.
  60. //
  61. // When creating a MIME document from parts, this is typically calculated
  62. // automatically after all parts have been added.
  63. @property(nonatomic, copy) NSString *boundary;
  64. #pragma mark - Methods for Creating a MIME Document
  65. + (instancetype)MIMEDocument;
  66. // Adds a new part to this mime document with the given headers and body.
  67. // The headers keys and values should be NSStrings.
  68. // Adding a part may cause the boundary string to change.
  69. - (void)addPartWithHeaders:(GTM_NSDictionaryOf(NSString *, NSString *) *)headers
  70. body:(NSData *)body GTM_NONNULL((1,2));
  71. // An inputstream that can be used to efficiently read the contents of the MIME document.
  72. //
  73. // Any parameter may be null if the result is not wanted.
  74. - (void)generateInputStream:(NSInputStream **)outStream
  75. length:(unsigned long long *)outLength
  76. boundary:(NSString **)outBoundary;
  77. // A dispatch_data_t with the contents of the MIME document.
  78. //
  79. // Note: dispatch_data_t is one-way toll-free bridged so the result
  80. // may be cast directly to NSData *.
  81. //
  82. // Any parameter may be null if the result is not wanted.
  83. - (void)generateDispatchData:(dispatch_data_t *)outDispatchData
  84. length:(unsigned long long *)outLength
  85. boundary:(NSString **)outBoundary;
  86. // Utility method for making a header section, including trailing newlines.
  87. + (NSData *)dataWithHeaders:(GTM_NSDictionaryOf(NSString *, NSString *) *)headers;
  88. #pragma mark - Methods for Parsing a MIME Document
  89. // Method for parsing out an array of MIME parts from a MIME document.
  90. //
  91. // Returns an array of GTMMIMEDocumentParts. Returns nil if no part can
  92. // be found.
  93. + (GTM_NSArrayOf(GTMMIMEDocumentPart *) *)MIMEPartsWithBoundary:(NSString *)boundary
  94. data:(NSData *)fullDocumentData;
  95. // Utility method for efficiently searching possibly discontiguous NSData
  96. // for occurrences of target byte. This method does not "flatten" an NSData
  97. // that is composed of discontiguous blocks.
  98. //
  99. // The byte offsets of non-overlapping occurrences of the target are returned as
  100. // NSNumbers in the array.
  101. + (void)searchData:(NSData *)data
  102. targetBytes:(const void *)targetBytes
  103. targetLength:(NSUInteger)targetLength
  104. foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets;
  105. // Utility method to parse header bytes into an NSDictionary.
  106. + (GTM_NSDictionaryOf(NSString *, NSString *) *)headersWithData:(NSData *)data;
  107. // ------ UNIT TESTING ONLY BELOW ------
  108. // Internal methods, exposed for unit testing only.
  109. - (void)seedRandomWith:(u_int32_t)seed;
  110. + (NSUInteger)findBytesWithNeedle:(const unsigned char *)needle
  111. needleLength:(NSUInteger)needleLength
  112. haystack:(const unsigned char *)haystack
  113. haystackLength:(NSUInteger)haystackLength
  114. foundOffset:(NSUInteger *)foundOffset;
  115. + (void)searchData:(NSData *)data
  116. targetBytes:(const void *)targetBytes
  117. targetLength:(NSUInteger)targetLength
  118. foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets
  119. foundBlockNumbers:(GTM_NSArrayOf(NSNumber *) **)outFoundBlockNumbers;
  120. @end