GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/file_bundle.h
Date: 2026-06-21 02:37:04
Exec Total Coverage
Lines: 40 41 97.6%
Branches: 27 52 51.9%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 *
4 * This class implements the format for .cvmfsbundle files
5 */
6
7 #ifndef CVMFS_FILE_BUNDLE_H_
8 #define CVMFS_FILE_BUNDLE_H_
9
10 #include <cassert>
11 #include <fstream>
12 #include <sstream>
13 #include <string>
14
15 #include "json_document.h"
16 #include "shortstring.h"
17 #include "util/single_copy.h"
18
19 /*
20
21 The .cvmfsbundle file serves both as a file list and as a trigger for loading a
22 bundle. The convention is to call it .cvmfsbundle.<filename>, where <filename>
23 should trigger the bundle.
24
25 ? The content could be structured in json.
26
27 The file format should be versioned, with the header:
28
29 #%CVMFS_BUNDLE version=1 encoding=UTF-8
30
31 ? end marker
32
33 The json file should contain an array of labeled objects as follows:
34 {
35 "name":"CVMFS_BUNDLE",
36 "version":"1.0.0",
37 "encoding":"UTF-8",
38 "dependencies":["/absolute/path/to/file/from/repositories/root"]
39 }
40
41 */
42
43 class BundleFileMgr : SingleCopy {
44 public:
45 BundleFileMgr(const PathString &bundle_file_path) {
46 std::ifstream file(bundle_file_path.ToString());
47 if (!file.is_open()) {
48 bundle_doc_ = nullptr;
49 } else {
50 std::stringstream rbuf;
51 rbuf << file.rdbuf();
52 Manage(JsonDocument::Create(rbuf.str()));
53 }
54 }
55
56 142 BundleFileMgr(JsonDocument *fc) { Manage(fc); }
57
58 568 virtual ~BundleFileMgr() { ReleaseDocument(); }
59
60 16 std::string GetVersion() const {
61
2/4
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
32 const JSON *ptr = JsonDocument::SearchInObject(
62 16 bundle_doc_->root(), "version", JSON_STRING);
63
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
32 return (ptr) ? ptr->get<std::string>() : std::string();
64 }
65
66 16 std::string GetEncoding() const {
67
2/4
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
32 const JSON *ptr = JsonDocument::SearchInObject(
68 16 bundle_doc_->root(), "encoding", JSON_STRING);
69
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
32 return (ptr) ? ptr->get<std::string>() : std::string();
70 }
71
72 64 virtual PathString GetNext() {
73
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 const JSON *deps = Dependencies();
74
5/6
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 48 times.
64 if (deps == nullptr || current_index_ >= deps->size()) {
75 // This should be handled as an error code. Path string should never be
76 // empty;
77 16 return PathString();
78 }
79
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 const JSON &entry = (*deps)[current_index_++];
80
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 assert(entry.is_string());
81 const PathString result = static_cast<PathString>(
82
2/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
48 entry.get<std::string>());
83
3/8
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 9 taken 48 times.
✗ Branch 10 not taken.
48 return (result.IsEmpty()) ? GetNext() : result;
84 48 }
85
86 16 virtual size_t Size() const { return size_; }
87
88 64 operator bool() const {
89
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 64 times.
✗ Branch 4 not taken.
64 return (bundle_doc_ != nullptr) ? bundle_doc_->IsValid() : false;
90 }
91
92 private:
93 142 void Manage(JsonDocument *fc) {
94 142 bundle_doc_ = fc;
95 142 current_index_ = 0;
96 142 ResetSize();
97 142 }
98
99 206 const JSON *Dependencies() const {
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 206 times.
206 if (bundle_doc_ == nullptr)
101 return nullptr;
102
2/4
✓ Branch 2 taken 206 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 206 times.
✗ Branch 6 not taken.
618 return JsonDocument::SearchInObject(
103 412 bundle_doc_->root(), "dependencies", JSON_ARRAY);
104 }
105
106 142 void ResetSize() {
107 142 const JSON *deps = Dependencies();
108
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 size_ = (deps != nullptr) ? deps->size() : 0;
109 142 }
110
111 142 void ReleaseDocument() {
112
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 if (bundle_doc_ != nullptr) {
113
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 delete bundle_doc_;
114 142 bundle_doc_ = nullptr;
115 }
116 142 }
117 size_t size_ = 0;
118 size_t current_index_ = 0;
119 JsonDocument *bundle_doc_ = nullptr;
120 };
121
122 #endif
123