FastWaveBackend/src/main.rs

175 lines
4.3 KiB
Rust
Raw Normal View History

2022-04-14 04:50:37 +00:00
use std::io::prelude::*;
use std::io;
use std::fs::File;
2022-05-18 02:04:32 +00:00
use std::collections::BTreeMap;
2022-05-19 07:44:24 +00:00
use chrono::prelude::*;
use ::function_name::named;
2022-04-14 04:50:37 +00:00
use num::*;
use clap::Parser;
2022-06-02 20:51:56 +00:00
use std::slice;
use std::str;
use std::collections::VecDeque;
2022-04-14 04:50:37 +00:00
#[derive(Parser)]
struct Cli {
/// The path to the file to read
#[clap(parse(from_os_str))]
path: std::path::PathBuf}
2022-04-14 04:50:37 +00:00
2022-05-23 03:00:03 +00:00
#[derive(Debug)]
struct Version(String);
2022-05-23 03:00:03 +00:00
#[derive(Debug)]
enum Timescale {ps, ns, us, ms, s, unit}
2022-05-19 07:44:24 +00:00
2022-05-23 03:00:03 +00:00
#[derive(Debug)]
struct Metadata {
2022-05-23 23:19:17 +00:00
date : Option<DateTime<Utc>>,
version : Option<Version>,
2022-05-28 00:48:17 +00:00
timescale : (Option<u32>, Timescale)}
2022-05-19 07:44:24 +00:00
#[derive(Debug)]
struct Scope_Idx(usize);
#[derive(Debug)]
struct Signal_Idx(usize);
2022-05-23 03:00:03 +00:00
#[derive(Debug)]
2022-05-19 07:44:24 +00:00
enum SignalGeneric{
2022-05-23 03:00:03 +00:00
Signal{
name : String,
timeline : BTreeMap<BigInt, BigInt>,
scope_parent : Scope_Idx},
SignalAlias{
name : String,
signal_alias : Signal_Idx}
}
2022-05-18 02:04:32 +00:00
2022-05-23 03:00:03 +00:00
#[derive(Debug)]
2022-05-19 07:44:24 +00:00
struct Scope {
name : String,
child_signals : Vec<Signal_Idx>,
child_scopes : Vec<Scope_Idx>}
2022-05-19 07:44:24 +00:00
2022-05-23 03:00:03 +00:00
#[derive(Debug)]
2022-05-19 07:44:24 +00:00
struct VCD {
metadata : Metadata,
all_signals : Vec<SignalGeneric>,
// the root scope should always be placed at index 0
all_scopes : Vec<Scope>}
impl VCD {
pub fn new() -> Self {
let metadata = Metadata {
2022-05-23 23:19:17 +00:00
date : None,
version : None,
2022-05-28 00:48:17 +00:00
timescale : (None, Timescale::unit)};
VCD {
metadata : metadata,
all_signals : Vec::<SignalGeneric>::new(),
2022-05-24 03:59:57 +00:00
all_scopes : Vec::<Scope>::new()}
}
}
#[derive(Debug)]
struct Line(usize);
#[derive(Debug)]
struct Word(usize);
#[derive(Debug)]
struct Cursor(Line, Word);
2022-06-02 20:51:56 +00:00
struct YieldByWord {
reader : io::BufReader<File>,
EOF : bool,
buffers : Vec<String>,
curr_line : usize,
str_slices : VecDeque<(*const u8, usize, Cursor)>,
2022-06-02 20:51:56 +00:00
}
impl YieldByWord {
fn new(file : File) -> YieldByWord {
let mut reader = io::BufReader::new(file);
YieldByWord {
reader : reader,
EOF : false,
buffers : vec![],
curr_line : 0,
str_slices : VecDeque::new()
2022-06-02 20:51:56 +00:00
}
}
fn next_word(&mut self) -> Option<(&str, Cursor)> {
2022-06-02 20:51:56 +00:00
// if there are no more words, attempt to read more content
// from the file
if self.str_slices.is_empty() {
self.buffers.clear();
2022-06-02 20:51:56 +00:00
if self.EOF {return None}
let num_buffers = 10;
for buf_idx in 0..num_buffers {
self.buffers.push(String::new());
self.curr_line += 1;
let bytes_read = self.reader.read_line(&mut self.buffers[buf_idx]).unwrap();
// if we've reached the end of the file on the first attempt to read
// a line in this for loop, no further attempts are necessary and we
if bytes_read == 0 {
self.EOF = true;
break;
}
let mut words = self.buffers[buf_idx].split_ascii_whitespace();
for word in words.enumerate() {
let (word_idx, word) = word;
let position = Cursor(Line(self.curr_line), Word(word_idx + 1));
self.str_slices.push_back((word.as_ptr(), word.len(), position))
}
2022-06-02 20:51:56 +00:00
}
}
2022-06-02 20:51:56 +00:00
// if after we've attempted to read in more content from the file,
// there are still no words...
if self.str_slices.is_empty() {
return None
2022-06-02 20:51:56 +00:00
}
// if we make it here, we return the next word
unsafe {
let (ptr, len, position) = self.str_slices.pop_front().unwrap();
2022-06-02 20:51:56 +00:00
let slice = slice::from_raw_parts(ptr, len);
return Some((str::from_utf8(slice).unwrap(), position));
2022-06-02 20:51:56 +00:00
};
}
}
fn main() -> std::io::Result<()> {
let args = Cli::parse();
2022-05-19 07:44:24 +00:00
let file = File::open(&args.path)?;
2022-06-02 20:51:56 +00:00
let mut word_gen = YieldByWord::new(file);
let mut word_count = 0;
while word_gen.next_word().is_some() {
word_count += 1;
}
dbg!(word_count);
// loop {
// let word = word_gen.next_word();
// if word.is_none() {break};
// dbg!(word.unwrap());
2022-06-02 20:51:56 +00:00
// }
2022-05-23 03:00:03 +00:00
2022-04-14 04:50:37 +00:00
Ok(())
}