1 /* low_level.c --- low level r/w access to FSX file structures
2  *
3  * ====================================================================
4  *    Licensed to the Apache Software Foundation (ASF) under one
5  *    or more contributor license agreements.  See the NOTICE file
6  *    distributed with this work for additional information
7  *    regarding copyright ownership.  The ASF licenses this file
8  *    to you under the Apache License, Version 2.0 (the
9  *    "License"); you may not use this file except in compliance
10  *    with the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *    Unless required by applicable law or agreed to in writing,
15  *    software distributed under the License is distributed on an
16  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  *    KIND, either express or implied.  See the License for the
18  *    specific language governing permissions and limitations
19  *    under the License.
20  * ====================================================================
21  */
22 
23 #ifndef SVN_LIBSVN_FS_X_LOW_LEVEL_H
24 #define SVN_LIBSVN_FS_X_LOW_LEVEL_H
25 
26 #include "svn_fs.h"
27 
28 #include "fs_x.h"
29 #include "id.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif /* __cplusplus */
34 
35 /* Kinds that a node-rev can be. */
36 #define SVN_FS_X__KIND_FILE          "file"
37 #define SVN_FS_X__KIND_DIR           "dir"
38 
39 /* The functions are grouped as follows:
40  *
41  * - revision footer
42  * - representation (as in "text:" and "props:" lines)
43  * - node revision
44  * - representation header ("DELTA" lines)
45  * - changed path list
46  */
47 
48 /* Given the FSX revision / pack FOOTER, parse it destructively
49  * and return the start offsets of the index data in *L2P_OFFSET and
50  * *P2L_OFFSET, respectively.  Also, return the expected checksums in
51  * in *L2P_CHECKSUM and *P2L_CHECKSUM.
52  *
53  * FOOTER_OFFSET is used for validation.
54  *
55  * Note that REV is only used to construct nicer error objects that
56  * mention this revision.  Allocate the checksums in RESULT_POOL.
57  */
58 svn_error_t *
59 svn_fs_x__parse_footer(apr_off_t *l2p_offset,
60                        svn_checksum_t **l2p_checksum,
61                        apr_off_t *p2l_offset,
62                        svn_checksum_t **p2l_checksum,
63                        svn_stringbuf_t *footer,
64                        svn_revnum_t rev,
65                        apr_off_t footer_offset,
66                        apr_pool_t *result_pool);
67 
68 /* Given the offset of the L2P index data in L2P_OFFSET, the content
69  * checksum in L2P_CHECKSUM and the offset plus checksum of the P2L
70  * index data in P2L_OFFSET and P2L_CHECKSUM.
71  *
72  * Return the corresponding format 7+ revision / pack file footer.
73  * Allocate it in RESULT_POOL and use SCRATCH_POOL for temporary.
74  */
75 svn_stringbuf_t *
76 svn_fs_x__unparse_footer(apr_off_t l2p_offset,
77                          svn_checksum_t *l2p_checksum,
78                          apr_off_t p2l_offset,
79                          svn_checksum_t *p2l_checksum,
80                          apr_pool_t *result_pool,
81                          apr_pool_t *scratch_pool);
82 
83 /* Parse the description of a representation from TEXT and store it
84    into *REP_P.  TEXT will be invalidated by this call.  Allocate *REP_P in
85    RESULT_POOL and use SCRATCH_POOL for temporaries. */
86 svn_error_t *
87 svn_fs_x__parse_representation(svn_fs_x__representation_t **rep_p,
88                                svn_stringbuf_t *text,
89                                apr_pool_t *result_pool,
90                                apr_pool_t *scratch_pool);
91 
92 /* Return a formatted string that represents the location of representation
93  * REP.  If MUTABLE_REP_TRUNCATED is given, the rep is for props or dir
94  * contents, and only a "-1" revision number will be given for a mutable rep.
95  * If MAY_BE_CORRUPT is true, guard for NULL when constructing the string.
96  * Allocate the result in RESULT_POOL and temporaries in SCRATCH_POOL. */
97 svn_stringbuf_t *
98 svn_fs_x__unparse_representation(svn_fs_x__representation_t *rep,
99                                  svn_boolean_t mutable_rep_truncated,
100                                  apr_pool_t *result_pool,
101                                  apr_pool_t *scratch_pool);
102 
103 /* Read a node-revision from STREAM. Set *NODEREV to the new structure,
104    allocated in RESULT_POOL. */
105 svn_error_t *
106 svn_fs_x__read_noderev(svn_fs_x__noderev_t **noderev,
107                        svn_stream_t *stream,
108                        apr_pool_t *result_pool,
109                        apr_pool_t *scratch_pool);
110 
111 /* Write the node-revision NODEREV into the stream OUTFILE.
112    Temporary allocations are from SCRATCH_POOL. */
113 svn_error_t *
114 svn_fs_x__write_noderev(svn_stream_t *outfile,
115                         svn_fs_x__noderev_t *noderev,
116                         apr_pool_t *scratch_pool);
117 
118 /* This type enumerates all forms of representations that we support. */
119 typedef enum svn_fs_x__rep_type_t
120 {
121   /* this is a DELTA representation with no base representation */
122   svn_fs_x__rep_self_delta,
123 
124   /* this is a DELTA representation against some base representation */
125   svn_fs_x__rep_delta,
126 
127   /* this is a representation in a star-delta container */
128   svn_fs_x__rep_container
129 } svn_fs_x__rep_type_t;
130 
131 /* This structure is used to hold the information stored in a representation
132  * header. */
133 typedef struct svn_fs_x__rep_header_t
134 {
135   /* type of the representation, i.e. whether self-DELTA etc. */
136   svn_fs_x__rep_type_t type;
137 
138   /* if this rep is a delta against some other rep, that base rep can
139    * be found in this revision.  Should be 0 if there is no base rep. */
140   svn_revnum_t base_revision;
141 
142   /* if this rep is a delta against some other rep, that base rep can
143    * be found at this item index within the base rep's revision.  Should
144    * be 0 if there is no base rep. */
145   apr_off_t base_item_index;
146 
147   /* if this rep is a delta against some other rep, this is the (deltified)
148    * size of that base rep.  Should be 0 if there is no base rep. */
149   svn_filesize_t base_length;
150 
151   /* length of the textual representation of the header in the rep or pack
152    * file, including EOL.  Only valid after reading it from disk.
153    * Should be 0 otherwise. */
154   apr_size_t header_size;
155 } svn_fs_x__rep_header_t;
156 
157 /* Read the next line from STREAM and parse it as a text
158    representation header.  Return the parsed entry in *HEADER, allocated
159    in RESULT_POOL. Perform temporary allocations in SCRATCH_POOL. */
160 svn_error_t *
161 svn_fs_x__read_rep_header(svn_fs_x__rep_header_t **header,
162                           svn_stream_t *stream,
163                           apr_pool_t *result_pool,
164                           apr_pool_t *scratch_pool);
165 
166 /* Write the representation HEADER to STREAM.
167  * Use SCRATCH_POOL for allocations. */
168 svn_error_t *
169 svn_fs_x__write_rep_header(svn_fs_x__rep_header_t *header,
170                            svn_stream_t *stream,
171                            apr_pool_t *scratch_pool);
172 
173 /* Read up to MAX_COUNT of the changes from STREAM and store them in
174    *CHANGES, allocated in RESULT_POOL.  Do temporary allocations in
175    SCRATCH_POOL. */
176 svn_error_t *
177 svn_fs_x__read_changes(apr_array_header_t **changes,
178                        svn_stream_t *stream,
179                        int max_count,
180                        apr_pool_t *result_pool,
181                        apr_pool_t *scratch_pool);
182 
183 /* Callback function used by svn_fs_x__read_changes_incrementally(),
184  * asking the receiver to process to process CHANGE using BATON.  CHANGE
185  * and SCRATCH_POOL will not be valid beyond the current callback invocation.
186  */
187 typedef svn_error_t *(*svn_fs_x__change_receiver_t)(
188   void *baton,
189   svn_fs_x__change_t *change,
190   apr_pool_t *scratch_pool);
191 
192 /* Read all the changes from STREAM and invoke CHANGE_RECEIVER on each change.
193    Do all allocations in SCRATCH_POOL. */
194 svn_error_t *
195 svn_fs_x__read_changes_incrementally(svn_stream_t *stream,
196                                      svn_fs_x__change_receiver_t
197                                        change_receiver,
198                                      void *change_receiver_baton,
199                                      apr_pool_t *scratch_pool);
200 
201 /* Write the changed path info from CHANGES in filesystem FS to the
202    output stream STREAM.  You may call this function multiple time on
203    the same stream.  If you are writing to a (proto-)revision file,
204    the last call must set TERMINATE_LIST to write an extra empty line
205    that marks the end of the changed paths list.
206    Perform temporary allocations in SCRATCH_POOL.
207  */
208 svn_error_t *
209 svn_fs_x__write_changes(svn_stream_t *stream,
210                         svn_fs_t *fs,
211                         apr_hash_t *changes,
212                         svn_boolean_t terminate_list,
213                         apr_pool_t *scratch_pool);
214 
215 /* Parse the property list serialized in CONTENT and return it in
216    *PROPERTIES, allocated from RESULT_POOL.  CONTENT must remain
217    valid at least until the next cleanup of RESULT_POOL.
218  */
219 svn_error_t *
220 svn_fs_x__parse_properties(apr_hash_t **properties,
221                            const svn_string_t *content,
222                            apr_pool_t *result_pool);
223 
224 /* Write the property list PROPLIST to STREAM in serialized format.
225    Use SCRATCH_POOL for temporary allocations.
226  */
227 svn_error_t *
228 svn_fs_x__write_properties(svn_stream_t *stream,
229                            apr_hash_t *proplist,
230                            apr_pool_t *scratch_pool);
231 
232 #ifdef __cplusplus
233 }
234 #endif /* __cplusplus */
235 
236 #endif /* SVN_LIBSVN_FS_X_LOW_LEVEL_H */
237