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
106
107
108
|
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
106
107
108
|
-
+
-
+
|
@end
OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileReadStream: OFStream
{
OFStream *_stream, *_decompressedStream;
OFZIPArchiveEntry *_entry;
uint64_t _toRead;
unsigned long long _toRead;
uint32_t _CRC32;
bool _atEndOfStream;
}
- (instancetype)of_initWithStream: (OFStream *)stream
entry: (OFZIPArchiveEntry *)entry;
@end
OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileWriteStream: OFStream
{
OFStream *_stream;
uint32_t _CRC32;
@public
int64_t _bytesWritten;
unsigned long long _bytesWritten;
OFMutableZIPArchiveEntry *_entry;
}
- (instancetype)initWithStream: (OFStream *)stream
entry: (OFMutableZIPArchiveEntry *)entry;
@end
|
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
|
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
|
-
+
|
if ((_mode == modeWrite || _mode == modeAppend) &&
[_lastReturnedStream isKindOfClass:
[OFZIPArchiveFileWriteStream class]]) {
OFZIPArchiveFileWriteStream *stream =
(OFZIPArchiveFileWriteStream *)_lastReturnedStream;
if (INT64_MAX - _offset < stream->_bytesWritten)
if (ULLONG_MAX - _offset < stream->_bytesWritten)
@throw [OFOutOfRangeException exception];
_offset += stream->_bytesWritten;
if (stream->_entry != nil) {
[_entries addObject: stream->_entry];
[_pathToEntryMap setObject: stream->_entry
|
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
|
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
|
-
+
|
@throw [OFTruncatedDataException exception];
#if SIZE_MAX >= UINT64_MAX
if (length > UINT64_MAX)
@throw [OFOutOfRangeException exception];
#endif
if ((uint64_t)length > _toRead)
if (length > _toRead)
length = (size_t)_toRead;
ret = [_decompressedStream readIntoBuffer: buffer length: length];
_toRead -= ret;
_CRC32 = OFCRC32(_CRC32, buffer, ret);
|
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
|
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
|
-
+
-
+
-
+
+
+
+
-
-
+
+
|
- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
#if SIZE_MAX >= INT64_MAX
if (length > INT64_MAX)
@throw [OFOutOfRangeException exception];
#endif
if (INT64_MAX - _bytesWritten < (int64_t)length)
if (ULLONG_MAX - _bytesWritten < length)
@throw [OFOutOfRangeException exception];
@try {
[_stream writeBuffer: buffer length: length];
} @catch (OFWriteFailedException *e) {
OFEnsure(e.bytesWritten <= length);
_bytesWritten += (int64_t)e.bytesWritten;
_bytesWritten += e.bytesWritten;
_CRC32 = OFCRC32(_CRC32, buffer, e.bytesWritten);
if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN)
return e.bytesWritten;
@throw e;
}
_bytesWritten += (int64_t)length;
_bytesWritten += length;
_CRC32 = OFCRC32(_CRC32, buffer, length);
return length;
}
- (void)close
{
if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_bytesWritten > UINT64_MAX)
@throw [OFOutOfRangeException exception];
[_stream writeLittleEndianInt32: 0x08074B50];
[_stream writeLittleEndianInt32: _CRC32];
[_stream writeLittleEndianInt64: _bytesWritten];
[_stream writeLittleEndianInt64: _bytesWritten];
[_stream writeLittleEndianInt64: (uint64_t)_bytesWritten];
[_stream writeLittleEndianInt64: (uint64_t)_bytesWritten];
[_stream release];
_stream = nil;
_entry.CRC32 = ~_CRC32;
_entry.compressedSize = _bytesWritten;
_entry.uncompressedSize = _bytesWritten;
|