OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__ | 5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__ |
6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__ | 6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__ |
7 | 7 |
8 #include <string> | |
9 #include <vector> | |
10 #include "chromeos/obsolete_logging.h" | |
11 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
12 #include "update_engine/update_metadata.pb.h" | |
13 | |
14 // The DeltaDiffParser class is used to parse a delta file on disk. It will | |
15 // copy the metadata into memory, but not the file data. This class can | |
16 // also be used to copy file data out to disk. | |
17 | |
18 // The DeltaDiffParserIterator class is used to iterate through the | |
19 // metadata of a delta file. It will return directories before their | |
20 // children. | |
21 | 9 |
22 namespace chromeos_update_engine { | 10 namespace chromeos_update_engine { |
23 | 11 |
24 class DeltaDiffParser; | |
25 | |
26 class DeltaDiffParserIterator { | |
27 friend class DeltaDiffParser; | |
28 public: | |
29 void Increment(); | |
30 | |
31 // Returns the full path for the current file, e.g. "/bin/bash". | |
32 // Returns empty string for root. | |
33 const std::string& path() const { | |
34 return path_; | |
35 } | |
36 | |
37 // Returns the basename for the current file. If path() returns | |
38 // "/bin/bash", then GetName() returns "bash". | |
39 // Returns empty string for root | |
40 const std::string GetName() const; | |
41 | |
42 const DeltaArchiveManifest_File& GetFile() const; | |
43 bool operator==(const DeltaDiffParserIterator& that) const { | |
44 return path_indices_ == that.path_indices_ && | |
45 child_indices_ == that.child_indices_ && | |
46 path_ == that.path_ && | |
47 archive_ == that.archive_; | |
48 } | |
49 bool operator!=(const DeltaDiffParserIterator& that) const { | |
50 return !(*this == that); | |
51 } | |
52 private: | |
53 // Container of all the File messages. Each File message has an index | |
54 // in archive_. The root directory is always stored at index 0. | |
55 const DeltaArchiveManifest* archive_; | |
56 | |
57 // These variables are used to implement the common recursive depth-first | |
58 // search algorithm (which we can't use here, since we need to walk the | |
59 // tree incrementally). | |
60 | |
61 // Indices into 'archive_' of the current path components. For example, if | |
62 // the current path is "/bin/bash", 'path_stack_' will contain the archive | |
63 // indices for "/", "/bin", and "/bin/bash", in that order. This is | |
64 // analogous to the call stack of the recursive algorithm. | |
65 std::vector<int> path_indices_; | |
66 | |
67 // For each component in 'path_stack_', the currently-selected child in its | |
68 // child vector. In the previous example, if "/" has "abc" and "bin" | |
69 // subdirectories and "/bin" contains only "bash", this will contain | |
70 // [0, 1, 0], since we are using the 0th child at the root directory level | |
71 // (there's only one child there), the first of the root dir's children | |
72 // ("bin"), and the 0th child of /bin ("bash"). This is analogous to the | |
73 // state of each function (in terms of which child it's currently | |
74 // handling) in the call stack of the recursive algorithm. | |
75 std::vector<int> child_indices_; | |
76 | |
77 std::string path_; | |
78 // Instantiated by friend class DeltaDiffParser | |
79 explicit DeltaDiffParserIterator(const DeltaArchiveManifest* archive) | |
80 : archive_(archive) {} | |
81 DeltaDiffParserIterator() { | |
82 CHECK(false); // Should never be called. | |
83 } | |
84 }; | |
85 | |
86 class DeltaDiffParser { | |
87 public: | |
88 DeltaDiffParser(const std::string& delta_file); | |
89 ~DeltaDiffParser(); | |
90 bool valid() const { return valid_; } | |
91 bool ContainsPath(const std::string& path) const; | |
92 const DeltaArchiveManifest_File& GetFileAtPath(const std::string& path) const; | |
93 | |
94 // Reads length bytes at offset of the delta file into the out string | |
95 // or vector. Be careful not to call this with large length values, | |
96 // since that much memory will have to be allocated to store the output. | |
97 // Returns true on success. | |
98 bool ReadDataVector(off_t offset, off_t length, std::vector<char>* out) const; | |
99 | |
100 // Copies length bytes of data from offset into a new file at path specified. | |
101 // If should_decompress is true, will gzip decompress while writing to the | |
102 // file. Returns true on success. | |
103 bool CopyDataToFile(off_t offset, off_t length, bool should_decompress, | |
104 const std::string& path) const; | |
105 | |
106 typedef DeltaDiffParserIterator Iterator; | |
107 const Iterator Begin(); | |
108 const Iterator End(); | |
109 | |
110 // The identifier we expect at the beginning of a delta file. | |
111 static const char* const kFileMagic; | |
112 | |
113 private: | |
114 // (Binary) Searches the children of 'file' for one named child_name. | |
115 // If found, returns the index into the archive. If not found, returns -1. | |
116 int GetIndexOfFileChild(const DeltaArchiveManifest_File& file, | |
117 const std::string& child_name) const; | |
118 | |
119 // Returns -1 if not found, 0 for root | |
120 int GetIndexForPath(const std::string& path) const; | |
121 | |
122 // We keep a filedescriptor open to the delta file. | |
123 int fd_; | |
124 | |
125 DeltaArchiveManifest archive_; | |
126 bool valid_; | |
127 DISALLOW_COPY_AND_ASSIGN(DeltaDiffParser); | |
128 }; | |
129 | |
130 }; // namespace chromeos_update_engine | 12 }; // namespace chromeos_update_engine |
131 | 13 |
132 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__ | 14 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__ |
OLD | NEW |