Skip to content

Commit 785d698

Browse files
committed
Merge branch 'svn-fe' of git://repo.or.cz/git/jrn
* 'svn-fe' of git://repo.or.cz/git/jrn: vcs-svn: use strchr to find RFC822 delimiter vcs-svn: implement perfect hash for top-level keys vcs-svn: implement perfect hash for node-prop keys vcs-svn: use strbuf for author, UUID, and URL vcs-svn: use strbuf for revision log vcs-svn: improve reporting of input errors vcs-svn: make buffer_copy_bytes return length read vcs-svn: make buffer_skip_bytes return length read vcs-svn: improve support for reading large files vcs-svn: allow input errors to be detected promptly vcs-svn: simplify repo_modify_path and repo_copy vcs-svn: handle_node: use repo_read_path vcs-svn: introduce repo_read_path to check the content at a path
2 parents 1ea9f9d + 41b9dd9 commit 785d698

File tree

8 files changed

+265
-172
lines changed

8 files changed

+265
-172
lines changed

vcs-svn/fast_export.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,24 @@ void fast_export_modify(uint32_t depth, uint32_t *path, uint32_t mode,
3131
}
3232

3333
static char gitsvnline[MAX_GITSVN_LINE_LEN];
34-
void fast_export_commit(uint32_t revision, uint32_t author, char *log,
35-
uint32_t uuid, uint32_t url,
34+
void fast_export_commit(uint32_t revision, const char *author, char *log,
35+
const char *uuid, const char *url,
3636
unsigned long timestamp)
3737
{
3838
if (!log)
3939
log = "";
40-
if (~uuid && ~url) {
40+
if (*uuid && *url) {
4141
snprintf(gitsvnline, MAX_GITSVN_LINE_LEN,
4242
"\n\ngit-svn-id: %s@%"PRIu32" %s\n",
43-
pool_fetch(url), revision, pool_fetch(uuid));
43+
url, revision, uuid);
4444
} else {
4545
*gitsvnline = '\0';
4646
}
4747
printf("commit refs/heads/master\n");
4848
printf("committer %s <%s@%s> %ld +0000\n",
49-
~author ? pool_fetch(author) : "nobody",
50-
~author ? pool_fetch(author) : "nobody",
51-
~uuid ? pool_fetch(uuid) : "local", timestamp);
49+
*author ? author : "nobody",
50+
*author ? author : "nobody",
51+
*uuid ? uuid : "local", timestamp);
5252
printf("data %"PRIu32"\n%s%s\n",
5353
(uint32_t) (strlen(log) + strlen(gitsvnline)),
5454
log, gitsvnline);
@@ -63,14 +63,23 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
6363
printf("progress Imported commit %"PRIu32".\n\n", revision);
6464
}
6565

66+
static void die_short_read(struct line_buffer *input)
67+
{
68+
if (buffer_ferror(input))
69+
die_errno("error reading dump file");
70+
die("invalid dump: unexpected end of file");
71+
}
72+
6673
void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input)
6774
{
6875
if (mode == REPO_MODE_LNK) {
6976
/* svn symlink blobs start with "link " */
70-
buffer_skip_bytes(input, 5);
7177
len -= 5;
78+
if (buffer_skip_bytes(input, 5) != 5)
79+
die_short_read(input);
7280
}
7381
printf("blob\nmark :%"PRIu32"\ndata %"PRIu32"\n", mark, len);
74-
buffer_copy_bytes(input, len);
82+
if (buffer_copy_bytes(input, len) != len)
83+
die_short_read(input);
7584
fputc('\n', stdout);
7685
}

vcs-svn/fast_export.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
void fast_export_delete(uint32_t depth, uint32_t *path);
77
void fast_export_modify(uint32_t depth, uint32_t *path, uint32_t mode,
88
uint32_t mark);
9-
void fast_export_commit(uint32_t revision, uint32_t author, char *log,
10-
uint32_t uuid, uint32_t url, unsigned long timestamp);
9+
void fast_export_commit(uint32_t revision, const char *author, char *log,
10+
const char *uuid, const char *url,
11+
unsigned long timestamp);
1112
void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len,
1213
struct line_buffer *input);
1314

