ArgumentCodersMac.mm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /*
  2. * Copyright (C) 2011 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #import "config.h"
  26. #import "ArgumentCodersMac.h"
  27. #import "ArgumentCodersCF.h"
  28. #import "ArgumentDecoder.h"
  29. #import "ArgumentEncoder.h"
  30. #import "WebCoreArgumentCoders.h"
  31. #import <WebCore/ColorMac.h>
  32. using namespace WebCore;
  33. namespace CoreIPC {
  34. enum NSType {
  35. NSAttributedStringType,
  36. #if USE(APPKIT)
  37. NSColorType,
  38. #endif
  39. NSDictionaryType,
  40. NSArrayType,
  41. #if USE(APPKIT)
  42. NSFontType,
  43. #endif
  44. NSNumberType,
  45. NSStringType,
  46. NSDateType,
  47. NSDataType,
  48. Unknown,
  49. };
  50. static NSType typeFromObject(id object)
  51. {
  52. ASSERT(object);
  53. if ([object isKindOfClass:[NSAttributedString class]])
  54. return NSAttributedStringType;
  55. #if USE(APPKIT)
  56. if ([object isKindOfClass:[NSColor class]])
  57. return NSColorType;
  58. #endif
  59. if ([object isKindOfClass:[NSDictionary class]])
  60. return NSDictionaryType;
  61. #if USE(APPKIT)
  62. if ([object isKindOfClass:[NSFont class]])
  63. return NSFontType;
  64. #endif
  65. if ([object isKindOfClass:[NSNumber class]])
  66. return NSNumberType;
  67. if ([object isKindOfClass:[NSString class]])
  68. return NSStringType;
  69. if ([object isKindOfClass:[NSArray class]])
  70. return NSArrayType;
  71. if ([object isKindOfClass:[NSDate class]])
  72. return NSDateType;
  73. if ([object isKindOfClass:[NSData class]])
  74. return NSDataType;
  75. ASSERT_NOT_REACHED();
  76. return Unknown;
  77. }
  78. void encode(ArgumentEncoder& encoder, id object)
  79. {
  80. NSType type = typeFromObject(object);
  81. encoder.encodeEnum(type);
  82. switch (type) {
  83. case NSAttributedStringType:
  84. encode(encoder, static_cast<NSAttributedString *>(object));
  85. return;
  86. #if USE(APPKIT)
  87. case NSColorType:
  88. encode(encoder, static_cast<NSColor *>(object));
  89. return;
  90. #endif
  91. case NSDictionaryType:
  92. encode(encoder, static_cast<NSDictionary *>(object));
  93. return;
  94. #if USE(APPKIT)
  95. case NSFontType:
  96. encode(encoder, static_cast<NSFont *>(object));
  97. return;
  98. #endif
  99. case NSNumberType:
  100. encode(encoder, static_cast<NSNumber *>(object));
  101. return;
  102. case NSStringType:
  103. encode(encoder, static_cast<NSString *>(object));
  104. return;
  105. case NSArrayType:
  106. encode(encoder, static_cast<NSArray *>(object));
  107. return;
  108. case NSDateType:
  109. encode(encoder, static_cast<NSDate *>(object));
  110. return;
  111. case NSDataType:
  112. encode(encoder, static_cast<NSData *>(object));
  113. return;
  114. case Unknown:
  115. break;
  116. }
  117. ASSERT_NOT_REACHED();
  118. }
  119. bool decode(ArgumentDecoder& decoder, RetainPtr<id>& result)
  120. {
  121. NSType type;
  122. if (!decoder.decodeEnum(type))
  123. return false;
  124. switch (type) {
  125. case NSAttributedStringType: {
  126. RetainPtr<NSAttributedString> string;
  127. if (!decode(decoder, string))
  128. return false;
  129. result = string;
  130. return true;
  131. }
  132. #if USE(APPKIT)
  133. case NSColorType: {
  134. RetainPtr<NSColor> color;
  135. if (!decode(decoder, color))
  136. return false;
  137. result = color;
  138. return true;
  139. }
  140. #endif
  141. case NSDictionaryType: {
  142. RetainPtr<NSDictionary> dictionary;
  143. if (!decode(decoder, dictionary))
  144. return false;
  145. result = dictionary;
  146. return true;
  147. }
  148. #if USE(APPKIT)
  149. case NSFontType: {
  150. RetainPtr<NSFont> font;
  151. if (!decode(decoder, font))
  152. return false;
  153. result = font;
  154. return true;
  155. }
  156. #endif
  157. case NSNumberType: {
  158. RetainPtr<NSNumber> number;
  159. if (!decode(decoder, number))
  160. return false;
  161. result = number;
  162. return true;
  163. }
  164. case NSStringType: {
  165. RetainPtr<NSString> string;
  166. if (!decode(decoder, string))
  167. return false;
  168. result = string;
  169. return true;
  170. }
  171. case NSArrayType: {
  172. RetainPtr<NSArray> array;
  173. if (!decode(decoder, array))
  174. return false;
  175. result = array;
  176. return true;
  177. }
  178. case NSDateType: {
  179. RetainPtr<NSDate> date;
  180. if (!decode(decoder, date))
  181. return false;
  182. result = date;
  183. return true;
  184. }
  185. case NSDataType: {
  186. RetainPtr<NSData> data;
  187. if (!decode(decoder, data))
  188. return false;
  189. result = data;
  190. return true;
  191. }
  192. case Unknown:
  193. ASSERT_NOT_REACHED();
  194. return false;
  195. }
  196. return false;
  197. }
  198. void encode(ArgumentEncoder& encoder, NSAttributedString *string)
  199. {
  200. // Even though NSAttributedString is toll free bridged with CFAttributedStringRef, attributes' values may be not, so we should stay within this file's code.
  201. NSString *plainString = [string string];
  202. NSUInteger length = [plainString length];
  203. CoreIPC::encode(encoder, plainString);
  204. Vector<pair<NSRange, RetainPtr<NSDictionary>>> ranges;
  205. NSUInteger position = 0;
  206. while (position < length) {
  207. // Collect ranges in a vector, becasue the total count should be encoded first.
  208. NSRange effectiveRange;
  209. RetainPtr<NSDictionary> attributesAtIndex = [string attributesAtIndex:position effectiveRange:&effectiveRange];
  210. ASSERT(effectiveRange.location == position);
  211. ASSERT(effectiveRange.length);
  212. ASSERT(NSMaxRange(effectiveRange) <= length);
  213. ranges.append(std::make_pair(effectiveRange, attributesAtIndex));
  214. position = NSMaxRange(effectiveRange);
  215. }
  216. encoder << static_cast<uint64_t>(ranges.size());
  217. for (size_t i = 0; i < ranges.size(); ++i) {
  218. encoder << static_cast<uint64_t>(ranges[i].first.location);
  219. encoder << static_cast<uint64_t>(ranges[i].first.length);
  220. CoreIPC::encode(encoder, ranges[i].second.get());
  221. }
  222. }
  223. bool decode(ArgumentDecoder& decoder, RetainPtr<NSAttributedString>& result)
  224. {
  225. RetainPtr<NSString> plainString;
  226. if (!CoreIPC::decode(decoder, plainString))
  227. return false;
  228. NSUInteger stringLength = [plainString.get() length];
  229. RetainPtr<NSMutableAttributedString> resultString = adoptNS([[NSMutableAttributedString alloc] initWithString:plainString.get()]);
  230. uint64_t rangeCount;
  231. if (!decoder.decode(rangeCount))
  232. return false;
  233. while (rangeCount--) {
  234. uint64_t rangeLocation;
  235. uint64_t rangeLength;
  236. RetainPtr<NSDictionary> attributes;
  237. if (!decoder.decode(rangeLocation))
  238. return false;
  239. if (!decoder.decode(rangeLength))
  240. return false;
  241. ASSERT(rangeLocation + rangeLength > rangeLocation);
  242. ASSERT(rangeLocation + rangeLength <= stringLength);
  243. if (rangeLocation + rangeLength <= rangeLocation || rangeLocation + rangeLength > stringLength)
  244. return false;
  245. if (!CoreIPC::decode(decoder, attributes))
  246. return false;
  247. [resultString.get() addAttributes:attributes.get() range:NSMakeRange(rangeLocation, rangeLength)];
  248. }
  249. result = adoptNS(resultString.leakRef());
  250. return true;
  251. }
  252. #if USE(APPKIT)
  253. void encode(ArgumentEncoder& encoder, NSColor *color)
  254. {
  255. encoder << colorFromNSColor(color);
  256. }
  257. bool decode(ArgumentDecoder& decoder, RetainPtr<NSColor>& result)
  258. {
  259. Color color;
  260. if (!decoder.decode(color))
  261. return false;
  262. result = nsColor(color);
  263. return true;
  264. }
  265. #endif
  266. void encode(ArgumentEncoder& encoder, NSDictionary *dictionary)
  267. {
  268. // Even though NSDictionary is toll free bridged with CFDictionaryRef, values may be not, so we should stay within this file's code.
  269. NSUInteger size = [dictionary count];
  270. NSArray *keys = [dictionary allKeys];
  271. NSArray *values = [dictionary allValues];
  272. encoder << static_cast<uint64_t>(size);
  273. for (NSUInteger i = 0; i < size; ++i) {
  274. id key = [keys objectAtIndex:i];
  275. id value = [values objectAtIndex:i];
  276. ASSERT(key);
  277. ASSERT([key isKindOfClass:[NSString class]]);
  278. ASSERT(value);
  279. // Ignore values we don't recognize.
  280. if (typeFromObject(value) == Unknown)
  281. continue;
  282. encode(encoder, (NSString *)key);
  283. encode(encoder, value);
  284. }
  285. }
  286. bool decode(ArgumentDecoder& decoder, RetainPtr<NSDictionary>& result)
  287. {
  288. uint64_t size;
  289. if (!decoder.decode(size))
  290. return false;
  291. RetainPtr<NSMutableDictionary> dictionary = adoptNS([[NSMutableDictionary alloc] initWithCapacity:size]);
  292. for (uint64_t i = 0; i < size; ++i) {
  293. // Try to decode the key name.
  294. RetainPtr<NSString> key;
  295. if (!decode(decoder, key))
  296. return false;
  297. RetainPtr<id> value;
  298. if (!decode(decoder, value))
  299. return false;
  300. [dictionary.get() setObject:value.get() forKey:key.get()];
  301. }
  302. result = adoptNS(dictionary.leakRef());
  303. return true;
  304. }
  305. #if USE(APPKIT)
  306. void encode(ArgumentEncoder& encoder, NSFont *font)
  307. {
  308. // NSFont could use CTFontRef code if we had it in ArgumentCodersCF.
  309. encode(encoder, [[font fontDescriptor] fontAttributes]);
  310. }
  311. bool decode(ArgumentDecoder& decoder, RetainPtr<NSFont>& result)
  312. {
  313. RetainPtr<NSDictionary> fontAttributes;
  314. if (!decode(decoder, fontAttributes))
  315. return false;
  316. NSFontDescriptor *fontDescriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:fontAttributes.get()];
  317. result = [NSFont fontWithDescriptor:fontDescriptor size:0];
  318. return true;
  319. }
  320. #endif
  321. void encode(ArgumentEncoder& encoder, NSNumber *number)
  322. {
  323. encode(encoder, (CFNumberRef)number);
  324. }
  325. bool decode(ArgumentDecoder& decoder, RetainPtr<NSNumber>& result)
  326. {
  327. RetainPtr<CFNumberRef> number;
  328. if (!decode(decoder, number))
  329. return false;
  330. result = adoptNS((NSNumber *)number.leakRef());
  331. return true;
  332. }
  333. void encode(ArgumentEncoder& encoder, NSString *string)
  334. {
  335. encode(encoder, (CFStringRef)string);
  336. }
  337. bool decode(ArgumentDecoder& decoder, RetainPtr<NSString>& result)
  338. {
  339. RetainPtr<CFStringRef> string;
  340. if (!decode(decoder, string))
  341. return false;
  342. result = adoptNS((NSString *)string.leakRef());
  343. return true;
  344. }
  345. void encode(ArgumentEncoder& encoder, NSArray *array)
  346. {
  347. NSUInteger size = [array count];
  348. encoder << static_cast<uint64_t>(size);
  349. for (NSUInteger i = 0; i < size; ++i) {
  350. id value = [array objectAtIndex:i];
  351. // Ignore values we don't recognize.
  352. if (typeFromObject(value) == Unknown)
  353. continue;
  354. encode(encoder, value);
  355. }
  356. }
  357. bool decode(ArgumentDecoder& decoder, RetainPtr<NSArray>& result)
  358. {
  359. uint64_t size;
  360. if (!decoder.decode(size))
  361. return false;
  362. RetainPtr<NSMutableArray> array = adoptNS([[NSMutableArray alloc] initWithCapacity:size]);
  363. for (uint64_t i = 0; i < size; ++i) {
  364. RetainPtr<id> value;
  365. if (!decode(decoder, value))
  366. return false;
  367. [array.get() addObject:value.get()];
  368. }
  369. result = adoptNS(array.leakRef());
  370. return true;
  371. }
  372. void encode(ArgumentEncoder& encoder, NSDate *date)
  373. {
  374. encode(encoder, (CFDateRef)date);
  375. }
  376. bool decode(ArgumentDecoder& decoder, RetainPtr<NSDate>& result)
  377. {
  378. RetainPtr<CFDateRef> date;
  379. if (!decode(decoder, date))
  380. return false;
  381. result = adoptNS((NSDate *)date.leakRef());
  382. return true;
  383. }
  384. void encode(ArgumentEncoder& encoder, NSData *data)
  385. {
  386. encode(encoder, (CFDataRef)data);
  387. }
  388. bool decode(ArgumentDecoder& decoder, RetainPtr<NSData>& result)
  389. {
  390. RetainPtr<CFDataRef> data;
  391. if (!decode(decoder, data))
  392. return false;
  393. result = adoptNS((NSData *)data.leakRef());
  394. return true;
  395. }
  396. } // namespace CoreIPC