• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2007--2009, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <sstream>
29 
30 #include "talk/base/common.h"
31 #include "talk/base/logging.h"
32 #include "talk/base/macutils.h"
33 #include "talk/base/scoped_ptr.h"
34 #include "talk/base/stringutils.h"
35 
36 namespace talk_base {
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 
ToUtf8(const CFStringRef str16,std::string * str8)40 bool ToUtf8(const CFStringRef str16, std::string* str8) {
41   if ((NULL == str16) || (NULL == str8))
42     return false;
43   size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16),
44                                                     kCFStringEncodingUTF8)
45                   + 1;
46   scoped_array<char> buffer(new char[maxlen]);
47   if (!buffer.get()
48       || !CFStringGetCString(str16, buffer.get(), maxlen,
49                              kCFStringEncodingUTF8))
50     return false;
51   str8->assign(buffer.get());
52   return true;
53 }
54 
ToUtf16(const std::string & str8,CFStringRef * str16)55 bool ToUtf16(const std::string& str8, CFStringRef* str16) {
56   if (NULL == str16)
57     return false;
58   *str16 = CFStringCreateWithBytes(kCFAllocatorDefault,
59                                    reinterpret_cast<const UInt8*>(str8.data()),
60                                    str8.length(), kCFStringEncodingUTF8,
61                                    false);
62   return (NULL != *str16);
63 }
64 
DecodeFourChar(UInt32 fc,std::string * out)65 void DecodeFourChar(UInt32 fc, std::string* out) {
66   std::stringstream ss;
67   ss << '\'';
68   bool printable = true;
69   for (int i = 3; i >= 0; --i) {
70     char ch = (fc >> (8 * i)) & 0xFF;
71     if (isprint(static_cast<unsigned char>(ch))) {
72       ss << ch;
73     } else {
74       printable = false;
75       break;
76     }
77   }
78   if (printable) {
79     ss << '\'';
80   } else {
81     ss.str("");
82     ss << "0x" << std::hex << fc;
83   }
84   out->append(ss.str());
85 }
86 
DecodeEvent(EventRef event)87 std::string DecodeEvent(EventRef event) {
88   std::string str;
89   DecodeFourChar(::GetEventClass(event), &str);
90   str.push_back(':');
91   DecodeFourChar(::GetEventKind(event), &str);
92   return str;
93 }
94 
GetGestalt(OSType ostype,int * value)95 static bool GetGestalt(OSType ostype, int* value) {
96   ASSERT(NULL != value);
97   SInt32 native_value;
98   OSStatus result = Gestalt(ostype, &native_value);
99   if (noErr == result) {
100     *value = native_value;
101     return true;
102   }
103   std::string str;
104   DecodeFourChar(ostype, &str);
105   LOG_E(LS_ERROR, OS, result) << "Gestalt(" << str << ")";
106   return false;
107 }
108 
GetOSVersion(int * major,int * minor,int * bugfix)109 bool GetOSVersion(int* major, int* minor, int* bugfix) {
110   ASSERT(major && minor && bugfix);
111   if (!GetGestalt(gestaltSystemVersion, major))
112     return false;
113   if (*major < 0x1040) {
114     *bugfix = *major & 0xF;
115     *minor = (*major >> 4) & 0xF;
116     *major = (*major >> 8);
117     return true;
118   }
119   return GetGestalt(gestaltSystemVersionMajor, major)
120       && GetGestalt(gestaltSystemVersionMinor, minor)
121       && GetGestalt(gestaltSystemVersionBugFix, bugfix);
122 }
123 
GetOSVersionName()124 MacOSVersionName GetOSVersionName() {
125   int major = 0, minor = 0, bugfix = 0;
126   if (!GetOSVersion(&major, &minor, &bugfix))
127     return kMacOSUnknown;
128   if (major > 10)
129     return kMacOSNewer;
130   if ((major < 10) || (minor < 3))
131     return kMacOSOlder;
132   switch (minor) {
133     case 3:
134       return kMacOSPanther;
135     case 4:
136       return kMacOSTiger;
137     case 5:
138       return kMacOSLeopard;
139   }
140   return kMacOSNewer;
141 }
142 
GetQuickTimeVersion(std::string * out)143 bool GetQuickTimeVersion(std::string* out) {
144   int ver;
145   if (!GetGestalt(gestaltQuickTimeVersion, &ver))
146     return false;
147 
148   std::stringstream ss;
149   ss << std::hex << ver;
150   *out = ss.str();
151   return true;
152 }
153 
RunAppleScript(const std::string & script)154 bool RunAppleScript(const std::string& script) {
155   ComponentInstance component = NULL;
156   AEDesc script_desc;
157   AEDesc result_data;
158   OSStatus err;
159   OSAID script_id, result_id;
160 
161   AECreateDesc(typeNull, NULL, 0, &script_desc);
162   AECreateDesc(typeNull, NULL, 0, &result_data);
163   script_id = kOSANullScript;
164   result_id = kOSANullScript;
165 
166   component = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
167   if (component == NULL) {
168     LOG(LS_ERROR) << "Failed opening Apple Script component";
169     return false;
170   }
171   err = AECreateDesc(typeUTF8Text, script.data(), script.size(), &script_desc);
172   if (err != noErr) {
173     CloseComponent(component);
174     LOG(LS_ERROR) << "Failed creating Apple Script description";
175     return false;
176   }
177 
178   err = OSACompile(component, &script_desc, kOSAModeCanInteract, &script_id);
179   if (err != noErr) {
180     AEDisposeDesc(&script_desc);
181     if (script_id != kOSANullScript) {
182       OSADispose(component, script_id);
183     }
184     CloseComponent(component);
185     LOG(LS_ERROR) << "Error compiling Apple Script";
186     return false;
187   }
188 
189   err = OSAExecute(component, script_id, kOSANullScript, kOSAModeCanInteract,
190 		   &result_id);
191 
192   if (err == errOSAScriptError) {
193     LOG(LS_ERROR) << "Error when executing Apple Script: " << script;
194     AECreateDesc(typeNull, NULL, 0, &result_data);
195     OSAScriptError(component, kOSAErrorMessage, typeChar, &result_data);
196     int len = AEGetDescDataSize(&result_data);
197     char* data = (char*) malloc(len);
198     if (data != NULL) {
199       err = AEGetDescData(&result_data, data, len);
200       LOG(LS_ERROR) << "Script error: " << data;
201     }
202     AEDisposeDesc(&script_desc);
203     AEDisposeDesc(&result_data);
204     return false;
205   }
206   AEDisposeDesc(&script_desc);
207   if (script_id != kOSANullScript) {
208     OSADispose(component, script_id);
209   }
210   if (result_id != kOSANullScript) {
211     OSADispose(component, result_id);
212   }
213   CloseComponent(component);
214   return true;
215 }
216 
217 
218 ///////////////////////////////////////////////////////////////////////////////
219 
220 }  // namespace talk_base
221