rb-scpt 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rb-scpt-1.0.1.gem +0 -0
  3. data/extconf.rb +12 -12
  4. data/rb-scpt.gemspec +10 -10
  5. data/sample/AB_export_vcard.rb +16 -16
  6. data/sample/AB_list_people_with_emails.rb +4 -4
  7. data/sample/Add_iCal_event.rb +12 -12
  8. data/sample/Create_daily_iCal_todos.rb +28 -28
  9. data/sample/Export_Address_Book_phone_numbers.rb +52 -52
  10. data/sample/Hello_world.rb +10 -10
  11. data/sample/List_iTunes_playlist_names.rb +3 -3
  12. data/sample/Make_Mail_message.rb +24 -24
  13. data/sample/Open_file_in_TextEdit.rb +5 -5
  14. data/sample/Organize_Mail_messages.rb +46 -46
  15. data/sample/Print_folder_tree.rb +5 -5
  16. data/sample/Select_all_HTML_files.rb +6 -6
  17. data/sample/Set_iChat_status.rb +12 -12
  18. data/sample/Simple_Finder_GUI_Scripting.rb +6 -6
  19. data/sample/Stagger_Finder_windows.rb +9 -9
  20. data/sample/TextEdit_demo.rb +71 -71
  21. data/sample/iTunes_top40_to_html.rb +28 -30
  22. data/src/SendThreadSafe.c +293 -293
  23. data/src/SendThreadSafe.h +108 -108
  24. data/src/lib/_aem/aemreference.rb +997 -998
  25. data/src/lib/_aem/codecs.rb +609 -610
  26. data/src/lib/_aem/connect.rb +197 -197
  27. data/src/lib/_aem/encodingsupport.rb +67 -67
  28. data/src/lib/_aem/findapp.rb +75 -75
  29. data/src/lib/_aem/mactypes.rb +241 -242
  30. data/src/lib/_aem/send.rb +268 -268
  31. data/src/lib/_aem/typewrappers.rb +52 -52
  32. data/src/lib/_appscript/defaultterminology.rb +266 -266
  33. data/src/lib/_appscript/referencerenderer.rb +230 -233
  34. data/src/lib/_appscript/reservedkeywords.rb +106 -106
  35. data/src/lib/_appscript/safeobject.rb +125 -125
  36. data/src/lib/_appscript/terminology.rb +448 -449
  37. data/src/lib/aem.rb +238 -238
  38. data/src/lib/kae.rb +1487 -1487
  39. data/src/lib/osax.rb +647 -647
  40. data/src/lib/rb-scpt.rb +1065 -1065
  41. data/src/rbae.c +595 -595
  42. data/test/test_aemreference.rb +104 -107
  43. data/test/test_appscriptcommands.rb +131 -134
  44. data/test/test_appscriptreference.rb +96 -99
  45. data/test/test_codecs.rb +166 -168
  46. data/test/test_findapp.rb +13 -16
  47. data/test/test_mactypes.rb +70 -72
  48. data/test/test_osax.rb +46 -48
  49. data/test/testall.sh +4 -4
  50. metadata +8 -7
@@ -5,201 +5,201 @@
5
5
  #
6
6
 
7
7
  module Connect
