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 {
40 kAll, // Select any supported checksum.
41 kUnknown, // Indicates an unset value; `kUnknown - 1` is used in for-loops to iterate through all checksums.
42};
43
44inline const std::string GetTypeString(ChecksumType ctype) {
45 switch (ctype) {
47 return "adler32";
49 return "crc32";
51 return "crc32c";
53 return "md5";
55 return "sha1";
57 return "sha256";
58 case ChecksumType::kAll: // fallthrough
60 return "unknown";
61 }
62 return "unknown";
63}
64
65inline size_t GetChecksumLength(ChecksumType ctype) {
66 switch (ctype) {
70 return 4;
72 return 16;
74 return 20;
76 return 32;
77 case ChecksumType::kAll: // fallthrough
79 return 0;
80 }
81 return 0;
82}
83
84inline ChecksumType GetTypeFromString(const std::string &str) {
85 if (str == "adler" || str == "adler32") {
87 } else if (str == "crc32") {
89 } else if (str == "crc32c") {
91 } else if (str == "md5") {
92 return ChecksumType::kMD5;
93 } else if (str == "sha1") {
95 } else if (str == "sha256") {
97 }
99}
100
101// A single checksum type / value pair
102// Value is stored as raw bytes in memory.
105 std::array<unsigned char, g_max_checksum_length> value;
106};
107
108// All known checksums for a given object
109//
110// If the checksum is not available, then checksums[ctype].type == kUnknown.
111// Otherwise, checksums[type].value contains the checksum and checksums[ctype].type
112// is set to ctype for a given ctype in the ChecksumType enum.
114public:
115
116 // Check to see if a checksum's value is set
117 //
118 // Always returns false if kAll or kUnknown are requested.
119 bool IsSet(ChecksumType ctype) const {
120 if ((ctype == ChecksumType::kUnknown) || (ctype == ChecksumType::kAll)) return false;
121 return checksums[static_cast<size_t>(ctype)].type != ChecksumType::kUnknown;
122 }
123
124 // Get the checksum value for a given checksum type
125 //
126 // If an invalid value is requested (kAll, kUnknown), then the return value is
127 // undefined (as opposed to throwing an exception).
128 //
129 // If the checksum value is not set (IsSet returns false), then the return value
130 // is undefined.
131 const std::array<unsigned char, g_max_checksum_length> &Get(ChecksumType ctype) const {
132 if ((ctype == ChecksumType::kUnknown) || (ctype == ChecksumType::kAll))
133 ctype = ChecksumType::kCRC32C;
134 return checksums[static_cast<size_t>(ctype)].value;
135 }
136
137 // Set the value of the checksum for a known type.
138 //
139 // Returns true if the checksum type is valid, false otherwise (kAll, kUnknown).
140 bool Set(ChecksumType ctype, const std::array<unsigned char, g_max_checksum_length> &value) {
141 if ((ctype == ChecksumType::kUnknown) || (ctype == ChecksumType::kAll)) return false;
142 checksums[static_cast<size_t>(ctype)] = ChecksumEntry{ctype, value};
143 return true;
144 }
145
146 // Returns a tuple of the type and value of the first set checksum in the object.
147 //
148 // If no value is set, then the returned type will be kUnknown.
149 std::tuple<ChecksumType, std::array<unsigned char, g_max_checksum_length>, bool> GetFirst() const {
150 for (int idx=0; idx < static_cast<int>(ChecksumType::kAll); ++idx) {
151 if (checksums[idx].type != ChecksumType::kUnknown) {
152 return std::make_tuple(static_cast<ChecksumType>(idx), checksums[idx].value, true);
153 }
154 }
155 return std::make_tuple(ChecksumType::kUnknown, std::array<unsigned char, g_max_checksum_length>(), false);
156 }
157
158private:
159 std::array<ChecksumEntry, static_cast<int>(ChecksumType::kAll)> checksums;
160};
161
162}
163
164#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)