Skip to content

Commit

Permalink
Move SeekableMemWriter into librbml
Browse files Browse the repository at this point in the history
  • Loading branch information
erickt authored and alexcrichton committed Jul 31, 2014
1 parent e1dcbef commit fd9ad77
Show file tree
Hide file tree
Showing 7 changed files with 11 additions and 235 deletions.
3 changes: 2 additions & 1 deletion src/librustc/util/io.rs → src/librbml/io.rs
Expand Up @@ -39,7 +39,7 @@ fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64>
///
/// ```rust
/// # #![allow(unused_must_use)]
/// use std::io::SeekableMemWriter;
/// use rbml::io::SeekableMemWriter;
///
/// let mut w = SeekableMemWriter::new();
/// w.write([0, 1, 2]);
Expand Down Expand Up @@ -128,6 +128,7 @@ impl Seek for SeekableMemWriter {

#[cfg(test)]
mod tests {
extern crate test;
use super::SeekableMemWriter;
use std::io;
use test::Bencher;
Expand Down
120 changes: 4 additions & 116 deletions src/librbml/lib.rs
Expand Up @@ -32,9 +32,9 @@ extern crate serialize;
#[phase(plugin, link)] extern crate log;
#[cfg(test)] extern crate test;

use std::io;
use std::str;

pub mod io;

/// Common data structures
#[deriving(Clone)]
Expand Down Expand Up @@ -105,7 +105,7 @@ pub enum EbmlEncoderTag {
pub enum Error {
IntTooBig(uint),
Expected(String),
IoError(io::IoError)
IoError(std::io::IoError)
}
// --------------------------------------

Expand Down Expand Up @@ -1038,127 +1038,15 @@ pub mod writer {
#[cfg(test)]
mod tests {
use super::{Doc, reader, writer};
use super::io::SeekableMemWriter;

use serialize::{Encodable, Decodable};

use std::io::{IoError, IoResult, SeekStyle};
use std::io;
use std::option::{None, Option, Some};
use std::slice;

static BUF_CAPACITY: uint = 128;

fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
// compute offset as signed and clamp to prevent overflow
let pos = match seek {
io::SeekSet => 0,
io::SeekEnd => end,
io::SeekCur => cur,
} as i64;

if offset + pos < 0 {
Err(IoError {
kind: io::InvalidInput,
desc: "invalid seek to a negative offset",
detail: None
})
} else {
Ok((offset + pos) as u64)
}
}

/// Writes to an owned, growable byte vector that supports seeking.
///
/// # Example
///
/// ```rust
/// # #![allow(unused_must_use)]
/// use std::io::SeekableMemWriter;
///
/// let mut w = SeekableMemWriter::new();
/// w.write([0, 1, 2]);
///
/// assert_eq!(w.unwrap(), vec!(0, 1, 2));
/// ```
pub struct SeekableMemWriter {
buf: Vec<u8>,
pos: uint,
}

impl SeekableMemWriter {
/// Create a new `SeekableMemWriter`.
#[inline]
pub fn new() -> SeekableMemWriter {
SeekableMemWriter::with_capacity(BUF_CAPACITY)
}
/// Create a new `SeekableMemWriter`, allocating at least `n` bytes for
/// the internal buffer.
#[inline]
pub fn with_capacity(n: uint) -> SeekableMemWriter {
SeekableMemWriter { buf: Vec::with_capacity(n), pos: 0 }
}

/// Acquires an immutable reference to the underlying buffer of this
/// `SeekableMemWriter`.
///
/// No method is exposed for acquiring a mutable reference to the buffer
/// because it could corrupt the state of this `MemWriter`.
#[inline]
pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }

/// Unwraps this `SeekableMemWriter`, returning the underlying buffer
#[inline]
pub fn unwrap(self) -> Vec<u8> { self.buf }
}

impl Writer for SeekableMemWriter {
#[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
if self.pos == self.buf.len() {
self.buf.push_all(buf)
} else {
// Make sure the internal buffer is as least as big as where we
// currently are
let difference = self.pos as i64 - self.buf.len() as i64;
if difference > 0 {
self.buf.grow(difference as uint, &0);
}

// Figure out what bytes will be used to overwrite what's currently
// there (left), and what will be appended on the end (right)
let cap = self.buf.len() - self.pos;
let (left, right) = if cap <= buf.len() {
(buf.slice_to(cap), buf.slice_from(cap))
} else {
(buf, &[])
};

// Do the necessary writes
if left.len() > 0 {
slice::bytes::copy_memory(self.buf.mut_slice_from(self.pos), left);
}
if right.len() > 0 {
self.buf.push_all(right);
}
}

// Bump us forward
self.pos += buf.len();
Ok(())
}
}

impl Seek for SeekableMemWriter {
#[inline]
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }

#[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
self.pos = new as uint;
Ok(())
}
}

