osrs_buffer/lib.rs
1//! A Rust library for working with the Oldschool Runescape data types.
2//!
3//! Data types in Oldschool Runescape are slightly different compared to normal types. Example of these types are the smart type, middle endian, and occassional switching to little endian. Therefore it has been seen as necessary to have a buffer that can work with these data types.
4//!
5//! This crate provides Read and Write extensions for working with the data types on any data structure implementing `&[u8]` such as Vec, Cursor etc.
6
7use std::io::{self, Error, ErrorKind, Read, Result, Write};
8
9pub trait ReadExt: Read {
10 /// Reads an unsigned byte
11 ///
12 /// # Examples
13 ///
14 /// ```rust
15 /// use std::io::Cursor;
16 /// use osrs_buffer::ReadExt;
17 ///
18 /// let mut rdr = Cursor::new(vec![2, 5]);
19 /// assert_eq!(rdr.read_u8().unwrap(), 2);
20 /// assert_eq!(rdr.read_u8().unwrap(), 5);
21 /// ```
22 #[inline]
23 fn read_u8(&mut self) -> Result<u8> {
24 let mut buf = [0; 1];
25 self.read_exact(&mut buf)?;
26 Ok(buf[0])
27 }
28
29 /// Reads a signed byte
30 ///
31 /// # Examples
32 ///
33 /// ```rust
34 /// use std::io::Cursor;
35 /// use osrs_buffer::ReadExt;
36 ///
37 /// let mut rdr = Cursor::new(vec![248, 6]);
38 /// assert_eq!(rdr.read_i8().unwrap(), -8);
39 /// assert_eq!(rdr.read_i8().unwrap(), 6);
40 /// ```
41 #[inline]
42 fn read_i8(&mut self) -> Result<i8> {
43 Ok(self.read_u8()? as i8)
44 }
45
46 /// Reads a bool
47 ///
48 /// # Examples
49 ///
50 /// ```rust
51 /// use std::io::Cursor;
52 /// use osrs_buffer::ReadExt;
53 ///
54 /// let mut rdr = Cursor::new(vec![0, 1, 2]);
55 /// assert_eq!(rdr.read_bool().unwrap(), false);
56 /// assert_eq!(rdr.read_bool().unwrap(), true);
57 /// assert_eq!(rdr.read_bool().unwrap(), true);
58 /// ```
59 #[inline]
60 fn read_bool(&mut self) -> Result<bool> {
61 let mut buf = [0; 1];
62 self.read_exact(&mut buf)?;
63 Ok(buf[0] != 0)
64 }
65
66 /// Reads an unsigned short as big endian
67 ///
68 /// # Examples
69 ///
70 /// ```rust
71 /// use std::io::Cursor;
72 /// use osrs_buffer::ReadExt;
73 ///
74 /// let mut rdr = Cursor::new(vec![66, 89]);
75 /// assert_eq!(rdr.read_u16().unwrap(), 16985);
76 /// ```
77 #[inline]
78 fn read_u16(&mut self) -> Result<u16> {
79 let mut buf = [0; 2];
80 self.read_exact(&mut buf)?;
81 Ok(u16::from_be_bytes(buf))
82 }
83
84 /// Reads an unsigned short as little endian
85 ///
86 /// # Examples
87 ///
88 /// ```rust
89 /// use std::io::Cursor;
90 /// use osrs_buffer::ReadExt;
91 ///
92 /// let mut rdr = Cursor::new(vec![89, 66]);
93 /// assert_eq!(rdr.read_u16_le().unwrap(), 16985);
94 /// ```
95 #[inline]
96 fn read_u16_le(&mut self) -> Result<u16> {
97 let mut buf = [0; 2];
98 self.read_exact(&mut buf)?;
99 Ok(u16::from_le_bytes(buf))
100 }
101
102 /// Reads an unsigned short as big endian
103 ///
104 /// # Examples
105 ///
106 /// ```rust
107 /// use std::io::Cursor;
108 /// use osrs_buffer::ReadExt;
109 ///
110 /// let mut rdr = Cursor::new(vec![99, 130]);
111 /// assert_eq!(rdr.read_u16_add().unwrap(), 25346);
112 /// ```
113 #[inline]
114 fn read_u16_add(&mut self) -> Result<u16> {
115 Ok(((self.read_u8()? as u16) << 8) | ((self.read_u8()?.wrapping_sub(128)) as u16))
116 }
117
118 /// Reads an unsigned short add as little endian
119 ///
120 /// # Examples
121 ///
122 /// ```rust
123 /// use std::io::Cursor;
124 /// use osrs_buffer::ReadExt;
125 ///
126 /// let mut rdr = Cursor::new(vec![89, 66]);
127 /// assert_eq!(rdr.read_u16_add_le().unwrap(), 17113);
128 /// ```
129 #[inline]
130 fn read_u16_add_le(&mut self) -> Result<u16> {
131 Ok(((self.read_u8()?.wrapping_sub(128)) as u16) | ((self.read_u8()? as u16) << 8))
132 }
133
134 /// Reads a signed short as big endian
135 ///
136 /// # Examples
137 ///
138 /// ```rust
139 /// use std::io::Cursor;
140 /// use osrs_buffer::ReadExt;
141 ///
142 /// let mut rdr = Cursor::new(vec![255, 98]);
143 /// assert_eq!(rdr.read_i16().unwrap(), -158);
144 /// ```
145 #[inline]
146 fn read_i16(&mut self) -> Result<i16> {
147 Ok(self.read_u16()? as i16)
148 }
149
150 /// Reads a signed short as little endian
151 ///
152 /// # Examples
153 ///
154 /// ```rust
155 /// use std::io::Cursor;
156 /// use osrs_buffer::ReadExt;
157 ///
158 /// let mut rdr = Cursor::new(vec![98, 255]);
159 /// assert_eq!(rdr.read_i16_le().unwrap(), -158);
160 /// ```
161 #[inline]
162 fn read_i16_le(&mut self) -> Result<i16> {
163 Ok(self.read_u16_le()? as i16)
164 }
165
166 /// Reads a signed short add
167 ///
168 /// # Examples
169 ///
170 /// ```rust
171 /// use std::io::Cursor;
172 /// use osrs_buffer::ReadExt;
173 ///
174 /// let mut rdr = Cursor::new(vec![253, 177]);
175 /// assert_eq!(rdr.read_i16_add().unwrap(), -719);
176 /// ```
177 #[inline]
178 fn read_i16_add(&mut self) -> Result<i16> {
179 Ok(self.read_u16_add()? as i16)
180 }
181
182 /// Reads an unsigned short add as little endian
183 ///
184 /// # Examples
185 ///
186 /// ```rust
187 /// use std::io::Cursor;
188 /// use osrs_buffer::ReadExt;
189 ///
190 /// let mut rdr = Cursor::new(vec![98, 255]);
191 /// assert_eq!(rdr.read_i16_add_le().unwrap(), -30);
192 /// ```
193 #[inline]
194 fn read_i16_add_le(&mut self) -> Result<i16> {
195 Ok(self.read_u16_add_le()? as i16)
196 }
197
198 /// Reads an unsigned dword as big endian
199 ///
200 /// # Examples
201 ///
202 /// ```rust
203 /// use std::io::Cursor;
204 /// use osrs_buffer::ReadExt;
205 ///
206 /// let mut rdr = Cursor::new(vec![42, 87, 33, 16]);
207 /// assert_eq!(rdr.read_u32().unwrap(), 710353168);
208 /// ```
209 #[inline]
210 fn read_u32(&mut self) -> Result<u32> {
211 let mut buf = [0; 4];
212 self.read_exact(&mut buf)?;
213 Ok(u32::from_be_bytes(buf))
214 }
215
216 /// Reads an unsigned dword as little endian
217 ///
218 /// # Examples
219 ///
220 /// ```rust
221 /// use std::io::Cursor;
222 /// use osrs_buffer::ReadExt;
223 ///
224 /// let mut rdr = Cursor::new(vec![16, 33, 87, 42]);
225 /// assert_eq!(rdr.read_u32_le().unwrap(), 710353168);
226 /// ```
227 #[inline]
228 fn read_u32_le(&mut self) -> Result<u32> {
229 let mut buf = [0; 4];
230 self.read_exact(&mut buf)?;
231 Ok(u32::from_le_bytes(buf))
232 }
233
234 /// Reads an unsigned dword as middle endian
235 ///
236 /// # Examples
237 ///
238 /// ```rust
239 /// use std::io::Cursor;
240 /// use osrs_buffer::ReadExt;
241 ///
242 /// let mut rdr = Cursor::new(vec![1, 5, 9, 49]);
243 /// assert_eq!(rdr.read_u32_me().unwrap(), 83964169);
244 ///
245 /// ```
246 #[inline]
247 fn read_u32_me(&mut self) -> Result<u32> {
248 Ok((self.read_u16_le()? as u32) << 16 | (self.read_u16_le()? as u32))
249 }
250
251 /// Reads an unsigned dword as inversed middle endian
252 ///
253 /// # Examples
254 ///
255 /// ```rust
256 /// use std::io::Cursor;
257 /// use osrs_buffer::ReadExt;
258 ///
259 /// let mut rdr = Cursor::new(vec![0, 0, 0, 149]);
260 /// assert_eq!(rdr.read_u32_ime().unwrap(), 9764864);
261 ///
262 /// ```
263 #[inline]
264 fn read_u32_ime(&mut self) -> Result<u32> {
265 Ok((self.read_u16()? as u32) | ((self.read_u16()? as u32) << 16))
266 }
267
268 /// Reads a signed dword as big endian
269 ///
270 /// # Examples
271 ///
272 /// ```rust
273 /// use std::io::Cursor;
274 /// use osrs_buffer::ReadExt;
275 ///
276 /// let mut rdr = Cursor::new(vec![255, 87, 33, 16]);
277 /// assert_eq!(rdr.read_i32().unwrap(), -11067120);
278 /// ```
279 #[inline]
280 fn read_i32(&mut self) -> Result<i32> {
281 Ok(self.read_u32()? as i32)
282 }
283
284 /// Reads an signed dword as little endian
285 ///
286 /// # Examples
287 ///
288 /// ```rust
289 /// use std::io::Cursor;
290 /// use osrs_buffer::ReadExt;
291 ///
292 /// let mut rdr = Cursor::new(vec![16, 33, 87, 250]);
293 /// assert_eq!(rdr.read_i32_le().unwrap(), -94953200);
294 /// ```
295 #[inline]
296 fn read_i32_le(&mut self) -> Result<i32> {
297 Ok(self.read_u32_le()? as i32)
298 }
299
300 /// Reads an signed dword as middle endian
301 ///
302 /// # Examples
303 ///
304 /// ```rust
305 /// use std::io::Cursor;
306 /// use osrs_buffer::ReadExt;
307 ///
308 /// let mut rdr = Cursor::new(vec![0, 149, 0, 0]);
309 /// assert_eq!(rdr.read_i32_me().unwrap(), -1795162112);
310 ///
311 /// ```
312 #[inline]
313 fn read_i32_me(&mut self) -> Result<i32> {
314 Ok(self.read_u32_me()? as i32)
315 }
316
317 /// Reads an unsigned dword as inversed middle endian
318 ///
319 /// # Examples
320 ///
321 /// ```rust
322 /// use std::io::Cursor;
323 /// use osrs_buffer::ReadExt;
324 ///
325 /// let mut rdr = Cursor::new(vec![118, 195, 254, 193]);
326 /// assert_eq!(rdr.read_i32_ime().unwrap(), -20875581);
327 ///
328 /// ```
329 #[inline]
330 fn read_i32_ime(&mut self) -> Result<i32> {
331 Ok(self.read_u32_ime()? as i32)
332 }
333
334 /// Reads an unsigned dword as big endian
335 ///
336 /// # Examples
337 ///
338 /// ```rust
339 /// use std::io::Cursor;
340 /// use osrs_buffer::ReadExt;
341 ///
342 /// let mut rdr = Cursor::new(vec![31, 84, 11, 99, 45, 12, 94, 36]);
343 /// assert_eq!(rdr.read_u64().unwrap(), 2257441833804914212);
344 /// ```
345 #[inline]
346 fn read_u64(&mut self) -> Result<u64> {
347 let mut buf = [0; 8];
348 self.read_exact(&mut buf)?;
349 Ok(u64::from_be_bytes(buf))
350 }
351
352 /// Reads an signed dword as big endian
353 ///
354 /// # Examples
355 ///
356 /// ```rust
357 /// use std::io::Cursor;
358 /// use osrs_buffer::ReadExt;
359 ///
360 /// let mut rdr = Cursor::new(vec![255, 84, 11, 99, 45, 12, 94, 36]);
361 /// assert_eq!(rdr.read_i64().unwrap(), -48401175408779740);
362 /// ```
363 #[inline]
364 fn read_i64(&mut self) -> Result<i64> {
365 Ok(self.read_u64()? as i64)
366 }
367
368 /// Reads a CP1252 string
369 ///
370 /// # Examples
371 ///
372 /// ```rust
373 /// use std::io::Cursor;
374 /// use osrs_buffer::ReadExt;
375 ///
376 /// let mut rdr = Cursor::new(vec![109, 121, 32, 116, 101, 115, 116, 0]);
377 /// assert_eq!(rdr.read_string_cp1252().unwrap(), "my test");
378 /// ```
379 #[inline]
380 fn read_string_cp1252(&mut self) -> Result<String> {
381 let mut str = Vec::new();
382
383 while let Ok(x) = self.read_u8() {
384 if x != 0 {
385 str.push(x);
386 } else {
387 break;
388 }
389 }
390
391 let s = match std::str::from_utf8(&str) {
392 Ok(v) => v,
393 Err(e) => {
394 return Err(Error::new(
395 ErrorKind::Other,
396 format!("Invalid UTF-8 sequence: {}", e),
397 ))
398 }
399 };
400
401 Ok(s.to_owned())
402 }
403}
404
405impl<R: io::Read + ?Sized> ReadExt for R {}
406
407pub trait WriteExt: Write {
408 /// Writes an unsigned byte to the writer.
409 ///
410 /// Examples
411 ///
412 /// ```rust
413 /// use osrs_buffer::WriteExt;
414 ///
415 /// let mut wtr = Vec::new();
416 /// wtr.write_u8(42).unwrap();
417 /// assert_eq!(wtr[0], 42);
418 /// ```
419 #[inline]
420 fn write_u8(&mut self, n: u8) -> Result<()> {
421 self.write_all(&[n])
422 }
423
424 /// Writes an signed byte to the writer.
425 ///
426 /// Examples
427 ///
428 /// ```rust
429 /// use osrs_buffer::WriteExt;
430 ///
431 /// let mut wtr = Vec::new();
432 /// wtr.write_i8(-67).unwrap();
433 /// assert_eq!(wtr[0] as i8, -67);
434 /// ```
435 #[inline]
436 fn write_i8(&mut self, n: i8) -> Result<()> {
437 self.write_u8(n as u8)
438 }
439
440 /// Writes the number 128, subtracted by the signed byte to the writer.
441 ///
442 /// # Examples
443 ///
444 /// ```rust
445 /// use osrs_buffer::WriteExt;
446 ///
447 /// let mut wtr = Vec::new();
448 /// wtr.write_i8_sub(99).unwrap();
449 /// assert_eq!(wtr[0] as i8, 29);
450 /// ```
451 #[inline]
452 fn write_i8_sub(&mut self, n: i8) -> Result<()> {
453 self.write_u8(128 - n as u8)
454 }
455
456 /// Writes the byte and adds 128.
457 ///
458 /// # Examples
459 ///
460 /// ```rust
461 /// use osrs_buffer::WriteExt;
462 ///
463 /// let mut wtr = Vec::new();
464 /// wtr.write_i8_add(42).unwrap();
465 /// assert_eq!(wtr[0], 170);
466 /// ```
467 #[inline]
468 fn write_i8_add(&mut self, n: i8) -> Result<()> {
469 self.write_u8(n as u8 + 128)
470 }
471
472 /// Writes a negated byte to the writer.
473 ///
474 /// # Examples
475 ///
476 /// ```rust
477 /// use osrs_buffer::WriteExt;
478 ///
479 /// let mut wtr = Vec::new();
480 /// wtr.write_i8_neg(55).unwrap();
481 /// assert_eq!(wtr[0], 201);
482 /// ```
483 #[inline]
484 fn write_i8_neg(&mut self, n: i8) -> Result<()> {
485 self.write_u8(-n as u8)
486 }
487
488 /// Writes a bool to the writer.
489 ///
490 /// Examples
491 ///
492 /// ```rust
493 /// use osrs_buffer::WriteExt;
494 ///
495 /// let mut wtr = Vec::new();
496 /// wtr.write_bool(true).unwrap();
497 /// assert_eq!(wtr[0], 1);
498 /// ```
499 #[inline]
500 fn write_bool(&mut self, b: bool) -> Result<()> {
501 self.write_all(&[b as u8])
502 }
503
504 /// Writes an unsigned short to the writer.
505 ///
506 /// # Examples
507 ///
508 /// ```rust
509 /// use osrs_buffer::WriteExt;
510 ///
511 /// let mut wtr = Vec::new();
512 /// wtr.write_u16(20065).unwrap();
513 /// assert_eq!(wtr[0], 78);
514 /// assert_eq!(wtr[1], 97);
515 /// ```
516 #[inline]
517 fn write_u16(&mut self, n: u16) -> Result<()> {
518 self.write_all(&n.to_be_bytes())
519 }
520
521 /// Writes an unsigned short as a little endian to the writer.
522 ///
523 /// # Examples
524 ///
525 /// ```rust
526 /// use osrs_buffer::WriteExt;
527 ///
528 /// let mut wtr = Vec::new();
529 /// wtr.write_u16_le(29543).unwrap();
530 /// assert_eq!(wtr[0], 103);
531 /// assert_eq!(wtr[1], 115);
532 /// ```
533 ///
534 #[inline]
535 fn write_u16_le(&mut self, n: u16) -> Result<()> {
536 self.write_all(&n.to_le_bytes())
537 }
538
539 /// Writes an unsigned short smart to the writer.
540 ///
541 /// # Examples
542 ///
543 /// Writing a value lesser than or equal to 127 makes it write out a single unsigned byte.
544 ///
545 /// ```rust
546 /// use osrs_buffer::WriteExt;
547 ///
548 /// let mut wtr = Vec::new();
549 /// wtr.write_u16_smart(65).unwrap();
550 /// assert_eq!(wtr[0], 65);
551 /// assert!(wtr.get(1).is_none());
552 /// ```
553 ///
554 /// Writing a value greater than 127 will make it write out two unsigned bytes.
555 ///
556 /// ```rust
557 /// use osrs_buffer::WriteExt;
558 ///
559 /// let mut wtr = Vec::new();
560 /// wtr.write_u16_smart(986).unwrap();
561 /// assert_eq!(wtr[0], 131);
562 /// assert_eq!(wtr[1], 218);
563 /// ```
564 ///
565 #[inline]
566 fn write_u16_smart(&mut self, n: u16) -> Result<()> {
567 match n {
568 0..=127 => self.write_u8(n as u8),
569 128..=32767 => self.write_u16(n + 32768),
570 _ => Err(Error::new(
571 ErrorKind::Other,
572 format!("Failed writing smart, value is {}", n),
573 )),
574 }
575 }
576
577 /// Writes a signed short to the writer.
578 ///
579 /// # Examples
580 ///
581 /// ```rust
582 /// use osrs_buffer::WriteExt;
583 ///
584 /// let mut wtr = Vec::new();
585 /// wtr.write_i16(-14632).unwrap();
586 /// assert_eq!(wtr[0], 198);
587 /// assert_eq!(wtr[1], 216);
588 /// ```
589 #[inline]
590 fn write_i16(&mut self, n: i16) -> Result<()> {
591 self.write_u16(n as u16)
592 }
593
594 /// Writes a signed short as little endian to the writer.
595 ///
596 /// # Examples
597 ///
598 /// ```rust
599 /// use osrs_buffer::WriteExt;
600 ///
601 /// let mut wtr = Vec::new();
602 /// wtr.write_i16_le(-7654).unwrap();
603 /// assert_eq!(wtr[0], 26);
604 /// assert_eq!(wtr[1], 226);
605 /// ```
606 #[inline]
607 fn write_i16_le(&mut self, n: i16) -> Result<()> {
608 self.write_u16_le(n as u16)
609 }
610
611 /// Writes a signed short add to the writer.
612 ///
613 /// # Examples
614 ///
615 /// ```rust
616 /// use osrs_buffer::WriteExt;
617 ///
618 /// let mut wtr = Vec::new();
619 /// wtr.write_i16_add(-9867).unwrap();
620 /// assert_eq!(wtr[0], 217);
621 /// assert_eq!(wtr[1], 245);
622 /// ```
623 ///
624 #[inline]
625 fn write_i16_add(&mut self, n: i16) -> Result<()> {
626 self.write_i8((n >> 8) as i8)?;
627 self.write_i8((n + 128) as i8)
628 }
629
630 /// Writes a signed short add as a little endian to the writer.
631 ///
632 /// # Examples
633 ///
634 /// ```rust
635 /// use osrs_buffer::WriteExt;
636 ///
637 /// let mut wtr = Vec::new();
638 /// wtr.write_i16_le_add(-12632).unwrap();
639 /// assert_eq!(wtr[0], 40);
640 /// assert_eq!(wtr[1], 206);
641 /// ```
642 ///
643 #[inline]
644 fn write_i16_le_add(&mut self, n: i16) -> Result<()> {
645 self.write_i8((n + 128) as i8)?;
646 self.write_i8((n >> 8) as i8)
647 }
648
649 /// Writes an unsigned dword to the writer.
650 ///
651 /// # Examples
652 ///
653 /// ```rust
654 /// use osrs_buffer::WriteExt;
655 ///
656 /// let mut wtr = Vec::new();
657 /// wtr.write_u32(98571).unwrap();
658 /// assert_eq!(wtr[0], 0);
659 /// assert_eq!(wtr[1], 1);
660 /// assert_eq!(wtr[2], 129);
661 /// assert_eq!(wtr[3], 11);
662 /// ```
663 ///
664 #[inline]
665 fn write_u32(&mut self, n: u32) -> Result<()> {
666 self.write_all(&n.to_be_bytes())
667 }
668
669 /// Writes am unsigned integer as little endian to the writer.
670 ///
671 /// # Examples
672 ///
673 /// ```rust
674 /// use osrs_buffer::WriteExt;
675 ///
676 /// let mut wtr = Vec::new();
677 /// wtr.write_u32_le(26904).unwrap();
678 /// assert_eq!(wtr[0], 24);
679 /// assert_eq!(wtr[1], 105);
680 /// assert_eq!(wtr[2], 0);
681 /// assert_eq!(wtr[3], 0);
682 /// ```
683 ///
684 #[inline]
685 fn write_u32_le(&mut self, n: u32) -> Result<()> {
686 self.write_all(&n.to_le_bytes())
687 }
688
689 /// Writes a signed dword to the writer.
690 ///
691 /// # Examples
692 ///
693 /// ```rust
694 /// use osrs_buffer::WriteExt;
695 ///
696 /// let mut wtr = Vec::new();
697 /// wtr.write_i32(-131045).unwrap();
698 /// assert_eq!(wtr[0], 255);
699 /// assert_eq!(wtr[1], 254);
700 /// assert_eq!(wtr[2], 0);
701 /// assert_eq!(wtr[3], 27);
702 /// ```
703 ///
704 #[inline]
705 fn write_i32(&mut self, n: i32) -> Result<()> {
706 self.write_u32(n as u32)
707 }
708
709 /// Writes a signed integer as little endian to the writer.
710 ///
711 /// # Examples
712 ///
713 /// ```rust
714 /// use osrs_buffer::WriteExt;
715 ///
716 /// let mut wtr = Vec::new();
717 /// wtr.write_i32_le(18879).unwrap();
718 /// assert_eq!(wtr[0], 191);
719 /// assert_eq!(wtr[1], 73);
720 /// assert_eq!(wtr[2], 0);
721 /// assert_eq!(wtr[3], 0);
722 /// ```
723 ///
724 #[inline]
725 fn write_i32_le(&mut self, n: i32) -> Result<()> {
726 self.write_u32_le(n as u32)
727 }
728
729 /// Writes a signed dword as a middle endian to the writer.
730 ///
731 /// # Examples
732 ///
733 /// ```rust
734 /// use osrs_buffer::WriteExt;
735 ///
736 /// let mut wtr = Vec::new();
737 /// wtr.write_i32_me(-98231).unwrap();
738 /// assert_eq!(wtr[0], 254);
739 /// assert_eq!(wtr[1], 255);
740 /// assert_eq!(wtr[2], 73);
741 /// assert_eq!(wtr[3], 128);
742 /// ```
743 ///
744 #[inline]
745 fn write_i32_me(&mut self, n: i32) -> Result<()> {
746 self.write_i16_le((n >> 16) as i16)?;
747 self.write_i16_le(n as i16)
748 }
749
750 /// Writes a signed dword as an inversed middle endian to the writer.
751 ///
752 /// # Examples
753 ///
754 /// ```rust
755 /// use osrs_buffer::WriteExt;
756 ///
757 /// let mut wtr = Vec::new();
758 /// wtr.write_i32_ime(-98231).unwrap();
759 /// assert_eq!(wtr[0], 128);
760 /// assert_eq!(wtr[1], 73);
761 /// assert_eq!(wtr[2], 255);
762 /// assert_eq!(wtr[3], 254);
763 /// ```
764 ///
765 #[inline]
766 fn write_i32_ime(&mut self, n: i32) -> Result<()> {
767 self.write_i16(n as i16)?;
768 self.write_i16((n >> 16) as i16)
769 }
770
771 /// Writes an unsigned qword to the writer.
772 ///
773 /// # Examples
774 ///
775 /// ```rust
776 /// use osrs_buffer::WriteExt;
777 ///
778 /// let mut wtr = Vec::new();
779 /// wtr.write_u64(8589934592).unwrap();
780 /// assert_eq!(wtr[0], 0);
781 /// assert_eq!(wtr[1], 0);
782 /// assert_eq!(wtr[2], 0);
783 /// assert_eq!(wtr[3], 2);
784 /// assert_eq!(wtr[4], 0);
785 /// assert_eq!(wtr[5], 0);
786 /// assert_eq!(wtr[6], 0);
787 /// assert_eq!(wtr[7], 0);
788 /// ```
789 ///
790 #[inline]
791 fn write_u64(&mut self, n: u64) -> Result<()> {
792 self.write_all(&n.to_be_bytes())
793 }
794
795 /// Writes a signed qword to the writer.
796 ///
797 /// # Examples
798 ///
799 /// ```rust
800 /// use osrs_buffer::WriteExt;
801 ///
802 /// let mut wtr = Vec::new();
803 /// wtr.write_i64(-8589934592).unwrap();
804 /// assert_eq!(wtr[0], 255);
805 /// assert_eq!(wtr[1], 255);
806 /// assert_eq!(wtr[2], 255);
807 /// assert_eq!(wtr[3], 254);
808 /// assert_eq!(wtr[4], 0);
809 /// assert_eq!(wtr[5], 0);
810 /// assert_eq!(wtr[6], 0);
811 /// assert_eq!(wtr[7], 0);
812 /// ```
813 ///
814 #[inline]
815 fn write_i64(&mut self, n: i64) -> Result<()> {
816 self.write_u64(n as u64)
817 }
818
819 /// Writes a CP1252 string to the writer.
820 ///
821 /// # Examples
822 ///
823 /// ```rust
824 /// use osrs_buffer::WriteExt;
825 ///
826 /// let mut wtr = Vec::new();
827 /// wtr.write_string_cp1252("hello").unwrap();
828 /// assert_eq!(wtr[0], 104);
829 /// assert_eq!(wtr[1], 101);
830 /// assert_eq!(wtr[2], 108);
831 /// assert_eq!(wtr[3], 108);
832 /// assert_eq!(wtr[4], 111);
833 /// assert_eq!(wtr[5], 0);
834 /// ```
835 ///
836 #[inline]
837 fn write_string_cp1252(&mut self, s: &str) -> Result<()> {
838 for b in s.as_bytes() {
839 self.write_u8(*b)?;
840 }
841 self.write_i8(0)
842 }
843
844 /// Write bytes reversed with add to the writer.
845 ///
846 /// # Examples
847 ///
848 /// ```rust
849 /// use osrs_buffer::WriteExt;
850 ///
851 /// let wtr1 = vec![1, 2, 3];
852 ///
853 /// let mut wtr2 = Vec::new();
854 /// wtr2.write_bytes_reversed_add(&wtr1);
855 /// assert_eq!(wtr2[0], 131);
856 /// assert_eq!(wtr2[1], 130);
857 /// assert_eq!(wtr2[2], 129);
858 /// ```
859 ///
860 #[inline]
861 fn write_bytes_reversed_add(&mut self, buf: &[u8]) -> Result<()> {
862 for b in buf.iter().rev() {
863 self.write_i8(b.wrapping_add((i8::MAX as u8) + 1) as i8)?;
864 }
865 Ok(())
866 }
867}
868
869impl<W: io::Write + ?Sized> WriteExt for W {}
870
871/*
872#[cfg(test)]
873mod tests {
874 //use super::*;
875
876 // Tests that do not fit in documentation should be placed here.
877
878
879 #[test]
880 fn test_write_u8() {
881 ...
882 }
883}
884*/