Exemplo n.º 1
0
	def _parseAttributes(self):
		index = 0
		exploded = self.attributes.split(',')
		
		# attributes defined by a single letter.
		__singleLetters = {
			'C': ('accessMethod', 'copy'),
			'&': ('accessMethod', 'retain'),
			'N': ('atomic', False),
			'D': ('synthesizedIvar', ''),
			'P': ('gcStrength', '__strong'),
			'W': ('gcStrength', '__weak'),
			'G': ('hasGetter', True),
			'S': ('hasSetter', True),
			'R': ('readOnly', True)
		}
		
		# attributes defined by a letter followed by some strings.
		__multiLetters = {
			'G': 'getter',
			'S': 'setter',
			'V': 'synthesizedIvar'
		}
		
		buffer = []
		for string in exploded:
			if buffer:
				buffer.append(string)
			else:
				typ = string[0]
				if typ in __multiLetters:
					setattr(self, __multiLetters[typ], string[1:])
				if typ in __singleLetters:
					(attr, val) = __singleLetters[typ]
					setattr(self, attr, val)
				if typ == 'T':
					buffer = [string[1:]]
			
			if buffer:
				joinedBuffer = ','.join(buffer)
				joinedBufferLength = len(joinedBuffer)
				if balancedSubstring(joinedBuffer) <= joinedBufferLength:
					self.encoding = joinedBuffer
					buffer = []
Exemplo n.º 2
0
    def _parseAttributes(self):
        index = 0
        exploded = self.attributes.split(',')

        # attributes defined by a single letter.
        __singleLetters = {
            'C': ('accessMethod', 'copy'),
            '&': ('accessMethod', 'retain'),
            'N': ('atomic', False),
            'D': ('synthesizedIvar', ''),
            'P': ('gcStrength', '__strong'),
            'W': ('gcStrength', '__weak'),
            'G': ('hasGetter', True),
            'S': ('hasSetter', True),
            'R': ('readOnly', True)
        }

        # attributes defined by a letter followed by some strings.
        __multiLetters = {'G': 'getter', 'S': 'setter', 'V': 'synthesizedIvar'}

        buffer = []
        for string in exploded:
            if buffer:
                buffer.append(string)
            else:
                typ = string[0]
                if typ in __multiLetters:
                    setattr(self, __multiLetters[typ], string[1:])
                if typ in __singleLetters:
                    (attr, val) = __singleLetters[typ]
                    setattr(self, attr, val)
                if typ == 'T':
                    buffer = [string[1:]]

            if buffer:
                joinedBuffer = ','.join(buffer)
                joinedBufferLength = len(joinedBuffer)
                if balancedSubstring(joinedBuffer) <= joinedBufferLength:
                    self.encoding = joinedBuffer
                    buffer = []
Exemplo n.º 3
0
def parse(encoding, start=0, end=None, hasMemberName=True):
    """
    Parse an encoded type string into an Objective-C type.
    
    If you supply *start* and *end*, only the substring ``encoding[start:end]``
    will be parsed.
    
    Returns a tuple of :class:`~objctype2.types.Type` and the next index to
    parse. If nothing can be parsed, the type will become ``None``.
    
    Example::
    
        from objctype2.parser import parse
        from balanced_substring import numericSubstring
        
        typeinfo = 'c24@0:4@8@12{_NSRange=II}16'
        index = 0
        while True:
            (type_, index) = parse(typeinfo, index)
            if type_ is None:
                break
            (stackIndex, index) = numericSubstring(typeinfo, index)
            print (type_, '@', stackIndex)

        # prints:            
        #    Primitive('c') @ 24
        #    ObjCType() @ 0
        #    Primitive(':') @ 4
        #    ObjCType() @ 8
        #    ObjCType() @ 12
        #    Struct('_NSRange').append(Primitive('I')).append(Primitive('I')).freeze() @ 16

    """

    if end is None:
        end = len(encoding)

    if start >= end:
        return (None, end)

    firstChar = encoding[start]
    start += 1

    # primitives
    if firstChar in _primitive1c:
        return (Primitive(firstChar), start)

    # unary, or function pointer (^ and ^?)
    elif firstChar in _modifier1c:
        if start >= end or encoding[start] in "]})":
            return (Primitive(FUNCTION_POINTER), start)
        elif encoding[start] == '?':
            return (Primitive(FUNCTION_POINTER), start + 1)
        else:
            (baseType, newStart) = parse(encoding, start, end, hasMemberName)
            return (Unary(firstChar, baseType), newStart)

    # char pointer
    elif firstChar == '*':
        return (Unary(POINTER, Primitive(CHAR)), start)

    # bitfield
    elif firstChar == 'b':
        (bitlen, newStart) = numericSubstring(encoding, start)
        return (Bitfield(bitlen), newStart)

    # array
    elif firstChar == '[':
        (length, newStart) = numericSubstring(encoding, start)
        (baseType, newNewStart) = parse(encoding, newStart, end, hasMemberName)
        assert encoding[newNewStart] == ']'
        return (Array(length, baseType), newNewStart + 1)

    # objective-C type, or blocks
    elif firstChar == '@':
        if start >= end or encoding[start] not in '?"':
            return (ObjCType(), start)
        elif encoding[start] == '?':
            return (Primitive(BLOCK), start + 1)
        else:
            # "foo"@"bar"@
            # "foo"@"NSObject""bar"@
            # "foo"@"bar"@"NSObject"
            m = _objcRe(encoding, start)
            if not m or (hasMemberName and m.end() < end
                         and encoding[m.end() - 1] not in '"]})'):
                return (ObjCType(), start)

            (name, protos) = m.groups()
            if protos:
                protos = protos.split(',')

            return (ObjCType(name, protos), m.end())

    # struct or union
    elif firstChar in '{(':
        isUnion = firstChar == '('
        newStart = start
        while encoding[newStart] not in '=)}':
            newStart = balancedSubstring(encoding, newStart)
        name = encoding[start:newStart]
        if encoding[newStart] == '=':
            newStart += 1
        stru = Struct(name, isUnion)
        while newStart <= end and encoding[newStart] not in ')}':
            hasMemberName = encoding[newStart] == '"'
            if hasMemberName:
                m = _struMemRe(encoding, newStart)
                memberName = m.group(1)
                newStart = m.end()
            else:
                memberName = None
            (baseType, newNewStart) = parse(encoding, newStart, end,
                                            hasMemberName)
            stru.append(baseType, memberName)
            newStart = newNewStart
        stru.freeze()
        return (stru, newStart + 1)