#[test]
fn test_vuint_at() {
let data = [
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Expand Up @@ -133,7 +133,6 @@ pub mod util {

pub mod common;
pub mod ppaux;
pub mod io;
pub mod nodemap;
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/encoder.rs
Expand Up @@ -26,7 +26,6 @@ use middle::ty;
use middle::typeck;
use middle::stability;
use middle;
use util::io::SeekableMemWriter;
use util::nodemap::{NodeMap, NodeSet};

use serialize::Encodable;
Expand All @@ -53,6 +52,7 @@ use syntax::visit::Visitor;
use syntax::visit;
use syntax;
use rbml::writer;
use rbml::io::SeekableMemWriter;

/// A borrowed version of ast::InlinedItem.
pub enum InlinedItemRef<'a> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/tyencode.rs
Expand Up @@ -27,7 +27,7 @@ use syntax::ast::*;
use syntax::diagnostic::SpanHandler;
use syntax::parse::token;

use util::io::SeekableMemWriter;
use rbml::io::SeekableMemWriter;

macro_rules! mywrite( ($($arg:tt)*) => ({ write!($($arg)*); }) )

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/astencode.rs
Expand Up @@ -28,7 +28,6 @@ use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
use middle::{ty, typeck};
use util::io::SeekableMemWriter;
use util::ppaux::ty_to_string;

use syntax::{ast, ast_map, ast_util, codemap, fold};
Expand All @@ -43,6 +42,7 @@ use std::io::Seek;
use std::mem;
use std::gc::GC;

use rbml::io::SeekableMemWriter;
use rbml::{reader, writer};
use rbml;
use serialize;
Expand Down
116 changes: 2 additions & 114 deletions src/test/run-pass/issue-11881.rs
Expand Up @@ -17,121 +17,9 @@ use std::slice;

use serialize::{Encodable, Encoder};
use serialize::json;
use rbml::writer;

static BUF_CAPACITY: uint = 128;

fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
// compute offset as signed and clamp to prevent overflow
let pos = match seek {
io::SeekSet => 0,
io::SeekEnd => end,
io::SeekCur => cur,
} as i64;

if offset + pos < 0 {
Err(IoError {
kind: io::InvalidInput,
desc: "invalid seek to a negative offset",
detail: None
})
} else {
Ok((offset + pos) as u64)
}
}

/// Writes to an owned, growable byte vector that supports seeking.
///
/// # Example
///
/// ```rust
/// # #![allow(unused_must_use)]
/// use std::io::SeekableMemWriter;
///
/// let mut w = SeekableMemWriter::new();
/// w.write([0, 1, 2]);
///
/// assert_eq!(w.unwrap(), vec!(0, 1, 2));
/// ```
pub struct SeekableMemWriter {
buf: Vec<u8>,
pos: uint,
}

impl SeekableMemWriter {
/// Create a new `SeekableMemWriter`.
#[inline]
pub fn new() -> SeekableMemWriter {
SeekableMemWriter::with_capacity(BUF_CAPACITY)
}
/// Create a new `SeekableMemWriter`, allocating at least `n` bytes for
/// the internal buffer.
#[inline]
pub fn with_capacity(n: uint) -> SeekableMemWriter {
SeekableMemWriter { buf: Vec::with_capacity(n), pos: 0 }
}

/// Acquires an immutable reference to the underlying buffer of this
/// `SeekableMemWriter`.
///
/// No method is exposed for acquiring a mutable reference to the buffer
/// because it could corrupt the state of this `MemWriter`.
#[inline]
pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }

/// Unwraps this `SeekableMemWriter`, returning the underlying buffer
#[inline]
pub fn unwrap(self) -> Vec<u8> { self.buf }
}

impl Writer for SeekableMemWriter {
#[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
if self.pos == self.buf.len() {
self.buf.push_all(buf)
} else {
// Make sure the internal buffer is as least as big as where we
// currently are
let difference = self.pos as i64 - self.buf.len() as i64;
if difference > 0 {
self.buf.grow(difference as uint, &0);
}

// Figure out what bytes will be used to overwrite what's currently
// there (left), and what will be appended on the end (right)
let cap = self.buf.len() - self.pos;
let (left, right) = if cap <= buf.len() {
(buf.slice_to(cap), buf.slice_from(cap))
} else {
(buf, &[])
};

// Do the necessary writes
if left.len() > 0 {
slice::bytes::copy_memory(self.buf.mut_slice_from(self.pos), left);
}
if right.len() > 0 {
self.buf.push_all(right);
}
}

// Bump us forward
self.pos += buf.len();
Ok(())
}
}

impl Seek for SeekableMemWriter {
#[inline]
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }

#[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
self.pos = new as uint;
Ok(())
}
}
use rbml::writer;
use rbml::io::SeekableMemWriter;

#[deriving(Encodable)]
struct Foo {
Expand Down

0 comments on commit fd9ad77

Please sign in to comment.