8
- # Creates Apple event descriptor records of typeProcessSerialNumber, typeKernelProcessID and typeApplicationURL, used to specify the target application in Send::Event constructor.
9
-
10
- require "ae"
11
- require "kae"
12
- require "_aem/codecs"
13
- require "_aem/send"
14
- require "_aem/encodingsupport"
15
-
16
- @@encoding_support = AEMEncodingSupport.encoding_support
17
-
18
- LSLaunchDefaults = 0x00000001
19
- LSLaunchAndPrint = 0x00000002
20
- LSLaunchReserved2 = 0x00000004
21
- LSLaunchReserved3 = 0x00000008
22
- LSLaunchReserved4 = 0x00000010
23
- LSLaunchReserved5 = 0x00000020
24
- LSLaunchAndDisplayErrors = 0x00000040
25
- LSLaunchInhibitBGOnly = 0x00000080
26
- LSLaunchDontAddToRecents = 0x00000100
27
- LSLaunchDontSwitch = 0x00000200
28
- LSLaunchNoParams = 0x00000800
29
- LSLaunchAsync = 0x00010000
30
- LSLaunchStartClassic = 0x00020000
31
- LSLaunchInClassic = 0x00040000
32
- LSLaunchNewInstance = 0x00080000
33
- LSLaunchAndHide = 0x00100000
34
- LSLaunchAndHideOthers = 0x00200000
35
- LSLaunchHasUntrustedContents = 0x00400000
36
-
37
- KNoProcess = 0
38
- KCurrentProcess = 2
39
-
40
- def Connect.make_address_desc(psn)
41
- return AE::AEDesc.new(KAE::TypeProcessSerialNumber, psn.pack('LL'))
42
- end
43
-
44
- NullAddress = make_address_desc([0,KNoProcess])
45
- LaunchEvent = Send::Event.new(Connect::NullAddress, 'ascrnoop').AEM_event
46
- RunEvent = Send::Event.new(Connect::NullAddress, 'aevtoapp').AEM_event
47
-
48
- #######
49
- # public
50
-
51
- class CantLaunchApplicationError < RuntimeError
52
-
53
- # Taken from <http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference>:
54
- LSErrors = {
55
- -10660 => "The application cannot be run because it is inside a Trash folder.",
56
- -10810 => "An unknown error has occurred.",
57
- -10811 => "The item to be registered is not an application.",
58
- -10813 => "Data of the desired type is not available (for example, there is no kind string).",
59
- -10814 => "No application in the Launch Services database matches the input criteria.",
60
- -10817 => "Data is structured improperly (for example, an item's information property list is malformed).",
61
- -10818 => "A launch of the application is already in progress.",
62
- -10822 => "There is a problem communicating with the server process that maintains the Launch Services database.",
63
- -10823 => "The filename extension to be hidden cannot be hidden.",
64
- -10825 => "The application to be launched cannot run on the current Mac OS version.",
65
- -10826 => "The user does not have permission to launch the application (on a managed network).",
66
- -10827 => "The executable file is missing or has an unusable format.",
67
- -10828 => "The Classic emulation environment was required but is not available.",
68
- -10829 => "The application to be launched cannot run simultaneously in two different user sessions.",
69
- }
70
-
71
- def initialize(error_number)
72
- @error_number = error_number
73
- super("#{ LSErrors.fetch(@error_number, 'OS error') } (#{ @error_number })")
74
- end
75
-
76
- def to_i
77
- return @error_number
78
- end
79
- end
80
-
81
- ##
82
-
83
- def Connect.launch_application(path, event)
84
- path = @@encoding_support.to_utf8_string(path)
85
- begin
86
- return AE.launch_application(path, event,
87
- LSLaunchNoParams | LSLaunchStartClassic | LSLaunchDontSwitch)
88
- rescue AE::MacOSError => err
89
- raise CantLaunchApplicationError, err.to_i
90
- end
91
- end
92
-
93
- def Connect.launch_app_with_launch_event(path)
94
- # Send a 'launch' event to an application. If application is not already running, it will be launched in background first.
95
- path = @@encoding_support.to_utf8_string(path)
96
- begin
97
- # If app is already running, calling AE.launch_application will send a 'reopen' event, so need to check for this first:
98
- psn = AE.psn_for_application_path(path)
99
- rescue AE::MacOSError => err
100
- if err.to_i == -600 # Application isn't running, so launch it and send it a 'launch' event
101
- sleep(1)
102
- launch_application(path, LaunchEvent)
103
- else
104
- raise
105
- end
106
- else # App is already running, so send it a 'launch' event
107
- Send::Event.new(make_address_desc(psn), 'ascrnoop').send(60, KAE::KAENoReply)
108
- end
109
- end
110
-
111
- ##
112
-
113
- def Connect.process_exists_for_path?(path)
114
- path = @@encoding_support.to_utf8_string(path)
115
- # Does a local process launched from the specified application file exist?
116
- # Note: if path is invalid, an AE::MacOSError is raised.
117
- begin
118
- AE.psn_for_application_path(path)
119
- return true
120
- rescue AE::MacOSError => err
121
- if err.to_i == -600
122
- return false
123
- else
124
- raise
125
- end
126
- end
127
- end
128
-
129
- def Connect.process_exists_for_pid?(pid)
130
- # Is there a local application process with the given unix process id?
131
- begin
132
- AE.psn_for_process_id(pid)
133
- return true
134
- rescue AE::MacOSError => err
135
- if err.to_i == -600
136
- return false
137
- else
138
- raise
139
- end
140
- end
141
- end
142
-
143
- def Connect.process_exists_for_url?(url)
144
- # Does an application process specified by the given eppc:// URL exist?
145
- # Note: this will send a 'launch' Apple event to the target application.
146
- raise ArgumentError, "Invalid url: #{url}" if not url.include?(':') # workaround: process will crash if no colon in URL (OS bug)
147
- return process_exists_for_desc?(AE::AEDesc.new(KAE::TypeApplicationURL, url))
148
- end
149
-
150
- def Connect.process_exists_for_desc?(desc)
151
- # Does an application process specified by the given AEAddressDesc exist?
152
- # Returns false if process doesn't exist OR remote Apple events aren't allowed.
153
- # Note: this will send a 'launch' Apple event to the target application.
154
- begin
155
- # This will usually raise error -1708 if process is running, and various errors
156
- # if the process doesn't exist/can't be reached. If app is running but busy,
157
- # AESendMessage may return a timeout error (this should be -1712, but
158
- # -609 is often returned instead for some reason).
159
- Send::Event.new(desc, 'ascrnoop').send
160
- rescue Send::EventError => err
161
- return (not [-600, -905].include?(err.to_i)) # not running/no network access
162
- end
163
- return true
164
- end
165
-
166
- ##
167
-
168
- CurrentApp = make_address_desc([0, KCurrentProcess])
169
-
170
- def Connect.local_app(path)
171
- # Make an AEAddressDesc identifying a local application. (Application will be launched if not already running.)
172
- # path : string -- full path to application, e.g. '/Applications/TextEdit.app'
173
- # Result : AEAddressDesc
174
- #
175
- # Always creates AEAddressDesc by process serial number; that way there's no confusion if multiple versions of the same app are running.
176
- path = @@encoding_support.to_utf8_string(path)
177
- begin
178
- psn = AE.psn_for_application_path(path)
179
- rescue AE::MacOSError => err
180
- if err.to_i == -600 # Application isn't running, so launch it in background and send it a standard 'run' event.
181
- sleep(1)
182
- psn = launch_application(path, RunEvent)
183
- else
184
- raise
185
- end
186
- end
187
- return make_address_desc(psn)
188
- end
189
-
190
- def Connect.local_app_by_pid(pid)
191
- # Make an AEAddressDesc identifying a running application by Unix process id.
192
- # pid : integer -- unsigned 32-bit integer
193
- # Result : AEAddressDesc
194
- return AE::AEDesc.new(KAE::TypeKernelProcessID, [pid].pack('L'))
195
- end
196
-
197
- def Connect.remote_app(url)
198
- url = @@encoding_support.to_utf8_string(url)
199
- # Make an AEAddressDesc identifying a running application on another machine.
200
- # url : string -- URL for remote application, e.g. 'eppc://user:password@0.0.0.1/TextEdit'
201
- # Result : AEAddressDesc
202
- raise ArgumentError, "Invalid url: #{url}" if not url.include?(':') # workaround: process will crash if no colon in URL (OS bug)
203
- return AE::AEDesc.new(KAE::TypeApplicationURL, url)
204
- end
8
+ # Creates Apple event descriptor records of typeProcessSerialNumber, typeKernelProcessID and typeApplicationURL, used to specify the target application in Send::Event constructor.
9
+
10
+ require "ae"
11
+ require "kae"
12
+ require "_aem/codecs"
13
+ require "_aem/send"
14
+ require "_aem/encodingsupport"
15
+
16
+ @@encoding_support = AEMEncodingSupport.encoding_support
17
+
18
+ LSLaunchDefaults = 0x00000001
19
+ LSLaunchAndPrint = 0x00000002
20
+ LSLaunchReserved2 = 0x00000004
21
+ LSLaunchReserved3 = 0x00000008
22
+ LSLaunchReserved4 = 0x00000010
23
+ LSLaunchReserved5 = 0x00000020
24
+ LSLaunchAndDisplayErrors = 0x00000040
25
+ LSLaunchInhibitBGOnly = 0x00000080
26
+ LSLaunchDontAddToRecents = 0x00000100
27
+ LSLaunchDontSwitch = 0x00000200
28
+ LSLaunchNoParams = 0x00000800
29
+ LSLaunchAsync = 0x00010000
30
+ LSLaunchStartClassic = 0x00020000
31
+ LSLaunchInClassic = 0x00040000
32
+ LSLaunchNewInstance = 0x00080000
33
+ LSLaunchAndHide = 0x00100000
34
+ LSLaunchAndHideOthers = 0x00200000
35
+ LSLaunchHasUntrustedContents = 0x00400000
36
+
37
+ KNoProcess = 0
38
+ KCurrentProcess = 2
39
+
40
+ def Connect.make_address_desc(psn)
41
+ return AE::AEDesc.new(KAE::TypeProcessSerialNumber, psn.pack('LL'))
42
+ end
43
+
44
+ NullAddress = make_address_desc([0,KNoProcess])
45
+ LaunchEvent = Send::Event.new(Connect::NullAddress, 'ascrnoop').AEM_event
46
+ RunEvent = Send::Event.new(Connect::NullAddress, 'aevtoapp').AEM_event
47
+
48
+ #######
49
+ # public
50
+
51
+ class CantLaunchApplicationError < RuntimeError
52
+
53
+ # Taken from <http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference>:
54
+ LSErrors = {
55
+ -10660 => "The application cannot be run because it is inside a Trash folder.",
56
+ -10810 => "An unknown error has occurred.",
57
+ -10811 => "The item to be registered is not an application.",
58
+ -10813 => "Data of the desired type is not available (for example, there is no kind string).",
59
+ -10814 => "No application in the Launch Services database matches the input criteria.",
60
+ -10817 => "Data is structured improperly (for example, an item's information property list is malformed).",
61
+ -10818 => "A launch of the application is already in progress.",
62
+ -10822 => "There is a problem communicating with the server process that maintains the Launch Services database.",
63
+ -10823 => "The filename extension to be hidden cannot be hidden.",
64
+ -10825 => "The application to be launched cannot run on the current Mac OS version.",
65
+ -10826 => "The user does not have permission to launch the application (on a managed network).",
66
+ -10827 => "The executable file is missing or has an unusable format.",
67
+ -10828 => "The Classic emulation environment was required but is not available.",
68
+ -10829 => "The application to be launched cannot run simultaneously in two different user sessions.",
69
+ }
70
+
71
+ def initialize(error_number)
72
+ @error_number = error_number
73
+ super("#{ LSErrors.fetch(@error_number, 'OS error') } (#{ @error_number })")
74
+ end
75
+
76
+ def to_i
77
+ return @error_number
78
+ end
79
+ end
80
+
81
+ ##
82
+
83
+ def Connect.launch_application(path, event)
84
+ path = @@encoding_support.to_utf8_string(path)
85
+ begin
86
+ return AE.launch_application(path, event,
87
+ LSLaunchNoParams | LSLaunchStartClassic | LSLaunchDontSwitch)
88
+ rescue AE::MacOSError => err
89
+ raise CantLaunchApplicationError, err.to_i
90
+ end
91
+ end
92
+
93
+ def Connect.launch_app_with_launch_event(path)
94
+ # Send a 'launch' event to an application. If application is not already running, it will be launched in background first.
95
+ path = @@encoding_support.to_utf8_string(path)
96
+ begin
97
+ # If app is already running, calling AE.launch_application will send a 'reopen' event, so need to check for this first:
98
+ psn = AE.psn_for_application_path(path)
99
+ rescue AE::MacOSError => err
100
+ if err.to_i == -600 # Application isn't running, so launch it and send it a 'launch' event
101
+ sleep(1)
102
+ launch_application(path, LaunchEvent)
103
+ else
104
+ raise
105
+ end
106
+ else # App is already running, so send it a 'launch' event
107
+ Send::Event.new(make_address_desc(psn), 'ascrnoop').send(60, KAE::KAENoReply)
108
+ end
109
+ end
110
+
111
+ ##
112
+
113
+ def Connect.process_exists_for_path?(path)
114
+ path = @@encoding_support.to_utf8_string(path)
115
+ # Does a local process launched from the specified application file exist?
116
+ # Note: if path is invalid, an AE::MacOSError is raised.
117
+ begin
118
+ AE.psn_for_application_path(path)
119
+ return true
120
+ rescue AE::MacOSError => err
121
+ if err.to_i == -600
122
+ return false
123
+ else
124
+ raise
125
+ end
126
+ end
127
+ end
128
+
129
+ def Connect.process_exists_for_pid?(pid)
130
+ # Is there a local application process with the given unix process id?
131
+ begin
132
+ AE.psn_for_process_id(pid)
133
+ return true
134
+ rescue AE::MacOSError => err
135
+ if err.to_i == -600
136
+ return false
137
+ else
138
+ raise
139
+ end
140
+ end
141
+ end
142
+
143
+ def Connect.process_exists_for_url?(url)
144
+ # Does an application process specified by the given eppc:// URL exist?
145
+ # Note: this will send a 'launch' Apple event to the target application.
146
+ raise ArgumentError, "Invalid url: #{url}" if not url.include?(':') # workaround: process will crash if no colon in URL (OS bug)
147
+ return process_exists_for_desc?(AE::AEDesc.new(KAE::TypeApplicationURL, url))
148
+ end
149
+
150
+ def Connect.process_exists_for_desc?(desc)
151
+ # Does an application process specified by the given AEAddressDesc exist?
152
+ # Returns false if process doesn't exist OR remote Apple events aren't allowed.
153
+ # Note: this will send a 'launch' Apple event to the target application.
154
+ begin
155
+ # This will usually raise error -1708 if process is running, and various errors
156
+ # if the process doesn't exist/can't be reached. If app is running but busy,
157
+ # AESendMessage may return a timeout error (this should be -1712, but
158
+ # -609 is often returned instead for some reason).
159
+ Send::Event.new(desc, 'ascrnoop').send
160
+ rescue Send::EventError => err
161
+ return (not [-600, -905].include?(err.to_i)) # not running/no network access
162
+ end
163
+ return true
164
+ end
165
+
166
+ ##
167
+
168
+ CurrentApp = make_address_desc([0, KCurrentProcess])
169
+
170
+ def Connect.local_app(path)
171
+ # Make an AEAddressDesc identifying a local application. (Application will be launched if not already running.)
172
+ # path : string -- full path to application, e.g. '/Applications/TextEdit.app'
173
+ # Result : AEAddressDesc
174
+ #
175
+ # Always creates AEAddressDesc by process serial number; that way there's no confusion if multiple versions of the same app are running.
176
+ path = @@encoding_support.to_utf8_string(path)
177
+ begin
178
+ psn = AE.psn_for_application_path(path)
179
+ rescue AE::MacOSError => err
180
+ if err.to_i == -600 # Application isn't running, so launch it in background and send it a standard 'run' event.
181
+ sleep(1)
182
+ psn = launch_application(path, RunEvent)
183
+ else
184
+ raise
185
+ end
186
+ end
187
+ return make_address_desc(psn)
188
+ end
189
+
190
+ def Connect.local_app_by_pid(pid)
191
+ # Make an AEAddressDesc identifying a running application by Unix process id.
192
+ # pid : integer -- unsigned 32-bit integer
193
+ # Result : AEAddressDesc
194
+ return AE::AEDesc.new(KAE::TypeKernelProcessID, [pid].pack('L'))
195
+ end
196
+
197
+ def Connect.remote_app(url)
198
+ url = @@encoding_support.to_utf8_string(url)
199
+ # Make an AEAddressDesc identifying a running application on another machine.
200
+ # url : string -- URL for remote application, e.g. 'eppc://user:password@0.0.0.1/TextEdit'
201
+ # Result : AEAddressDesc
202
+ raise ArgumentError, "Invalid url: #{url}" if not url.include?(':') # workaround: process will crash if no colon in URL (OS bug)
203
+ return AE::AEDesc.new(KAE::TypeApplicationURL, url)
204
+ end
205
205
  end
