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*/