1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/base/platform_mime_util.h"
6
7#import <Foundation/Foundation.h>
8
9#include <string>
10
11#include "base/mac/foundation_util.h"
12#include "base/mac/scoped_cftyperef.h"
13#include "base/strings/sys_string_conversions.h"
14
15#if defined(OS_IOS)
16#include <MobileCoreServices/MobileCoreServices.h>
17#else
18#include <CoreServices/CoreServices.h>
19#endif  // defined(OS_IOS)
20
21namespace net {
22
23bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
24    const base::FilePath::StringType& ext, std::string* result) const {
25  std::string ext_nodot = ext;
26  if (ext_nodot.length() >= 1 && ext_nodot[0] == L'.')
27    ext_nodot.erase(ext_nodot.begin());
28  base::ScopedCFTypeRef<CFStringRef> ext_ref(
29      base::SysUTF8ToCFStringRef(ext_nodot));
30  if (!ext_ref)
31    return false;
32  base::ScopedCFTypeRef<CFStringRef> uti(UTTypeCreatePreferredIdentifierForTag(
33      kUTTagClassFilenameExtension, ext_ref, nullptr));
34  if (!uti)
35    return false;
36  base::ScopedCFTypeRef<CFStringRef> mime_ref(
37      UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
38  if (!mime_ref)
39    return false;
40
41  *result = base::SysCFStringRefToUTF8(mime_ref);
42  return true;
43}
44
45bool PlatformMimeUtil::GetPlatformPreferredExtensionForMimeType(
46    const std::string& mime_type,
47    base::FilePath::StringType* ext) const {
48  base::ScopedCFTypeRef<CFStringRef> mime_ref(
49      base::SysUTF8ToCFStringRef(mime_type));
50  if (!mime_ref)
51    return false;
52  base::ScopedCFTypeRef<CFStringRef> uti(UTTypeCreatePreferredIdentifierForTag(
53      kUTTagClassMIMEType, mime_ref, nullptr));
54  if (!uti)
55    return false;
56  base::ScopedCFTypeRef<CFStringRef> ext_ref(
57      UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension));
58  if (!ext_ref)
59    return false;
60
61  *ext = base::SysCFStringRefToUTF8(ext_ref);
62  return true;
63}
64
65void PlatformMimeUtil::GetPlatformExtensionsForMimeType(
66    const std::string& mime_type,
67    std::unordered_set<base::FilePath::StringType>* extensions) const {
68  base::ScopedCFTypeRef<CFArrayRef> exts_ref;
69
70  base::ScopedCFTypeRef<CFStringRef> mime_ref(
71      base::SysUTF8ToCFStringRef(mime_type));
72  if (mime_ref) {
73    base::ScopedCFTypeRef<CFStringRef> uti(
74        UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime_ref,
75                                              nullptr));
76    if (uti) {
77      exts_ref.reset(
78          UTTypeCopyAllTagsWithClass(uti, kUTTagClassFilenameExtension));
79    }
80  }
81
82  NSArray* extensions_list = base::mac::CFToNSCast(exts_ref);
83
84  if (extensions_list) {
85    for (NSString* extension in extensions_list)
86      extensions->insert(base::SysNSStringToUTF8(extension));
87  } else {
88    // Huh? Give up.
89    base::FilePath::StringType ext;
90    if (GetPlatformPreferredExtensionForMimeType(mime_type, &ext))
91      extensions->insert(ext);
92  }
93}
94
95}  // namespace net
96