internal override unsafe int GetBytes(char *chars, int charCount, byte *bytes, int byteCount, EncoderNLS baseEncoder) { Debug.Assert(byteCount >= 0, "[UTF7Encoding.GetBytes]byteCount >=0"); Debug.Assert(chars != null, "[UTF7Encoding.GetBytes]chars!=null"); Debug.Assert(charCount >= 0, "[UTF7Encoding.GetBytes]charCount >=0"); // Get encoder info UTF7Encoding.Encoder encoder = (UTF7Encoding.Encoder)baseEncoder; // Default bits & count int bits = 0; int bitCount = -1; // prepare our helpers Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer( this, encoder, bytes, byteCount, chars, charCount); if (encoder != null) { bits = encoder.bits; bitCount = encoder.bitCount; // May have had too many left over while (bitCount >= 6) { bitCount -= 6; // If we fail we'll never really have enough room if (!buffer.AddByte(_base64Bytes[(bits >> bitCount) & 0x3F])) { ThrowBytesOverflow(encoder, buffer.Count == 0); } } } while (buffer.MoreData) { char currentChar = buffer.GetNextChar(); if (currentChar < 0x80 && _directEncode[currentChar]) { if (bitCount >= 0) { if (bitCount > 0) { // Try to add the next byte if (!buffer.AddByte(_base64Bytes[bits << 6 - bitCount & 0x3F])) { break; // Stop here, didn't throw } bitCount = 0; } // Need to get emit '-' and our char, 2 bytes total if (!buffer.AddByte((byte)'-')) { break; // Stop here, didn't throw } bitCount = -1; } // Need to emit our char if (!buffer.AddByte((byte)currentChar)) { break; // Stop here, didn't throw } } else if (bitCount < 0 && currentChar == '+') { if (!buffer.AddByte((byte)'+', (byte)'-')) { break; // Stop here, didn't throw } } else { if (bitCount < 0) { // Need to emit a + and 12 bits (3 bytes) // Only 12 of the 16 bits will be emitted this time, the other 4 wait 'til next time if (!buffer.AddByte((byte)'+')) { break; // Stop here, didn't throw } // We're now in bit mode, but haven't stored data yet bitCount = 0; } // Add our bits bits = bits << 16 | currentChar; bitCount += 16; while (bitCount >= 6) { bitCount -= 6; if (!buffer.AddByte(_base64Bytes[(bits >> bitCount) & 0x3F])) { bitCount += 6; // We didn't use these bits currentChar = buffer.GetNextChar(); // We're processing this char still, but AddByte // --'d it when we ran out of space break; // Stop here, not enough room for bytes } } if (bitCount >= 6) { break; // Didn't have room to encode enough bits } } } // Now if we have bits left over we have to encode them. // MustFlush may have been cleared by encoding.ThrowBytesOverflow earlier if converting if (bitCount >= 0 && (encoder == null || encoder.MustFlush)) { // Do we have bits we have to stick in? if (bitCount > 0) { if (buffer.AddByte(_base64Bytes[(bits << (6 - bitCount)) & 0x3F])) { // Emitted spare bits, 0 bits left bitCount = 0; } } // If converting and failed bitCount above, then we'll fail this too if (buffer.AddByte((byte)'-')) { // turned off bit mode'; bits = 0; bitCount = -1; } else { // If not successful, convert will maintain state for next time, also // AddByte will have decremented our char count, however we need it to remain the same buffer.GetNextChar(); } } // Do we have an encoder we're allowed to use? // bytes == null if counting, so don't use encoder then if (bytes != null && encoder != null) { // We already cleared bits & bitcount for mustflush case encoder.bits = bits; encoder.bitCount = bitCount; encoder._charsUsed = buffer.CharsUsed; } return(buffer.Count); }