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