抽离重复部分为函数

This commit is contained in:
MeiK 2021-04-19 17:57:09 +08:00
parent c8f477fc5c
commit 717779fec1

View File

@ -1,4 +1,4 @@
use std::path::Path;
use std::path::{Path, PathBuf};
use tokio::fs;
use tokio::fs::{remove_file, File};
@ -15,7 +15,7 @@ use crate::result::{
standard_result, time_limit_exceeded, wrong_answer,
};
use crate::river::{JudgeResponse, JudgeResultEnum, JudgeType};
use crate::sandbox::Sandbox;
use crate::sandbox::{ProcessExitStatus, Sandbox};
fn path_to_string(path: &Path) -> Result<String> {
if let Some(s) = path.to_str() {
@ -56,32 +56,15 @@ pub async fn compile(language: &str, code: &str, path: &Path) -> Result<JudgeRes
if status.exit_code != 0 || status.signal != 0 {
// 合并 stdout 与 stderr 为 errmsg
// 因为不同的语言、不同的编译器,错误信息输出到了不同的地方
let mut buffer = [0; 2048];
let mut outfile = try_io!(File::open(path.join(STDOUT_FILENAME)).await);
let mut errfile = try_io!(File::open(path.join(STDERR_FILENAME)).await);
try_io!(outfile.read(&mut buffer).await);
let mut out_offset = 0;
let mut err_offset = 0;
for i in 0..2047 {
out_offset = i;
if buffer[i] == 0 {
break;
}
}
if out_offset != 0 {
buffer[out_offset] = b'\n';
out_offset += 1;
}
try_io!(errfile.read(&mut buffer[out_offset..]).await);
for i in out_offset..2048 {
err_offset = i;
if buffer[i] == 0 {
break;
}
}
let errmsg = String::from_utf8_lossy(&buffer[..err_offset]);
let outmsg = read_file_2048(path.join(STDOUT_FILENAME)).await?;
let errmsg = read_file_2048(path.join(STDERR_FILENAME)).await?;
let errmsg = if outmsg == "" {
errmsg
} else if errmsg == "" {
outmsg
} else {
format!("{}\n{}", outmsg, errmsg)
};
return Ok(compile_error(status.time_used, status.memory_used, &errmsg));
}
Ok(compile_success(status.time_used, status.memory_used))
@ -169,6 +152,20 @@ pub async fn judge(
};
} else if judge_type == JudgeType::Special as i32 {
// Special Judge
return special_judge(in_file, out_file, spj_file, path, data_dir, status).await;
}
Err(Error::SystemError(String::from(format!("Unknown Error!"))))
}
async fn special_judge(
in_file: &str,
out_file: &str,
spj_file: &str,
path: &Path,
data_dir: &Path,
status: ProcessExitStatus,
) -> Result<JudgeResponse> {
if spj_file == "" {
return Err(Error::SystemError(format!("field spj_file is required!")));
}
@ -216,30 +213,8 @@ pub async fn judge(
drop(permit);
// 读取 spj 程序的输出,无论结果 ac 与否,都要将其返回
// TODO: 抽离此处读取文件的部分为单独的模块
let mut out_buffer = [0; 1024];
let mut outfile = try_io!(File::open(path.join(STDOUT_FILENAME)).await);
try_io!(outfile.read(&mut out_buffer).await);
let mut out_offset = 0;
for i in 0..1024 {
if out_buffer[i] == 0 {
out_offset = i;
break;
}
}
let outmsg = String::from_utf8_lossy(&out_buffer[..out_offset]);
let mut err_buffer = [0; 1024];
let mut errfile = try_io!(File::open(path.join(STDERR_FILENAME)).await);
try_io!(errfile.read(&mut err_buffer).await);
let mut err_offset = 0;
for i in 0..1024 {
if err_buffer[i] == 0 {
err_offset = i;
break;
}
}
let errmsg = String::from_utf8_lossy(&err_buffer[..err_offset]);
let outmsg = read_file_2048(path.join(SPJ_STDOUT_FILENAME)).await?;
let errmsg = read_file_2048(path.join(SPJ_STDERR_FILENAME)).await?;
// spj 程序的返回值code代表了结果0 ac1 wa
return if spj_status.exit_code == 0 {
Ok(spj_result(
@ -260,5 +235,18 @@ pub async fn judge(
};
}
Err(Error::SystemError(String::from(format!("Unknown Error!"))))
async fn read_file_2048(filename: PathBuf) -> Result<String> {
let mut buffer = [0; 2048];
let mut file = try_io!(File::open(filename).await);
try_io!(file.read(&mut buffer).await);
let mut offset = 0;
for i in 0..2047 {
offset = i;
if buffer[i] == 0 {
break;
}
}
try_io!(file.read(&mut buffer[offset..]).await);
Ok(String::from(String::from_utf8_lossy(&buffer[..offset])))
}