XRootD
Loading...
Searching...
No Matches
XrdClHttpChecksum.hh
Go to the documentation of this file.
1/******************************************************************************/
2/* Copyright (C) 2025, Pelican Project, Morgridge Institute for Research */
3/* */
4/* This file is part of the XrdClHttp client plugin for XRootD. */
5/* */
6/* XRootD is free software: you can redistribute it and/or modify it under */
7/* the terms of the GNU Lesser General Public License as published by the */
8/* Free Software Foundation, either version 3 of the License, or (at your */
9/* option) any later version. */
10/* */
11/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
12/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
13/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
14/* License for more details. */
15/* */
16/* The copyright holder's institutional names and contributor's names may not */
17/* be used to endorse or promote products derived from this software without */
18/* specific prior written permission of the institution or contributor. */
19/******************************************************************************/
20
21#ifndef XRDCLHTTPCHECKSUM_HH_
22#define XRDCLHTTPCHECKSUM_HH_
23
24#include <array>
25#include <string>
26#include <tuple>
27
28namespace XrdClHttp {
29
30constexpr size_t g_max_checksum_length = 32;
31
32// Checksum types known to this cache
33enum class ChecksumType {
38 kAll, // Short-hand for setting all checksums at once.
39 kUnknown, // Indicates an unset value; `kUnknown - 1` is used in for-loops to iterate through all checksums.
40};
41
42inline const std::string GetTypeString(ChecksumType ctype) {
43 switch (ctype) {
45 return "crc32c";
47 return "md5";
49 return "sha1";
51 return "sha256";
52 case ChecksumType::kAll: // fallthrough
54 return "unknown";
55 }
56 return "unknown";
57}
58
59inline size_t GetChecksumLength(ChecksumType ctype) {
60 switch (ctype) {
62 return 4;
64 return 16;
66 return 20;
68 return 32;
69 case ChecksumType::kAll: // fallthrough
71 return 0;
72 }
73 return 0;
74}
75
76inline ChecksumType GetTypeFromString(const std::string &str) {
77 if (str == "crc32c") {
79 } else if (str == "md5") {
80 return ChecksumType::kMD5;
81 } else if (str == "sha1") {
83 } else if (str == "sha256") {
85 }
87}
88
89// A single checksum type / value pair
90// Value is stored as raw bytes in memory.
93 std::array<unsigned char, g_max_checksum_length> value;
94};
95
96// All known checksums for a given object
97//
98// If the checksum is not available, then checksums[ctype].type == kUnknown.
99// Otherwise, checksums[type].value contains the checksum and checksums[ctype].type
100// is set to ctype for a given ctype in the ChecksumType enum.
102public:
103
104 // Check to see if a checksum's value is set
105 //
106 // Always returns false if kAll or kUnknown are requested.
107 bool IsSet(ChecksumType ctype) const {
108 if ((ctype == ChecksumType::kUnknown) || (ctype == ChecksumType::kAll)) return false;
109 return checksums[static_cast<size_t>(ctype)].type != ChecksumType::kUnknown;
110 }
111
112 // Get the checksum value for a given checksum type
113 //
114 // If an invalid value is requested (kAll, kUnknown), then the return value is
115 // undefined (as opposed to throwing an exception).
116 //
117 // If the checksum value is not set (IsSet returns false), then the return value
118 // is undefined.
119 const std::array<unsigned char, g_max_checksum_length> &Get(ChecksumType ctype) const {
120 if ((ctype == ChecksumType::kUnknown) || (ctype == ChecksumType::kAll))
121 ctype = ChecksumType::kCRC32C;
122 return checksums[static_cast<size_t>(ctype)].value;
123 }
124
125 // Set the value of the checksum for a known type.
126 //
127 // Returns true if the checksum type is valid, false otherwise (kAll, kUnknown).
128 bool Set(ChecksumType ctype, const std::array<unsigned char, g_max_checksum_length> &value) {
129 if ((ctype == ChecksumType::kUnknown) || (ctype == ChecksumType::kAll)) return false;
130 checksums[static_cast<size_t>(ctype)] = ChecksumEntry{ctype, value};
131 return true;
132 }
133
134 // Returns a tuple of the type and value of the first set checksum in the object.
135 //
136 // If no value is set, then the returned type will be kUnknown.
137 std::tuple<ChecksumType, std::array<unsigned char, g_max_checksum_length>, bool> GetFirst() const {
138 for (int idx=0; idx < static_cast<int>(ChecksumType::kAll); ++idx) {
139 if (checksums[idx].type != ChecksumType::kUnknown) {
140 return std::make_tuple(static_cast<ChecksumType>(idx), checksums[idx].value, true);
141 }
142 }
143 return std::make_tuple(ChecksumType::kUnknown, std::array<unsigned char, g_max_checksum_length>(), false);
144 }
145
146private:
147 std::array<ChecksumEntry, static_cast<int>(ChecksumType::kAll)> checksums;
148};
149
150}
151
152#endif // XRDCLHTTPCHECKSUM_HH_
const std::array< unsigned char, g_max_checksum_length > & Get(ChecksumType ctype) const
bool IsSet(ChecksumType ctype) const
bool Set(ChecksumType ctype, const std::array< unsigned char, g_max_checksum_length > &value)
std::tuple< ChecksumType, std::array< unsigned char, g_max_checksum_length >, bool > GetFirst() const
size_t GetChecksumLength(ChecksumType ctype)
constexpr size_t g_max_checksum_length
ChecksumType GetTypeFromString(const std::string &str)
std::array< unsigned char, g_max_checksum_length > value
const std::string GetTypeString(ChecksumType ctype)