mirror of
				https://github.com/SoPat712/YTLitePlus.git
				synced 2025-10-31 04:44:14 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			158 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
| //
 | |
| //  FLEXBlockDescription.m
 | |
| //  FLEX
 | |
| //
 | |
| //  Created by Oliver Letterer on 2012-09-01
 | |
| //  Forked from CTObjectiveCRuntimeAdditions (MIT License)
 | |
| //  https://github.com/ebf/CTObjectiveCRuntimeAdditions
 | |
| //
 | |
| //  Copyright (c) 2020 FLEX Team-EDV Beratung Föllmer GmbH
 | |
| //  Permission is hereby granted, free of charge, to any person obtaining a copy of this
 | |
| //  software and associated documentation files (the "Software"), to deal in the Software
 | |
| //  without restriction, including without limitation the rights to use, copy, modify, merge,
 | |
| //  publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 | |
| //  to whom the Software is furnished to do so, subject to the following conditions:
 | |
| //  The above copyright notice and this permission notice shall be included in all copies or
 | |
| //  substantial portions of the Software.
 | |
| //
 | |
| //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 | |
| //  BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | |
| //  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 | |
| //  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| 
 | |
| #import "FLEXBlockDescription.h"
 | |
| #import "FLEXRuntimeUtility.h"
 | |
| 
 | |
| struct block_object {
 | |
|     void *isa;
 | |
|     int flags;
 | |
|     int reserved;
 | |
|     void (*invoke)(void *, ...);
 | |
|     struct block_descriptor {
 | |
|         unsigned long int reserved;    // NULL
 | |
|         unsigned long int size;     // sizeof(struct Block_literal_1)
 | |
|         // optional helper functions
 | |
|         void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
 | |
|         void (*dispose_helper)(void *src);             // IFF (1<<25)
 | |
|         // required ABI.2010.3.16
 | |
|         const char *signature;                         // IFF (1<<30)
 | |
|     } *descriptor;
 | |
|     // imported variables
 | |
| };
 | |
| 
 | |
| @implementation FLEXBlockDescription
 | |
| 
 | |
| + (instancetype)describing:(id)block {
 | |
|     return [[self alloc] initWithObjcBlock:block];
 | |
| }
 | |
| 
 | |
| - (id)initWithObjcBlock:(id)block {
 | |
|     self = [super init];
 | |
|     if (self) {
 | |
|         _block = block;
 | |
|         
 | |
|         struct block_object *blockRef = (__bridge struct block_object *)block;
 | |
|         _flags = blockRef->flags;
 | |
|         _size = blockRef->descriptor->size;
 | |
|         
 | |
|         if (_flags & FLEXBlockOptionHasSignature) {
 | |
|             void *signatureLocation = blockRef->descriptor;
 | |
|             signatureLocation += sizeof(unsigned long int);
 | |
|             signatureLocation += sizeof(unsigned long int);
 | |
|             
 | |
|             if (_flags & FLEXBlockOptionHasCopyDispose) {
 | |
|                 signatureLocation += sizeof(void(*)(void *dst, void *src));
 | |
|                 signatureLocation += sizeof(void (*)(void *src));
 | |
|             }
 | |
|             
 | |
|             const char *signature = (*(const char **)signatureLocation);
 | |
|             _signatureString = @(signature);
 | |
|             
 | |
|             @try {
 | |
|                 _signature = [NSMethodSignature signatureWithObjCTypes:signature];
 | |
|             } @catch (NSException *exception) { }
 | |
|         }
 | |
|         
 | |
|         NSMutableString *summary = [NSMutableString stringWithFormat:
 | |
|             @"Type signature: %@\nSize: %@\nIs global: %@\nHas constructor: %@\nIs stret: %@",
 | |
|             self.signatureString ?: @"nil", @(self.size),
 | |
|             @((BOOL)(_flags & FLEXBlockOptionIsGlobal)),
 | |
|             @((BOOL)(_flags & FLEXBlockOptionHasCtor)),
 | |
|             @((BOOL)(_flags & FLEXBlockOptionHasStret))
 | |
|         ];
 | |
|         
 | |
|         if (!self.signature) {
 | |
|             [summary appendFormat:@"\nNumber of arguments: %@", @(self.signature.numberOfArguments)];
 | |
|         }
 | |
|         
 | |
|         _summary = summary.copy;
 | |
|         _sourceDeclaration = [self buildLikelyDeclaration];
 | |
|     }
 | |
|     
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| - (BOOL)isCompatibleForBlockSwizzlingWithMethodSignature:(NSMethodSignature *)methodSignature {
 | |
|     if (!self.signature) {
 | |
|         return NO;
 | |
|     }
 | |
|     
 | |
|     if (self.signature.numberOfArguments != methodSignature.numberOfArguments + 1) {
 | |
|         return NO;
 | |
|     }
 | |
|     
 | |
|     if (strcmp(self.signature.methodReturnType, methodSignature.methodReturnType) != 0) {
 | |
|         return NO;
 | |
|     }
 | |
|     
 | |
|     for (int i = 0; i < methodSignature.numberOfArguments; i++) {
 | |
|         if (i == 1) {
 | |
|             // SEL in method, IMP in block
 | |
|             if (strcmp([methodSignature getArgumentTypeAtIndex:i], ":") != 0) {
 | |
|                 return NO;
 | |
|             }
 | |
|             
 | |
|             if (strcmp([self.signature getArgumentTypeAtIndex:i + 1], "^?") != 0) {
 | |
|                 return NO;
 | |
|             }
 | |
|         } else {
 | |
|             if (strcmp([self.signature getArgumentTypeAtIndex:i], [self.signature getArgumentTypeAtIndex:i + 1]) != 0) {
 | |
|                 return NO;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     return YES;
 | |
| }
 | |
| 
 | |
| - (NSString *)buildLikelyDeclaration {
 | |
|     NSMethodSignature *signature = self.signature;
 | |
|     NSUInteger numberOfArguments = signature.numberOfArguments;
 | |
|     const char *returnType       = signature.methodReturnType;
 | |
|     
 | |
|     // Return type
 | |
|     NSMutableString *decl = [NSMutableString stringWithString:@"^"];
 | |
|     if (returnType[0] != FLEXTypeEncodingVoid) {
 | |
|         [decl appendString:[FLEXRuntimeUtility readableTypeForEncoding:@(returnType)]];
 | |
|         [decl appendString:@" "];
 | |
|     }
 | |
|     
 | |
|     // Arguments
 | |
|     if (numberOfArguments) {
 | |
|         [decl appendString:@"("];
 | |
|         for (NSUInteger i = 1; i < numberOfArguments; i++) {
 | |
|             const char *argType = [self.signature getArgumentTypeAtIndex:i] ?: "?";
 | |
|             NSString *readableArgType = [FLEXRuntimeUtility readableTypeForEncoding:@(argType)];
 | |
|             [decl appendFormat:@"%@ arg%@, ", readableArgType, @(i)];
 | |
|         }
 | |
|         
 | |
|         [decl deleteCharactersInRange:NSMakeRange(decl.length-2, 2)];
 | |
|         [decl appendString:@")"];
 | |
|     }
 | |
|     
 | |
|     return decl.copy;
 | |
| }
 | |
| 
 | |
| @end
 | 
