#include "svn_ctype.h"
#include "svn_dirent_uri.h"
#include "svn_io.h"
#include "svn_pools.h"
#include "private/svn_fs_fs_private.h"
#include "private/svn_sorts_private.h"
#include "svn_private_config.h"
#include "svnfsfs.h"
static const char *item_type_str[]
= {"none", "frep", "drep", "fprop", "dprop", "node", "chgs", "rep"};
static svn_error_t *
str_to_item_type(unsigned *type,
const char *str)
{
unsigned i;
for (i = 0; i < sizeof(item_type_str) / sizeof(item_type_str[0]); ++i)
if (strcmp(item_type_str[i], str) == 0)
{
*type = i;
return SVN_NO_ERROR;
}
return svn_error_createf(SVN_ERR_BAD_TOKEN, NULL,
_("Unknown item type '%s'"), str);
}
static svn_error_t *
token_to_i64(apr_int64_t *value_p,
apr_array_header_t *tokens,
int idx,
int radix)
{
const char *hex;
char *end;
apr_int64_t value;
SVN_ERR_ASSERT(idx >= 0);
if (tokens->nelts <= idx)
return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
_("%i columns needed, %i provided"),
idx + 1, tokens->nelts);
hex = APR_ARRAY_IDX(tokens, idx, const char *);
value = apr_strtoi64(hex, &end, radix);
if (errno || *end != '\0')
return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
_("%s is not a value HEX string"), hex);
*value_p = value;
return SVN_NO_ERROR;
}
static svn_error_t *
parse_index_line(svn_fs_fs__p2l_entry_t **entry,
svn_stringbuf_t *line,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
apr_array_header_t *tokens = svn_cstring_split(line->data, " ", TRUE,
scratch_pool);
svn_fs_fs__p2l_entry_t *result = apr_pcalloc(result_pool, sizeof(*result));
apr_int64_t value;
SVN_ERR(token_to_i64(&value, tokens, 0, 16));
result->offset = (apr_off_t)value;
SVN_ERR(token_to_i64(&value, tokens, 1, 16));
result->size = (apr_off_t)value;
SVN_ERR(token_to_i64(&value, tokens, 4, 10));
result->item.number = (apr_uint64_t)value;
SVN_ERR(str_to_item_type(&result->type,
APR_ARRAY_IDX(tokens, 2, const char *)));
SVN_ERR(svn_revnum_parse(&result->item.revision,
APR_ARRAY_IDX(tokens, 3, const char *), NULL));
*entry = result;
return SVN_NO_ERROR;
}
static svn_error_t *
load_index(const char *path,
svn_stream_t *input,
apr_pool_t *pool)
{
svn_fs_t *fs;
svn_revnum_t revision = SVN_INVALID_REVNUM;
apr_array_header_t *entries = apr_array_make(pool, 16, sizeof(void*));
apr_pool_t *iterpool = svn_pool_create(pool);
SVN_ERR(open_fs(&fs, path, pool));
while (TRUE)
{
svn_stringbuf_t *line;
svn_fs_fs__p2l_entry_t *entry;
svn_boolean_t eol;
svn_pool_clear(iterpool);
svn_stream_readline(input, &line, "\n", &eol, iterpool);
if (eol)
break;
if (strstr(line->data, "tart"))
continue;
svn_stringbuf_strip_whitespace(line);
if (line->len == 0)
continue;
SVN_ERR(parse_index_line(&entry, line, pool, iterpool));
APR_ARRAY_PUSH(entries, svn_fs_fs__p2l_entry_t *) = entry;
if ( revision == SVN_INVALID_REVNUM
&& entry->item.revision != SVN_INVALID_REVNUM)
revision = entry->item.revision;
}
SVN_ERR(svn_fs_fs__load_index(fs, revision, entries, iterpool));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
svn_error_t *
subcommand__load_index(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
svnfsfs__opt_state *opt_state = baton;
svn_stream_t *input;
SVN_ERR(svn_stream_for_stdin2(&input, TRUE, pool));
SVN_ERR(load_index(opt_state->repository_path, input, pool));
return SVN_NO_ERROR;
}