@@ -1137,14 +1137,16 @@ public override void WriteByte(byte value)
11371137 // As it turns out, strings cannot be treated as char arrays, since strings use pointers to store data rather than C# arrays
11381138 public void WriteString ( string s , bool oneByteChars = false )
11391139 {
1140- WriteUInt64Packed ( ( ulong ) s . Length * ( oneByteChars ? 1UL : 2UL ) ) ;
1140+ WriteUInt32Packed ( ( uint ) s . Length ) ;
11411141 int target = s . Length ;
1142- for ( int i = 0 ; i < target ; ++ i ) WriteChar ( s [ i ] ) ;
1142+ for ( int i = 0 ; i < target ; ++ i )
1143+ if ( oneByteChars ) WriteByte ( ( byte ) s [ i ] ) ;
1144+ else WriteChar ( s [ i ] ) ;
11431145 }
11441146
1145- public void WriteStringPacked ( string s , bool oneByteChars = false )
1147+ public void WriteStringPacked ( string s )
11461148 {
1147- WriteUInt64Packed ( ( ulong ) s . Length * ( oneByteChars ? 1UL : 2UL ) ) ;
1149+ WriteUInt32Packed ( ( uint ) s . Length ) ;
11481150 int target = s . Length ;
11491151 for ( int i = 0 ; i < target ; ++ i ) WriteCharPacked ( s [ i ] ) ;
11501152 }
@@ -1154,7 +1156,7 @@ public void WriteStringDiff(string write, string compare, bool oneByteChars = fa
11541156#if ! ARRAY_DIFF_ALLOW_RESIZE
11551157 if ( write . Length != compare . Length ) throw new ArgumentException ( "Mismatched string lengths" ) ;
11561158#endif
1157- WriteUInt64Packed ( ( ulong ) write . Length * ( oneByteChars ? 1UL : 2UL ) ) ;
1159+ WriteUInt32Packed ( ( uint ) write . Length ) ;
11581160
11591161 // Premapping
11601162#if ARRAY_WRITE_PREMAP
@@ -1181,13 +1183,13 @@ public void WriteStringDiff(string write, string compare, bool oneByteChars = fa
11811183 }
11821184 }
11831185
1184- public void WriteStringPackedDiff ( string write , string compare , bool oneByteChars = false )
1186+ public void WriteStringPackedDiff ( string write , string compare )
11851187 {
11861188
11871189#if ! ARRAY_DIFF_ALLOW_RESIZE
11881190 if ( write . Length != compare . Length ) throw new ArgumentException ( "Mismatched string lengths" ) ;
11891191#endif
1190- WriteUInt64Packed ( ( ulong ) write . Length * ( oneByteChars ? 1UL : 2UL ) ) ;
1192+ WriteUInt32Packed ( ( uint ) write . Length ) ;
11911193
11921194 // Premapping
11931195#if ARRAY_WRITE_PREMAP
@@ -1206,11 +1208,7 @@ public void WriteStringPackedDiff(string write, string compare, bool oneByteChar
12061208#if ! ARRAY_WRITE_PREMAP
12071209 WriteBit ( ! b ) ;
12081210#endif
1209- if ( b )
1210- {
1211- if ( oneByteChars ) WriteByte ( ( byte ) write [ i ] ) ;
1212- else WriteCharPacked ( write [ i ] ) ;
1213- }
1211+ if ( b ) WriteCharPacked ( write [ i ] ) ;
12141212 }
12151213 }
12161214
@@ -1691,6 +1689,151 @@ public void WriteDoubleArrayPackedDiff(double[] write, double[] compare, long co
16911689
16921690
16931691 // Read arrays
1692+ public StringBuilder ReadString ( bool oneByteChars ) => ReadString ( null , oneByteChars ) ;
1693+ public StringBuilder ReadString ( StringBuilder builder = null , bool oneByteChars = false )
1694+ {
1695+ int expectedLength = ( int ) ReadUInt32Packed ( ) ;
1696+ if ( builder == null ) builder = new StringBuilder ( expectedLength ) ;
1697+ else if ( builder . Capacity + builder . Length < expectedLength ) builder . Capacity = expectedLength + builder . Length ;
1698+ for ( int i = 0 ; i < expectedLength ; ++ i )
1699+ builder . Insert ( i , oneByteChars ? ( char ) _ReadByte ( ) : ReadChar ( ) ) ;
1700+ return builder ;
1701+ }
1702+
1703+ public StringBuilder ReadStringPacked ( StringBuilder builder = null )
1704+ {
1705+ int expectedLength = ( int ) ReadUInt32Packed ( ) ;
1706+ if ( builder == null ) builder = new StringBuilder ( expectedLength ) ;
1707+ else if ( builder . Capacity + builder . Length < expectedLength ) builder . Capacity = expectedLength + builder . Length ;
1708+ for ( int i = 0 ; i < expectedLength ; ++ i )
1709+ builder . Insert ( i , ReadCharPacked ( ) ) ;
1710+ return builder ;
1711+ }
1712+
1713+ public StringBuilder ReadStringDiff ( string compare , bool oneByteChars = false ) => ReadStringDiff ( null , compare , oneByteChars ) ;
1714+ public StringBuilder ReadStringDiff ( StringBuilder builder , string compare , bool oneByteChars = false )
1715+ {
1716+ int expectedLength = ( int ) ReadUInt32Packed ( ) ;
1717+ if ( builder == null ) builder = new StringBuilder ( expectedLength ) ;
1718+ else if ( builder . Capacity < expectedLength ) builder . Capacity = expectedLength ;
1719+ ulong dBlockStart = BitPosition + ( ulong ) ( compare == null ? 0 : Math . Min ( expectedLength , compare . Length ) ) ;
1720+ ulong mapStart ;
1721+ int compareLength = compare == null ? 0 : compare . Length ;
1722+ for ( int i = 0 ; i < expectedLength ; ++ i )
1723+ {
1724+ if ( i >= compareLength || ReadBit ( ) )
1725+ {
1726+ #if ARRAY_WRITE_PREMAP
1727+ // Move to data section
1728+ mapStart = BitPosition ;
1729+ BitPosition = dBlockStart ;
1730+ #endif
1731+ // Read datum
1732+ builder . Insert ( i , oneByteChars ? ( char ) _ReadByte ( ) : ReadChar ( ) ) ;
1733+ #if ARRAY_WRITE_PREMAP
1734+ dBlockStart = BitPosition ;
1735+ // Return to mapping section
1736+ BitPosition = mapStart ;
1737+ #endif
1738+ }
1739+ else if ( i < compareLength ) builder . Insert ( i , compare [ i ] ) ;
1740+ }
1741+ BitPosition = dBlockStart ;
1742+ return builder ;
1743+ }
1744+
1745+ public StringBuilder ReadStringDiff ( StringBuilder compareAndBuffer , bool oneByteChars = false )
1746+ {
1747+ int expectedLength = ( int ) ReadUInt32Packed ( ) ;
1748+ if ( compareAndBuffer == null ) throw new ArgumentNullException ( "Buffer cannot be null" ) ;
1749+ else if ( compareAndBuffer . Capacity < expectedLength ) compareAndBuffer . Capacity = expectedLength ;
1750+ ulong dBlockStart = BitPosition + ( ulong ) Math . Min ( expectedLength , compareAndBuffer . Length ) ;
1751+ ulong mapStart ;
1752+ for ( int i = 0 ; i < expectedLength ; ++ i )
1753+ {
1754+ if ( i >= compareAndBuffer . Length || ReadBit ( ) )
1755+ {
1756+ #if ARRAY_WRITE_PREMAP
1757+ // Move to data section
1758+ mapStart = BitPosition ;
1759+ BitPosition = dBlockStart ;
1760+ #endif
1761+ // Read datum
1762+ compareAndBuffer . Remove ( i , 1 ) ;
1763+ compareAndBuffer . Insert ( i , oneByteChars ? ( char ) _ReadByte ( ) : ReadChar ( ) ) ;
1764+ #if ARRAY_WRITE_PREMAP
1765+ dBlockStart = BitPosition ;
1766+ // Return to mapping section
1767+ BitPosition = mapStart ;
1768+ #endif
1769+ }
1770+ }
1771+ BitPosition = dBlockStart ;
1772+ return compareAndBuffer ;
1773+ }
1774+
1775+ public StringBuilder ReadStringPackedDiff ( string compare ) => ReadStringPackedDiff ( null , compare ) ;
1776+ public StringBuilder ReadStringPackedDiff ( StringBuilder builder , string compare )
1777+ {
1778+ int expectedLength = ( int ) ReadUInt32Packed ( ) ;
1779+ if ( builder == null ) builder = new StringBuilder ( expectedLength ) ;
1780+ else if ( builder . Capacity < expectedLength ) builder . Capacity = expectedLength ;
1781+ ulong dBlockStart = BitPosition + ( ulong ) ( compare == null ? 0 : Math . Min ( expectedLength , compare . Length ) ) ;
1782+ ulong mapStart ;
1783+ int compareLength = compare == null ? 0 : compare . Length ;
1784+ for ( int i = 0 ; i < expectedLength ; ++ i )
1785+ {
1786+ if ( i >= compareLength || ReadBit ( ) )
1787+ {
1788+ #if ARRAY_WRITE_PREMAP
1789+ // Move to data section
1790+ mapStart = BitPosition ;
1791+ BitPosition = dBlockStart ;
1792+ #endif
1793+ // Read datum
1794+ builder . Insert ( i , ReadCharPacked ( ) ) ;
1795+ #if ARRAY_WRITE_PREMAP
1796+ dBlockStart = BitPosition ;
1797+ // Return to mapping section
1798+ BitPosition = mapStart ;
1799+ #endif
1800+ }
1801+ else if ( i < compareLength ) builder . Insert ( i , compare [ i ] ) ;
1802+ }
1803+ BitPosition = dBlockStart ;
1804+ return builder ;
1805+ }
1806+
1807+ public StringBuilder ReadStringPackedDiff ( StringBuilder compareAndBuffer )
1808+ {
1809+ int expectedLength = ( int ) ReadUInt32Packed ( ) ;
1810+ if ( compareAndBuffer == null ) throw new ArgumentNullException ( "Buffer cannot be null" ) ;
1811+ else if ( compareAndBuffer . Capacity < expectedLength ) compareAndBuffer . Capacity = expectedLength ;
1812+ ulong dBlockStart = BitPosition + ( ulong ) Math . Min ( expectedLength , compareAndBuffer . Length ) ;
1813+ ulong mapStart ;
1814+ for ( int i = 0 ; i < expectedLength ; ++ i )
1815+ {
1816+ if ( i >= compareAndBuffer . Length || ReadBit ( ) )
1817+ {
1818+ #if ARRAY_WRITE_PREMAP
1819+ // Move to data section
1820+ mapStart = BitPosition ;
1821+ BitPosition = dBlockStart ;
1822+ #endif
1823+ // Read datum
1824+ compareAndBuffer . Remove ( i , 1 ) ;
1825+ compareAndBuffer . Insert ( i , ReadCharPacked ( ) ) ;
1826+ #if ARRAY_WRITE_PREMAP
1827+ dBlockStart = BitPosition ;
1828+ // Return to mapping section
1829+ BitPosition = mapStart ;
1830+ #endif
1831+ }
1832+ }
1833+ BitPosition = dBlockStart ;
1834+ return compareAndBuffer ;
1835+ }
1836+
16941837 public byte [ ] ReadByteArray ( byte [ ] readTo = null , long knownLength = - 1 )
16951838 {
16961839 if ( knownLength < 0 ) knownLength = ( long ) ReadUInt64Packed ( ) ;
0 commit comments