Module: AE

Defined in:
ext/ae/ae.c

Defined Under Namespace

Classes: AEDesc, MacOSError

Class Method Summary collapse

Class Method Details

.convert_long_date_time_to_string(ldt) ⇒ Object

Date conversion



616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
# File 'ext/ae/ae.c', line 616

static VALUE
rbAE_convertLongDateTimeToString(VALUE self, VALUE ldt)
{
  Boolean bErr;
  OSStatus err = 0;
  CFAbsoluteTime cfTime;
  CFDateFormatterRef formatter;
  CFStringRef str;
  char buffer[20]; // size of format string + nul

  err = UCConvertLongDateTimeToCFAbsoluteTime(NUM2LL(ldt), &cfTime);
  if (err != noErr) rbAE_raiseMacOSError("Can't convert LongDateTime to seconds.", err);
  formatter = CFDateFormatterCreate(NULL, NULL,  kCFDateFormatterNoStyle,  kCFDateFormatterNoStyle);
  if (!formatter) rbAE_raiseMacOSError("Can't create date formatter.", err);
  CFDateFormatterSetFormat(formatter, CFSTR("yyyy-MM-dd HH:mm:ss"));
  str = CFDateFormatterCreateStringWithAbsoluteTime(NULL, formatter, cfTime);
  CFRelease(formatter);
  if (!str) rbAE_raiseMacOSError("Can't create date string.", err);
  bErr = CFStringGetCString(str,
                            buffer,
                            sizeof(buffer),
                            kCFStringEncodingUTF8);
  CFRelease(str);
  if (!bErr) rb_raise(rb_eRuntimeError, "Can't convert date string.");
  return rb_str_new2(buffer);
}

.convert_long_date_time_to_unix_seconds(ldt) ⇒ Object



673
674
675
676
677
678
679
680
681
682
# File 'ext/ae/ae.c', line 673

static VALUE
rbAE_convertLongDateTimeToUnixSeconds(VALUE self, VALUE ldt)
{
  OSStatus err = 0;
  CFAbsoluteTime cfTime;

  err = UCConvertLongDateTimeToCFAbsoluteTime(NUM2LL(ldt), &cfTime);
  if (err != noErr) rbAE_raiseMacOSError("Can't convert LongDateTime to seconds.", err);
  return rb_float_new(cfTime + kCFAbsoluteTimeIntervalSince1970);
}

.convert_path_to_url(path, pathStyle) ⇒ Object

HFS/POSIX path conversions



562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
# File 'ext/ae/ae.c', line 562

static VALUE
rbAE_convertPathToURL(VALUE self, VALUE path, VALUE pathStyle)
{
  CFStringRef str;
  CFURLRef url;
  UInt8 buffer[PATH_MAX];

  str = CFStringCreateWithBytes(NULL,
                                (UInt8 *)(RSTRING_PTR(path)),
                                (CFIndex)(RSTRING_LEN(path)),
                                kCFStringEncodingUTF8,
                                false);
  if (str == NULL) rb_raise(rb_eRuntimeError, "Bad path string.");
  url = CFURLCreateWithFileSystemPath(NULL,
                                      str,
                                      NUM2LONG(pathStyle),
                                      false);
  CFRelease(str);
  if (url == NULL) rb_raise(rb_eRuntimeError, "Invalid path.");
  buffer[CFURLGetBytes(url, buffer, PATH_MAX - 1)] = '\0';
  CFRelease(url);
  return rb_str_new2((char *)buffer);
}

.convert_string_to_long_date_time(datetime) ⇒ Object



644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
# File 'ext/ae/ae.c', line 644

static VALUE
rbAE_convertStringToLongDateTime(VALUE self, VALUE datetime)
{
  CFStringRef str;
  CFAbsoluteTime cfTime;
  CFDateFormatterRef formatter;
  OSStatus err = 0;
  Boolean bErr;
  SInt64 ldt;

  str = CFStringCreateWithBytes(NULL,
                                (UInt8 *)(RSTRING_PTR(datetime)),
                                (CFIndex)(RSTRING_LEN(datetime)),
                                kCFStringEncodingUTF8,
                                false);
  if (str == NULL || CFStringGetLength(str) != 19) rb_raise(rb_eRuntimeError, "Bad datetime string.");
  formatter = CFDateFormatterCreate(NULL, NULL,  kCFDateFormatterNoStyle,  kCFDateFormatterNoStyle);
  if (!formatter) rbAE_raiseMacOSError("Can't create date formatter.", err);
  CFDateFormatterSetFormat(formatter, CFSTR("yyyy-MM-dd HH:mm:ss"));
  bErr = CFDateFormatterGetAbsoluteTimeFromString(formatter, str, NULL, &cfTime);
  CFRelease(formatter);
  CFRelease(str);
  if (!bErr) rb_raise(rb_eRuntimeError, "Can't convert date string.");
  err = UCConvertCFAbsoluteTimeToLongDateTime(cfTime, &ldt);
  if (err != noErr) rbAE_raiseMacOSError("Can't convert seconds to LongDateTime.", err);
  return LL2NUM(ldt);
}

