ObjFW  Diff

Differences From Artifact [23b893292f]:

To Artifact [aa9fa8f2dc]:


22
23
24
25
26
27
28
29

30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

55









56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89






90
91
92
93
94
95
96
22
23
24
25
26
27
28

29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92






93
94
95
96
97
98
99
100
101
102
103
104
105







-
+





-
+


















-
+

+
+
+
+
+
+
+
+
+
-
+


















-
+








-
-
-
-
-
-
+
+
+
+
+
+







#import "OFTarArchiveEntry+Private.h"
#import "OFStream.h"
#import "OFDate.h"

#import "OFOutOfRangeException.h"

static OFString *
stringFromBuffer(const char *buffer, size_t length)
stringFromBuffer(const unsigned char *buffer, size_t length)
{
	for (size_t i = 0; i < length; i++)
		if (buffer[i] == '\0')
			length = i;

	return [OFString stringWithUTF8String: buffer
	return [OFString stringWithUTF8String: (const char *)buffer
				       length: length];
}

static void
stringToBuffer(unsigned char *buffer, OFString *string, size_t length)
{
	size_t UTF8StringLength = [string UTF8StringLength];

	if (UTF8StringLength > length)
		@throw [OFOutOfRangeException exception];

	memcpy(buffer, [string UTF8String], UTF8StringLength);

	for (size_t i = UTF8StringLength; i < length; i++)
		buffer[i] = '\0';
}

static uintmax_t
octalValueFromBuffer(const char *buffer, size_t length, uintmax_t max)
octalValueFromBuffer(const unsigned char *buffer, size_t length, uintmax_t max)
{
	uintmax_t value;

	if (length == 0)
		return 0;

	if (buffer[0] == 0x80) {
		for (size_t i = 1; i < length; i++)
			value = (value << 8) | buffer[i];
	} else
	uintmax_t value = [stringFromBuffer(buffer, length) octalValue];
		value = [stringFromBuffer(buffer, length) octalValue];

	if (value > max)
		@throw [OFOutOfRangeException exception];

	return value;
}

@implementation OFTarArchiveEntry
+ (instancetype)entryWithFileName: (OFString *)fileName
{
	return [[[self alloc] initWithFileName: fileName] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)of_initWithHeader: (char [512])header
- (instancetype)of_initWithHeader: (unsigned char [512])header
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFString *targetFileName;

		_fileName = [stringFromBuffer(header, 100) copy];
		_mode = (uint16_t)octalValueFromBuffer(
		    header + 100, 8, UINT16_MAX);
		_UID = (uint16_t)octalValueFromBuffer(
		    header + 108, 8, UINT16_MAX);
		_GID = (uint16_t)octalValueFromBuffer(
		    header + 116, 8, UINT16_MAX);
		_mode = (uint32_t)octalValueFromBuffer(
		    header + 100, 8, UINT32_MAX);
		_UID = (uint32_t)octalValueFromBuffer(
		    header + 108, 8, UINT32_MAX);
		_GID = (uint32_t)octalValueFromBuffer(
		    header + 116, 8, UINT32_MAX);
		_size = (uint64_t)octalValueFromBuffer(
		    header + 124, 12, UINT64_MAX);
		_modificationDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970:
		    (of_time_interval_t)octalValueFromBuffer(
		    header + 136, 12, UINTMAX_MAX)];
		_type = header[156];
188
189
190
191
192
193
194
195

196
197
198
199
200

201
202
203
204
205

206
207
208
209
210
211
212
197
198
199
200
201
202
203

204
205
206
207
208

209
210
211
212
213

214
215
216
217
218
219
220
221







-
+




-
+




-
+







}

- (OFString *)fileName
{
	return _fileName;
}

- (uint16_t)mode
- (uint32_t)mode
{
	return _mode;
}

- (uint16_t)UID
- (uint32_t)UID
{
	return _UID;
}

- (uint16_t)GID
- (uint32_t)GID
{
	return _GID;
}

- (uint64_t)size
{
	return _size;