1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <libsnapshot/cow_format.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20
21 #include <android-base/logging.h>
22
23 namespace android {
24 namespace snapshot {
25
operator <<(std::ostream & os,CowOperation const & op)26 std::ostream& operator<<(std::ostream& os, CowOperation const& op) {
27 os << "CowOperation(type:";
28 if (op.type == kCowCopyOp)
29 os << "kCowCopyOp, ";
30 else if (op.type == kCowReplaceOp)
31 os << "kCowReplaceOp, ";
32 else if (op.type == kCowZeroOp)
33 os << "kZeroOp, ";
34 else if (op.type == kCowFooterOp)
35 os << "kCowFooterOp, ";
36 else if (op.type == kCowLabelOp)
37 os << "kCowLabelOp, ";
38 else if (op.type == kCowClusterOp)
39 os << "kCowClusterOp ";
40 else if (op.type == kCowXorOp)
41 os << "kCowXorOp ";
42 else if (op.type == kCowSequenceOp)
43 os << "kCowSequenceOp ";
44 else if (op.type == kCowFooterOp)
45 os << "kCowFooterOp ";
46 else
47 os << (int)op.type << "?,";
48 os << "compression:";
49 if (op.compression == kCowCompressNone)
50 os << "kCowCompressNone, ";
51 else if (op.compression == kCowCompressGz)
52 os << "kCowCompressGz, ";
53 else if (op.compression == kCowCompressBrotli)
54 os << "kCowCompressBrotli, ";
55 else
56 os << (int)op.compression << "?, ";
57 os << "data_length:" << op.data_length << ",\t";
58 os << "new_block:" << op.new_block << ",\t";
59 os << "source:" << op.source;
60 if (op.type == kCowXorOp)
61 os << " (block:" << op.source / BLOCK_SZ << " offset:" << op.source % BLOCK_SZ << ")";
62 os << ")";
63 return os;
64 }
65
GetNextOpOffset(const CowOperation & op,uint32_t cluster_ops)66 int64_t GetNextOpOffset(const CowOperation& op, uint32_t cluster_ops) {
67 if (op.type == kCowClusterOp) {
68 return op.source;
69 } else if ((op.type == kCowReplaceOp || op.type == kCowXorOp) && cluster_ops == 0) {
70 return op.data_length;
71 } else {
72 return 0;
73 }
74 }
75
GetNextDataOffset(const CowOperation & op,uint32_t cluster_ops)76 int64_t GetNextDataOffset(const CowOperation& op, uint32_t cluster_ops) {
77 if (op.type == kCowClusterOp) {
78 return cluster_ops * sizeof(CowOperation);
79 } else if (cluster_ops == 0) {
80 return sizeof(CowOperation);
81 } else {
82 return 0;
83 }
84 }
85
IsMetadataOp(const CowOperation & op)86 bool IsMetadataOp(const CowOperation& op) {
87 switch (op.type) {
88 case kCowLabelOp:
89 case kCowClusterOp:
90 case kCowFooterOp:
91 case kCowSequenceOp:
92 return true;
93 default:
94 return false;
95 }
96 }
97
IsOrderedOp(const CowOperation & op)98 bool IsOrderedOp(const CowOperation& op) {
99 switch (op.type) {
100 case kCowCopyOp:
101 case kCowXorOp:
102 return true;
103 default:
104 return false;
105 }
106 }
107
108 } // namespace snapshot
109 } // namespace android
110