vcs-svn/line_buffer.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ long buffer_tmpfile_prepare_to_read(struct line_buffer *buf)
5959
return pos;
6060
}
6161

62+
int buffer_ferror(struct line_buffer *buf)
63+
{
64+
return ferror(buf->infile);
65+
}
66+
6267
int buffer_read_char(struct line_buffer *buf)
6368
{
6469
return fgetc(buf->infile);
@@ -99,31 +104,32 @@ void buffer_read_binary(struct line_buffer *buf,
99104
strbuf_fread(sb, size, buf->infile);
100105
}
101106

102-
void buffer_copy_bytes(struct line_buffer *buf, uint32_t len)
107+
off_t buffer_copy_bytes(struct line_buffer *buf, off_t nbytes)
103108
{
104109
char byte_buffer[COPY_BUFFER_LEN];
105-
uint32_t in;
106-
while (len > 0 && !feof(buf->infile) && !ferror(buf->infile)) {
107-
in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
110+
off_t done = 0;
111+
while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
112+
off_t len = nbytes - done;
113+
size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
108114
in = fread(byte_buffer, 1, in, buf->infile);
109-
len -= in;
115+
done += in;
110116
fwrite(byte_buffer, 1, in, stdout);
111-
if (ferror(stdout)) {
112-
buffer_skip_bytes(buf, len);
113-
return;
114-
}
117+
if (ferror(stdout))
118+
return done + buffer_skip_bytes(buf, nbytes - done);
115119
}
120+
return done;
116121
}
117122

118-
void buffer_skip_bytes(struct line_buffer *buf, uint32_t len)
123+
off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes)
119124
{
120125
char byte_buffer[COPY_BUFFER_LEN];
121-
uint32_t in;
122-
while (len > 0 && !feof(buf->infile) && !ferror(buf->infile)) {
123-
in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
124-
in = fread(byte_buffer, 1, in, buf->infile);
125-
len -= in;
126+
off_t done = 0;
127+
while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
128+
off_t len = nbytes - done;
129+
size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
130+
done += fread(byte_buffer, 1, in, buf->infile);
126131
}
132+
return done;
127133
}
128134

129135
void buffer_reset(struct line_buffer *buf)

vcs-svn/line_buffer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ int buffer_tmpfile_init(struct line_buffer *buf);
2121
FILE *buffer_tmpfile_rewind(struct line_buffer *buf); /* prepare to write. */
2222
long buffer_tmpfile_prepare_to_read(struct line_buffer *buf);
2323

24+
int buffer_ferror(struct line_buffer *buf);
2425
char *buffer_read_line(struct line_buffer *buf);
2526
char *buffer_read_string(struct line_buffer *buf, uint32_t len);
2627
int buffer_read_char(struct line_buffer *buf);
2728
void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t len);
28-
void buffer_copy_bytes(struct line_buffer *buf, uint32_t len);
29-
void buffer_skip_bytes(struct line_buffer *buf, uint32_t len);
29+
/* Returns number of bytes read (not necessarily written). */
30+
off_t buffer_copy_bytes(struct line_buffer *buf, off_t len);
31+
off_t buffer_skip_bytes(struct line_buffer *buf, off_t len);
3032

3133
#endif

vcs-svn/line_buffer.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ Functions
7676

7777
`buffer_skip_bytes`::
7878
Discards `len` bytes from the input stream (stopping early
79-
if necessary because of an error or eof).
79+
if necessary because of an error or eof). Return value is
80+
the number of bytes successfully read.
8081

8182
`buffer_reset`::
8283
Deallocates non-static buffers.

vcs-svn/repo_tree.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ static struct repo_dir *repo_clone_dir(struct repo_dir *orig_dir)
8787
return dir_pointer(new_o);
8888
}
8989

90-
static struct repo_dirent *repo_read_dirent(uint32_t revision, uint32_t *path)
90+
static struct repo_dirent *repo_read_dirent(uint32_t revision,
91+
const uint32_t *path)
9192
{
9293
uint32_t name = 0;
9394
struct repo_dirent *key = dent_pointer(dent_alloc(1));
@@ -105,7 +106,7 @@ static struct repo_dirent *repo_read_dirent(uint32_t revision, uint32_t *path)
105106
return dent;
106107
}
107108