@@ -7,71 +7,71 @@
7
7
 
8
8
  module AEMEncodingSupport
9
9
 
10
- module EnableStringEncodings
11
- # AE extension methods consume and return Strings containing UTF-8 encoded data, ignoring
12
- # any attached encoding information. This module provides wrappers for AE interactions that
13
- # take care of any encoding issues in Ruby 1.9+.
14
-
15
- def EnableStringEncodings.to_utf8_string(s)
16
- # Call before passing a string to an AE method that expects it to contain UTF-8 encoded data.
17
- return s if [Encoding::ASCII_8BIT, Encoding::UTF_8].include?(s.encoding)
18
- return s.encode('UTF-8')
19
- end
20
-
21
- def EnableStringEncodings.pack_string(s, as_type)
22
- begin
23
- return AE::AEDesc.new(KAE::TypeUTF8Text, EnableStringEncodings.to_utf8_string(s)).coerce(as_type)
24
- rescue AE::MacOSError => e
25
- if e.to_i == -1700 # couldn't coerce to TypeUnicodeText
26
- raise TypeError, "Not valid UTF8 data or couldn't coerce to type %{as_type}: #{s.inspect}"
27
- else
28
- raise
29
- end
30
- end
31
- end
32
-
33
- def EnableStringEncodings.unpack_string(desc)
34
- # String instances returned by AE methods contain UTF-8 data and ASCII-8BIT encoding,
35
- # so change the encoding to match the data
36
- return desc.coerce(KAE::TypeUTF8Text).data.force_encoding('UTF-8')
37
- end
38
- end
39
-
40
-
41
- module DisableStringEncodings
42
- # Support for Ruby 1.8 Strings, which do not contain encoding information. User is responsible
43
- # for ensuring String instances passed to AE APIs contain UTF-8 encoded data; String instances
44
- # returned by unpack_string will always contain contain UTF-8 encoded data.
45
-
46
- def DisableStringEncodings.to_utf8_string(s)
47
- return s
48
- end
49
-
50
- def DisableStringEncodings.pack_string(s, as_type)
51
- begin
52
- # Note: while the BOM is optional in typeUnicodeText, it's not included by AS
53
- # and some apps, e.g. iTunes 7, will handle it incorrectly, so it's omitted here.)
54
- return AE::AEDesc.new(KAE::TypeUTF8Text, s).coerce(as_type)
55
- rescue AE::MacOSError => e
56
- if e.to_i == -1700 # couldn't coerce to TypeUnicodeText
57
- raise TypeError, "Not valid UTF8 data or couldn't coerce to type %{as_type}: #{s.inspect}"
58
- else
59
- raise
60
- end
61
- end
62
- end
63
-
64
- def DisableStringEncodings.unpack_string(desc)
65
- return desc.coerce(KAE::TypeUTF8Text).data
66
- end
67
-
68
- end
69
-
70
-
71
- def AEMEncodingSupport.encoding_support
72
- # get the appropriate module for the Ruby version used
73
- version, sub_version = RUBY_VERSION.split('.').collect {|n| n.to_i} [0, 2]
74
- return (version >= 1 and sub_version >= 9) ? AEMEncodingSupport::EnableStringEncodings : AEMEncodingSupport::DisableStringEncodings
75
- end
10
+ module EnableStringEncodings
11
+ # AE extension methods consume and return Strings containing UTF-8 encoded data, ignoring
12
+ # any attached encoding information. This module provides wrappers for AE interactions that
13
+ # take care of any encoding issues in Ruby 1.9+.
76
14
 
