Skip to content

Commit 753b683

Browse files
committed
More slice use in vec, io, str, ebml, metadata encoder and decoder.
1 parent 90c1b46 commit 753b683

File tree

7 files changed

+220
-118
lines changed

7 files changed

+220
-118
lines changed

src/libcore/io.rs

Lines changed: 111 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -297,23 +297,22 @@ enum fileflag { append, create, truncate, no_flag, }
297297
// FIXME: eventually u64
298298
// #2004
299299
iface writer {
300-
fn write([const u8]);
300+
fn write([const u8]/&);
301301
fn seek(int, seek_style);
302302
fn tell() -> uint;
303303
fn flush() -> int;
304304
}
305305

306306
impl <T: writer, C> of writer for {base: T, cleanup: C} {
307-
fn write(bs: [const u8]) { self.base.write(bs); }
307+
fn write(bs: [const u8]/&) { self.base.write(bs); }
308308
fn seek(off: int, style: seek_style) { self.base.seek(off, style); }
309309
fn tell() -> uint { self.base.tell() }
310310
fn flush() -> int { self.base.flush() }
311311
}
312312

313313
impl of writer for *libc::FILE {
314-
fn write(v: [const u8]) unsafe {
315-
let len = vec::len(v);
316-
vec::as_buf(v) {|vbuf|
314+
fn write(v: [const u8]/&) unsafe {
315+
vec::unpack_slice(v) {|vbuf, len|
317316
let nout = libc::fwrite(vbuf as *c_void, len, 1u, self);
318317
if nout < 1 as size_t {
319318
#error("error writing buffer");
@@ -339,10 +338,9 @@ fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer {
339338
}
340339

341340
impl of writer for fd_t {
342-
fn write(v: [const u8]) unsafe {
343-
let len = vec::len(v);
341+
fn write(v: [const u8]/&) unsafe {
344342
let mut count = 0u;
345-
vec::as_buf(v) {|vbuf|
343+
vec::unpack_slice(v) {|vbuf, len|
346344
while count < len {
347345
let vb = ptr::offset(vbuf, count) as *c_void;
348346
let nout = libc::write(self, vb, len);
@@ -408,26 +406,66 @@ fn mk_file_writer(path: str, flags: [fileflag])
408406
}
409407
}
410408

411-
fn u64_to_le_bytes(n: u64, size: uint) -> [u8] {
412-
let mut bytes: [u8] = [], i = size, n = n;
413-
while i > 0u {
414-
bytes += [(n & 255_u64) as u8];
415-
n >>= 8_u64;
416-
i -= 1u;
409+
fn u64_to_le_bytes<T>(n: u64, size: uint, f: fn([u8]/&) -> T) -> T {
410+
assert size <= 8u;
411+
alt size {
412+
1u { f([n as u8]/&) }
413+
2u { f([n as u8,
414+
(n >> 8) as u8]/&) }
415+
4u { f([n as u8,
416+
(n >> 8) as u8,
417+
(n >> 16) as u8,
418+
(n >> 24) as u8]/&) }
419+
8u { f([n as u8,
420+
(n >> 8) as u8,
421+
(n >> 16) as u8,
422+
(n >> 24) as u8,
423+
(n >> 32) as u8,
424+
(n >> 40) as u8,
425+
(n >> 48) as u8,
426+
(n >> 56) as u8]/&) }
427+
_ {
428+
429+
let mut bytes: [u8] = [], i = size, n = n;
430+
while i > 0u {
431+
bytes += [(n & 255_u64) as u8];
432+
n >>= 8_u64;
433+
i -= 1u;
434+
}
435+
f(bytes)
436+
}
417437
}
418-
ret bytes;
419438
}
420439

421-
fn u64_to_be_bytes(n: u64, size: uint) -> [u8] {
440+
fn u64_to_be_bytes<T>(n: u64, size: uint, f: fn([u8]/&) -> T) -> T {
422441
assert size <= 8u;
423-
let mut bytes: [u8] = [];
424-
let mut i = size;
425-
while i > 0u {
426-
let shift = ((i - 1u) * 8u) as u64;
427-
bytes += [(n >> shift) as u8];
428-
i -= 1u;
442+
alt size {
443+
1u { f([n as u8]/&) }
444+
2u { f([(n >> 8) as u8,
445+
n as u8]/&) }
446+
4u { f([(n >> 24) as u8,
447+
(n >> 16) as u8,
448+
(n >> 8) as u8,
449+
n as u8]/&) }
450+
8u { f([(n >> 56) as u8,
451+
(n >> 48) as u8,
452+
(n >> 40) as u8,
453+
(n >> 32) as u8,
454+
(n >> 24) as u8,
455+
(n >> 16) as u8,
456+
(n >> 8) as u8,
457+
n as u8]/&) }
458+
_ {
459+
let mut bytes: [u8] = [];
460+
let mut i = size;
461+
while i > 0u {
462+
let shift = ((i - 1u) * 8u) as u64;
463+
bytes += [(n >> shift) as u8];
464+
i -= 1u;
465+
}
466+
f(bytes)
467+
}
429468
}
430-
ret bytes;
431469
}
432470

433471
fn u64_from_be_bytes(data: [u8], start: uint, size: uint) -> u64 {
@@ -448,45 +486,67 @@ impl writer_util for writer {
448486
if ch as uint < 128u {
449487
self.write([ch as u8]);
450488
} else {
451-
self.write(str::bytes(str::from_char(ch)));
489+
self.write_str(str::from_char(ch));
452490
}
453491
}
454-
fn write_str(s: str) { self.write(str::bytes(s)); }
455-
fn write_line(s: str) { self.write(str::bytes(s + "\n")); }
456-
fn write_int(n: int) { self.write(str::bytes(int::to_str(n, 10u))); }
457-
fn write_uint(n: uint) { self.write(str::bytes(uint::to_str(n, 10u))); }
492+
fn write_str(s: str/&) { str::byte_slice(s) {|v| self.write(v); } }
493+
fn write_line(s: str/&) {
494+
self.write_str(s);
495+
self.write_str("\n"/&);
496+
}
497+
fn write_int(n: int) { self.write_str(int::to_str(n, 10u)); }
498+
fn write_uint(n: uint) { self.write_str(uint::to_str(n, 10u)); }
458499

459500
fn write_le_uint(n: uint, size: uint) {
460-
self.write(u64_to_le_bytes(n as u64, size));
501+
u64_to_le_bytes(n as u64, size) {|v| self.write(v); }
461502
}
462503
fn write_le_int(n: int, size: uint) {
463-
self.write(u64_to_le_bytes(n as u64, size));
504+
u64_to_le_bytes(n as u64, size) {|v| self.write(v); }
464505
}
465-
466506
fn write_be_uint(n: uint, size: uint) {
467-
self.write(u64_to_be_bytes(n as u64, size));
507+
u64_to_be_bytes(n as u64, size) {|v| self.write(v); }
468508
}
469509
fn write_be_int(n: int, size: uint) {
470-
self.write(u64_to_be_bytes(n as u64, size));
510+
u64_to_be_bytes(n as u64, size) {|v| self.write(v); }
511+
}
512+
fn write_be_u64(n: u64) {
513+
u64_to_be_bytes(n, 8u) {|v| self.write(v); }
514+
}
515+
fn write_be_u32(n: u32) {
516+
u64_to_be_bytes(n as u64, 4u) {|v| self.write(v); }
517+
}
518+
fn write_be_u16(n: u16) {
519+
u64_to_be_bytes(n as u64, 2u) {|v| self.write(v); }
520+
}
521+
fn write_be_i64(n: i64) {
522+
u64_to_be_bytes(n as u64, 8u) {|v| self.write(v); }
523+
}
524+
fn write_be_i32(n: i32) {
525+
u64_to_be_bytes(n as u64, 4u) {|v| self.write(v); }
526+
}
527+
fn write_be_i16(n: i16) {
528+
u64_to_be_bytes(n as u64, 2u) {|v| self.write(v); }
529+
}
530+
fn write_le_u64(n: u64) {
531+
u64_to_le_bytes(n, 8u) {|v| self.write(v); }
532+
}
533+
fn write_le_u32(n: u32) {
534+
u64_to_le_bytes(n as u64, 4u) {|v| self.write(v); }
535+
}
536+
fn write_le_u16(n: u16) {
537+
u64_to_le_bytes(n as u64, 2u) {|v| self.write(v); }
538+
}
539+
fn write_le_i64(n: i64) {
540+
u64_to_le_bytes(n as u64, 8u) {|v| self.write(v); }
541+
}
542+
fn write_le_i32(n: i32) {
543+
u64_to_le_bytes(n as u64, 4u) {|v| self.write(v); }
544+
}
545+
fn write_le_i16(n: i16) {
546+
u64_to_le_bytes(n as u64, 2u) {|v| self.write(v); }
471547
}
472548

473-
fn write_be_u64(n: u64) { self.write(u64_to_be_bytes(n, 8u)); }
474-
fn write_be_u32(n: u32) { self.write(u64_to_be_bytes(n as u64, 4u)); }
475-
fn write_be_u16(n: u16) { self.write(u64_to_be_bytes(n as u64, 2u)); }
476-
477-
fn write_be_i64(n: i64) { self.write(u64_to_be_bytes(n as u64, 8u)); }
478-
fn write_be_i32(n: i32) { self.write(u64_to_be_bytes(n as u64, 4u)); }
479-
fn write_be_i16(n: i16) { self.write(u64_to_be_bytes(n as u64, 2u)); }
480-
481-
fn write_le_u64(n: u64) { self.write(u64_to_le_bytes(n, 8u)); }
482-
fn write_le_u32(n: u32) { self.write(u64_to_le_bytes(n as u64, 4u)); }
483-
fn write_le_u16(n: u16) { self.write(u64_to_le_bytes(n as u64, 2u)); }
484-
485-
fn write_le_i64(n: i64) { self.write(u64_to_le_bytes(n as u64, 8u)); }
486-
fn write_le_i32(n: i32) { self.write(u64_to_le_bytes(n as u64, 4u)); }
487-
fn write_le_i16(n: i16) { self.write(u64_to_le_bytes(n as u64, 2u)); }
488-
489-
fn write_u8(n: u8) { self.write([n]) }
549+
fn write_u8(n: u8) { self.write([n]/&) }
490550
}
491551

492552
fn file_writer(path: str, flags: [fileflag]) -> result<writer, str> {
@@ -518,7 +578,7 @@ type mem_buffer = @{mut buf: [mut u8],
518578
mut pos: uint};
519579

520580
impl of writer for mem_buffer {
521-
fn write(v: [const u8]) {
581+
fn write(v: [const u8]/&) {
522582
// Fast path.
523583
if self.pos == vec::len(self.buf) {
524584
for vec::each(v) {|b| self.buf += [mut b]; }

src/libcore/str.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export
3333

3434
// Transforming strings
3535
bytes,
36+
byte_slice,
3637
chars,
3738
substr,
3839
slice,
@@ -323,6 +324,16 @@ fn bytes(s: str) -> [u8] unsafe {
323324
ret v;
324325
}
325326

327+
#[doc = "
328+
Work with the string as a byte slice, not including trailing null.
329+
"]
330+
#[inline(always)]
331+
fn byte_slice<T>(s: str/&, f: fn([u8]/&) -> T) -> T unsafe {
332+
unpack_slice(s) {|p,n|
333+
vec::unsafe::form_slice(p, n-1u, f)
334+
}
335+
}
336+
326337
#[doc = "Convert a string to a vector of characters"]
327338
fn chars(s: str) -> [char] {
328339
let mut buf = [], i = 0u;
@@ -1549,6 +1560,7 @@ length of the string. This is to permit probing the byte past the
15491560
indexable area for a null byte, as is the case in slices pointing
15501561
to full strings, or suffixes of them.
15511562
"]
1563+
#[inline(always)]
15521564
fn unpack_slice<T>(s: str/&, f: fn(*u8, uint) -> T) -> T unsafe {
15531565
let v : *(*u8,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
15541566
let (buf,len) = *v;

src/libcore/vec.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,8 @@ fn capacity<T>(&&v: [const T]) -> uint unsafe {
150150

151151
#[doc = "Returns the length of a vector"]
152152
#[inline(always)]
153-
pure fn len<T>(&&v: [const T]) -> uint unsafe {
154-
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
155-
(**repr).fill / sys::size_of::<T>()
153+
pure fn len<T>(&&v: [const T]/&) -> uint unsafe {
154+
unpack_slice(v) {|_p, len| len}
156155
}
157156

158157
#[doc = "
@@ -823,27 +822,31 @@ fn iter_between<T>(v: [const T], start: uint, end: uint, f: fn(T)) {
823822
Iterates over a vector, with option to break
824823
"]
825824
#[inline(always)]
826-
fn each<T>(v: [const T], f: fn(T) -> bool) unsafe {
827-
let mut n = len(v);
828-
let mut p = ptr::offset(unsafe::to_ptr(v), 0u);
829-
while n > 0u {
830-
if !f(*p) { break; }
831-
p = ptr::offset(p, 1u);
832-
n -= 1u;
825+
fn each<T>(v: [const T]/&, f: fn(T) -> bool) unsafe {
826+
vec::unpack_slice(v) {|p, n|
827+
let mut n = n;
828+
let mut p = p;
829+
while n > 0u {
830+
if !f(*p) { break; }
831+
p = ptr::offset(p, 1u);
832+
n -= 1u;
833+
}
833834
}
834835
}
835836

836837
#[doc = "
837838
Iterates over a vector's elements and indices
838839
"]
839840
#[inline(always)]
840-
fn eachi<T>(v: [const T], f: fn(uint, T) -> bool) unsafe {
841-
let mut i = 0u, l = len(v);
842-
let mut p = ptr::offset(unsafe::to_ptr(v), 0u);
843-
while i < l {
844-
if !f(i, *p) { break; }
845-
p = ptr::offset(p, 1u);
846-
i += 1u;
841+
fn eachi<T>(v: [const T]/&, f: fn(uint, T) -> bool) unsafe {
842+
vec::unpack_slice(v) {|p, n|
843+
let mut i = 0u;
844+
let mut p = p;
845+
while i < n {
846+
if !f(i, *p) { break; }
847+
p = ptr::offset(p, 1u);
848+
i += 1u;
849+
}
847850
}
848851
}
849852

@@ -958,6 +961,7 @@ fn as_mut_buf<E,T>(v: [mut E], f: fn(*mut E) -> T) -> T unsafe {
958961
#[doc = "
959962
Work with the buffer and length of a slice.
960963
"]
964+
#[inline(always)]
961965
fn unpack_slice<T,U>(s: [const T]/&, f: fn(*T, uint) -> U) -> U unsafe {
962966
let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
963967
let (buf,len) = *v;
@@ -1191,6 +1195,17 @@ mod unsafe {
11911195
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
11921196
ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
11931197
}
1198+
1199+
1200+
#[doc = "
1201+
Form a slice from a pointer and length (as a number of units, not bytes).
1202+
"]
1203+
#[inline(always)]
1204+
unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn([T]/&) -> U) -> U {
1205+
let pair = (p, len * sys::size_of::<T>());
1206+
let v : *([T]/&) = ::unsafe::reinterpret_cast(ptr::addr_of(pair));
1207+
f(*v)
1208+
}
11941209
}
11951210

11961211
#[doc = "Operations on `[u8]`"]

0 commit comments

Comments
 (0)