108-
static void repo_write_dirent(uint32_t *path, uint32_t mode,
109+
static void repo_write_dirent(const uint32_t *path, uint32_t mode,
109110
uint32_t content_offset, uint32_t del)
110111
{
111112
uint32_t name, revision, dir_o = ~0, parent_dir_o = ~0;
@@ -157,7 +158,24 @@ static void repo_write_dirent(uint32_t *path, uint32_t mode,
157158
dent_remove(&dir_pointer(parent_dir_o)->entries, dent);
158159
}
159160

160-
uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst)
161+
uint32_t repo_read_path(const uint32_t *path)
162+
{
163+
uint32_t content_offset = 0;
164+
struct repo_dirent *dent = repo_read_dirent(active_commit, path);
165+
if (dent != NULL)
166+
content_offset = dent->content_offset;
167+
return content_offset;
168+
}
169+
170+
uint32_t repo_read_mode(const uint32_t *path)
171+
{
172+
struct repo_dirent *dent = repo_read_dirent(active_commit, path);
173+
if (dent == NULL)
174+
die("invalid dump: path to be modified is missing");
175+
return dent->mode;
176+
}
177+
178+
void repo_copy(uint32_t revision, const uint32_t *src, const uint32_t *dst)
161179
{
162180
uint32_t mode = 0, content_offset = 0;
163181
struct repo_dirent *src_dent;
@@ -167,28 +185,13 @@ uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst)
167185
content_offset = src_dent->content_offset;
168186
repo_write_dirent(dst, mode, content_offset, 0);
169187
}
170-
return mode;
171188
}
172189

173190
void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark)
174191
{
175192
repo_write_dirent(path, mode, blob_mark, 0);
176193
}
177194

178-
uint32_t repo_modify_path(uint32_t *path, uint32_t mode, uint32_t blob_mark)
179-
{
180-
struct repo_dirent *src_dent;
181-
src_dent = repo_read_dirent(active_commit, path);
182-
if (!src_dent)
183-
return 0;
184-
if (!blob_mark)
185-
blob_mark = src_dent->content_offset;
186-
if (!mode)
187-
mode = src_dent->mode;
188-
repo_write_dirent(path, mode, blob_mark, 0);
189-
return mode;
190-
}
191-
192195
void repo_delete(uint32_t *path)
193196
{
194197
repo_write_dirent(path, 0, 0, 1);
@@ -275,8 +278,8 @@ void repo_diff(uint32_t r1, uint32_t r2)
275278
repo_commit_root_dir(commit_pointer(r2)));
276279
}
277280

278-
void repo_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid,
279-
uint32_t url, unsigned long timestamp)
281+
void repo_commit(uint32_t revision, const char *author, char *log,
282+
const char *uuid, const char *url, unsigned long timestamp)
280283
{
281284
fast_export_commit(revision, author, log, uuid, url, timestamp);
282285
dent_commit();

vcs-svn/repo_tree.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
#define REPO_MAX_PATH_DEPTH 1000
1313

1414
uint32_t next_blob_mark(void);
15-
uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst);
15+
void repo_copy(uint32_t revision, const uint32_t *src, const uint32_t *dst);
1616
void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark);
17-
uint32_t repo_modify_path(uint32_t *path, uint32_t mode, uint32_t blob_mark);
17+
uint32_t repo_read_path(const uint32_t *path);
18+
uint32_t repo_read_mode(const uint32_t *path);
1819
void repo_delete(uint32_t *path);
19-
void repo_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid,
20-
uint32_t url, long unsigned timestamp);
20+
void repo_commit(uint32_t revision, const char *author,
21+
char *log, const char *uuid, const char *url,
22+
long unsigned timestamp);
2123
void repo_diff(uint32_t r1, uint32_t r2);
2224
void repo_init(void);
2325
void repo_reset(void);

0 commit comments

Comments
 (0)