Exemplo n.º 1
0
        internal unsafe EncodingByteBuffer(EncodingNLS inEncoding, EncoderNLS?inEncoder, byte *inByteStart, int inByteCount, char *inCharStart, int inCharCount)
        {
            _enc     = inEncoding;
            _encoder = inEncoder;

            _charStart = inCharStart;
            _chars     = inCharStart;
            _charEnd   = inCharStart + inCharCount;

            _bytes     = inByteStart;
            _byteStart = inByteStart;
            _byteEnd   = inByteStart + inByteCount;

            if (_encoder == null)
            {
                fallbackBuffer = _enc.EncoderFallback.CreateFallbackBuffer();
            }
            else
            {
                fallbackBuffer = _encoder.FallbackBuffer;
                // If we're not converting we must not have data in our fallback buffer
                if (_encoder.m_throwOnOverflow && _encoder.InternalHasFallbackBuffer && fallbackBuffer.Remaining > 0)
                {
                    throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, _encoder.Encoding.EncodingName, _encoder.Fallback.GetType()));
                }
            }
            fallbackBufferHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
            fallbackBufferHelper.InternalInitialize(_chars, _charEnd, _encoder, _bytes != null);
        }
Exemplo n.º 2
0
        //
        // End of standard methods copied from EncodingNLS.cs
        //
        internal sealed override unsafe int GetByteCount(char *chars, int count, EncoderNLS?baseEncoder)
        {
            Debug.Assert(chars != null, "[UTF7Encoding.GetByteCount]chars!=null");
            Debug.Assert(count >= 0, "[UTF7Encoding.GetByteCount]count >=0");

            // Just call GetBytes with bytes == null
            return(GetBytes(chars, count, null, 0, baseEncoder));
        }
Exemplo n.º 3
0
 // Set the above values
 // This can't be part of the constructor because EncoderFallbacks would have to know how to implement these.
 internal unsafe void InternalInitialize(char *charStart, char *charEnd, EncoderNLS?encoder, bool setEncoder)
 {
     this.charStart       = charStart;
     this.charEnd         = charEnd;
     this.encoder         = encoder;
     this.setEncoder      = setEncoder;
     this.bUsedEncoder    = false;
     this.bFallingBack    = false;
     this.iRecursionCount = 0;
 }
Exemplo n.º 4
0
 // Set the above values
 // This can't be part of the constructor because EncoderFallbacks would have to know how to implement these.
 internal unsafe void InternalInitialize(char *_charStart, char *_charEnd, EncoderNLS?_encoder, bool _setEncoder)
 {
     charStart       = _charStart;
     charEnd         = _charEnd;
     encoder         = _encoder;
     setEncoder      = _setEncoder;
     bUsedEncoder    = false;
     bFallingBack    = false;
     iRecursionCount = 0;
 }
Exemplo n.º 5
0
        internal static EncoderFallbackBuffer CreateAndInitialize(Encoding encoding, EncoderNLS?encoder, int originalCharCount)
        {
            // The original char count is only used for keeping track of what 'index' value needs
            // to be passed to the abstract Fallback method. The index value is calculated by subtracting
            // 'chars.Length' (where chars is expected to be the entire remaining input buffer)
            // from the 'originalCharCount' value specified here.

            EncoderFallbackBuffer fallbackBuffer = (encoder is null) ? encoding.EncoderFallback.CreateFallbackBuffer() : encoder.FallbackBuffer;

            fallbackBuffer.encoding          = encoding;
            fallbackBuffer.encoder           = encoder;
            fallbackBuffer.originalCharCount = originalCharCount;

            return(fallbackBuffer);
        }
Exemplo n.º 6
0
 public unsafe abstract int GetBytes(char *chars, int charCount, byte *bytes, int byteCount, EncoderNLS?encoder);
Exemplo n.º 7
0
 public unsafe abstract int GetByteCount(char *chars, int count, EncoderNLS?encoder);
Exemplo n.º 8
0
        internal sealed 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
                            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);
        }
Exemplo n.º 9
0
        private protected sealed override unsafe int GetBytesWithFallback(ReadOnlySpan <char> chars, int originalCharsLength, Span <byte> bytes, int originalBytesLength, EncoderNLS?encoder)
        {
            // We special-case EncoderReplacementFallback if it's telling us to write a single ASCII char,
            // since we believe this to be relatively common and we can handle it more efficiently than
            // the base implementation.

            if (((encoder is null) ? this.EncoderFallback : encoder.Fallback) is EncoderReplacementFallback replacementFallback &&
                replacementFallback.MaxCharCount == 1 &&
                replacementFallback.DefaultString[0] <= 0x7F)
            {
                byte replacementByte = (byte)replacementFallback.DefaultString[0];

                int numElementsToConvert = Math.Min(chars.Length, bytes.Length);
                int idx = 0;

                fixed(char *pChars = &MemoryMarshal.GetReference(chars))
                fixed(byte *pBytes = &MemoryMarshal.GetReference(bytes))
                {
                    // In a loop, replace the non-convertible data, then bulk-convert as much as we can.

                    while (idx < numElementsToConvert)
                    {
                        pBytes[idx++] = replacementByte;

                        if (idx < numElementsToConvert)
                        {
                            idx += (int)ASCIIUtility.NarrowUtf16ToAscii(&pChars[idx], &pBytes[idx], (uint)(numElementsToConvert - idx));
                        }

                        Debug.Assert(idx <= numElementsToConvert, "Somehow went beyond bounds of source or destination buffer?");
                    }
                }

                // Slice off how much we consumed / wrote.

                chars = chars.Slice(numElementsToConvert);
                bytes = bytes.Slice(numElementsToConvert);
            }

            // If we couldn't go through our fast fallback mechanism, or if we still have leftover
            // data because we couldn't consume everything in the loop above, we need to go down the
            // slow fallback path.

            if (chars.IsEmpty)
            {
                return(originalBytesLength - bytes.Length); // total number of bytes written
            }
            else
            {
                return(base.GetBytesWithFallback(chars, originalCharsLength, bytes, originalBytesLength, encoder));
            }
        }