1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
pub mod character_sets;
use std::error::Error;
use crate::{
binary::BitVec,
context::{Context, ContextError},
decoder::Decoder,
encoder::{Capacity, Encoder, EncoderResult},
};
use log::trace;
use crate::binary::Bit;
use self::character_sets::{CharacterSetType, GetCharacterSet};
use super::Method;
#[derive(Debug, PartialEq)]
pub struct TrailingUnicodeMethod {
character_set: CharacterSetType,
}
impl Default for TrailingUnicodeMethod {
fn default() -> Self {
Self::new(CharacterSetType::FullUnicodeSet)
}
}
impl TrailingUnicodeMethod {
pub fn new(unicode_set: CharacterSetType) -> Self {
TrailingUnicodeMethod {
character_set: unicode_set,
}
}
}
impl Capacity for TrailingUnicodeMethod {
fn bitrate(&self) -> usize {
let amount_of_bits = std::mem::size_of::<usize>() * 8;
amount_of_bits - self.character_set.size().leading_zeros() as usize
}
}
impl<E> Encoder<E> for TrailingUnicodeMethod
where
E: Context,
{
fn partial_encode(
&self,
context: &mut E,
data: &mut dyn Iterator<Item = Bit>,
) -> Result<EncoderResult, Box<dyn Error>> {
let set_capacity = self.bitrate();
let next_n_bits = data.take(set_capacity).collect::<Vec<Bit>>();
let amount_bits_taken = next_n_bits.len();
let mut number: u32 = BitVec::from(next_n_bits).into();
number <<= set_capacity - amount_bits_taken;
trace!(
"Took {} bits and assembled a number: {}",
set_capacity,
number
);
if let Some(character) = self.character_set.get_character(number) {
trace!(
"Putting unicode character {:?} at the end of the line",
character
);
context.get_current_text_mut()?.push(*character);
}
Ok(EncoderResult::Success)
}
}
impl<D> Decoder<D> for TrailingUnicodeMethod
where
D: Context,
{
fn partial_decode(&self, context: &D) -> Result<Vec<Bit>, ContextError> {
if let Some(character) = context.get_current_text()?.chars().last() {
let decoded_number = self.character_set.character_to_bits(&character);
trace!(
"Found {:?} at the end of the line, decoded into {}",
&character,
decoded_number
);
let data: Vec<Bit> = BitVec::from(decoded_number).into();
let data_length = data.len();
let data_iter = data.into_iter().skip(data_length - self.bitrate());
let decoded_data = data_iter.collect::<Vec<Bit>>();
return Ok(decoded_data);
}
Ok(BitVec::filled_with(0, self.bitrate()).into())
}
}
impl<E, D> Method<E, D> for TrailingUnicodeMethod
where
E: Context,
D: Context,
{
fn method_name(&self) -> String {
"TrailingUnicodeMethod".to_string()
}
}