.convert_unix_seconds_to_long_date_time(secs) ⇒ Object



685
686
687
688
689
690
691
692
693
694
# File 'ext/ae/ae.c', line 685

static VALUE
rbAE_convertUnixSecondsToLongDateTime(VALUE self, VALUE secs)
{
  OSStatus err = 0;
  SInt64 ldt;

  err = UCConvertCFAbsoluteTimeToLongDateTime(NUM2DBL(secs) - kCFAbsoluteTimeIntervalSince1970, &ldt);
  if (err != noErr) rbAE_raiseMacOSError("Can't convert seconds to LongDateTime.", err);
  return LL2NUM(ldt);
}

.convert_url_to_path(urlStr, pathStyle) ⇒ Object



586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'ext/ae/ae.c', line 586

static VALUE
rbAE_convertURLToPath(VALUE self, VALUE urlStr, VALUE pathStyle)
{
  Boolean err;
  CFURLRef url;
  CFStringRef str;
  char buffer[PATH_MAX];

  url = CFURLCreateWithBytes(NULL,
                             (UInt8 *)(RSTRING_PTR(urlStr)),
                             (CFIndex)(RSTRING_LEN(urlStr)),
                             kCFStringEncodingUTF8,
                             NULL);
  if (url == NULL) rb_raise(rb_eRuntimeError, "Bad URL string.");
  str = CFURLCopyFileSystemPath(url, NUM2LONG(pathStyle));
  CFRelease(url);
  if (str == NULL) rb_raise(rb_eRuntimeError, "Can't get path.");
  err = CFStringGetCString(str,
                           buffer,
                           PATH_MAX,
                           kCFStringEncodingUTF8);
  CFRelease(str);
  if (!err) rb_raise(rb_eRuntimeError, "Can't get path.");
  return rb_str_new2(buffer);
}

.copy_scripting_definition(path) ⇒ Object

Get aete



700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
# File 'ext/ae/ae.c', line 700

static VALUE
rbAE_OSACopyScriptingDefinition(VALUE self, VALUE path)
{
  FSRef fsRef;
  CFDataRef sdef;
  CFIndex dataSize;
  char *data;
  VALUE res;
  OSErr err = noErr;

  err = FSPathMakeRef((UInt8 *)StringValuePtr(path), &fsRef, NULL);
  if (err != 0) rbAE_raiseMacOSError("Couldn't make FSRef for path.", err);
  err = OSACopyScriptingDefinition(&fsRef, 0, &sdef);
  if (err) rbAE_raiseMacOSError("Couldn't get sdef.", err);
  dataSize = CFDataGetLength(sdef);
  data = (char *)CFDataGetBytePtr(sdef);
  if (data != NULL) {
    res = rb_str_new(data, dataSize);
  } else {
    data = malloc(dataSize);
    CFDataGetBytes(sdef, CFRangeMake(0, dataSize), (UInt8 *)data);
    res = rb_str_new(data, dataSize);
    free(data);
  }
  CFRelease(sdef);
  return res;
}

.find_application(creator, bundleID, name) ⇒ Object

Find and launch applications



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'ext/ae/ae.c', line 459

