1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
12
13#include <CoreFoundation/CoreFoundation.h>
14
15#include "webrtc/base/logging.h"
16#include "webrtc/base/macconversion.h"
17
18bool p_convertHostCFStringRefToCPPString(
19  const CFStringRef cfstr, std::string& cppstr) {
20  bool result = false;
21
22  // First this must be non-null,
23  if (NULL != cfstr) {
24    // it must actually *be* a CFString, and not something just masquerading
25    // as one,
26    if (CFGetTypeID(cfstr) == CFStringGetTypeID()) {
27      // and we must be able to get the characters out of it.
28      // (The cfstr owns this buffer; it came from somewhere else,
29      // so someone else gets to take care of getting rid of the cfstr,
30      // and then this buffer will go away automatically.)
31      unsigned length = CFStringGetLength(cfstr);
32      char* buf = new char[1 + length];
33      if (CFStringGetCString(cfstr, buf, 1 + length, kCFStringEncodingASCII)) {
34        if (strlen(buf) == length) {
35          cppstr.assign(buf);
36          result = true;
37        }
38      }
39      delete [] buf;
40    }
41  }
42
43  return result;
44}
45
46bool p_convertCFNumberToInt(CFNumberRef cfn, int* i) {
47  bool converted = false;
48
49  // It must not be null.
50  if (NULL != cfn) {
51    // It must actually *be* a CFNumber and not something just masquerading
52    // as one.
53    if (CFGetTypeID(cfn) == CFNumberGetTypeID()) {
54      CFNumberType ntype = CFNumberGetType(cfn);
55      switch (ntype) {
56        case kCFNumberSInt8Type:
57          SInt8 sint8;
58          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint8));
59          if (converted) *i = static_cast<int>(sint8);
60          break;
61        case kCFNumberSInt16Type:
62          SInt16 sint16;
63          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint16));
64          if (converted) *i = static_cast<int>(sint16);
65          break;
66        case kCFNumberSInt32Type:
67          SInt32 sint32;
68          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint32));
69          if (converted) *i = static_cast<int>(sint32);
70          break;
71        case kCFNumberSInt64Type:
72          SInt64 sint64;
73          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint64));
74          if (converted) *i = static_cast<int>(sint64);
75          break;
76        case kCFNumberFloat32Type:
77          Float32 float32;
78          converted = CFNumberGetValue(cfn, ntype,
79                                       static_cast<void*>(&float32));
80          if (converted) *i = static_cast<int>(float32);
81          break;
82        case kCFNumberFloat64Type:
83          Float64 float64;
84          converted = CFNumberGetValue(cfn, ntype,
85                                       static_cast<void*>(&float64));
86          if (converted) *i = static_cast<int>(float64);
87          break;
88        case kCFNumberCharType:
89          char charvalue;
90          converted = CFNumberGetValue(cfn, ntype,
91                                       static_cast<void*>(&charvalue));
92          if (converted) *i = static_cast<int>(charvalue);
93          break;
94        case kCFNumberShortType:
95          short shortvalue;
96          converted = CFNumberGetValue(cfn, ntype,
97                                       static_cast<void*>(&shortvalue));
98          if (converted) *i = static_cast<int>(shortvalue);
99          break;
100        case kCFNumberIntType:
101          int intvalue;
102          converted = CFNumberGetValue(cfn, ntype,
103                                       static_cast<void*>(&intvalue));
104          if (converted) *i = static_cast<int>(intvalue);
105          break;
106        case kCFNumberLongType:
107          long longvalue;
108          converted = CFNumberGetValue(cfn, ntype,
109                     static_cast<void*>(&longvalue));
110          if (converted) *i = static_cast<int>(longvalue);
111          break;
112        case kCFNumberLongLongType:
113          long long llvalue;
114          converted = CFNumberGetValue(cfn, ntype,
115                                       static_cast<void*>(&llvalue));
116          if (converted) *i = static_cast<int>(llvalue);
117          break;
118        case kCFNumberFloatType:
119          float floatvalue;
120          converted = CFNumberGetValue(cfn, ntype,
121                                       static_cast<void*>(&floatvalue));
122          if (converted) *i = static_cast<int>(floatvalue);
123          break;
124        case kCFNumberDoubleType:
125          double doublevalue;
126          converted = CFNumberGetValue(cfn, ntype,
127                                       static_cast<void*>(&doublevalue));
128          if (converted) *i = static_cast<int>(doublevalue);
129          break;
130        case kCFNumberCFIndexType:
131          CFIndex cfindex;
132          converted = CFNumberGetValue(cfn, ntype,
133                                       static_cast<void*>(&cfindex));
134          if (converted) *i = static_cast<int>(cfindex);
135          break;
136        default:
137          LOG(LS_ERROR) << "got unknown type.";
138          break;
139      }
140    }
141  }
142
143  return converted;
144}
145
146bool p_isCFNumberTrue(CFNumberRef cfn) {
147  // We assume it's false until proven otherwise.
148  bool result = false;
149  int asInt;
150  bool converted = p_convertCFNumberToInt(cfn, &asInt);
151
152  if (converted && (0 != asInt)) {
153    result = true;
154  }
155
156  return result;
157}
158
159#endif  // WEBRTC_MAC && !defined(WEBRTC_IOS)
160