Skip to content

Commit 0d3216b

Browse files
committed
Add a buffer when writing
As we did when writing in the `segwit` module; add a buffer to cache characters and do writes a buffer at a time. Here we do not have a known maximum length of the string we are encoding so we use an arbitrary sized buffer and do multiple writes if it fills up.
1 parent 1f4eff8 commit 0d3216b

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

src/lib.rs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ pub use {
166166
crate::primitives::{Bech32, Bech32m, NoChecksum},
167167
};
168168

169+
// Write to fmt buffer, small during testing to exercise full code path.
170+
#[cfg(not(test))]
171+
const BUF_LENGTH: usize = 1024;
172+
#[cfg(test)]
173+
const BUF_LENGTH: usize = 10;
174+
169175
/// Decodes a bech32 encoded string.
170176
///
171177
/// If this function succeeds the input string was found to be well formed (hrp, separator, bech32
@@ -319,11 +325,25 @@ pub fn encode_lower_to_fmt<Ck: Checksum, W: fmt::Write>(
319325
hrp: &Hrp,
320326
data: &[u8],
321327
) -> Result<(), fmt::Error> {
328+
let mut buf = [0u8; BUF_LENGTH];
329+
let mut pos = 0;
330+
322331
let iter = data.iter().copied().bytes_to_fes();
323332
let chars = iter.with_checksum::<Ck>(hrp).chars();
333+
324334
for c in chars {
325-
fmt.write_char(c)?;
335+
buf[pos] = c as u8;
336+
pos += 1;
337+
if pos == BUF_LENGTH {
338+
let s = core::str::from_utf8(&buf).expect("we only write ASCII");
339+
fmt.write_str(s)?;
340+
pos = 0;
341+
}
326342
}
343+
344+
let s = core::str::from_utf8(&buf[..pos]).expect("we only write ASCII");
345+
fmt.write_str(s)?;
346+
327347
Ok(())
328348
}
329349

@@ -346,11 +366,25 @@ pub fn encode_upper_to_fmt<Ck: Checksum, W: fmt::Write>(
346366
hrp: &Hrp,
347367
data: &[u8],
348368
) -> Result<(), fmt::Error> {
369+
let mut buf = [0u8; BUF_LENGTH];
370+
let mut pos = 0;
371+
349372
let iter = data.iter().copied().bytes_to_fes();
350373
let chars = iter.with_checksum::<Ck>(hrp).chars();
374+
351375
for c in chars {
352-
fmt.write_char(c.to_ascii_uppercase())?;
376+
buf[pos] = c.to_ascii_uppercase() as u8;
377+
pos += 1;
378+
if pos == BUF_LENGTH {
379+
let s = core::str::from_utf8(&buf).expect("we only write ASCII");
380+
fmt.write_str(s)?;
381+
pos = 0;
382+
}
353383
}
384+
385+
let s = core::str::from_utf8(&buf[..pos]).expect("we only write ASCII");
386+
fmt.write_str(s)?;
387+
354388
Ok(())
355389
}
356390

@@ -397,11 +431,23 @@ pub fn encode_lower_to_writer<Ck: Checksum, W: std::io::Write>(
397431
hrp: &Hrp,
398432
data: &[u8],
399433
) -> Result<(), std::io::Error> {
434+
let mut buf = [0u8; BUF_LENGTH];
435+
let mut pos = 0;
436+
400437
let iter = data.iter().copied().bytes_to_fes();
401438
let chars = iter.with_checksum::<Ck>(hrp).chars();
439+
402440
for c in chars {
403-
w.write_all(&[c as u8])?;
441+
buf[pos] = c as u8;
442+
pos += 1;
443+
if pos == BUF_LENGTH {
444+
w.write_all(&buf)?;
445+
pos = 0;
446+
}
404447
}
448+
449+
w.write_all(&buf[..pos])?;
450+
405451
Ok(())
406452
}
407453

@@ -425,11 +471,23 @@ pub fn encode_upper_to_writer<Ck: Checksum, W: std::io::Write>(
425471
hrp: &Hrp,
426472
data: &[u8],
427473
) -> Result<(), std::io::Error> {
474+
let mut buf = [0u8; BUF_LENGTH];
475+
let mut pos = 0;
476+
428477
let iter = data.iter().copied().bytes_to_fes();
429478
let chars = iter.with_checksum::<Ck>(hrp).chars();
479+
430480
for c in chars {
431-
w.write_all(&[c.to_ascii_uppercase() as u8])?;
481+
buf[pos] = c.to_ascii_uppercase() as u8;
482+
pos += 1;
483+
if pos == BUF_LENGTH {
484+
w.write_all(&buf)?;
485+
pos = 0;
486+
}
432487
}
488+
489+
w.write_all(&buf[..pos])?;
490+
433491
Ok(())
434492
}
435493

0 commit comments

Comments
 (0)