Exemplo n.º 4
0
def parse(encoding, start=0, end=None, hasMemberName=True):
    """
    Parse an encoded type string into an Objective-C type.
    
    If you supply *start* and *end*, only the substring ``encoding[start:end]``
    will be parsed.
    
    Returns a tuple of :class:`~objctype2.types.Type` and the next index to
    parse. If nothing can be parsed, the type will become ``None``.
    
    Example::
    
        from objctype2.parser import parse
        from balanced_substring import numericSubstring
        
        typeinfo = 'c24@0:4@8@12{_NSRange=II}16'
        index = 0
        while True:
            (type_, index) = parse(typeinfo, index)
            if type_ is None:
                break
            (stackIndex, index) = numericSubstring(typeinfo, index)
            print (type_, '@', stackIndex)

        # prints:            
        #    Primitive('c') @ 24
        #    ObjCType() @ 0
        #    Primitive(':') @ 4
        #    ObjCType() @ 8
        #    ObjCType() @ 12
        #    Struct('_NSRange').append(Primitive('I')).append(Primitive('I')).freeze() @ 16

    """

    if end is None:
        end = len(encoding)

    if start >= end:
        return (None, end)
    
    firstChar = encoding[start]
    start += 1
    
    # primitives
    if firstChar in _primitive1c:
        return (Primitive(firstChar), start)
        
    # unary, or function pointer (^ and ^?)
    elif firstChar in _modifier1c:
        if start >= end or encoding[start] in "]})":
            return (Primitive(FUNCTION_POINTER), start)
        elif encoding[start] == '?':
            return (Primitive(FUNCTION_POINTER), start+1)
        else:
            (baseType, newStart) = parse(encoding, start, end, hasMemberName)
            return (Unary(firstChar, baseType), newStart)
    
    # char pointer
    elif firstChar == '*':
        return (Unary(POINTER, Primitive(CHAR)), start)
    
    # bitfield
    elif firstChar == 'b':
        (bitlen, newStart) = numericSubstring(encoding, start)
        return (Bitfield(bitlen), newStart)
    
    # array
    elif firstChar == '[':
        (length, newStart) = numericSubstring(encoding, start)
        (baseType, newNewStart) = parse(encoding, newStart, end, hasMemberName)
        assert encoding[newNewStart] == ']'
        return (Array(length, baseType), newNewStart+1)

    # objective-C type, or blocks
    elif firstChar == '@':
        if start >= end or encoding[start] not in '?"':
            return (ObjCType(), start)
        elif encoding[start] == '?':
            return (Primitive(BLOCK), start+1)
        else:
            # "foo"@"bar"@
            # "foo"@"NSObject""bar"@
            # "foo"@"bar"@"NSObject"
            m = _objcRe(encoding, start)
            if not m or (hasMemberName and m.end() < end and encoding[m.end()] not in '"]})'):
                return (ObjCType(), start)
            
            (name, protos) = m.groups()
            if protos:
                protos = protos.split(',')
            
            return (ObjCType(name, protos), m.end())
    
    # struct or union
    elif firstChar in '{(':
        isUnion = firstChar == '('
        newStart = start
        while encoding[newStart] not in '=)}':
            newStart = balancedSubstring(encoding, newStart)
        name = encoding[start:newStart]
        if encoding[newStart] == '=':
            newStart += 1
        stru = Struct(name, isUnion)
        while newStart <= end and encoding[newStart] not in ')}':
            hasMemberName = encoding[newStart] == '"'
            if hasMemberName:
                m = _struMemRe(encoding, newStart)
                memberName = m.group(1)
                newStart = m.end()
            else:
                memberName = None
            (baseType, newNewStart) = parse(encoding, newStart, end, hasMemberName)
            stru.append(baseType, memberName)
            newStart = newNewStart
        stru.freeze()
        return (stru, newStart+1)