static VALUE
rbAE_findApplication(VALUE self, VALUE creator, VALUE bundleID, VALUE name)
{
  OSStatus err = 0;

  OSType inCreator;
  CFStringRef inName;
  CFStringRef inBundleID;
  FSRef outAppRef;
  UInt8 path[PATH_MAX];

  inCreator = (creator == Qnil) ? kLSUnknownCreator : rbStringToDescType(creator);
  if (bundleID != Qnil) {
    inBundleID = CFStringCreateWithBytes(NULL,
                                         (UInt8 *)(RSTRING_PTR(bundleID)),
                                         (CFIndex)(RSTRING_LEN(bundleID)),
                                         kCFStringEncodingUTF8,
                                         false);
    if (inBundleID == NULL) rb_raise(rb_eRuntimeError, "Invalid bundle ID string.");
  } else {
    inBundleID = NULL;
  }
  if (name != Qnil) {
    inName = CFStringCreateWithBytes(NULL,
                                     (UInt8 *)(RSTRING_PTR(name)),
                                     (CFIndex)(RSTRING_LEN(name)),
                                     kCFStringEncodingUTF8,
                                     false);
    if (inName == NULL) {
      if (inBundleID != NULL) CFRelease(inBundleID);
      rb_raise(rb_eRuntimeError, "Invalid name string.");
    }
  } else {
    inName = NULL;
  }
  err = LSFindApplicationForInfo(inCreator,
                                 inBundleID,
                                 inName,
                                 &outAppRef,
                                 NULL);
  if (inBundleID != NULL) CFRelease(inBundleID);
  if (inName != NULL) CFRelease(inName);
  if (err != 0) rbAE_raiseMacOSError("Couldn't find application.", err);
  err = FSRefMakePath(&outAppRef, path, PATH_MAX);
  if (err != 0) rbAE_raiseMacOSError("Couldn't get application path.", err);
  return rb_str_new2((char *)path);
}

.get_coercion_handler(fromType, toType) ⇒ Object



863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
# File 'ext/ae/ae.c', line 863

static VALUE
rbAE_AEGetCoercionHandler(VALUE self, VALUE fromType, VALUE toType)
{
  OSErr err = noErr;
  AECoercionHandlerUPP handlerUPP;
  SRefCon handler;
  Boolean fromTypeIsDesc;

  err = AEGetCoercionHandler(rbStringToDescType(fromType),
                             rbStringToDescType(toType),
                             &handlerUPP, &handler,
                             &fromTypeIsDesc,
                             0);
  if (err != noErr) rbAE_raiseMacOSError("Can't get coercion handler.", err);
  return rb_ary_new3(2, handler, fromTypeIsDesc ? Qtrue : Qfalse);
}

.get_event_handler(eventClass, eventID) ⇒ Object



786
787
788
789
790
791
792
793
794
795
796
797
798
799
# File 'ext/ae/ae.c', line 786

static VALUE
rbAE_AEGetEventHandler(VALUE self, VALUE eventClass, VALUE eventID)
{
  OSErr err = noErr;
  AEEventHandlerUPP handlerUPP;
  SRefCon handler;

  err = AEGetEventHandler(rbStringToDescType(eventClass),
                          rbStringToDescType(eventID),
                          &handlerUPP, &handler,
                          0);
  if (err != noErr) rbAE_raiseMacOSError("Can't get event handler.", err);
  return (VALUE)handler;
}

.install_coercion_handler(fromType, toType, _handler) ⇒ Object

****



825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
# File 'ext/ae/ae.c', line 825

static VALUE
rbAE_AEInstallCoercionHandler(VALUE self, VALUE fromType, VALUE toType, VALUE _handler)
{
  SRefCon handler = (SRefCon)_handler;
  /*
   * fromType and toType must be four-character code strings
   *
   * handler must be a Ruby object containing a method named 'handle_coercion' that takes an
   * AEDesc and a four-character code (original value, desired type) as arguments, and returns an
   * AEDesc of the desired type.Note that this object is responsible for trapping any unhandled
   * exceptions and returning nil (or any other non-AEDesc value) as appropriate, otherwise the
   * program will exit.
   */
  OSErr err = noErr;

  err = AEInstallCoercionHandler(rbStringToDescType(fromType),
                                 rbStringToDescType(toType),
                                 upp_GenericCoercionHandler, handler,
                                 1, 0);
  if (err != noErr) rbAE_raiseMacOSError("Can't install coercion handler.", err);
  return Qnil;
}

.install_event_handler(eventClass, eventID, _handler) ⇒ Object

****



749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
# File 'ext/ae/ae.c', line 749

static VALUE
rbAE_AEInstallEventHandler(VALUE self, VALUE eventClass, VALUE eventID, VALUE _handler)
{
  SRefCon handler = (SRefCon)_handler;
  /*
   * eventClass and eventID must be four-character code strings
   *
   * handler must be a Ruby object containing a method named 'handle_event' that takes two
   * AppleEvent descriptors (request and reply) as arguments, and returns an integer.
   * Note that this object is responsible for trapping any unhandled exceptions and returning
   * an OS error number as appropriate (or 0 if no error), otherwise the program will exit.
   */
  OSErr err = noErr;

  err = AEInstallEventHandler(rbStringToDescType(eventClass),
                              rbStringToDescType(eventID),
                              upp_GenericEventHandler, handler,
                              0);
  if (err != noErr) rbAE_raiseMacOSError("Can't install event handler.", err);
  return Qnil;
}

