GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/file_bundle.h
Date: 2026-07-05 02:36:18
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 303 BundleFileMgr(JsonDocument *fc) { Manage(fc); }
57
58 1212 virtual ~BundleFileMgr() { ReleaseDocument(); }
59
60 39 std::string GetVersion() const {
61
2/4
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39 times.
✗ Branch 6 not taken.
78 const JSON *ptr = JsonDocument::SearchInObject(
62 39 bundle_doc_->root(), "version", JSON_STRING);
63
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
78 return (ptr) ? ptr->get<std::string>() : std::string();
64 }
65
66 39 std::string GetEncoding() const {
67
2/4
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39 times.
✗ Branch 6 not taken.
78 const JSON *ptr = JsonDocument::SearchInObject(
68 39 bundle_doc_->root(), "encoding", JSON_STRING);
69
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
78 return (ptr) ? ptr->get<std::string>() : std::string();
70 }
71
72 352 virtual PathString GetNext() {
73
1/2
✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
352 const JSON *deps = Dependencies();
74
5/6
✓ Branch 0 taken 352 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 88 times.
✓ Branch 4 taken 264 times.
✓ Branch 5 taken 88 times.
✓ Branch 6 taken 264 times.
352 if (deps == nullptr || current_index_ >= deps->size()) {
75 // This should be handled as an error code. Path string should never be
76 // empty;
77 88 return PathString();
78 }
79
1/2
✓ Branch 1 taken 264 times.
✗ Branch 2 not taken.
264 const JSON &entry = (*deps)[current_index_++];
80
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 264 times.
264 assert(entry.is_string());
81 const PathString result = static_cast<PathString>(
82
2/4
✓ Branch 1 taken 264 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 264 times.
✗ Branch 5 not taken.
264 entry.get<std::string>());
83
3/8
✓ Branch 1 taken 264 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 264 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 9 taken 264 times.
✗ Branch 10 not taken.
264 return (result.IsEmpty()) ? GetNext() : result;
84 264 }
85
86 39 virtual size_t Size() const { return size_; }
87
88 156 operator bool() const {
89
2/4
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 156 times.
✗ Branch 4 not taken.
156 return (bundle_doc_ != nullptr) ? bundle_doc_->IsValid() : false;
90 }
91
92 private:
93 303 void Manage(JsonDocument *fc) {
94 303 bundle_doc_ = fc;
95 303 current_index_ = 0;
96 303 ResetSize();
97 303 }
98
99 655 const JSON *Dependencies() const {
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 655 times.
655 if (bundle_doc_ == nullptr)
101 return nullptr;
102
2/4
✓ Branch 2 taken 655 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 655 times.
✗ Branch 6 not taken.
1965 return JsonDocument::SearchInObject(
103 1310 bundle_doc_->root(), "dependencies", JSON_ARRAY);
104 }
105
106 303 void ResetSize() {
107 303 const JSON *deps = Dependencies();
108
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
303 size_ = (deps != nullptr) ? deps->size() : 0;
109 303 }
110
111 303 void ReleaseDocument() {
112
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
303 if (bundle_doc_ != nullptr) {
113
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
303 delete bundle_doc_;
114 303 bundle_doc_ = nullptr;
115 }
116 303 }
117 size_t size_ = 0;
118 size_t current_index_ = 0;
119 JsonDocument *bundle_doc_ = nullptr;
120 };
121
122 #endif
123