Mercurial > projects > dstep
view dstep/objc/bridge/TypeEncoding.d @ 16:19885b43130e
Huge update, the bridge actually works now
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sun, 03 Jan 2010 22:06:11 +0100 |
parents | 07194b026fa4 |
children |
line wrap: on
line source
/** * Copyright: Copyright (c) 2009 Jacob Carlborg. * Authors: Jacob Carlborg * Version: Initial created: Feb 8, 2009 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) */ module dstep.objc.bridge.TypeEncoding; version (Tango) import tango.core.Traits; else import std.traits; import dstep.internal.String; import dstep.internal.Traits; import dstep.objc.bridge.Type; import dstep.objc.objc; import dstep.objc.runtime; /** * Creates the encoded (mangled) form of a type for the * Objective-C runtime. */ template encode (TL...) { const string encode = encodeImpl!(TL)(); } private string encodeImpl (TL...) () { char[] s; foreach (T ; TL) { static if (is (T == id) || needsEncapsulation!(T)) s ~= _C_ID; else static if (is (T == Class)) s ~= _C_CLASS; else static if (is (T == SEL)) s ~= _C_SEL; else static if (is (T == byte)) s ~= _C_CHR; else static if (is (T == ubyte)) s ~= _C_UCHR; else static if (is (T == short)) s ~= _C_SHT; else static if (is (T == ushort)) s ~= _C_USHT; else static if (is (T == int)) s ~= _C_INT; else static if (is (T == uint)) s ~= _C_UINT; else static if (is (T == long)) s ~= _C_LNG_LNG; else static if (is (T == ulong)) s ~= _C_ULNG_LNG; else static if (is (T == float)) s ~= _C_FLT; else static if (is (T == double)) s ~= _C_DBL; else static if (is (T == bool)) s ~= _C_BOOL; else static if (is (T == void)) s ~= _C_VOID; else static if (is (T U : T*)) s ~= _C_VOID ~ encode!(U); else static if (is (T : char*)) s ~= _C_CHARPTR; else static if (is (T U : T)) s ~= _C_ARY_B ~ encode!(U) ~ _C_ARY_E; else static if (is (T == union)) s ~= _C_UNION_B ~ encode!(typeof(T.tupleof)) ~ _C_UNION_E; else static if (is (T == struct)) s ~= _C_STRUCT_B ~ encode!(typeof(T.tupleof)) ~ _C_STRUCT_E; else s ~= _C_UNDEF; } return s; } /** * Create the encoded (mangled) form of a type for the * Objective-C runtime out of the given callable type. * This is a shortcut for encode */ template encodeCallable (alias Callable) { static assert(isCallableType!(typeof(Callable)), "dstep.objc.bridge.TypeCoding.encodeCallable: The given type is not a callable type"); const encodeCallable = encode!(ReturnTypeOf!(typeof(Callable)), id, SEL, ParameterTupleOf!(typeof(Callable))); } template checkSelector (string selector, ARGS...) { const checkSelector = checkSelectorImpl!(selector, ARGS); } private bool checkSelectorImpl (string selector, ARGS...) () { size_t i = 0; foreach (c ; selector) if (c == ':') i++; return i == ARGS.length; } /** * Builds a string representing a selector out of the given function * * It will build the string like this: * * --- * foo (int x, int y); // foo:y: * bar (); // bar * fooBar (int x); // fooBar: * --- * * Params: * func = the function alias to build the selector of * * Returns: a string representing the selector */ template buildSelector (alias method) { const buildSelector = buildSelectorImpl!(method); } private string buildSelectorImpl (alias method) () { string result = functionNameOf!(method); string[] parameterNames = parameterNamesOf!(method); if (parameterNames.length == 0) return result; else if (parameterNames.length == 1) return result ~ ':'; else if (parameterNames.length >= 2) parameterNames = parameterNames[1 .. $]; result ~= ':'; foreach (str ; parameterNames) result ~= str ~ ':'; return result; } template decimalDigit (int n) // [3] { const string decimalDigit = "0123456789"[n .. n + 1]; } template itoa (long n) { static if (n < 0) const string itoa = "-" ~ itoa!(-n); else static if (n < 10) const string itoa = decimalDigit!(n); else const string itoa = itoa!(n / 10L) ~ decimalDigit!(n % 10L); } /// Converts the given string representing an OSType into an integer. template getOSType (string osType) { static assert(osType.length == 4, `dstep.objc.bridge.TypeEncoding.getOSType: The length of the given string, "` ~ osType ~ `", is not four`); const getOSType = (cast(int)osType[0]) << 24 | (cast(int)osType[1]) << 16 | (cast(int)osType[2]) << 8 | (cast(int)osType[3]); }