User:KennyTM~/std.cy

From iPhone Development Wiki
< User:KennyTM~
Revision as of 21:00, 8 November 2009 by KennyTM~ (talk | contribs)
// Standard C functions
function CGPointMake(x, y) { return {x:x, y:y}; }
function CGSizeMake(w, h) { return {width:w, height:h}; }
function CGRectMake(x, y, w, h) { return {origin:CGPointMake(x,y), size:CGSizeMake(w, h)}; }
function NSMakeRange(loc, len) { return {location:loc, length:len}; }
var CFRangeMake = NSMakeRange;

// Standard C types
var IMP = new Type("^?"), SEL = new Type(":"), unsigned = new Type("I");
var int8_t = char, int16_t = short, int32_t = long, int64_t = new Type("q");
var uint8_t = new Type("C"), uint16_t = new Type("S"), uint32_t = new Type("L"), uint64_t = new Type("Q");
var SInt8 = int8_t, SInt16 = int16_t, SInt32 = int32_t, SInt64 = int64_t;
var UInt8 = uint8_t, UInt16 = uint16_t, UInt32 = uint32_t, UInt64 = uint64_t;
var unichar = int16_t, UniChar = int16_t, wchar_t = int32_t;
var size_t = NSUInteger, intptr_t = NSInteger;
var BOOL = char, bool = new Type("B");
var mach_port_t = int, pid_t = int32_t;
var CGRect = new Type("{CGRect}"), CGSize = new Type("{CGSize}"), CGPoint = new Type("{CGPoint}");
var NSRange = new Type("{NSRange}"), CFRange = new Type("{CFRange}");
var CGAffineTransform = new Type("{CGAffineTransform}"), UIEdgeInsets = new Type("{UIEdgeInsets}");

// Standard enum values
var UIControlStateNormal = 0, UIControlStateHighlighted = 1 << 0, UIControlStateDisabled = 1 << 1,
    UIControlStateSelected = 1 << 2, UIControlStateApplication = 0x00FF0000, UIControlStateReserved = 0xFF000000;

// Usage: dlfun("notify_post", "I*")
function dlfun(fn, encoding, altname) { var f = new Functor(dlsym(RTLD_DEFAULT, fn), encoding); if (f) this[altname || fn] = f; return f; }

// MobileSubstrate
dlfun("MSHookMessageEx", "v#:^?^^?");
dlfun("MSHookMessage", "^?#:^?*");
dlfun("MSHookFunction", "v^v^v^^v");
dlfun("_Z8MSLogHexPKvmPKc", "v^vL*", "MSLogHex");

// Declare a struct
// e.g. var CGSize = struct(CGFloat, CGFloat);
function struct(n) {
  var typestr = ["{?="];
  for (var i = 0; i < arguments.length; ++ i) {
    var arg = arguments[i];
    typestr.push(arguments[i].toString());
  }
  typestr.push("}");
  return new Type(typestr.join(""));
}

// Hack!
function quit() { MSHookFunction(dlsym(RTLD_DEFAULT, "readline"), new Functor(function(x){return null;}, "**"), null); }

// Usage: $encode("int*") --> new Type("^i").
// Cannot handle structs, unions and function pointers yet. 
function $encode(ss, dontKeepClassName) {
 function _encode(s) {
  s = s.replace(/\s{2,}/g, " ").replace(/^\s|\s$/g, "").replace(/(\W)\s|\s(\W)/g, "$1$2")
  var m;
  if ((m = /\((\*+)\)\[(\d*)\]/.exec(s))) {
    var left = s.substr(0, m.index), right = s.substr(m.index + m[0].length);
    var t = _encode(left+right), px = m[1].replace(/\*/g, "^");
    if (m[2]) return px + "[" + m[2] + t + "]";
    else      return px + "^" + t;
  } else if ((m = /\[(\d*)\]$/.exec(s))) {
    var t = _encode(s.substr(0, m.index));
    if (m[1]) return "[" + m[1] + t + "]";
    else      return "^" + t;
  } else if ((m = /\*+$/.exec(s))) {
    var t = _encode(s.substr(0, m.index));
    var px = m[0].replace(/\*/g, "^");
    if (t[0] == '1') { px = px.substr(1); t = t.substr(1); }
    return px+t;
  } else if ((m = /:(\d+)$/.exec(s))) {
    return "b" + m[1];
  } else {
    var prefix = "", longcount = 0, isunsigned = null, theType = "";
    for each (comp in s.split(/\s/)) {
      if ((mod = _encode.modifiers[comp])) prefix += mod;
      else if (comp == "unsigned") isunsigned = true;
      else if (comp == "signed")   isunsigned = false;
      else if (comp == "long")  ++ longcount;
      else if (comp == "short") -- longcount;
      else if (comp == "void") theType = "v";
      else if ((typ = this[comp])) {
        if (typ instanceof Type) theType = typ.toString();
        else theType = dontKeepClassName ? "1@" : "1@\"" + typ.toString() + "\"";
      } else theType = "{" + comp + "}";
    }
    if (theType == "" || theType == "i") {
      if (longcount < 0) theType = "s";
      else if (longcount == 1) theType = "l";
      else if (longcount >= 2) theType = "q";
    }
    if (isunsigned !== null && theType[0] !== '1' && theType[0] !== '{')
      theType = theType[isunsigned ? 'toUpperCase' : 'toLowerCase']();
    return prefix + theType;
  }
 }
 _encode.modifiers = {
  "inout": "N", "bycopy": "O", "byref": "R", "oneway": "V",
  "_Complex": "j", "in": "n", "out": "o", "const": "r"
 };
 return ss instanceof Type ? ss : new Type(_encode(ss).replace(/\^c/g, "*"));
}


/* 
Usage:

addMethod(UIWindow, "-(void)setAutorotates:(BOOL)autorotates forceUpdateInterfaceOrientation:(BOOL)orientation", function(autorotates, orientation){});

Bug: [super xxx] doesn't work by default. You need to call
  $cyr = new Super(this, @selector(...));
yourself.
*/
function addMethod(cls, decl, func) {
  if (/^\s*\+/.test(decl)) cls = cls->isa;
  var typeMatcher = /\(([^)]+)\)/g, selMatcher = /[\s\)]([^:\s]+)\s*:/g
  var typestr = "", typecount = 0;
  var selname = "";
  var m;
  while ((m = typeMatcher.exec(decl))) {
    typestr += $encode(m[1], true).toString();
    if (++typecount == 1) typestr += "@:";
  }
  if (typecount == 1) selname = /\)(.+)$/.exec(decl)[0];
  else {
    while ((m = selMatcher.exec(decl))) selname += m[1] + ":";
  }
  selname = selname.replace(/\s/g, "");
  return class_addMethod(cls, new Selector(selname), new Functor(function(self,_cmd){
    return func.apply(self,Array.prototype.slice.call(arguments,2));
  }, typestr), typestr);
}