public static void SetPreviousByte(StringIO /*!*/ self, [DefaultProtocol] int b) { // MRI: this checks if the IO is readable although it actually modifies the string: MutableString content = self.GetReadableContent(); int pos = self._position - 1; if (pos >= 0) { int length = content.GetByteCount(); try { if (pos >= length) { content.Append(0, pos - length); content.Append(unchecked ((byte)b)); } else { content.SetByte(pos, unchecked ((byte)b)); } self._position = pos; } catch (InvalidOperationException) { throw RubyExceptions.CreateIOError("not modifiable string"); } } }
private static MutableString ReadLine(MutableString /*!*/ content, MutableString separator, ref int position) { int length = content.GetByteCount(); if (position >= length) { return(null); } int oldPosition = position; if (separator == null) { position = length; } else if (separator.IsEmpty) { // skip initial ends of line: while (oldPosition < length && content.GetByte(oldPosition) == '\n') { oldPosition++; } position = content.IndexOf(ParagraphSeparator, oldPosition); position = (position != -1) ? position + 1 : length; } else { position = content.IndexOf(separator, oldPosition); position = (position != -1) ? position + separator.Length : length; } return(content.GetSlice(oldPosition, position - oldPosition)); }
public static int Write(StringIO /*!*/ self, [NotNull] MutableString /*!*/ value) { var content = self.GetWritableContent(); int length = content.GetByteCount(); var bytesWritten = value.GetByteCount(); int pos; if ((self._mode & IOMode.WriteAppends) != 0) { pos = length; } else { pos = self._position; } try { content.WriteBytes(pos, value, 0, bytesWritten); } catch (InvalidOperationException) { throw RubyExceptions.CreateIOError("not modifiable string"); } content.TaintBy(value); self._position = pos + bytesWritten; return(bytesWritten); }
public static Win32API /*!*/ Reinitialize(Win32API /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ libraryName, [DefaultProtocol, NotNull] MutableString /*!*/ functionName, [DefaultProtocol, NotNull] MutableString /*!*/ parameterTypes, [DefaultProtocol, NotNull] MutableString /*!*/ returnType) { return(self.Reinitialize( GetFunction(libraryName, functionName), MakeSignature(parameterTypes.GetByteCount(), parameterTypes.GetByte), returnType.IsEmpty ? ArgType.None : ToArgType(returnType.GetByte(0)) )); }
private static int ReadUtf8CodePoint(MutableString/*!*/ data, ref int index) { int length = data.GetByteCount(); if (index >= length) { return -1; } int b = data.GetByte(index++); int count, mask; if ((b & 0x80) == 0) { count = 1; mask = 0xff; } else if ((b & 0xe0) == 0xc0) { count = 2; mask = 0x1f; } else if ((b & 0xf0) == 0xe0) { count = 3; mask = 0x0f; } else if ((b & 0xf8) == 0xf0) { count = 4; mask = 0x07; } else if ((b & 0xfc) == 0xf8) { count = 5; mask = 0x03; } else if ((b & 0xfe) == 0xfc) { count = 6; mask = 0x01; } else { throw RubyExceptions.CreateArgumentError("malformed UTF-8 character"); } int codepoint = b & mask; for (int i = 1; i < count; i++) { if (index >= length) { throw RubyExceptions.CreateArgumentError( "malformed UTF-8 character (expected {0} bytes, given {1} bytes)", count, i ); } b = data.GetByte(index++); if ((b & 0xc0) != 0x80) { throw RubyExceptions.CreateArgumentError("malformed UTF-8 character"); } codepoint = (codepoint << 6) | (b & 0x3f); } int requiredCount; int mark; GetCodePointByteCount(codepoint, out requiredCount, out mark); if (requiredCount != count) { throw RubyExceptions.CreateArgumentError("redundant UTF-8 sequence"); } return codepoint; }
public static int Send(ConversionStorage <int> /*!*/ fixnumCast, RubyBasicSocket /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ message, object flags, [DefaultProtocol, NotNull] MutableString /*!*/ to) { Protocols.CheckSafeLevel(fixnumCast.Context, 4, "send"); // Convert the parameters SocketFlags socketFlags = ConvertToSocketFlag(fixnumCast, flags); // Unpack the socket address information from the to parameter SocketAddress address = new SocketAddress(AddressFamily.InterNetwork); for (int i = 0; i < to.GetByteCount(); i++) { address[i] = to.GetByte(i); } EndPoint toEndPoint = self.Socket.LocalEndPoint.Create(address); return(self.Socket.SendTo(message.ConvertToBytes(), socketFlags, toEndPoint)); }
public static int Send(RubyContext /*!*/ context, RubyBasicSocket /*!*/ self, object message, object flags, object to) { Protocols.CheckSafeLevel(context, 4, "send"); // Convert the parameters SocketFlags socketFlags = ConvertToSocketFlag(context, flags); MutableString strMessage = Protocols.CastToString(context, message); MutableString strToAddress = Protocols.CastToString(context, to); // Unpack the socket address information from the to parameter SocketAddress address = new SocketAddress(AddressFamily.InterNetwork); for (int i = 0; i < strToAddress.GetByteCount(); i++) { address[i] = strToAddress.GetByte(i); } EndPoint toEndPoint = self.Socket.LocalEndPoint.Create(address); return(self.Socket.SendTo(strMessage.ConvertToBytes(), socketFlags, toEndPoint)); }
/// <summary> /// Returns true if the string binary representation contains bytes from set: 0..0x1f + 0x7f..0xff - [0x0a, 0x0d]. /// </summary> internal static bool ContainsBinaryData(MutableString /*!*/ str) { if (!str.IsAscii()) { return(true); } // for ascii strings we can iterate over bytes or characters without converting the string repr: for (int i = 0; i < str.GetByteCount(); i++) { byte b = str.GetByte(i); if (b < 0x20 && b != 0x0a && b != 0x0d || b >= 0x7f) { return(true); } } return(false); }
public static object GetChecksum(MutableString/*!*/ self, [DefaultProtocol, DefaultParameterValue(16)]int bitCount) { int length = self.GetByteCount(); uint mask = (bitCount > 31) ? 0xffffffff : (1U << bitCount) - 1; uint sum = 0; for (int i = 0; i < length; i++) { byte b = self.GetByte(i); try { checked { sum = (sum + b) & mask; } } catch (OverflowException) { return GetBigChecksum(self, i, sum, bitCount); } } return (sum > Int32.MaxValue) ? (BigInteger)sum : (object)(int)sum; }
public static MutableString GetSubstring(ConversionStorage<int>/*!*/ fixnumCast, MutableString/*!*/ self, [NotNull]Range/*!*/ range) { int begin, count; if (!NormalizeSubstringRange(fixnumCast, range, self.GetByteCount(), out begin, out count)) { return null; } return (count < 0) ? self.CreateInstance().TaintBy(self) : GetSubstring(self, begin, count); }
public static object GetChar(MutableString/*!*/ self, [DefaultProtocol]int index) { return InExclusiveRangeNormalized(self.GetByteCount(), ref index) ? ScriptingRuntimeHelpers.Int32ToObject(self.GetByte(index)) : null; }
public static object LastIndexOf(MutableString/*!*/ self, int character, [DefaultProtocol, DefaultParameterValue(Int32.MaxValue)]int start) { if (!self.IsBinaryEncoded && !self.Encoding.IsKCoding && !self.IsAscii()) { throw RubyExceptions.CreateTypeError("type mismatch: Fixnum given"); } int byteCount = self.GetByteCount(); start = IListOps.NormalizeIndex(byteCount, start); if (start < 0 || character < 0 || character > 255) { return null; } if (start >= byteCount) { start = byteCount - 1; } int result = self.LastIndexOf((byte)character, start); return (result != -1) ? ScriptingRuntimeHelpers.Int32ToObject(result) : null; }
public static int GetLength(MutableString/*!*/ self) { return (self.Encoding.IsKCoding) ? self.GetByteCount() : self.GetCharCount(); }
public MutableString ReadLine(MutableString/*!*/ separator, RubyEncoding/*!*/ encoding, bool preserveEndOfLines) { int b = ReadByteNormalizeEoln(preserveEndOfLines); if (b == -1) { return null; } int separatorOffset = 0; int separatorLength = separator.GetByteCount(); MutableString result = MutableString.CreateBinary(encoding); do { result.Append((byte)b); if (b == separator.GetByte(separatorOffset)) { if (separatorOffset == separatorLength - 1) { break; } separatorOffset++; } else if (separatorOffset > 0) { separatorOffset = 0; } b = ReadByteNormalizeEoln(preserveEndOfLines); } while (b != -1); return result; }
// count == Int32.MaxValue means means no bound public int AppendBytes(MutableString/*!*/ buffer, int count, bool preserveEndOfLines) { ContractUtils.RequiresNotNull(buffer, "buffer"); ContractUtils.Requires(count >= 0, "count"); if (count == 0) { return 0; } bool readAll = count == Int32.MaxValue; buffer.SwitchToBytes(); int initialBufferSize = buffer.GetByteCount(); if (preserveEndOfLines) { AppendRawBytes(buffer, count); } else { // allocate 3 more bytes at the end for a backstop and possible LF: byte[] bytes = Utils.EmptyBytes; int done = initialBufferSize; bool eof; do { AppendRawBytes(buffer, readAll ? 1024 : count); int end = buffer.GetByteCount(); int bytesRead = end - done; if (bytesRead == 0) { break; } eof = bytesRead < count; buffer.EnsureCapacity(end + 3); bytes = buffer.GetByteArray(); if (bytes[end - 1] == CR && PeekByte(0) == LF) { ReadByte(); bytes[end++] = LF; } // insert backstop: bytes[end] = CR; bytes[end + 1] = LF; int last = IndexOfCrLf(bytes, done); count -= last - done; done = last; while (last < end) { int next = IndexOfCrLf(bytes, last + 2); int chunk = next - last - 1; Buffer.BlockCopy(bytes, last + 1, bytes, done, chunk); done += chunk; count -= chunk; last = next; } buffer.Remove(done); } while (readAll || count > 0 && !eof); } if (readAll) { buffer.TrimExcess(); } return buffer.GetByteCount() - initialBufferSize; }
private void AppendRawBytes(MutableString/*!*/ buffer, int count) { Debug.Assert(count > 0); int remaining = count; if (_bufferCount > 0) { int c = Math.Min(_bufferCount, count); buffer.Append(_buffer, _bufferStart, c); ConsumeBuffered(c); remaining -= c; } if (count == Int32.MaxValue) { const int chunk = 1024; int done = buffer.GetByteCount(); int bytesRead; do { buffer.Append(_stream, chunk); bytesRead = buffer.GetByteCount() - done; done += bytesRead; } while (bytesRead == chunk); } else { buffer.Append(_stream, remaining); } }
private static MutableString ReadLine(MutableString/*!*/ content, MutableString separator, ref int position) { int length = content.GetByteCount(); if (position >= length) { return null; } int oldPosition = position; if (separator == null) { position = length; } else if (separator.IsEmpty) { // skip initial ends of line: while (oldPosition < length && content.GetByte(oldPosition) == '\n') { oldPosition++; } position = content.IndexOf(ParagraphSeparator, oldPosition); position = (position != -1) ? position + 1 : length; } else { position = content.IndexOf(separator, oldPosition); position = (position != -1) ? position + separator.Length : length; } return content.GetSlice(oldPosition, position - oldPosition); }
public static int GetByteCount(MutableString/*!*/ self) { return self.GetByteCount(); }
private static void FromHex(BinaryWriter/*!*/ writer, MutableString/*!*/ str, int nibbleCount, bool swap) { int maxCount = Math.Min(nibbleCount, str.GetByteCount()); for (int i = 0, j = 0; i < (nibbleCount + 1) / 2; i++, j += 2) { int hiNibble = (j < maxCount) ? FromHexDigit(str.GetByte(j)) : 0; int loNibble = (j + 1 < maxCount) ? FromHexDigit(str.GetByte(j + 1)) : 0; Debug.Assert(hiNibble >= 0 && hiNibble < 16 && loNibble >= 0 && loNibble < 16); int c = (swap) ? (loNibble << 4) | hiNibble : (hiNibble << 4) | loNibble; writer.Write((byte)c); } }
private static void WriteBits(Stream/*!*/ stream, int? countDef, bool reverse, MutableString/*!*/ str) { int length = str.GetByteCount(); int count = countDef ?? length; int bits = Math.Min(count, length); int paddingBits = (8 - bits % 8) % 8; long resultLength = stream.Length + (bits + paddingBits) / 8 + ((count - bits) + (count - bits) % 2) / 2; // estimate the total length: stream.SetLength(resultLength); int b = 0; int i = 0; int s = reverse ? 0 : 7; int ds = reverse ? +1 : -1; while (i < bits) { b |= (str.GetByte(i++) & 1) << s; s += ds; if (i % 8 == 0) { stream.WriteByte((byte)b); b = 0; s = reverse ? 0 : 7; } } if (paddingBits > 0) { stream.WriteByte((byte)b); } stream.Position = resultLength; }
public static MutableString/*!*/ Join(JoinConversionStorage/*!*/ conversions, IList/*!*/ self, MutableString separator) { var parts = new List<MutableString>(self.Count); bool? isBinary = (separator != null) ? separator.IsBinary : (bool?)null; Dictionary<object, bool> seen = null; // build a list of strings to join: JoinRecursive(conversions, self, parts, ref isBinary, ref seen); if (parts.Count == 0) { return MutableString.CreateEmpty(); } if (separator != null && separator.IsBinary != isBinary && !separator.IsAscii()) { isBinary = true; } // calculate length: MutableString any = separator; int length = (separator != null) ? (isBinary.HasValue && isBinary.Value ? separator.GetByteCount() : separator.GetCharCount()) * (parts.Count - 1) : 0; for (int i = 0, n = parts.Count; i < n; i++) { var part = parts[i]; if (part != null) { length += (isBinary.HasValue && isBinary.Value) ? part.GetByteCount() : part.GetCharCount(); if (any == null) { any = part; } } } if (any == null) { return MutableString.CreateEmpty(); } var result = isBinary.HasValue && isBinary.Value ? MutableString.CreateBinary(length, any.Encoding) : MutableString.CreateMutable(length, any.Encoding); for (int i = 0, n = parts.Count; i < n; i++) { var part = parts[i]; if (separator != null && i > 0) { result.Append(separator); } if (part != null) { result.Append(part); result.TaintBy(part); } } if (separator != null) { result.TaintBy(separator); } if (!result.IsTainted || !result.IsUntrusted) { result.TaintBy(self, conversions.Context); } return result; }
/// <summary> /// Printable characters: [33, 60], [62, 126], space (32), tab (9) but not at the end of line /// Escaped: others =XX /// Soft eolns (could be inserted anywhere, Ruby: after each count + 1 characters): =\n /// </summary> private static void WritePrintedQuotable(Stream/*!*/ stream, MutableString/*!*/ str, int bytesPerLine) { bytesPerLine++; int lineLength = 0; int length = str.GetByteCount(); for (int i = 0; i < length; i++) { byte c = str.GetByte(i); if (c >= 33 && c <= 60 || c >= 62 && c <= 126 || c == 9 || c == 32) { stream.WriteByte(c); lineLength++; } else if (c == (byte)'\n') { stream.WriteByte(c); lineLength = 0; } else { stream.WriteByte((byte)'='); stream.WriteByte((byte)(c >> 4).ToUpperHexDigit()); stream.WriteByte((byte)(c & 0x0f).ToUpperHexDigit()); lineLength += 3; } if (lineLength >= bytesPerLine) { stream.WriteByte((byte)'='); stream.WriteByte((byte)'\n'); lineLength = 0; } } if (lineLength > 0) { stream.WriteByte((byte)'='); stream.WriteByte((byte)'\n'); } }
private void AppendRawBytes(MutableString/*!*/ buffer, int count) { Debug.Assert(count > 0); int remaining = count; while (_bufferSize > 0) { buffer.Append(ReadBufferByte()); remaining--; } if (count == Int32.MaxValue) { const int chunk = 1024; int done = buffer.GetByteCount(); int bytesRead; do { buffer.Append(_stream, chunk); bytesRead = buffer.GetByteCount() - done; done += bytesRead; } while (bytesRead == chunk); } else { buffer.Append(_stream, remaining); } }
/*!*/ public static RubyArray Unpack(MutableString/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ format) { RubyArray result = new RubyArray(1 + self.Length / 2); // TODO: encodings int position = 0; int length = self.GetByteCount(); foreach (FormatDirective directive in FormatDirective.Enumerate(format.ToString())) { int count, maxCount; int nilCount = 0; switch (directive.Directive) { case '@': if (directive.Count.HasValue) { if (directive.Count.Value > length) { throw RubyExceptions.CreateArgumentError("@ outside of string"); } position = directive.Count.Value > 0 ? directive.Count.Value : 0; } else { position = length; } break; case 'A': case 'a': case 'Z': result.Add(ReadString(self, directive.Directive, directive.Count, ref position)); break; case 'B': case 'b': result.Add(ReadBits(self, directive.Count, ref position, directive.Directive == 'b')); break; case 'c': count = CalculateCounts(length - position, directive.Count, sizeof(sbyte), out nilCount); for (int j = 0; j < count; j++) { result.Add((int)unchecked((sbyte)self.GetByte(position++))); } break; case 'C': count = CalculateCounts(length - position, directive.Count, sizeof(byte), out nilCount); for (int j = 0; j < count; j++) { result.Add((int)self.GetByte(position++)); } break; case 'd': // 8-byte native-endian case 'D': count = CalculateCounts(length - position, directive.Count, sizeof(double), out nilCount); for (int j = 0; j < count; j++) { result.Add(ReadDouble(self, ref position, false)); } break; case 'e': // 4-byte little-endian count = CalculateCounts(length - position, directive.Count, sizeof(float), out nilCount); for (int j = 0; j < count; j++) { result.Add((double)ReadSingle(self, ref position, !BitConverter.IsLittleEndian)); } break; case 'E': // 8-byte little-endian count = CalculateCounts(length - position, directive.Count, sizeof(double), out nilCount); for (int j = 0; j < count; j++) { result.Add(ReadDouble(self, ref position, !BitConverter.IsLittleEndian)); } break; case 'f': // 4-byte native-endian case 'F': count = CalculateCounts(length - position, directive.Count, sizeof(float), out nilCount); for (int j = 0; j < count; j++) { result.Add((double)ReadSingle(self, ref position, false)); } break; case 'g': // 4-byte big-endian count = CalculateCounts(length - position, directive.Count, sizeof(float), out nilCount); for (int j = 0; j < count; j++) { result.Add((double)ReadSingle(self, ref position, BitConverter.IsLittleEndian)); } break; case 'G': // 8-byte big-endian count = CalculateCounts(length - position, directive.Count, sizeof(double), out nilCount); for (int j = 0; j < count; j++) { result.Add(ReadDouble(self, ref position, BitConverter.IsLittleEndian)); } break; case 'i': case 'l': // signed 4-byte native-endian count = CalculateCounts(length - position, directive.Count, sizeof(int), out nilCount); for (int j = 0; j < count; j++) { result.Add(unchecked((int)ReadUInt32(self, ref position, false))); } break; case 'I': case 'L': // unsigned 4-byte native-endian count = CalculateCounts(length - position, directive.Count, sizeof(uint), out nilCount); for (int j = 0; j < count; j++) { result.Add(Protocols.Normalize(ReadUInt32(self, ref position, false))); } break; case 'N': // unsigned 4-byte big-endian count = CalculateCounts(length - position, directive.Count, sizeof(uint), out nilCount); for (int j = 0; j < count; j++) { result.Add(Protocols.Normalize(ReadUInt32(self, ref position, BitConverter.IsLittleEndian))); } break; case 'n': // unsigned 2-byte big-endian count = CalculateCounts(length - position, directive.Count, sizeof(ushort), out nilCount); for (int j = 0; j < count; j++) { result.Add(ScriptingRuntimeHelpers.Int32ToObject(ReadUInt16(self, ref position, BitConverter.IsLittleEndian))); } break; case 'v': // unsigned 2-byte little-endian count = CalculateCounts(length - position, directive.Count, sizeof(ushort), out nilCount); for (int j = 0; j < count; j++) { result.Add(ScriptingRuntimeHelpers.Int32ToObject(ReadUInt16(self, ref position, !BitConverter.IsLittleEndian))); } break; case 'V': // unsigned 4-byte little-endian count = CalculateCounts(length - position, directive.Count, sizeof(uint), out nilCount); for (int j = 0; j < count; j++) { result.Add(Protocols.Normalize(ReadUInt32(self, ref position, !BitConverter.IsLittleEndian))); } break; case 'q': // signed 8-byte native-endian count = CalculateCounts(length - position, directive.Count, sizeof(long), out nilCount); for (int j = 0; j < count; j++) { result.Add(Protocols.Normalize(unchecked((long)ReadUInt64(self, ref position, false)))); } break; case 'Q': // unsigned 8-byte native-endian count = CalculateCounts(length - position, directive.Count, sizeof(ulong), out nilCount); nilCount = 0; for (int j = 0; j < count; j++) { result.Add(Protocols.Normalize(ReadUInt64(self, ref position, false))); } break; case 'm': // Base64 result.Add(ReadBase64(self, ref position)); break; case 'M': // quoted-printable, MIME encoding result.Add(ReadQuotedPrintable(self, ref position)); break; case 's': count = CalculateCounts(length - position, directive.Count, sizeof(short), out nilCount); for (int j = 0; j < count; j++) { result.Add(ScriptingRuntimeHelpers.Int32ToObject(unchecked((short)ReadUInt16(self, ref position, !BitConverter.IsLittleEndian)))); } break; case 'S': count = CalculateCounts(length - position, directive.Count, sizeof(ushort), out nilCount); for (int j = 0; j < count; j++) { result.Add(ScriptingRuntimeHelpers.Int32ToObject(ReadUInt16(self, ref position, !BitConverter.IsLittleEndian))); } break; case 'U': count = directive.Count ?? Int32.MaxValue; for (int i = 0; i < count; i++) { int cp = ReadUtf8CodePoint(self, ref position); if (cp == -1) { break; } result.Add(cp); } break; case 'w': // BER encoding count = directive.Count ?? Int32.MaxValue; for (int i = 0; i < count; i++) { object value = ReadBer(self, ref position); if (value == null) { break; } result.Add(value); } break; case 'u': // UU decoding result.Add(ReadUU(self, ref position)); break; case 'X': int len3 = directive.Count.HasValue ? directive.Count.Value : (int)(length - position); if (len3 > position) { throw RubyExceptions.CreateArgumentError("X outside of string"); } position -= len3; break; case 'x': int newPos = directive.Count.HasValue ? (int)position + directive.Count.Value : (int)length; if (newPos > length) { throw RubyExceptions.CreateArgumentError("X outside of string"); } position = newPos; break; case 'h': case 'H': maxCount = (int)(length - position) * 2; result.Add(ToHex(self, ref position, Math.Min(directive.Count ?? maxCount, maxCount), directive.Directive == 'h')); break; } for (int i = 0; i < nilCount; i++) { result.Add(null); } } return result; }
public static object EachByte(BlockParam block, MutableString/*!*/ self) { if (block == null && !self.IsEmpty) { throw RubyExceptions.NoBlockGiven(); } // MRI allows the string to be changed during iteration int i = 0; while (i < self.GetByteCount()) { object result; if (block.Yield(ScriptingRuntimeHelpers.Int32ToObject((int)self.GetByte(i)), out result)) { return result; } i++; } return self; }
public static void WriteBase64(Stream/*!*/ stream, MutableString/*!*/ str, int bytesPerLine) { ContractUtils.RequiresNotNull(stream, "stream"); ContractUtils.RequiresNotNull(str, "str"); ContractUtils.Requires(bytesPerLine > 2, "bytesPerLine"); bytesPerLine = bytesPerLine - bytesPerLine % 3; int a, b, c; int length = str.GetByteCount(); int remainingBytes = length % 3; int triples = length - remainingBytes; byte[] table = _Base64Table; int lineLength = 0; for (int i = 0; i < triples; i += 3) { a = str.GetByte(i); b = str.GetByte(i + 1); c = str.GetByte(i + 2); stream.WriteByte(table[(a & 0xfc) >> 2]); stream.WriteByte(table[((a & 3) << 4) | ((b & 240) >> 4)]); stream.WriteByte(table[((b & 15) << 2) | ((c & 0xc0) >> 6)]); stream.WriteByte(table[c & 0x3f]); lineLength += 3; if (lineLength == bytesPerLine) { stream.WriteByte((byte)'\n'); lineLength = 0; } } if (remainingBytes == 0) { if (lineLength != 0) { stream.WriteByte((byte)'\n'); } return; } a = str.GetByte(triples); stream.WriteByte(table[(a & 0xfc) >> 2]); switch (remainingBytes) { case 1: stream.WriteByte(table[(a & 3) << 4]); stream.WriteByte((byte)'='); break; case 2: b = str.GetByte(triples + 1); stream.WriteByte(table[((a & 3) << 4) | ((b & 240) >> 4)]); stream.WriteByte(table[(b & 15) << 2]); break; } stream.WriteByte((byte)'='); stream.WriteByte((byte)'\n'); }
public static object Index(MutableString/*!*/ self, int character, [DefaultProtocol, Optional]int start) { if (!self.IsBinaryEncoded && !self.Encoding.IsKCoding && !self.IsAscii()) { throw RubyExceptions.CreateTypeError("type mismatch: Fixnum given"); } if (!NormalizeStart(self.GetByteCount(), ref start) || character < 0 || character > 255) { return null; } int result = self.IndexOf((byte)character, start); return (result != -1) ? ScriptingRuntimeHelpers.Int32ToObject(result) : null; }
/*!*/ private static MutableString ReadBase64(MutableString/*!*/ data, ref int offset) { int length = data.GetByteCount(); var result = MutableString.CreateBinary(); while (true) { // The following should exactly match MRI handling of incomplete input: int a = DecodeBase64Byte(data, length, true, ref offset); int b = DecodeBase64Byte(data, length, true, ref offset); int c = DecodeBase64Byte(data, length, false, ref offset); int d = (c != -2) ? DecodeBase64Byte(data, length, false, ref offset) : -2; if (a == -1 || b == -1 || c == -1 || d == -1) { break; } int buffer = (a << 18) | (b << 12); result.Append((byte)((buffer >> 16) & 0xff)); if (c == -2) { break; } buffer |= (c << 6); result.Append((byte)((buffer >> 8) & 0xff)); if (d == -2) { break; } buffer |= d; result.Append((byte)(buffer & 0xff)); } return result; }
public static object RemoveCharInPlace(RubyContext/*!*/ context, MutableString/*!*/ self, [DefaultProtocol]int index) { if (!InExclusiveRangeNormalized(self.GetByteCount(), ref index)) { return null; } // TODO: optimize if the value is not read: int result = self.GetByte(index); self.Remove(index, 1); return result; }
/*!*/ private static MutableString ReadBits(MutableString/*!*/ data, int? bitCount, ref int offset, bool lowestFirst) { int inputSize = data.GetByteCount() - offset; int outputSize = inputSize * 8; if (bitCount.HasValue) { int c = CeilDiv(bitCount.Value, 8); if (c <= inputSize) { inputSize = c; outputSize = bitCount.Value; } } var result = MutableString.CreateBinary(outputSize); if (outputSize == 0) { return result; } while (true) { int b = data.GetByte(offset++); for (int i = 0; i < 8; i++) { result.Append((byte)('0' + ((b >> (lowestFirst ? i : 7 - i)) & 1))); if (--outputSize == 0) { return result; } } } }
public static MutableString GetSubstring(MutableString/*!*/ self, [DefaultProtocol]int start, [DefaultProtocol]int count) { int byteCount = self.GetByteCount(); if (!NormalizeSubstringRange(byteCount, ref start, ref count)) { return (start == byteCount) ? self.CreateInstance().TaintBy(self) : null; } return self.CreateInstance().Append(self, start, count).TaintBy(self); }
/*!*/ private static MutableString ReadQuotedPrintable(MutableString/*!*/ data, ref int index) { MutableString result = MutableString.CreateBinary(); int length = data.GetByteCount(); int i = index; while (i < length) { byte c = data.GetByte(i++); if (c == '=') { if (i >= length) { break; } c = data.GetByte(i); if (c == '\n') { i++; continue; } if (c == '\r' && i + 1 < length && data.GetByte(i + 1) == '\n') { i += 2; continue; } int hi = Tokenizer.ToDigit(c); if (hi >= 16) { break; } i++; if (i >= length) { break; } int lo = Tokenizer.ToDigit(data.GetByte(i)); if (lo >= 16) { break; } i++; result.Append((byte)((hi << 4) | lo)); } else { result.Append(c); } } index = i; return result; }
public static MutableString/*!*/ Join(ConversionStorage<MutableString>/*!*/ tosConversion, IList/*!*/ self, MutableString/*!*/ separator) { var parts = new List<MutableString>(self.Count); bool partTainted = false; bool? isBinary = (separator != null) ? separator.IsBinary : (bool?)null; Dictionary<object, bool> seen = null; JoinRecursive(tosConversion, self, parts, ref isBinary, ref partTainted, ref seen); if (parts.Count == 0) { return MutableString.CreateEmpty(); } if (separator != null && separator.IsBinary != isBinary && !separator.IsAscii()) { isBinary = true; } MutableString any = separator; int length = (separator != null) ? (isBinary.Value ? separator.GetByteCount() : separator.GetCharCount()) * (parts.Count - 1) : 0; foreach (MutableString part in parts) { if (part != null) { length += (isBinary.Value) ? part.GetByteCount() : part.GetCharCount(); if (any == null) { any = part; } } } if (any == null) { return MutableString.CreateEmpty(); } var result = isBinary.Value ? MutableString.CreateBinary(length, any.Encoding) : MutableString.CreateMutable(length, any.Encoding); for (int i = 0; i < parts.Count; i++) { if (separator != null && i > 0) { result.Append(separator); } result.Append(parts[i]); } result.IsTainted |= partTainted; if (!result.IsTainted && (separator != null && separator.IsTainted || tosConversion.Context.IsObjectTainted(self))) { result.IsTainted = true; } return result; }
/*!*/ private static MutableString ReadString(MutableString/*!*/ data, int trimMode, int? count, ref int offset) { int start = offset; int e = data.GetByteCount(); if (count.HasValue) { int end = start + count.Value; if (end < e) { e = end; } } offset = e; byte b; switch (trimMode) { case 'A': while (--e >= start && ((b = data.GetByte(e)) == 0 || b == ' ')) { } e++; break; case 'Z': int i = start; while (i < e && data.GetByte(i) != 0) { i++; } if (!count.HasValue) { offset = i + 1; } e = i; break; } return data.GetSlice(start, e - start); }
private static BigInteger GetBigChecksum(MutableString/*!*/ self, int start, BigInteger/*!*/ sum, int bitCount) { BigInteger mask = (((BigInteger)1) << bitCount) - 1; int length = self.GetByteCount(); for (int i = start; i < length; i++) { sum = (sum + self.GetByte(i)) & mask; } return sum; }
/// <summary> /// Returns true if the string binary representation contains bytes from set: 0..0x1f + 0x7f..0xff - [0x0a, 0x0d]. /// </summary> internal static bool ContainsBinaryData(MutableString/*!*/ str) { if (!str.IsAscii()) { return true; } // for ascii strings we can iterate over bytes or characters without converting the string repr: for (int i = 0; i < str.GetByteCount(); i++) { byte b = str.GetByte(i); if (b < 0x20 && b != 0x0a && b != 0x0d || b >= 0x7f) { return true; } } return false; }