.launch_application(path, firstEvent, flags) ⇒ Object



540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File 'ext/ae/ae.c', line 540

static VALUE
rbAE_launchApplication(VALUE self, VALUE path, VALUE firstEvent, VALUE flags)
{
  FSRef appRef;
  ProcessSerialNumber psn;
  OSStatus err = noErr;

  err = FSPathMakeRef((UInt8 *)StringValuePtr(path), &appRef, NULL);
  if (err != noErr) rbAE_raiseMacOSError("Couldn't make FSRef for application.", err);
  LSApplicationParameters appParams = {0,
                                       (LSLaunchFlags)NUM2UINT(flags),
                                       &appRef,
                                       NULL, NULL, NULL,
                                       &(AEDESC_OF(firstEvent))};
  err = LSOpenApplication(&appParams, &psn);
  if (err != noErr) rbAE_raiseMacOSError("Can't launch application.", err);
  return rb_ary_new3(2, INT2NUM(psn.highLongOfPSN), INT2NUM(psn.lowLongOfPSN));
}

.psn_for_application_path(path) ⇒ Object



508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
# File 'ext/ae/ae.c', line 508

static VALUE
rbAE_psnForApplicationPath(VALUE self, VALUE path)
{
  OSStatus err = noErr;
  ProcessSerialNumber psn = {0, kNoProcess};
  FSRef appRef, foundRef;

  err = FSPathMakeRef((UInt8 *)StringValuePtr(path), &appRef, NULL);
  if (err != 0) rbAE_raiseMacOSError("Couldn't make FSRef for application.", err);
  while (1) {
    err = GetNextProcess(&psn);
    if (err != 0) rbAE_raiseMacOSError("Can't get next process.", err); // -600 if no more processes left
    err = GetProcessBundleLocation(&psn, &foundRef);
    if (err != 0) continue;
    if (FSCompareFSRefs(&appRef, &foundRef) == noErr)
      return rb_ary_new3(2, INT2NUM(psn.highLongOfPSN), INT2NUM(psn.lowLongOfPSN));
  }
}

.psn_for_process_id(pid) ⇒ Object



528
529
530
531
532
533
534
535
536
537
# File 'ext/ae/ae.c', line 528

static VALUE
rbAE_psnForPID(VALUE self, VALUE pid)
{
  OSStatus err = noErr;
  ProcessSerialNumber psn = {0, kNoProcess};

  err = GetProcessForPID(NUM2INT(pid), &psn);
  if (err != 0) rbAE_raiseMacOSError("Can't get next process.", err); // -600 if process not found
  return rb_ary_new3(2, INT2NUM(psn.highLongOfPSN), INT2NUM(psn.lowLongOfPSN));
}

.remove_coercion_handler(fromType, toType) ⇒ Object



849
850
851
852
853
854
855
856
857
858
859
860
# File 'ext/ae/ae.c', line 849

static VALUE
rbAE_AERemoveCoercionHandler(VALUE self, VALUE fromType, VALUE toType)
{
  OSErr err = noErr;

  err = AERemoveCoercionHandler(rbStringToDescType(fromType),
                                rbStringToDescType(toType),
                                upp_GenericCoercionHandler,
                                0);
  if (err != noErr) rbAE_raiseMacOSError("Can't remove coercion handler.", err);
  return Qnil;
}

.remove_event_handler(eventClass, eventID) ⇒ Object



772
773
774
775
776
777
778
779
780
781
782
783
# File 'ext/ae/ae.c', line 772

static VALUE
rbAE_AERemoveEventHandler(VALUE self, VALUE eventClass, VALUE eventID)
{
  OSErr err = noErr;

  err = AERemoveEventHandler(rbStringToDescType(eventClass),
                             rbStringToDescType(eventID),
                             upp_GenericEventHandler,
                             0);
  if (err != noErr) rbAE_raiseMacOSError("Can't remove event handler.", err);
  return Qnil;
}

.transform_process_to_foreground_applicationObject

Process management



885
886
887
888
889
890
891
892
893
894
# File 'ext/ae/ae.c', line 885

static VALUE
rbAE_transformProcessToForegroundApplication(VALUE self)
{
  OSStatus err = 0;
  ProcessSerialNumber psn = {0, kCurrentProcess};

  err = TransformProcessType(& psn, kProcessTransformToForegroundApplication);
  if( err != 0) rbAE_raiseMacOSError("Can't transform process.", err);
  return Qnil;
}