@@ -163,6 +163,24 @@ extension type BinaryWriter._(_WriterState _ws) {
163163 writeVarUint (encoded);
164164 }
165165
166+ /// Writes a boolean value as a single byte.
167+ ///
168+ /// `true` is written as `1` and `false` as `0` .
169+ ///
170+ /// Example:
171+ /// ```dart
172+ /// writer.writeBool(true); // Writes byte 0x01
173+ /// writer.writeBool(false); // Writes byte 0x00
174+ /// ```
175+ ///
176+ @pragma ('vm:prefer-inline' )
177+ @pragma ('dart2js:tryInline' )
178+ // Disable lint to allow positional boolean parameter for simplicity
179+ // ignore: avoid_positional_boolean_parameters
180+ void writeBool (bool value) {
181+ writeUint8 (value ? 1 : 0 );
182+ }
183+
166184 /// Writes an 8-bit unsigned integer (0-255).
167185 ///
168186 /// Example:
@@ -657,7 +675,7 @@ extension type BinaryWriter._(_WriterState _ws) {
657675 }
658676
659677 @pragma ('vm:prefer-inline' )
660- @pragma ('vm:prefer-inline ' )
678+ @pragma ('dart2js:tryInline ' )
661679 int _varIntSize (int value) => switch (value) {
662680 < 0x80 => 1 ,
663681 < 0x4000 => 2 ,
@@ -684,7 +702,7 @@ extension type BinaryWriter._(_WriterState _ws) {
684702 /// writer.writeStringFixed('Hello', lengthEncoding: LengthEncoding.u16);
685703 /// ```
686704 @pragma ('vm:prefer-inline' )
687- @pragma ('vm:prefer-inline ' )
705+ @pragma ('dart2js:tryInline ' )
688706 void writeStringFixed (
689707 String value, {
690708 LengthEncoding lengthEncoding = .u8,
@@ -728,24 +746,6 @@ extension type BinaryWriter._(_WriterState _ws) {
728746 }
729747 }
730748
731- /// Writes a boolean value as a single byte.
732- ///
733- /// `true` is written as `1` and `false` as `0` .
734- ///
735- /// Example:
736- /// ```dart
737- /// writer.writeBool(true); // Writes byte 0x01
738- /// writer.writeBool(false); // Writes byte 0x00
739- /// ```
740- ///
741- @pragma ('vm:prefer-inline' )
742- @pragma ('dart2js:tryInline' )
743- // Disable lint to allow positional boolean parameter for simplicity
744- // ignore: avoid_positional_boolean_parameters
745- void writeBool (bool value) {
746- writeUint8 (value ? 1 : 0 );
747- }
748-
749749 /// Writes a sequence of bytes.
750750 ///
751751 /// This is a concise alias for [writeBytes] .
@@ -760,35 +760,51 @@ extension type BinaryWriter._(_WriterState _ws) {
760760
761761 /// Extracts all written bytes and resets the writer.
762762 ///
763- /// After calling this method, the writer is reset and ready for reuse.
764- /// This is more efficient than creating a new writer for each operation.
765- ///
766- /// Returns a view of the written bytes (no copying occurs).
763+ /// [copy] determines how the bytes are extracted:
764+ /// - If `true` : The written bytes are copied into a new [Uint8List] . The
765+ /// internal buffer is retained and its offset is reset to 0. This is
766+ /// highly efficient for pooling (e.g., [BinaryWriterPool] ) as the same
767+ /// large buffer is reused for subsequent operations without re-allocation.
768+ /// - If `false` (default): A view of the internal buffer is returned, and
769+ /// the writer detaches from it by allocating a fresh initial-sized buffer.
770+ /// While the returned bytes are "zero-copy" relative to the old buffer,
771+ /// this forces the writer to re-allocate memory, which is less efficient
772+ /// for pooling long-term.
767773 ///
768- /// **Use case:** When you're done with this batch and want to start fresh .
774+ /// After calling this method, the writer is reset and ready for reuse .
769775 ///
770776 /// Example:
771777 /// ```dart
772778 /// final writer = BinaryWriter();
773779 /// writer.writeUint32(42);
774- /// final packet1 = writer.takeBytes(); // Get bytes and reset
775- /// writer.writeUint32(100); // Writer is ready for reuse
776- /// final packet2 = writer.takeBytes();
780+ /// // For best pooling performance (retains internal buffer):
781+ /// final packet = writer.takeBytes(copy: true);
777782 /// ```
778783 @pragma ('vm:prefer-inline' )
779784 @pragma ('dart2js:tryInline' )
780- Uint8List takeBytes () {
785+ Uint8List takeBytes ({bool copy = false }) {
786+ if (copy) {
787+ final result = _ws.list.sublist (0 , _ws.offset);
788+ _ws.offset = 0 ;
789+
790+ return result;
791+ }
792+
781793 final result = Uint8List .sublistView (_ws.list, 0 , _ws.offset);
782794 _ws._initializeBuffer ();
783795
784796 return result;
785797 }
786798
787- /// Returns a view of the written bytes without resetting the writer.
799+ /// Returns a view of the written bytes (from index 0 up to the current
800+ /// [bytesWritten] ) without resetting the writer.
788801 ///
789802 /// Unlike [takeBytes] , this does not reset the writer's state.
790803 /// Subsequent writes will continue appending to the buffer.
791804 ///
805+ /// **Note:** Since this returns a view, the content of the returned list
806+ /// will change if you continue writing to this writer.
807+ ///
792808 /// **Use case:** When you need to inspect or copy data mid-stream.
793809 ///
794810 /// Example:
@@ -827,33 +843,60 @@ extension type BinaryWriter._(_WriterState _ws) {
827843 _ws.offset = position;
828844 }
829845
846+ /// Returns the byte at the specified [index] without changing the current
847+ /// write position.
848+ ///
849+ /// Throws [RangeError] if [index] is negative or greater than or equal to
850+ /// [bytesWritten] .
851+ @pragma ('vm:prefer-inline' )
852+ @pragma ('dart2js:tryInline' )
853+ int operator [](int index) {
854+ if (index < 0 || index >= _ws.offset) {
855+ throw RangeError .range (index, 0 , _ws.offset - 1 , 'index' );
856+ }
857+ return _ws.list[index];
858+ }
859+
860+ /// Writes a byte at the specified [index] without changing the current
861+ /// write position.
862+ ///
863+ /// This operator is used to overwrite already written bytes. To append data,
864+ /// use the standard `write*` methods.
865+ ///
866+ /// Throws [RangeError] if [index] is negative or greater than or equal to
867+ /// [bytesWritten] .
868+ @pragma ('vm:prefer-inline' )
869+ @pragma ('dart2js:tryInline' )
870+ void operator []= (int index, int value) {
871+ if (index < 0 || index >= _ws.offset) {
872+ throw RangeError .range (index, 0 , _ws.offset - 1 , 'index' );
873+ }
874+
875+ _checkRange (value, 0 , 255 , 'Uint8' );
876+ _ws.list[index] = value;
877+ }
878+
830879 /// Writes a byte at the specified [position] without changing the current
831880 /// write position.
832881 ///
833- /// This is useful for overwriting data at a known offset (e.g., updating a
834- /// length field after writing the payload ).
882+ /// Used to overwrite data at a previously written offset (e.g.,
883+ /// updating a length field ).
835884 ///
836- /// Throws [RangeError] if [position] is negative or exceeds [bytesWritten] .
885+ /// This is a functional alias for `operator []=` .
886+ ///
887+ /// Throws [RangeError] if [position] is negative or greater than or equal to
888+ /// [bytesWritten] .
837889 ///
838890 /// Example:
839891 /// ```dart
840892 /// writer.writeUint32(10); // Write length placeholder
841893 /// writer.writeString('data');
842894 /// writer.writeUint8At(0, 15); // Overwrite length at position 0
895+ /// // or: writer[0] = 15;
843896 /// ```
844897 @pragma ('vm:prefer-inline' )
845898 @pragma ('dart2js:tryInline' )
846- void writeUint8At (int position, int value) {
847- if (position < 0 || position > _ws.offset) {
848- throw RangeError .range (position, 0 , _ws.offset, 'position' );
849- }
850-
851- _checkRange (value, 0 , 255 , 'Uint8' );
852- _ws.list[position] = value;
853- if (position == _ws.offset) {
854- _ws.offset = position + 1 ;
855- }
856- }
899+ void writeUint8At (int position, int value) => this [position] = value;
857900
858901 /// Resets the writer to its initial state, discarding all written data.
859902 @pragma ('vm:prefer-inline' )
0 commit comments