77
- end
15
+ def EnableStringEncodings.to_utf8_string(s)
16
+ # Call before passing a string to an AE method that expects it to contain UTF-8 encoded data.
17
+ return s if [Encoding::ASCII_8BIT, Encoding::UTF_8].include?(s.encoding)
18
+ return s.encode('UTF-8')
19
+ end
20
+
21
+ def EnableStringEncodings.pack_string(s, as_type)
22
+ begin
23
+ return AE::AEDesc.new(KAE::TypeUTF8Text, EnableStringEncodings.to_utf8_string(s)).coerce(as_type)
24
+ rescue AE::MacOSError => e
25
+ if e.to_i == -1700 # couldn't coerce to TypeUnicodeText
26
+ raise TypeError, "Not valid UTF8 data or couldn't coerce to type %{as_type}: #{s.inspect}"
27
+ else
28
+ raise
29
+ end
30
+ end
31
+ end
32
+
33
+ def EnableStringEncodings.unpack_string(desc)
34
+ # String instances returned by AE methods contain UTF-8 data and ASCII-8BIT encoding,
35
+ # so change the encoding to match the data
36
+ return desc.coerce(KAE::TypeUTF8Text).data.force_encoding('UTF-8')
37
+ end
38
+ end
39
+
40
+
41
+ module DisableStringEncodings
42
+ # Support for Ruby 1.8 Strings, which do not contain encoding information. User is responsible
43
+ # for ensuring String instances passed to AE APIs contain UTF-8 encoded data; String instances
44
+ # returned by unpack_string will always contain contain UTF-8 encoded data.
45
+
46
+ def DisableStringEncodings.to_utf8_string(s)
47
+ return s
48
+ end
49
+
50
+ def DisableStringEncodings.pack_string(s, as_type)
51
+ begin
52
+ # Note: while the BOM is optional in typeUnicodeText, it's not included by AS
53
+ # and some apps, e.g. iTunes 7, will handle it incorrectly, so it's omitted here.)
54
+ return AE::AEDesc.new(KAE::TypeUTF8Text, s).coerce(as_type)
55
+ rescue AE::MacOSError => e
56
+ if e.to_i == -1700 # couldn't coerce to TypeUnicodeText
57
+ raise TypeError, "Not valid UTF8 data or couldn't coerce to type %{as_type}: #{s.inspect}"
58
+ else
59
+ raise
60
+ end
61
+ end
62
+ end
63
+
64
+ def DisableStringEncodings.unpack_string(desc)
65
+ return desc.coerce(KAE::TypeUTF8Text).data
66
+ end
67
+
68
+ end
69
+
70
+
71
+ def AEMEncodingSupport.encoding_support
72
+ # get the appropriate module for the Ruby version used
73
+ version, sub_version = RUBY_VERSION.split('.').collect {|n| n.to_i} [0, 2]
74
+ return (version >= 1 and sub_version >= 9) ? AEMEncodingSupport::EnableStringEncodings : AEMEncodingSupport::DisableStringEncodings
75
+ end
76
+
77
+ end