summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
blob: aa4ac44ab12466e112ebe2dd000b5b9002c15325 (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
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "chrome/browser/ui/cocoa/applescript/apple_event_util.h"

#import <Carbon/Carbon.h>

#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"

namespace chrome {
namespace mac {

NSAppleEventDescriptor* ValueToAppleEventDescriptor(const base::Value* value) {
  NSAppleEventDescriptor* descriptor = nil;

  switch (value->GetType()) {
    case base::Value::TYPE_NULL:
      descriptor = [NSAppleEventDescriptor
          descriptorWithTypeCode:cMissingValue];
      break;

    case base::Value::TYPE_BOOLEAN: {
      bool bool_value;
      value->GetAsBoolean(&bool_value);
      descriptor = [NSAppleEventDescriptor descriptorWithBoolean:bool_value];
      break;
    }

    case base::Value::TYPE_INTEGER: {
      int int_value;
      value->GetAsInteger(&int_value);
      descriptor = [NSAppleEventDescriptor descriptorWithInt32:int_value];
      break;
    }

    case base::Value::TYPE_DOUBLE: {
      double double_value;
      value->GetAsDouble(&double_value);
      descriptor = [NSAppleEventDescriptor
          descriptorWithDescriptorType:typeIEEE64BitFloatingPoint
                                 bytes:&double_value
                                length:sizeof(double_value)];
      break;
    }

    case base::Value::TYPE_STRING: {
      std::string string_value;
      value->GetAsString(&string_value);
      descriptor = [NSAppleEventDescriptor descriptorWithString:
          base::SysUTF8ToNSString(string_value)];
      break;
    }

    case base::Value::TYPE_BINARY:
      NOTREACHED();
      break;

    case base::Value::TYPE_DICTIONARY: {
      const base::DictionaryValue* dictionary_value;
      value->GetAsDictionary(&dictionary_value);
      descriptor = [NSAppleEventDescriptor recordDescriptor];
      NSAppleEventDescriptor* userRecord = [NSAppleEventDescriptor
          listDescriptor];
      for (base::DictionaryValue::Iterator iter(*dictionary_value);
           !iter.IsAtEnd();
           iter.Advance()) {
        [userRecord insertDescriptor:[NSAppleEventDescriptor
            descriptorWithString:base::SysUTF8ToNSString(iter.key())]
                             atIndex:0];
        [userRecord insertDescriptor:ValueToAppleEventDescriptor(&iter.value())
                             atIndex:0];
      }
      // Description of what keyASUserRecordFields does.
      // http://lists.apple.com/archives/cocoa-dev/2009/Jul/msg01216.html
      [descriptor setDescriptor:userRecord forKeyword:keyASUserRecordFields];
      break;
    }

    case base::Value::TYPE_LIST: {
      const base::ListValue* list_value;
      value->GetAsList(&list_value);
      descriptor = [NSAppleEventDescriptor listDescriptor];
      for (size_t i = 0; i < list_value->GetSize(); ++i) {
        const base::Value* item;
        list_value->Get(i, &item);
        [descriptor insertDescriptor:ValueToAppleEventDescriptor(item)
                             atIndex:0];
      }
      break;
    }
  }

  return descriptor;
}

}  // namespace mac
}  // namespace chrome