##// END OF EJS Templates
rhg: reduce verbosity in path_encode by using a trait for writing...
Arseniy Alekseyev -
r51439:96d31efd default
parent child Browse files
Show More
@@ -36,22 +36,31 b' enum dir_state {'
36 DDEFAULT,
36 DDEFAULT,
37 }
37 }
38
38
39 trait Sink {
40 fn write_byte(&mut self, c: u8);
41 fn write_bytes(&mut self, c: &[u8]);
42 }
43
39 fn inset(bitset: &[u32; 8], c: u8) -> bool {
44 fn inset(bitset: &[u32; 8], c: u8) -> bool {
40 bitset[(c as usize) >> 5] & (1 << (c & 31)) != 0
45 bitset[(c as usize) >> 5] & (1 << (c & 31)) != 0
41 }
46 }
42
47
43 fn charcopy(dest: Option<&mut [u8]>, destlen: &mut usize, c: u8) {
48 struct Dest<'a> {
44 if let Some(slice) = dest {
49 dest: Option<&'a mut [u8]>,
45 slice[*destlen] = c
50 pub len: usize,
46 }
47 *destlen += 1
48 }
51 }
49
52
50 fn memcopy(dest: Option<&mut [u8]>, destlen: &mut usize, src: &[u8]) {
53 impl<'a> Dest<'a> {
51 if let Some(slice) = dest {
54 pub fn create(buf: &'a mut [u8]) -> Dest<'a> {
52 slice[*destlen..*destlen + src.len()].copy_from_slice(src)
55 Dest {
56 dest: Some(buf),
57 len: 0,
58 }
53 }
59 }
54 *destlen += src.len();
60
61 pub fn create_measure() -> Dest<'a> {
62 Dest { dest: None, len: 0 }
63 }
55 }
64 }
56
65
57 fn rewrap_option<'a, 'b: 'a>(
66 fn rewrap_option<'a, 'b: 'a>(
@@ -63,38 +72,49 b" fn rewrap_option<'a, 'b: 'a>("
63 }
72 }
64 }
73 }
65
74
66 fn hexencode(mut dest: Option<&mut [u8]>, destlen: &mut usize, c: u8) {
75 impl<'a> Sink for Dest<'a> {
76 fn write_byte(&mut self, c: u8) {
77 if let Some(slice) = rewrap_option(&mut self.dest) {
78 slice[self.len] = c
79 }
80 self.len += 1
81 }
82
83 fn write_bytes(&mut self, src: &[u8]) {
84 if let Some(slice) = rewrap_option(&mut self.dest) {
85 slice[self.len..self.len + src.len()].copy_from_slice(src)
86 }
87 self.len += src.len();
88 }
89 }
90
91 fn hexencode(dest: &mut impl Sink, c: u8) {
67 let hexdigit = b"0123456789abcdef";
92 let hexdigit = b"0123456789abcdef";
68 charcopy(
93 dest.write_byte(hexdigit[(c as usize) >> 4]);
69 rewrap_option(&mut dest),
94 dest.write_byte(hexdigit[(c as usize) & 15]);
70 destlen,
71 hexdigit[(c as usize) >> 4],
72 );
73 charcopy(dest, destlen, hexdigit[(c as usize) & 15]);
74 }
95 }
75
96
76 /* 3-byte escape: tilde followed by two hex digits */
97 /* 3-byte escape: tilde followed by two hex digits */
77 fn escape3(mut dest: Option<&mut [u8]>, destlen: &mut usize, c: u8) {
98 fn escape3(dest: &mut impl Sink, c: u8) {
78 charcopy(rewrap_option(&mut dest), destlen, b'~');
99 dest.write_byte(b'~');
79 hexencode(dest, destlen, c);
100 hexencode(dest, c);
80 }
101 }
81
102
82 fn encode_dir(mut dest: Option<&mut [u8]>, src: &[u8]) -> usize {
103 fn encode_dir(dest: &mut impl Sink, src: &[u8]) {
83 let mut state = dir_state::DDEFAULT;
104 let mut state = dir_state::DDEFAULT;
84 let mut i = 0;
105 let mut i = 0;
85 let mut destlen = 0;
86
106
87 while i < src.len() {
107 while i < src.len() {
88 match state {
108 match state {
89 dir_state::DDOT => match src[i] {
109 dir_state::DDOT => match src[i] {
90 b'd' | b'i' => {
110 b'd' | b'i' => {
91 state = dir_state::DHGDI;
111 state = dir_state::DHGDI;
92 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
112 dest.write_byte(src[i]);
93 i += 1;
113 i += 1;
94 }
114 }
95 b'h' => {
115 b'h' => {
96 state = dir_state::DH;
116 state = dir_state::DH;
97 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
117 dest.write_byte(src[i]);
98 i += 1;
118 i += 1;
99 }
119 }
100 _ => {
120 _ => {
@@ -104,7 +124,7 b' fn encode_dir(mut dest: Option<&mut [u8]'
104 dir_state::DH => {
124 dir_state::DH => {
105 if src[i] == b'g' {
125 if src[i] == b'g' {
106 state = dir_state::DHGDI;
126 state = dir_state::DHGDI;
107 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
127 dest.write_byte(src[i]);
108 i += 1;
128 i += 1;
109 } else {
129 } else {
110 state = dir_state::DDEFAULT;
130 state = dir_state::DDEFAULT;
@@ -112,8 +132,8 b' fn encode_dir(mut dest: Option<&mut [u8]'
112 }
132 }
113 dir_state::DHGDI => {
133 dir_state::DHGDI => {
114 if src[i] == b'/' {
134 if src[i] == b'/' {
115 memcopy(rewrap_option(&mut dest), &mut destlen, b".hg");
135 dest.write_bytes(b".hg");
116 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
136 dest.write_byte(src[i]);
117 i += 1;
137 i += 1;
118 }
138 }
119 state = dir_state::DDEFAULT;
139 state = dir_state::DDEFAULT;
@@ -122,66 +142,64 b' fn encode_dir(mut dest: Option<&mut [u8]'
122 if src[i] == b'.' {
142 if src[i] == b'.' {
123 state = dir_state::DDOT
143 state = dir_state::DDOT
124 }
144 }
125 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
145 dest.write_byte(src[i]);
126 i += 1;
146 i += 1;
127 }
147 }
128 }
148 }
129 }
149 }
130 destlen
131 }
150 }
132
151
133 fn _encode(
152 fn _encode(
134 twobytes: &[u32; 8],
153 twobytes: &[u32; 8],
135 onebyte: &[u32; 8],
154 onebyte: &[u32; 8],
136 mut dest: Option<&mut [u8]>,
155 dest: &mut impl Sink,
137 src: &[u8],
156 src: &[u8],
138 encodedir: bool,
157 encodedir: bool,
139 ) -> usize {
158 ) {
140 let mut state = path_state::START;
159 let mut state = path_state::START;
141 let mut i = 0;
160 let mut i = 0;
142 let mut destlen = 0;
143 let len = src.len();
161 let len = src.len();
144
162
145 while i < len {
163 while i < len {
146 match state {
164 match state {
147 path_state::START => match src[i] {
165 path_state::START => match src[i] {
148 b'/' => {
166 b'/' => {
149 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
167 dest.write_byte(src[i]);
150 i += 1;
168 i += 1;
151 }
169 }
152 b'.' => {
170 b'.' => {
153 state = path_state::LDOT;
171 state = path_state::LDOT;
154 escape3(rewrap_option(&mut dest), &mut destlen, src[i]);
172 escape3(dest, src[i]);
155 i += 1;
173 i += 1;
156 }
174 }
157 b' ' => {
175 b' ' => {
158 state = path_state::DEFAULT;
176 state = path_state::DEFAULT;
159 escape3(rewrap_option(&mut dest), &mut destlen, src[i]);
177 escape3(dest, src[i]);
160 i += 1;
178 i += 1;
161 }
179 }
162 b'a' => {
180 b'a' => {
163 state = path_state::A;
181 state = path_state::A;
164 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
182 dest.write_byte(src[i]);
165 i += 1;
183 i += 1;
166 }
184 }
167 b'c' => {
185 b'c' => {
168 state = path_state::C;
186 state = path_state::C;
169 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
187 dest.write_byte(src[i]);
170 i += 1;
188 i += 1;
171 }
189 }
172 b'l' => {
190 b'l' => {
173 state = path_state::L;
191 state = path_state::L;
174 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
192 dest.write_byte(src[i]);
175 i += 1;
193 i += 1;
176 }
194 }
177 b'n' => {
195 b'n' => {
178 state = path_state::N;
196 state = path_state::N;
179 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
197 dest.write_byte(src[i]);
180 i += 1;
198 i += 1;
181 }
199 }
182 b'p' => {
200 b'p' => {
183 state = path_state::P;
201 state = path_state::P;
184 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
202 dest.write_byte(src[i]);
185 i += 1;
203 i += 1;
186 }
204 }
187 _ => {
205 _ => {
@@ -191,7 +209,7 b' fn _encode('
191 path_state::A => {
209 path_state::A => {
192 if src[i] == b'u' {
210 if src[i] == b'u' {
193 state = path_state::AU;
211 state = path_state::AU;
194 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
212 dest.write_byte(src[i]);
195 i += 1;
213 i += 1;
196 } else {
214 } else {
197 state = path_state::DEFAULT;
215 state = path_state::DEFAULT;
@@ -208,18 +226,14 b' fn _encode('
208 path_state::THIRD => {
226 path_state::THIRD => {
209 state = path_state::DEFAULT;
227 state = path_state::DEFAULT;
210 match src[i] {
228 match src[i] {
211 b'.' | b'/' | b'\0' => escape3(
229 b'.' | b'/' | b'\0' => escape3(dest, src[i - 1]),
212 rewrap_option(&mut dest),
213 &mut destlen,
214 src[i - 1],
215 ),
216 _ => i -= 1,
230 _ => i -= 1,
217 }
231 }
218 }
232 }
219 path_state::C => {
233 path_state::C => {
220 if src[i] == b'o' {
234 if src[i] == b'o' {
221 state = path_state::CO;
235 state = path_state::CO;
222 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
236 dest.write_byte(src[i]);
223 i += 1;
237 i += 1;
224 } else {
238 } else {
225 state = path_state::DEFAULT;
239 state = path_state::DEFAULT;
@@ -242,41 +256,25 b' fn _encode('
242 i += 1;
256 i += 1;
243 } else {
257 } else {
244 state = path_state::DEFAULT;
258 state = path_state::DEFAULT;
245 charcopy(
259 dest.write_byte(src[i - 1]);
246 rewrap_option(&mut dest),
247 &mut destlen,
248 src[i - 1],
249 );
250 }
260 }
251 }
261 }
252 path_state::COMLPTn => {
262 path_state::COMLPTn => {
253 state = path_state::DEFAULT;
263 state = path_state::DEFAULT;
254 match src[i] {
264 match src[i] {
255 b'.' | b'/' | b'\0' => {
265 b'.' | b'/' | b'\0' => {
256 escape3(
266 escape3(dest, src[i - 2]);
257 rewrap_option(&mut dest),
267 dest.write_byte(src[i - 1]);
258 &mut destlen,
259 src[i - 2],
260 );
261 charcopy(
262 rewrap_option(&mut dest),
263 &mut destlen,
264 src[i - 1],
265 );
266 }
268 }
267 _ => {
269 _ => {
268 memcopy(
270 dest.write_bytes(&src[i - 2..i]);
269 rewrap_option(&mut dest),
270 &mut destlen,
271 &src[i - 2..i],
272 );
273 }
271 }
274 }
272 }
275 }
273 }
276 path_state::L => {
274 path_state::L => {
277 if src[i] == b'p' {
275 if src[i] == b'p' {
278 state = path_state::LP;
276 state = path_state::LP;
279 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
277 dest.write_byte(src[i]);
280 i += 1;
278 i += 1;
281 } else {
279 } else {
282 state = path_state::DEFAULT;
280 state = path_state::DEFAULT;
@@ -293,7 +291,7 b' fn _encode('
293 path_state::N => {
291 path_state::N => {
294 if src[i] == b'u' {
292 if src[i] == b'u' {
295 state = path_state::NU;
293 state = path_state::NU;
296 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
294 dest.write_byte(src[i]);
297 i += 1;
295 i += 1;
298 } else {
296 } else {
299 state = path_state::DEFAULT;
297 state = path_state::DEFAULT;
@@ -310,7 +308,7 b' fn _encode('
310 path_state::P => {
308 path_state::P => {
311 if src[i] == b'r' {
309 if src[i] == b'r' {
312 state = path_state::PR;
310 state = path_state::PR;
313 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
311 dest.write_byte(src[i]);
314 i += 1;
312 i += 1;
315 } else {
313 } else {
316 state = path_state::DEFAULT;
314 state = path_state::DEFAULT;
@@ -327,12 +325,12 b' fn _encode('
327 path_state::LDOT => match src[i] {
325 path_state::LDOT => match src[i] {
328 b'd' | b'i' => {
326 b'd' | b'i' => {
329 state = path_state::HGDI;
327 state = path_state::HGDI;
330 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
328 dest.write_byte(src[i]);
331 i += 1;
329 i += 1;
332 }
330 }
333 b'h' => {
331 b'h' => {
334 state = path_state::H;
332 state = path_state::H;
335 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
333 dest.write_byte(src[i]);
336 i += 1;
334 i += 1;
337 }
335 }
338 _ => {
336 _ => {
@@ -342,30 +340,30 b' fn _encode('
342 path_state::DOT => match src[i] {
340 path_state::DOT => match src[i] {
343 b'/' | b'\0' => {
341 b'/' | b'\0' => {
344 state = path_state::START;
342 state = path_state::START;
345 memcopy(rewrap_option(&mut dest), &mut destlen, b"~2e");
343 dest.write_bytes(b"~2e");
346 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
344 dest.write_byte(src[i]);
347 i += 1;
345 i += 1;
348 }
346 }
349 b'd' | b'i' => {
347 b'd' | b'i' => {
350 state = path_state::HGDI;
348 state = path_state::HGDI;
351 charcopy(rewrap_option(&mut dest), &mut destlen, b'.');
349 dest.write_byte(b'.');
352 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
350 dest.write_byte(src[i]);
353 i += 1;
351 i += 1;
354 }
352 }
355 b'h' => {
353 b'h' => {
356 state = path_state::H;
354 state = path_state::H;
357 memcopy(rewrap_option(&mut dest), &mut destlen, b".h");
355 dest.write_bytes(b".h");
358 i += 1;
356 i += 1;
359 }
357 }
360 _ => {
358 _ => {
361 state = path_state::DEFAULT;
359 state = path_state::DEFAULT;
362 charcopy(rewrap_option(&mut dest), &mut destlen, b'.');
360 dest.write_byte(b'.');
363 }
361 }
364 },
362 },
365 path_state::H => {
363 path_state::H => {
366 if src[i] == b'g' {
364 if src[i] == b'g' {
367 state = path_state::HGDI;
365 state = path_state::HGDI;
368 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
366 dest.write_byte(src[i]);
369 i += 1;
367 i += 1;
370 } else {
368 } else {
371 state = path_state::DEFAULT;
369 state = path_state::DEFAULT;
@@ -375,13 +373,9 b' fn _encode('
375 if src[i] == b'/' {
373 if src[i] == b'/' {
376 state = path_state::START;
374 state = path_state::START;
377 if encodedir {
375 if encodedir {
378 memcopy(
376 dest.write_bytes(b".hg");
379 rewrap_option(&mut dest),
380 &mut destlen,
381 b".hg",
382 );
383 }
377 }
384 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
378 dest.write_byte(src[i]);
385 i += 1
379 i += 1
386 } else {
380 } else {
387 state = path_state::DEFAULT;
381 state = path_state::DEFAULT;
@@ -390,18 +384,18 b' fn _encode('
390 path_state::SPACE => match src[i] {
384 path_state::SPACE => match src[i] {
391 b'/' | b'\0' => {
385 b'/' | b'\0' => {
392 state = path_state::START;
386 state = path_state::START;
393 memcopy(rewrap_option(&mut dest), &mut destlen, b"~20");
387 dest.write_bytes(b"~20");
394 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
388 dest.write_byte(src[i]);
395 i += 1;
389 i += 1;
396 }
390 }
397 _ => {
391 _ => {
398 state = path_state::DEFAULT;
392 state = path_state::DEFAULT;
399 charcopy(rewrap_option(&mut dest), &mut destlen, b' ');
393 dest.write_byte(b' ');
400 }
394 }
401 },
395 },
402 path_state::DEFAULT => {
396 path_state::DEFAULT => {
403 while i != len && inset(onebyte, src[i]) {
397 while i != len && inset(onebyte, src[i]) {
404 charcopy(rewrap_option(&mut dest), &mut destlen, src[i]);
398 dest.write_byte(src[i]);
405 i += 1;
399 i += 1;
406 }
400 }
407 if i == len {
401 if i == len {
@@ -418,17 +412,13 b' fn _encode('
418 }
412 }
419 b'/' => {
413 b'/' => {
420 state = path_state::START;
414 state = path_state::START;
421 charcopy(rewrap_option(&mut dest), &mut destlen, b'/');
415 dest.write_byte(b'/');
422 i += 1;
416 i += 1;
423 }
417 }
424 _ => {
418 _ => {
425 if inset(onebyte, src[i]) {
419 if inset(onebyte, src[i]) {
426 loop {
420 loop {
427 charcopy(
421 dest.write_byte(src[i]);
428 rewrap_option(&mut dest),
429 &mut destlen,
430 src[i],
431 );
432 i += 1;
422 i += 1;
433 if !(i < len && inset(onebyte, src[i])) {
423 if !(i < len && inset(onebyte, src[i])) {
434 break;
424 break;
@@ -437,22 +427,14 b' fn _encode('
437 } else if inset(twobytes, src[i]) {
427 } else if inset(twobytes, src[i]) {
438 let c = src[i];
428 let c = src[i];
439 i += 1;
429 i += 1;
440 charcopy(
430 dest.write_byte(b'_');
441 rewrap_option(&mut dest),
431 dest.write_byte(if c == b'_' {
442 &mut destlen,
432 b'_'
443 b'_',
433 } else {
444 );
434 c + 32
445 charcopy(
435 });
446 rewrap_option(&mut dest),
447 &mut destlen,
448 if c == b'_' { b'_' } else { c + 32 },
449 );
450 } else {
436 } else {
451 escape3(
437 escape3(dest, src[i]);
452 rewrap_option(&mut dest),
453 &mut destlen,
454 src[i],
455 );
456 i += 1;
438 i += 1;
457 }
439 }
458 }
440 }
@@ -464,17 +446,13 b' fn _encode('
464 path_state::START => (),
446 path_state::START => (),
465 path_state::A => (),
447 path_state::A => (),
466 path_state::AU => (),
448 path_state::AU => (),
467 path_state::THIRD => {
449 path_state::THIRD => escape3(dest, src[i - 1]),
468 escape3(rewrap_option(&mut dest), &mut destlen, src[i - 1])
469 }
470 path_state::C => (),
450 path_state::C => (),
471 path_state::CO => (),
451 path_state::CO => (),
472 path_state::COMLPT => {
452 path_state::COMLPT => dest.write_byte(src[i - 1]),
473 charcopy(rewrap_option(&mut dest), &mut destlen, src[i - 1])
474 }
475 path_state::COMLPTn => {
453 path_state::COMLPTn => {
476 escape3(rewrap_option(&mut dest), &mut destlen, src[i - 2]);
454 escape3(dest, src[i - 2]);
477 charcopy(rewrap_option(&mut dest), &mut destlen, src[i - 1]);
455 dest.write_byte(src[i - 1]);
478 }
456 }
479 path_state::L => (),
457 path_state::L => (),
480 path_state::LP => (),
458 path_state::LP => (),
@@ -484,19 +462,18 b' fn _encode('
484 path_state::PR => (),
462 path_state::PR => (),
485 path_state::LDOT => (),
463 path_state::LDOT => (),
486 path_state::DOT => {
464 path_state::DOT => {
487 memcopy(rewrap_option(&mut dest), &mut destlen, b"~2e");
465 dest.write_bytes(b"~2e");
488 }
466 }
489 path_state::H => (),
467 path_state::H => (),
490 path_state::HGDI => (),
468 path_state::HGDI => (),
491 path_state::SPACE => {
469 path_state::SPACE => {
492 memcopy(rewrap_option(&mut dest), &mut destlen, b"~20");
470 dest.write_bytes(b"~20");
493 }
471 }
494 path_state::DEFAULT => (),
472 path_state::DEFAULT => (),
495 };
473 }
496 destlen
497 }
474 }
498
475
499 fn basic_encode(dest: Option<&mut [u8]>, src: &[u8]) -> usize {
476 fn basic_encode(dest: &mut impl Sink, src: &[u8]) {
500 let twobytes: [u32; 8] = [0, 0, 0x87ff_fffe, 0, 0, 0, 0, 0];
477 let twobytes: [u32; 8] = [0, 0, 0x87ff_fffe, 0, 0, 0, 0, 0];
501 let onebyte: [u32; 8] =
478 let onebyte: [u32; 8] =
502 [1, 0x2bff_3bfa, 0x6800_0001, 0x2fff_ffff, 0, 0, 0, 0];
479 [1, 0x2bff_3bfa, 0x6800_0001, 0x2fff_ffff, 0, 0, 0, 0];
@@ -505,24 +482,22 b' fn basic_encode(dest: Option<&mut [u8]>,'
505
482
506 const MAXSTOREPATHLEN: usize = 120;
483 const MAXSTOREPATHLEN: usize = 120;
507
484
508 fn lower_encode(mut dest: Option<&mut [u8]>, src: &[u8]) -> usize {
485 fn lower_encode(dest: &mut impl Sink, src: &[u8]) {
509 let onebyte: [u32; 8] =
486 let onebyte: [u32; 8] =
510 [1, 0x2bff_fbfb, 0xe800_0001, 0x2fff_ffff, 0, 0, 0, 0];
487 [1, 0x2bff_fbfb, 0xe800_0001, 0x2fff_ffff, 0, 0, 0, 0];
511 let lower: [u32; 8] = [0, 0, 0x07ff_fffe, 0, 0, 0, 0, 0];
488 let lower: [u32; 8] = [0, 0, 0x07ff_fffe, 0, 0, 0, 0, 0];
512 let mut destlen = 0;
513 for c in src {
489 for c in src {
514 if inset(&onebyte, *c) {
490 if inset(&onebyte, *c) {
515 charcopy(rewrap_option(&mut dest), &mut destlen, *c)
491 dest.write_byte(*c)
516 } else if inset(&lower, *c) {
492 } else if inset(&lower, *c) {
517 charcopy(rewrap_option(&mut dest), &mut destlen, *c + 32)
493 dest.write_byte(*c + 32)
518 } else {
494 } else {
519 escape3(rewrap_option(&mut dest), &mut destlen, *c)
495 escape3(dest, *c)
520 }
496 }
521 }
497 }
522 destlen
523 }
498 }
524
499
525 fn aux_encode(dest: Option<&mut [u8]>, src: &[u8]) -> usize {
500 fn aux_encode(dest: &mut impl Sink, src: &[u8]) {
526 let twobytes = [0; 8];
501 let twobytes = [0; 8];
527 let onebyte: [u32; 8] = [!0, 0xffff_3ffe, !0, !0, !0, !0, !0, !0];
502 let onebyte: [u32; 8] = [!0, 0xffff_3ffe, !0, !0, !0, !0, !0, !0];
528 _encode(&twobytes, &onebyte, dest, src, false)
503 _encode(&twobytes, &onebyte, dest, src, false)
@@ -531,7 +506,6 b' fn aux_encode(dest: Option<&mut [u8]>, s'
531 fn hash_mangle(src: &[u8], sha: &[u8]) -> Vec<u8> {
506 fn hash_mangle(src: &[u8], sha: &[u8]) -> Vec<u8> {
532 let dirprefixlen = 8;
507 let dirprefixlen = 8;
533 let maxshortdirslen = 68;
508 let maxshortdirslen = 68;
534 let mut destlen = 0;
535
509
536 let last_slash = src.iter().rposition(|b| *b == b'/');
510 let last_slash = src.iter().rposition(|b| *b == b'/');
537 let last_dot: Option<usize> = {
511 let last_dot: Option<usize> = {
@@ -539,25 +513,23 b' fn hash_mangle(src: &[u8], sha: &[u8]) -'
539 src[s..].iter().rposition(|b| *b == b'.').map(|i| i + s)
513 src[s..].iter().rposition(|b| *b == b'.').map(|i| i + s)
540 };
514 };
541
515
542 let mut dest = vec![0; MAXSTOREPATHLEN];
516 let mut dest_vec = vec![0; MAXSTOREPATHLEN];
543 memcopy(Some(&mut dest), &mut destlen, b"dh/");
517 let mut dest = Dest::create(&mut dest_vec);
518 dest.write_bytes(b"dh/");
544
519
545 if let Some(last_slash) = last_slash {
520 if let Some(last_slash) = last_slash {
546 for slice in src[..last_slash].split(|b| *b == b'/') {
521 for slice in src[..last_slash].split(|b| *b == b'/') {
547 let slice = &slice[..std::cmp::min(slice.len(), dirprefixlen)];
522 let slice = &slice[..std::cmp::min(slice.len(), dirprefixlen)];
548 if destlen + slice.len() > maxshortdirslen + 3 {
523 if dest.len + slice.len() > maxshortdirslen + 3 {
549 break;
524 break;
550 } else {
525 } else {
551 memcopy(Some(&mut dest), &mut destlen, slice);
526 dest.write_bytes(slice);
552 if dest[destlen - 1] == b'.' || dest[destlen - 1] == b' ' {
553 dest[destlen - 1] = b'_'
554 }
555 }
527 }
556 charcopy(Some(&mut dest), &mut destlen, b'/');
528 dest.write_byte(b'/');
557 }
529 }
558 }
530 }
559
531
560 let used = destlen + 40 + {
532 let used = dest.len + 40 + {
561 if let Some(l) = last_dot {
533 if let Some(l) = last_dot {
562 src.len() - l
534 src.len() - l
563 } else {
535 } else {
@@ -577,46 +549,51 b' fn hash_mangle(src: &[u8], sha: &[u8]) -'
577 Some(l) => l + 1,
549 Some(l) => l + 1,
578 None => 0,
550 None => 0,
579 };
551 };
580 memcopy(
552 dest.write_bytes(&src[start..][..basenamelen])
581 Some(&mut dest),
582 &mut destlen,
583 &src[start..][..basenamelen],
584 )
585 }
553 }
586 }
554 }
587 for c in sha {
555 for c in sha {
588 hexencode(Some(&mut dest), &mut destlen, *c);
556 hexencode(&mut dest, *c);
589 }
557 }
590 if let Some(l) = last_dot {
558 if let Some(l) = last_dot {
591 memcopy(Some(&mut dest), &mut destlen, &src[l..]);
559 dest.write_bytes(&src[l..]);
592 }
560 }
593 if destlen == dest.len() {
561 let destlen = dest.len;
594 dest
562 if destlen == dest_vec.len() {
563 dest_vec
595 } else {
564 } else {
596 // sometimes the path are shorter than MAXSTOREPATHLEN
565 // sometimes the path are shorter than MAXSTOREPATHLEN
597 dest[..destlen].to_vec()
566 dest_vec[..destlen].to_vec()
598 }
567 }
599 }
568 }
600
569
601 const MAXENCODE: usize = 4096 * 4;
570 const MAXENCODE: usize = 4096 * 4;
602 fn hash_encode(src: &[u8]) -> Vec<u8> {
571 fn hash_encode(src: &[u8]) -> Vec<u8> {
603 let dired = &mut [0; MAXENCODE];
572 let dired = &mut [0; MAXENCODE];
573 let mut dired_dest = Dest::create(dired);
604 let lowered = &mut [0; MAXENCODE];
574 let lowered = &mut [0; MAXENCODE];
575 let mut lowered_dest = Dest::create(lowered);
605 let auxed = &mut [0; MAXENCODE];
576 let auxed = &mut [0; MAXENCODE];
577 let mut auxed_dest = Dest::create(auxed);
606 let baselen = (src.len() - 5) * 3;
578 let baselen = (src.len() - 5) * 3;
607 if baselen >= MAXENCODE {
579 if baselen >= MAXENCODE {
608 panic!("path_encode::hash_encore: string too long: {}", baselen)
580 panic!("path_encode::hash_encore: string too long: {}", baselen)
609 };
581 };
610 let dirlen = encode_dir(Some(&mut dired[..]), src);
582 encode_dir(&mut dired_dest, src);
583 let dirlen = dired_dest.len;
611 let sha = Sha1::digest(&dired[..dirlen]);
584 let sha = Sha1::digest(&dired[..dirlen]);
612 let lowerlen = lower_encode(Some(&mut lowered[..]), &dired[..dirlen][5..]);
585 lower_encode(&mut lowered_dest, &dired[..dirlen][5..]);
613 let auxlen = aux_encode(Some(&mut auxed[..]), &lowered[..lowerlen]);
586 let lowerlen = lowered_dest.len;
587 aux_encode(&mut auxed_dest, &lowered[..lowerlen]);
588 let auxlen = auxed_dest.len;
614 hash_mangle(&auxed[..auxlen], &sha)
589 hash_mangle(&auxed[..auxlen], &sha)
615 }
590 }
616
591
617 pub fn path_encode(path: &[u8]) -> Vec<u8> {
592 pub fn path_encode(path: &[u8]) -> Vec<u8> {
618 let newlen = if path.len() <= MAXSTOREPATHLEN {
593 let newlen = if path.len() <= MAXSTOREPATHLEN {
619 basic_encode(None, path)
594 let mut measure = Dest::create_measure();
595 basic_encode(&mut measure, path);
596 measure.len
620 } else {
597 } else {
621 MAXSTOREPATHLEN + 1
598 MAXSTOREPATHLEN + 1
622 };
599 };
@@ -625,7 +602,9 b' pub fn path_encode(path: &[u8]) -> Vec<u'
625 path.to_vec()
602 path.to_vec()
626 } else {
603 } else {
627 let mut res = vec![0; newlen];
604 let mut res = vec![0; newlen];
628 basic_encode(Some(&mut res), path);
605 let mut dest = Dest::create(&mut res);
606 basic_encode(&mut dest, path);
607 assert!(dest.len == newlen);
629 res
608 res
630 }
609 }
631 } else {
610 } else {
General Comments 0
You need to be logged in to leave comments. Login now