1// 2// HFASCIITextRepresenter.m 3// HexFiend_2 4// 5// Copyright 2007 ridiculous_fish. All rights reserved. 6// 7 8#import <HexFiend/HFStringEncodingTextRepresenter.h> 9#import <HexFiend/HFRepresenterStringEncodingTextView.h> 10#import <HexFiend/HFPasteboardOwner.h> 11 12@interface HFStringEncodingPasteboardOwner : HFPasteboardOwner { 13 NSStringEncoding encoding; 14} 15@property (nonatomic) NSStringEncoding encoding; 16@end 17 18@implementation HFStringEncodingPasteboardOwner 19- (void)setEncoding:(NSStringEncoding)val { encoding = val; } 20- (NSStringEncoding)encoding { return encoding; } 21 22- (void)writeDataInBackgroundToPasteboard:(NSPasteboard *)pboard ofLength:(unsigned long long)length forType:(NSString *)type trackingProgress:(id)tracker { 23 HFASSERT([type isEqual:NSStringPboardType]); 24 HFByteArray *byteArray = [self byteArray]; 25 HFASSERT(length <= NSUIntegerMax); 26 NSUInteger dataLength = ll2l(length); 27 NSUInteger stringLength = dataLength; 28 NSUInteger offset = 0, remaining = dataLength; 29 unsigned char * restrict const stringBuffer = check_malloc(stringLength); 30 while (remaining > 0) { 31 NSUInteger amountToCopy = MIN(32u * 1024u, remaining); 32 [byteArray copyBytes:stringBuffer + offset range:HFRangeMake(offset, amountToCopy)]; 33 offset += amountToCopy; 34 remaining -= amountToCopy; 35 } 36 NSString *string = [[NSString alloc] initWithBytesNoCopy:stringBuffer length:stringLength encoding:encoding freeWhenDone:YES]; 37 [pboard setString:string forType:type]; 38 [string release]; 39} 40 41- (unsigned long long)stringLengthForDataLength:(unsigned long long)dataLength { 42 return dataLength; 43} 44 45@end 46 47@implementation HFStringEncodingTextRepresenter 48 49- (instancetype)init { 50 self = [super init]; 51 stringEncoding = [NSString defaultCStringEncoding]; 52 return self; 53} 54 55- (instancetype)initWithCoder:(NSCoder *)coder { 56 HFASSERT([coder allowsKeyedCoding]); 57 self = [super initWithCoder:coder]; 58 stringEncoding = (NSStringEncoding)[coder decodeInt64ForKey:@"HFStringEncoding"]; 59 return self; 60} 61 62- (void)encodeWithCoder:(NSCoder *)coder { 63 HFASSERT([coder allowsKeyedCoding]); 64 [super encodeWithCoder:coder]; 65 [coder encodeInt64:stringEncoding forKey:@"HFStringEncoding"]; 66} 67 68- (Class)_textViewClass { 69 return [HFRepresenterStringEncodingTextView class]; 70} 71 72- (NSStringEncoding)encoding { 73 return stringEncoding; 74} 75 76- (void)setEncoding:(NSStringEncoding)encoding { 77 stringEncoding = encoding; 78 [[self view] setEncoding:encoding]; 79 [[self controller] representer:self changedProperties:HFControllerViewSizeRatios]; 80} 81 82- (void)initializeView { 83 [[self view] setEncoding:stringEncoding]; 84 [super initializeView]; 85} 86 87- (void)insertText:(NSString *)text { 88 REQUIRE_NOT_NULL(text); 89 NSData *data = [text dataUsingEncoding:[self encoding] allowLossyConversion:NO]; 90 if (! data) { 91 NSBeep(); 92 } 93 else if ([data length]) { // a 0 length text can come about via e.g. option-e 94 [[self controller] insertData:data replacingPreviousBytes:0 allowUndoCoalescing:YES]; 95 } 96} 97 98- (NSData *)dataFromPasteboardString:(NSString *)string { 99 REQUIRE_NOT_NULL(string); 100 return [string dataUsingEncoding:[self encoding] allowLossyConversion:NO]; 101} 102 103+ (NSPoint)defaultLayoutPosition { 104 return NSMakePoint(1, 0); 105} 106 107- (void)copySelectedBytesToPasteboard:(NSPasteboard *)pb { 108 REQUIRE_NOT_NULL(pb); 109 HFByteArray *selection = [[self controller] byteArrayForSelectedContentsRanges]; 110 HFASSERT(selection != NULL); 111 if ([selection length] == 0) { 112 NSBeep(); 113 } 114 else { 115 HFStringEncodingPasteboardOwner *owner = [HFStringEncodingPasteboardOwner ownPasteboard:pb forByteArray:selection withTypes:@[HFPrivateByteArrayPboardType, NSStringPboardType]]; 116 [owner setEncoding:[self encoding]]; 117 [owner setBytesPerLine:[self bytesPerLine]]; 118 } 119} 120 121@end 122