use std::borrow::Cow;
use std::cell::RefCell;
use std::char;
use std::cmp;
use std::io::{self, Read, Write};
use std::marker::PhantomData;
use std::mem;
use std::ptr;
#[derive(Debug, Default, Clone)]
pub struct RawCircle {
buf: Vec<u8>, len: usize, n_chars: usize, read: usize, write: usize, }
impl RawCircle {
pub fn new(s: String) -> RawCircle {
let n_chars = s.chars().count();
let buf = s.into_bytes();
let len = buf.len();
RawCircle { buf, len, n_chars, read: 0, write: 0 }
}
pub fn empty() -> RawCircle {
RawCircle::default()
}
pub fn len(&self) -> usize {
self.len
}
pub fn n_chars(&self) -> usize {
self.n_chars
}
pub fn capacity(&self) -> usize {
self.buf.len()
}
fn grow_if_full(&mut self) {
unsafe {
let old_cap = self.capacity();
if self.read == old_cap { self.read = 0 };
if self.read == 0 { self.write = self.len };
if old_cap == 0 {
debug_assert!(self.read == 0);
debug_assert!(self.write == 0);
if self.buf.capacity() == 0 { self.buf.reserve(1); }
let new_cap = self.buf.capacity();
self.buf.set_len(new_cap);
} else if self.len == old_cap {
if old_cap == self.buf.capacity() {
self.buf.reserve(old_cap);
}
let new_cap = self.buf.capacity();
self.buf.set_len(new_cap);
if self.write == self.read {
let front_size = old_cap - self.read;
let new_read = new_cap - front_size;
let src = self.buf.get_unchecked_mut(self.read) as *mut u8;
let dest = self.buf.get_unchecked_mut(new_read) as *mut u8;
ptr::copy(src, dest, front_size);
self.read = new_read;
} else {
debug_assert!(self.read == 0);
debug_assert!(self.write == self.len);
}
}
}
}
fn peek_char_len(&self) -> Option<usize> {
if self.len == 0 { return None };
let byte = unsafe { self.buf.get_unchecked(self.read) };
let reverse = byte ^ 0b11111111;
let leading_ones = reverse.leading_zeros();
match leading_ones {
0 => Some(1),
1 => unreachable!("invalid utf-8"),
2 => Some(2),
3 => Some(3),
4 => Some(4),
_ => unreachable!("invalid utf-8"),
}
}
unsafe fn read_byte(&mut self) -> Option<u8> {
if self.len == 0 { return None };
if self.read == self.capacity() { self.read = 0 };
let byte = self.buf.get_unchecked(self.read);
self.read += 1;
self.len -= 1;
Some(*byte)
}
pub fn read_char(&mut self) -> Option<char> {
unsafe {
let byte = self.read_byte()?;
let reverse = byte ^ 0b11111111;
let leading_ones = reverse.leading_zeros();
let mask = 0b11111111 >> leading_ones;
let mut ch = (byte & mask) as u32;
let n_additional_bytes = leading_ones.saturating_sub(1);
for _ in 0..n_additional_bytes {
let byte = self.read_byte().unwrap();
let byte = byte & 0b00111111;
ch = (ch << 6) | byte as u32;
}
self.n_chars -= 1;
Some(char::from_u32_unchecked(ch))
}
}
pub fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let max_len = cmp::min(buf.len(), self.len());
let mut len = 0;
loop {
match self.peek_char_len() {
None => return Ok(len),
Some(n) => {
if len + n <= max_len {
for i in 0..n {
buf[len+i] = unsafe { self.read_byte().unwrap() };
}
self.n_chars -= 1;
len += n;
} else {
return Ok(len);
}
}
}
}
}
pub fn read_str<'a>(&mut self, buf: &'a mut [u8]) -> &'a str {
let n = self.read(buf).unwrap();
let str = &buf[..n] as *const [u8] as *const str;
return unsafe { &*str }
}
unsafe fn write_byte(&mut self, byte: u8) {
self.grow_if_full();
if self.write == self.capacity() { self.write = 0 };
let byte_ref = self.buf.get_unchecked_mut(self.write);
*byte_ref = byte;
self.write += 1;
self.len += 1;
}
pub fn write_char(&mut self, ch: char) {
unsafe {
let mut utf8 = [0u8; 4];
for byte in ch.encode_utf8(&mut utf8).as_bytes() {
self.write_byte(*byte)
}
self.n_chars += 1;
}
}
pub fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let mut len = 0;
let mut tmp = [0u8; 4];
loop {
if len == buf.len() { return Ok(len) };
let first_byte = unsafe { *buf.get_unchecked(len) };
let reverse = first_byte ^ 0b11111111;
let leading_ones = reverse.leading_zeros();
let n = match leading_ones {
0 => 1,
1 => return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid UTF-8")),
2 => 2,
3 => 3,
4 => 4,
_ => return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid UTF-8")),
};
tmp[0] = first_byte;
for i in 1..n {
if len + i == buf.len() { return Ok(len) };
let byte = unsafe { *buf.get_unchecked(len + i) };
let reverse = byte ^ 0b11111111;
let leading_ones = reverse.leading_zeros();
if leading_ones != 1 {
return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid UTF-8"));
}
tmp[i] = byte;
}
for i in 0..n {
unsafe { self.write_byte(tmp[i]) };
}
self.n_chars += 1;
len += n;
}
}
pub fn write_str(&mut self, buf: &str) -> usize {
self.write(buf.as_bytes()).unwrap()
}
fn realign(&mut self) {
unsafe {
if self.read == self.capacity() { self.read = 0 };
if self.read == 0 { self.write = self.len };
if self.len == 0 || self.read == 0 {
} else if self.read < self.write {
let src = self.buf.get_unchecked_mut(self.read) as *mut u8;
let dest = self.buf.get_unchecked_mut(0) as *mut u8;
ptr::copy(src, dest, self.len);
} else {
debug_assert!(self.write < self.read);
let mut back = (0, self.write);
let mut tmp = (self.write, self.read);
let mut front = (self.read, self.capacity());
let len = |bounds: (usize, usize)| bounds.1 - bounds.0;
let src = self.buf.get_unchecked_mut(front.0) as *mut u8;
let dest = self.buf.get_unchecked_mut(tmp.0) as *mut u8;
let count = len(front);
ptr::copy(src, dest, count);
front = (tmp.0, tmp.0 + count);
tmp = (front.1, self.capacity());
while len(tmp) < len(back) {
if len(front) < len(back) {
let count = len(front);
let b0 = (back.0, back.0 + count);
let b1 = (back.0 + count, back.1);
let x = self.buf.get_unchecked_mut(b0.0) as *mut u8;
let y = self.buf.get_unchecked_mut(front.0) as *mut u8;
ptr::swap_nonoverlapping(x, y, count);
back = b1;
} else {
let count = len(back);
let f0 = (front.0, front.0 + count);
let f1 = (front.0 + count, front.1);
let x = self.buf.get_unchecked_mut(f0.0) as *mut u8;
let y = self.buf.get_unchecked_mut(back.0) as *mut u8;
ptr::swap_nonoverlapping(x, y, count);
back = f0;
front = f1;
}
}
if len(tmp) != 0 {
let src = self.buf.get_unchecked_mut(back.0) as *mut u8;
let dest = self.buf.get_unchecked_mut(tmp.0) as *mut u8;
let count = len(back);
ptr::copy_nonoverlapping(src, dest, count);
let t0 = (back.0, back.0 + count);
back = (tmp.0, tmp.0 + count);
let src = self.buf.get_unchecked_mut(front.0) as *mut u8;
let dest = self.buf.get_unchecked_mut(t0.0) as *mut u8;
let count = len(front) + len(back);
ptr::copy(src, dest, count);
} else {
debug_assert!(len(back) == 0);
}
}
}
self.read = 0;
self.write = self.len;
}
pub fn into_vec(mut self) -> Vec<u8> {
self.realign();
let mut vec = self.buf;
unsafe { vec.set_len(self.len) };
vec
}
pub fn into_string(self) -> String {
let vec = self.into_vec();
unsafe { String::from_utf8_unchecked(vec) }
}
}
impl From<String> for RawCircle {
fn from(s: String) -> RawCircle {
RawCircle::new(s)
}
}
impl From<RawCircle> for String {
fn from(c: RawCircle) -> String {
c.into_string()
}
}
impl From<RawCircle> for Vec<u8> {
fn from(c: RawCircle) -> Vec<u8> {
c.into_vec()
}
}
impl Read for RawCircle {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
RawCircle::read(self, buf)
}
}
impl Write for RawCircle {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
RawCircle::write(self, buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[derive(Debug, Default, Clone)]
pub struct CharCircle {
raw: RefCell<RawCircle>,
}
impl CharCircle {
pub fn new(s: String) -> CharCircle {
CharCircle { raw: RefCell::new(RawCircle::new(s)) }
}
pub fn empty() -> CharCircle {
CharCircle::default()
}
pub fn len(&self) -> usize {
self.raw.borrow().len()
}
pub fn n_chars(&self) -> usize {
self.raw.borrow().n_chars()
}
pub fn capacity(&self) -> usize {
self.raw.borrow().capacity()
}
pub fn read_char(&self) -> Option<char> {
self.raw.borrow_mut().read_char()
}
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
self.raw.borrow_mut().read(buf)
}
pub fn read_str<'a>(&self, buf: &'a mut [u8]) -> &'a str {
self.raw.borrow_mut().read_str(buf)
}
pub fn write_char(&self, ch: char) {
self.raw.borrow_mut().write_char(ch)
}
pub fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.raw.borrow_mut().write(buf)
}
pub fn write_str(&self, buf: &str) -> usize {
self.raw.borrow_mut().write_str(buf)
}
pub fn into_vec(self) -> Vec<u8> {
self.raw.into_inner().into_vec()
}
pub fn into_string(self) -> String {
self.raw.into_inner().into_string()
}
pub fn take_chars(&self, n: usize) -> Chars {
Chars::new(&self, n)
}
pub fn take_current_chars(&self) -> Chars {
self.take_chars(self.n_chars())
}
}
impl From<String> for CharCircle {
fn from(s: String) -> CharCircle {
CharCircle::new(s)
}
}
impl From<CharCircle> for String {
fn from(c: CharCircle) -> String {
c.into_string()
}
}
impl From<CharCircle> for Vec<u8> {
fn from(c: CharCircle) -> Vec<u8> {
c.into_vec()
}
}
impl Read for CharCircle {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
CharCircle::read(self, buf)
}
}
impl Write for CharCircle {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
CharCircle::write(self, buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[derive(Debug)]
pub struct Chars<'a> {
circle: &'a CharCircle,
n_chars: usize,
}
impl<'a> Chars<'a> {
fn new(circle: &'a CharCircle, n_chars: usize) -> Chars<'a> {
Chars{ circle, n_chars }
}
}
impl<'a> Iterator for Chars<'a> {
type Item = char;
fn next(&mut self) -> Option<char> {
if self.n_chars == 0 {
None
} else {
let ch = self.circle.read_char()?;
self.n_chars -= 1;
Some(ch)
}
}
}
impl<'a> Drop for Chars<'a> {
fn drop(&mut self) {
for _ in self { }
}
}
pub trait StringTransform<'a> {
type Iter: Iterator<Item=char>;
fn transform_chars(&self, chars: Chars<'a>) -> Self::Iter;
#[allow(unused_variables)]
fn will_modify(&self, val: &str) -> bool {
return true
}
fn transform<'b, T: Into<Cow<'b, str>>>(&self, s: T) -> Cow<'b, str> {
let s = s.into();
if self.will_modify(&s) {
let s = s.into_owned();
let circle = CharCircle::new(s);
let old_chars = circle.take_current_chars();
let old_chars: Chars<'_> = unsafe { mem::transmute(old_chars) };
let new_chars = self.transform_chars(old_chars);
for ch in new_chars { circle.write_char(ch) }; let t = circle.into_string(); Cow::Owned(t)
} else {
s
}
}
}
pub trait SimpleTransform<'a>: Iterator<Item=char> + Sized {
fn transform_chars(chars: Chars<'a>) -> Self;
#[allow(unused_variables)]
fn will_modify(val: &str) -> bool {
return true
}
fn transform<'b, T: Into<Cow<'b, str>>>(s: T) -> Cow<'b, str> {
SimpleStringTransform::<Self>::new().transform(s)
}
}
pub struct SimpleStringTransform<T>(pub PhantomData<T>);
impl<'a, T: SimpleTransform<'a>> SimpleStringTransform<T> {
pub fn new() -> Self {
SimpleStringTransform(PhantomData)
}
}
impl<'a, T: SimpleTransform<'a>> StringTransform<'a> for SimpleStringTransform<T> {
type Iter = T;
fn transform_chars(&self, chars: Chars<'a>) -> Self::Iter {
Self::Iter::transform_chars(chars)
}
fn will_modify(&self, val: &str) -> bool {
Self::Iter::will_modify(val)
}
}
#[cfg(test)]
mod tests {
use super::*;
struct Identity<I>(I);
impl<I: Iterator<Item=char>> Iterator for Identity<I> {
type Item = char;
fn next(&mut self) -> Option<char> {
self.0.next()
}
}
impl<'a> SimpleTransform<'a> for Identity<Chars<'a>> {
fn transform_chars(chars: Chars<'a>) -> Self {
Identity(chars)
}
}
struct Half<I>(I);
impl<I: Iterator<Item=char>> Iterator for Half<I> {
type Item = char;
fn next(&mut self) -> Option<char> {
self.0.next()?;
self.0.next()
}
}
impl<'a> SimpleTransform<'a> for Half<Chars<'a>> {
fn transform_chars(chars: Chars<'a>) -> Self {
Half(chars)
}
}
struct Double<I> {
inner: I,
state: Option<char>,
}
impl<I: Iterator<Item=char>> Iterator for Double<I> {
type Item = char;
fn next(&mut self) -> Option<char> {
match self.state {
Some(_) => self.state.take(),
None => {
let state = self.inner.next();
self.state = state;
state
}
}
}
}
impl<'a> SimpleTransform<'a> for Double<Chars<'a>> {
fn transform_chars(chars: Chars<'a>) -> Self {
Double { inner: chars, state: None }
}
}
#[test]
fn test_transform() {
let s: String = "Hello World".to_string();
let ptr = s.as_ptr();
let cap = s.capacity();
let s = Identity::transform(s).into_owned();
assert_eq!(&s, "Hello World");
assert_eq!(s.as_ptr(), ptr);
assert_eq!(s.capacity(), cap);
let ptr = s.as_ptr();
let cap = s.capacity();
let s = Half::transform(s).into_owned();
assert_eq!(&s, "el ol");
assert_eq!(s.as_ptr(), ptr);
assert_eq!(s.capacity(), cap);
let ptr = s.as_ptr();
let cap = s.capacity();
let s = Double::transform(s).into_owned();
assert_eq!(&s, "eell ooll");
assert_eq!(s.as_ptr(), ptr);
assert_eq!(s.capacity(), cap);
let cap = s.capacity();
let s = Double::transform(s).into_owned();
assert_eq!(&s, "eeeellll oooollll");
assert_ne!(s.capacity(), cap);
}
#[test]
fn test_chars() {
let s: String = "Hello World".to_string();
let circle = CharCircle::new(s);
let mut chars = circle.take_chars(6);
assert_eq!(chars.next(), Some('H'));
assert_eq!(chars.next(), Some('e'));
assert_eq!(chars.next(), Some('l'));
std::mem::drop(chars);
let s = circle.into_string();
assert_eq!(s.as_str(), "World");
let s: String = "Hello World".to_string();
let circle = CharCircle::new(s);
let mut chars = circle.take_chars(6);
assert_eq!(chars.next(), Some('H'));
assert_eq!(chars.next(), Some('e'));
assert_eq!(chars.next(), Some('l'));
assert_eq!(chars.next(), Some('l'));
assert_eq!(chars.next(), Some('o'));
assert_eq!(chars.next(), Some(' '));
assert_eq!(chars.next(), None);
}
#[test]
fn test_circle() {
let circle = CharCircle::empty();
circle.write_str("Hello World!");
assert_eq!(circle.len(), 11);
assert_eq!(circle.n_chars(), 11);
let mut buf = [0u8; 6];
let buf_str = circle.read_str(&mut buf);
assert_eq!(buf_str, "Hello ");
assert_eq!(circle.len(), 5);
assert_eq!(circle.n_chars(), 5);
assert_eq!(&circle.into_string(), "World!");
let circle = CharCircle::empty();
circle.write_char('F');
circle.write_char('o');
circle.write_char('o');
circle.write_char('B');
circle.write_char('a');
circle.write_char('r');
assert_eq!(circle.read_char(), Some('F'));
assert_eq!(circle.read_char(), Some('o'));
assert_eq!(circle.read_char(), Some('o'));
assert_eq!(circle.read_char(), Some('B'));
assert_eq!(circle.read_char(), Some('a'));
assert_eq!(circle.read_char(), Some('r'));
assert_eq!(circle.read_char(), None);
circle.write_char('H');
circle.write_char('e');
circle.write_char('l');
circle.write_char('l');
circle.write_char('o');
circle.write_char(' ');
circle.write_char('W');
circle.write_char('o');
circle.write_char('r');
circle.write_char('l');
circle.write_char('d');
circle.write_char('!');
assert_eq!(circle.read_char(), Some('H'));
assert_eq!(circle.read_char(), Some('e'));
assert_eq!(circle.read_char(), Some('l'));
assert_eq!(circle.read_char(), Some('l'));
assert_eq!(circle.read_char(), Some('o'));
assert_eq!(circle.read_char(), Some(' '));
circle.write_char('F');
circle.write_char('o');
circle.write_char('o');
circle.write_char('F');
circle.write_char('o');
circle.write_char('o');
assert_eq!(circle.read_char(), Some('W'));
assert_eq!(circle.read_char(), Some('o'));
assert_eq!(circle.read_char(), Some('r'));
assert_eq!(circle.read_char(), Some('l'));
assert_eq!(circle.read_char(), Some('d'));
assert_eq!(circle.read_char(), Some('!'));
assert_eq!(circle.read_char(), Some('F'));
assert_eq!(circle.read_char(), Some('o'));
assert_eq!(circle.read_char(), Some('o'));
circle.write_char('B');
circle.write_char('a');
circle.write_char('r');
assert_eq!(&circle.into_string(), "FooBar");
}
}