2 * Copyright 2011-2013, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Oliver Tappe <zooey@hirschkaefer.de>
7 * Ingo Weinhold <ingo_weinhold@gmx.de>
13 #include <AutoDeleter.h>
16 #include <package/ChecksumAccessors.h>
19 namespace BPackageKit
{
24 #define NIBBLE_AS_HEX(nibble) \
25 (nibble >= 10 ? 'a' + nibble - 10 : '0' + nibble)
28 // #pragma mark - ChecksumAccessor
31 ChecksumAccessor::~ChecksumAccessor()
36 // #pragma mark - ChecksumFileChecksumAccessor
39 ChecksumFileChecksumAccessor::ChecksumFileChecksumAccessor(
40 const BEntry
& checksumFileEntry
)
42 fChecksumFileEntry(checksumFileEntry
)
48 ChecksumFileChecksumAccessor::GetChecksum(BString
& checksum
) const
50 BFile
checksumFile(&fChecksumFileEntry
, B_READ_ONLY
);
51 status_t result
= checksumFile
.InitCheck();
55 const int kSHA256ChecksumHexDumpSize
= 64;
56 char* buffer
= checksum
.LockBuffer(kSHA256ChecksumHexDumpSize
);
60 ssize_t bytesRead
= checksumFile
.Read(buffer
, kSHA256ChecksumHexDumpSize
);
61 buffer
[kSHA256ChecksumHexDumpSize
] = '\0';
62 checksum
.UnlockBuffer(kSHA256ChecksumHexDumpSize
);
65 if (bytesRead
!= kSHA256ChecksumHexDumpSize
)
72 // #pragma mark - GeneralFileChecksumAccessor
75 GeneralFileChecksumAccessor::GeneralFileChecksumAccessor(
76 const BEntry
& fileEntry
, bool skipMissingFile
)
78 fFileEntry(fileEntry
),
79 fSkipMissingFile(skipMissingFile
)
85 GeneralFileChecksumAccessor::GetChecksum(BString
& checksum
) const
92 BFile
file(&fFileEntry
, B_READ_ONLY
);
93 status_t result
= file
.InitCheck();
95 if (result
== B_ENTRY_NOT_FOUND
&& fSkipMissingFile
)
101 if ((result
= file
.GetSize(&fileSize
)) != B_OK
)
104 const int kBlockSize
= 64 * 1024;
105 void* buffer
= malloc(kBlockSize
);
108 MemoryDeleter
memoryDeleter(buffer
);
110 off_t handledSize
= 0;
111 while (handledSize
< fileSize
) {
112 ssize_t bytesRead
= file
.Read(buffer
, kBlockSize
);
116 sha
.Update(buffer
, bytesRead
);
118 handledSize
+= bytesRead
;
122 const int kSHA256ChecksumSize
= sha
.DigestLength();
123 char* buffer
= checksum
.LockBuffer(2 * kSHA256ChecksumSize
);
126 const uint8
* digest
= sha
.Digest();
127 for (int i
= 0; i
< kSHA256ChecksumSize
; ++i
) {
128 uint8 highNibble
= (digest
[i
] & 0xF0) >> 4;
129 buffer
[i
* 2] = NIBBLE_AS_HEX(highNibble
);
130 uint8 lowNibble
= digest
[i
] & 0x0F;
131 buffer
[1 + i
* 2] = NIBBLE_AS_HEX(lowNibble
);
133 buffer
[2 * kSHA256ChecksumSize
] = '\0';
134 checksum
.UnlockBuffer(2 * kSHA256ChecksumSize
);
140 // #pragma mark - StringChecksumAccessor
143 StringChecksumAccessor::StringChecksumAccessor(const BString
& checksum
)
151 StringChecksumAccessor::GetChecksum(BString
& _checksum
) const
153 _checksum
= fChecksum
;
159 } // namespace BPrivate
161 } // namespace BPackageKit