SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
HexFiend/HFByteArray.m
1 //
2 // HFByteArray.m
3 // HexFiend_2
4 //
5 // Copyright 2007 ridiculous_fish. All rights reserved.
6 //
7
8 #import <HexFiend/HFByteArray_Internal.h>
9 #import <HexFiend/HFFullMemoryByteSlice.h>
10
11
12 @implementation HFByteArray
13
14 - (instancetype)init {
15 if ([self class] == [HFByteArray class]) {
16 [NSException raise:NSInvalidArgumentException format:@"init sent to HFByteArray, but HFByteArray is an abstract class. Instantiate one of its subclasses instead, like HFBTreeByteArray."];
17 }
18 return [super init];
19 }
20
21 - (instancetype)initWithByteSlice:(HFByteSlice *)slice {
22 if(!(self = [self init])) return nil;
23 self = [self init];
24 [self insertByteSlice:slice inRange:HFRangeMake(0, 0)];
25 return self;
26 }
27
28 - (instancetype)initWithByteArray:(HFByteArray *)array {
29 if(!(self = [self init])) return nil;
30 NSEnumerator *e = [array byteSliceEnumerator];
31 HFByteSlice *slice;
32 while((slice = [e nextObject])) {
33 [self insertByteSlice:slice inRange:HFRangeMake([self length], 0)];
34 }
35 return self;
36 }
37
38 - (NSArray *)byteSlices { UNIMPLEMENTED(); }
39 - (unsigned long long)length { UNIMPLEMENTED(); }
40 - (void)copyBytes:(unsigned char *)dst range:(HFRange)range { USE(dst); USE(range); UNIMPLEMENTED_VOID(); }
41 - (void)insertByteSlice:(HFByteSlice *)slice inRange:(HFRange)lrange { USE(slice); USE(lrange); UNIMPLEMENTED_VOID(); }
42
43 - (NSEnumerator *)byteSliceEnumerator {
44 return [[self byteSlices] objectEnumerator];
45 }
46
47 - (HFByteSlice *)sliceContainingByteAtIndex:(unsigned long long)offset beginningOffset:(unsigned long long *)actualOffset {
48 HFByteSlice *slice;
49 unsigned long long current = 0;
50 NSEnumerator *enumer = [self byteSliceEnumerator];
51 while ((slice = [enumer nextObject])) {
52 unsigned long long sum = HFSum([slice length], current);
53 if (sum > offset) break;
54 current = sum;
55 }
56 if (actualOffset) *actualOffset = current;
57 return slice;
58 }
59
60 - (void)insertByteArray:(HFByteArray*)array inRange:(HFRange)lrange {
61 REQUIRE_NOT_NULL(array);
62 HFASSERT(HFRangeIsSubrangeOfRange(lrange, HFRangeMake(0, [self length])));
63 #ifndef NDEBUG
64 unsigned long long expectedLength = [self length] - lrange.length + [array length];
65 #endif
66 [self incrementGenerationOrRaiseIfLockedForSelector:_cmd];
67 NSEnumerator *sliceEnumerator;
68 HFByteSlice *byteSlice;
69 if (array == self) {
70 /* Guard against self insertion */
71 sliceEnumerator = [[array byteSlices] objectEnumerator];
72 }
73 else {
74 sliceEnumerator = [array byteSliceEnumerator];
75 }
76 while ((byteSlice = [sliceEnumerator nextObject])) {
77 [self insertByteSlice:byteSlice inRange:lrange];
78 lrange.location += [byteSlice length];
79 lrange.length = 0;
80 }
81 /* If there were no slices, delete the lrange */
82 if (lrange.length > 0) {
83 [self deleteBytesInRange:lrange];
84 }
85 #ifndef NDEBUG
86 HFASSERT(expectedLength == [self length]);
87 #endif
88 }
89
90 - (HFByteArray *)subarrayWithRange:(HFRange)range { USE(range); UNIMPLEMENTED(); }
91
92 - (id)mutableCopyWithZone:(NSZone *)zone {
93 USE(zone);
94 return [[self subarrayWithRange:HFRangeMake(0, [self length])] retain];
95 }
96
97 - (id)copyWithZone:(NSZone *)zone {
98 USE(zone);
99 return [[self subarrayWithRange:HFRangeMake(0, [self length])] retain];
100 }
101
102 - (void)deleteBytesInRange:(HFRange)lrange {
103 [self incrementGenerationOrRaiseIfLockedForSelector:_cmd];
104 HFByteSlice* slice = [[HFFullMemoryByteSlice alloc] initWithData:[NSData data]];
105 [self insertByteSlice:slice inRange:lrange];
106 [slice release];
107 }
108
109 - (BOOL)isEqual:v {
110 REQUIRE_NOT_NULL(v);
111 if (self == v) return YES;
112 else if (! [v isKindOfClass:[HFByteArray class]]) return NO;
113 else {
114 HFByteArray* obj = v;
115 unsigned long long length = [self length];
116 if (length != [obj length]) return NO;
117 unsigned long long offset;
118 unsigned char buffer1[1024];
119 unsigned char buffer2[sizeof buffer1 / sizeof *buffer1];
120 for (offset = 0; offset < length; offset += sizeof buffer1) {
121 size_t amountToGrab = sizeof buffer1;
122 if (amountToGrab > length - offset) amountToGrab = ll2l(length - offset);
123 [self copyBytes:buffer1 range:HFRangeMake(offset, amountToGrab)];
124 [obj copyBytes:buffer2 range:HFRangeMake(offset, amountToGrab)];
125 if (memcmp(buffer1, buffer2, amountToGrab)) return NO;
126 }
127 }
128 return YES;
129 }
130
131 - (unsigned long long)indexOfBytesEqualToBytes:(HFByteArray *)findBytes inRange:(HFRange)range searchingForwards:(BOOL)forwards trackingProgress:(id)progressTracker {
132 UNIMPLEMENTED();
133 }
134
135 - (BOOL)_debugIsEqual:(HFByteArray *)v {
136 REQUIRE_NOT_NULL(v);
137 if (! [v isKindOfClass:[HFByteArray class]]) return NO;
138 HFByteArray* obj = v;
139 unsigned long long length = [self length];
140 if (length != [obj length]) {
141 printf("Lengths differ: %llu versus %llu\n", length, [obj length]);
142 abort();
143 return NO;
144 }
145
146 unsigned long long offset;
147 unsigned char buffer1[1024];
148 unsigned char buffer2[sizeof buffer1 / sizeof *buffer1];
149 for (offset = 0; offset < length; offset += sizeof buffer1) {
150 memset(buffer1, 0, sizeof buffer1);
151 memset(buffer2, 0, sizeof buffer2);
152 size_t amountToGrab = sizeof buffer1;
153 if (amountToGrab > length - offset) amountToGrab = ll2l(length - offset);
154 [self copyBytes:buffer1 range:HFRangeMake(offset, amountToGrab)];
155 [obj copyBytes:buffer2 range:HFRangeMake(offset, amountToGrab)];
156 size_t i;
157 for (i=0; i < amountToGrab; i++) {
158 if (buffer1[i] != buffer2[i]) {
159 printf("Inconsistency found at %llu (%02x versus %02x)\n", i + offset, buffer1[i], buffer2[i]);
160 abort();
161 return NO;
162 }
163 }
164 }
165 return YES;
166 }
167
168 - (NSData *)_debugData {
169 NSMutableData *data = [NSMutableData dataWithLength:(NSUInteger)[self length]];
170 [self copyBytes:[data mutableBytes] range:HFRangeMake(0, [self length])];
171 return data;
172 }
173
174 - (BOOL)_debugIsEqualToData:(NSData *)val {
175 REQUIRE_NOT_NULL(val);
176 HFByteArray *byteArray = [[NSClassFromString(@"HFFullMemoryByteArray") alloc] init];
177 HFByteSlice *byteSlice = [[HFFullMemoryByteSlice alloc] initWithData:val];
178 [byteArray insertByteSlice:byteSlice inRange:HFRangeMake(0, 0)];
179 [byteSlice release];
180 BOOL result = [self _debugIsEqual:byteArray];
181 [byteArray release];
182 return result;
183 }
184
185 - (void)incrementChangeLockCounter {
186 [self willChangeValueForKey:@"changesAreLocked"];
187 if (HFAtomicIncrement(&changeLockCounter, NO) == 0) {
188 [NSException raise:NSInvalidArgumentException format:@"change lock counter overflow for %@", self];
189 }
190 [self didChangeValueForKey:@"changesAreLocked"];
191 }
192
193 - (void)decrementChangeLockCounter {
194 [self willChangeValueForKey:@"changesAreLocked"];
195 if (HFAtomicDecrement(&changeLockCounter, NO) == NSUIntegerMax) {
196 [NSException raise:NSInvalidArgumentException format:@"change lock counter underflow for %@", self];
197 }
198 [self didChangeValueForKey:@"changesAreLocked"];
199 }
200
201 - (BOOL)changesAreLocked {
202 return !! changeLockCounter;
203 }
204
205 - (NSUInteger)changeGenerationCount {
206 return changeGenerationCount;
207 }
208
209 - (void)incrementGenerationOrRaiseIfLockedForSelector:(SEL)sel {
210 if (changeLockCounter) {
211 [NSException raise:NSInvalidArgumentException format:@"Selector %@ sent to a locked byte array %@", NSStringFromSelector(sel), self];
212 }
213 else {
214 HFAtomicIncrement(&changeGenerationCount, YES);
215 }
216 }
217
218 @end
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.