// Workhorse internal override unsafe int GetBytes(char *chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder) { // Allow null bytes for counting BCLDebug.Assert(chars != null, "[ISCIIEncoding.GetBytes]chars!=null"); // BCLDebug.Assert(bytes != null, "[ISCIIEncoding.GetBytes]bytes!=null"); BCLDebug.Assert(charCount >=0, "[ISCIIEncoding.GetBytes]charCount >=0"); BCLDebug.Assert(byteCount >=0, "[ISCIIEncoding.GetBytes]byteCount >=0"); // Need the ISCII Encoder ISCIIEncoder encoder = (ISCIIEncoder) baseEncoder; // prepare our helpers Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer( this, encoder, bytes, byteCount, chars, charCount); int currentCodePage = this.defaultCodePage; bool bLastVirama = false; // Use encoder info if available if (encoder != null) { // Remember our old state currentCodePage = encoder.currentCodePage; bLastVirama = encoder.bLastVirama; // If we have a high surrogate left over, then fall it back if (encoder.charLeftOver > 0) { buffer.Fallback(encoder.charLeftOver); bLastVirama = false; // Redundant } } while (buffer.MoreData) { // Get our data char ch = buffer.GetNextChar(); // See if its a Multi Byte Character if (ch < MultiByteBegin) { // Its a boring low character, add it. if (!buffer.AddByte((byte)ch)) break; bLastVirama = false; continue; } // See if its outside of the Indic script Range range if ((ch < IndicBegin) || (ch > IndicEnd)) { // See if its a ZWJ or ZWNJ and if we has bLastVirama; if (bLastVirama && (ch == ZWNJ || ch == ZWJ)) { // It was a bLastVirama and ZWNJ || ZWJ if (ch == ZWNJ) { if (!buffer.AddByte(Virama)) break; } else // ZWJ { if (!buffer.AddByte(Nukta)) break; } // bLastVirama now counts as false bLastVirama = false; continue; } // Have to do our fallback // // Note that this will fallback 2 chars if this is a high surrogate. // Throws if recursive (knows because we called InternalGetNextChar) buffer.Fallback(ch); bLastVirama = false; continue; } // Its in the Unicode Indic script range int indicInfo = UnicodeToIndicChar[ch - IndicBegin]; byte byteIndic = (byte)indicInfo; int indicScript = (0x000f & (indicInfo >> 8)); int indicTwoBytes = (0xf000 & indicInfo); // If IndicInfo is 0 then have to do fallback if (indicInfo == 0) { // Its some Unicode character we don't have indic for. // Have to do our fallback // Add Fallback Count // Note that chars was preincremented, and GetEncoderFallbackString might add an extra // if chars != charEnd and there's a surrogate. // Throws if recursive (knows because we called InternalGetNextChar) buffer.Fallback(ch); bLastVirama = false; continue; } // See if our code page ("font" in ISCII spec) has to change // (This if doesn't add character, just changes character set) BCLDebug.Assert(indicScript!=0, "[ISCIIEncoding.GetBytes]expected an indic script value"); if (indicScript != currentCodePage) { // It changed, spit out the ATR if (!buffer.AddByte(ControlATR, (byte)(indicScript | ControlCodePageStart))) break; // Now spit out the new code page (& remember it) (do this afterwards in case AddByte failed) currentCodePage = indicScript; // We only know how to map from Unicode to pages from Devanagari to Punjabi (2 to 11) BCLDebug.Assert(currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi, "[ISCIIEncoding.GetBytes]Code page (" + currentCodePage + " shouldn't appear in ISCII from Unicode table!"); } // Safe to add our byte now if (!buffer.AddByte(byteIndic, indicTwoBytes != 0 ? 1:0)) break; // Remember if this one was a Virama bLastVirama = (byteIndic == Virama); // Some characters need extra bytes if (indicTwoBytes != 0) { // This one needs another byte BCLDebug.Assert((indicTwoBytes >> 12) > 0 && (indicTwoBytes >> 12) <= 3, "[ISCIIEncoding.GetBytes]Expected indicTwoBytes from 1-3, not " + (indicTwoBytes >> 12)); // Already did buffer checking, but... if (!buffer.AddByte(SecondIndicByte[indicTwoBytes >> 12])) break; } } // May need to switch back to our default code page if (currentCodePage != defaultCodePage && (encoder == null || encoder.MustFlush)) { // It changed, spit out the ATR if (buffer.AddByte(ControlATR, (byte)(defaultCodePage | ControlCodePageStart))) currentCodePage = defaultCodePage; 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(); bLastVirama = false; } // Make sure we remember our state if necessary // Note that we don't care about flush because Virama and code page // changes are legal at the end. // Don't set encoder if we're just counting if (encoder != null && bytes != null) { // Clear Encoder if necessary. if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = (char)0; } // Remember our code page/virama state encoder.currentCodePage = currentCodePage; encoder.bLastVirama = bLastVirama; // How many chars were used? encoder.m_charsUsed = buffer.CharsUsed; } // Return our length return buffer.Count; }
[System.Security.SecurityCritical] // auto-generated private unsafe int GetBytesCP52936(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder) { // prepare our helpers Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer( this, encoder, bytes, byteCount, chars, charCount); // Mode ISO2022Modes currentMode = ISO2022Modes.ModeASCII; // Check our encoder if (encoder != null) { char charLeftOver = encoder.charLeftOver; currentMode = encoder.currentMode; // We may have a left over character from last time, try and process it. if (charLeftOver > 0) { Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP52936]leftover character should be high surrogate"); // It has to be a high surrogate, which we don't support, so it has to be a fallback buffer.Fallback(charLeftOver); } } while (buffer.MoreData) { // Get our char char ch = buffer.GetNextChar(); // Get our bytes ushort sChar = mapUnicodeToBytes[ch]; if (sChar == 0 && ch != 0) { // Wasn't a legal byte sequence, its a surrogate or fallback // Throws if recursive (knows because we called InternalGetNextChar) buffer.Fallback(ch); // Done with our char, now process fallback continue; } // Check for halfwidth bytes byte bLeadByte = (byte)(sChar >> 8); byte bTrailByte = (byte)(sChar & 0xff); // If its a double byte, it has to fit in the lead byte 0xa1 - 0xf7, trail byte 0xa1 - 0xfe range // (including the 0x8080 that our codepage or's to the value) if ((bLeadByte != 0 && (bLeadByte < 0xa1 || bLeadByte > 0xf7 || bTrailByte < 0xa1 || bTrailByte > 0xfe)) || (bLeadByte == 0 && bTrailByte > 0x80 && bTrailByte != 0xff)) { // Illegal character, in 936 code page, but not in HZ subset, get fallback for it buffer.Fallback(ch); continue; } // sChar is now either ASCII or has an 0x8080 mask if (bLeadByte != 0) { // Its a double byte mode if (currentMode != ISO2022Modes.ModeHZ) { // Need to add the double byte mode marker if (!buffer.AddByte((byte)'~', (byte)'{', 2)) break; // Stop if no buffer space in convert currentMode = ISO2022Modes.ModeHZ; } // Go ahead and add the 2 bytes if (!buffer.AddByte(unchecked((byte)(bLeadByte & 0x7f)), unchecked((byte)(bTrailByte & 0x7f)))) break; // Stop if no buffer space in convert } else { // Its supposed to be ASCII if (currentMode != ISO2022Modes.ModeASCII) { // Need to add the ASCII mode marker // Will have 1 more byte (or 2 if ~) if (!buffer.AddByte((byte)'~', (byte)'}', bTrailByte == '~' ? 2:1)) break; currentMode = ISO2022Modes.ModeASCII; } // If its a '~' we'll need an extra one if (bTrailByte == '~') { // Need to add the extra ~ if (!buffer.AddByte((byte)'~', 1)) break; } // Need to add the character if (!buffer.AddByte(bTrailByte)) break; } } // Add ASCII shift out if we're at end of decoder if (currentMode != ISO2022Modes.ModeASCII && (encoder == null || encoder.MustFlush)) { // Need to add the ASCII mode marker // Only turn off other mode if this works if (buffer.AddByte((byte)'~',(byte)'}')) currentMode = ISO2022Modes.ModeASCII; 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(); } // Need to remember our mode if (encoder != null && bytes != null) { // This is ASCII if we had to flush encoder.currentMode = currentMode; if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = (char)0; } encoder.m_charsUsed = buffer.CharsUsed; } // Return our length return buffer.Count; }
[System.Security.SecurityCritical] // auto-generated internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder) { Contract.Assert(byteCount >=0, "[UTF7Encoding.GetBytes]byteCount >=0"); Contract.Assert(chars!=null, "[UTF7Encoding.GetBytes]chars!=null"); Contract.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.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }
[System.Security.SecurityCritical] // auto-generated private unsafe int GetBytesCP5022xJP(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder) { // prepare our helpers Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer( this, encoder, bytes, byteCount, chars, charCount); // Get our mode ISO2022Modes currentMode = ISO2022Modes.ModeASCII; // Mode ISO2022Modes shiftInMode = ISO2022Modes.ModeASCII; // Mode that shift in will go back to (only used by CP 50222) // Check our encoder if (encoder != null) { char charLeftOver = encoder.charLeftOver; currentMode = encoder.currentMode; shiftInMode = encoder.shiftInOutMode; // We may have a left over character from last time, try and process it. if (charLeftOver > 0) { Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP5022xJP]leftover character should be high surrogate"); // It has to be a high surrogate, which we don't support, so it has to be a fallback buffer.Fallback(charLeftOver); } } while (buffer.MoreData) { // Get our char char ch = buffer.GetNextChar(); // Get our bytes ushort iBytes = mapUnicodeToBytes[ch]; StartConvert: // Check for halfwidth bytes byte bLeadByte = (byte)(iBytes >> 8); byte bTrailByte = (byte)(iBytes & 0xff); if (bLeadByte == LEADBYTE_HALFWIDTH) { // Its Halfwidth Katakana if (CodePage == 50220) { // CodePage 50220 doesn't use halfwidth Katakana, convert to fullwidth // See if its out of range, fallback if so, throws if recursive fallback if (bTrailByte < 0x21 || bTrailByte >= 0x21 + HalfToFullWidthKanaTable.Length) { buffer.Fallback(ch); continue; } // Get the full width katakana char to use. iBytes = unchecked((ushort)(HalfToFullWidthKanaTable[bTrailByte - 0x21] & 0x7F7F)); // May have to do all sorts of fun stuff for mode, go back to start convert goto StartConvert; } // Can use halfwidth Katakana, make sure we're in right mode // Make sure we're in right mode if (currentMode != ISO2022Modes.ModeHalfwidthKatakana) { // 50222 or 50221, either shift in/out or escape to get to Katakana mode if (CodePage == 50222) { // Shift Out if (!buffer.AddByte(SHIFT_OUT)) break; // convert out of space, stop // Don't change modes until after AddByte in case it fails for convert // We get to shift out to Katakana, make sure we'll go back to the right mode // (This ends up always being ASCII) shiftInMode = currentMode; currentMode = ISO2022Modes.ModeHalfwidthKatakana; } else { // 50221 does halfwidth katakana by escape sequence Contract.Assert(CodePage == 50221, "[ISO2022Encoding.GetBytesCP5022xJP]Expected Code Page 50221"); // Add our escape sequence if (!buffer.AddByte(ESCAPE, unchecked((byte)'('), unchecked((byte)'I'))) break; // convert out of space, stop currentMode = ISO2022Modes.ModeHalfwidthKatakana; } } // We know we're in Katakana mode now, so add it. // Go ahead and add the Katakana byte. Our table tail bytes are 0x80 too big. if (!buffer.AddByte(unchecked((byte)(bTrailByte & 0x7F)))) break; // convert out of space, stop // Done with this one continue; } else if (bLeadByte != 0) { // // It's a double byte character. // // If we're CP 50222 we may have to shift in from Katakana mode first if (CodePage == 50222 && currentMode == ISO2022Modes.ModeHalfwidthKatakana) { // Shift In if (!buffer.AddByte(SHIFT_IN)) break; // convert out of space, stop // Need to shift in from katakana. (Still might not be right, but won't be shifted out anyway) currentMode = shiftInMode; } // Make sure we're in the right mode (JIS 0208 or JIS 0212) // Note: Right now we don't use JIS 0212. Also this table'd be wrong // Its JIS extension 0208 if (currentMode != ISO2022Modes.ModeJIS0208) { // Escape sequence, we can fail after this, mode will be correct for convert if (!buffer.AddByte(ESCAPE, unchecked((byte)'$'), unchecked((byte)'B'))) break; // Convert out of space, stop currentMode = ISO2022Modes.ModeJIS0208; } // Add our double bytes if (!buffer.AddByte(unchecked((byte)(bLeadByte)), unchecked((byte)(bTrailByte)))) break; // Convert out of space, stop continue; } else if (iBytes != 0 || ch == 0) { // Single byte Char // If we're CP 50222 we may have to shift in from Katakana mode first if (CodePage == 50222 && currentMode == ISO2022Modes.ModeHalfwidthKatakana) { // Shift IN if (!buffer.AddByte(SHIFT_IN)) break; // convert ran out of room // Need to shift in from katakana. (Still might not be right, but won't be shifted out anyway) currentMode = shiftInMode; } // Its a single byte character, switch to ASCII if we have to if (currentMode != ISO2022Modes.ModeASCII) { if (!buffer.AddByte(ESCAPE,unchecked((byte)'('), unchecked((byte)'B'))) break; // convert ran out of room currentMode = ISO2022Modes.ModeASCII; } // Add the ASCII char if (!buffer.AddByte(bTrailByte)) break; // convert had no room left continue; } // Its unknown, do fallback, throws if recursive (knows because we called InternalGetNextChar) buffer.Fallback(ch); } // Switch back to ASCII if MustFlush or no encoder if (currentMode != ISO2022Modes.ModeASCII && (encoder == null || encoder.MustFlush)) { // If we're CP 50222 we may have to shift in from Katakana mode first if (CodePage == 50222 && currentMode == ISO2022Modes.ModeHalfwidthKatakana) { // Shift IN, only shift mode if necessary. if (buffer.AddByte(SHIFT_IN)) // Need to shift in from katakana. (Still might not be right, but won't be shifted out anyway) currentMode = shiftInMode; 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(); } // switch back to ASCII to finish neatly if (currentMode != ISO2022Modes.ModeASCII && (CodePage != 50222 || currentMode != ISO2022Modes.ModeHalfwidthKatakana)) { // only shift if it was successful if (buffer.AddByte(ESCAPE, unchecked((byte)'('), unchecked((byte)'B'))) currentMode = ISO2022Modes.ModeASCII; 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(); } } // Remember our encoder state if (bytes != null && encoder != null) { // This is ASCII if we had to flush encoder.currentMode = currentMode; encoder.shiftInOutMode = shiftInMode; if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = (char)0; } encoder.m_charsUsed = buffer.CharsUsed; } // Return our length return buffer.Count; }
[System.Security.SecurityCritical] // auto-generated private unsafe int GetBytesCP50225KR(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder) { // prepare our helpers Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer( this, encoder, bytes, byteCount, chars, charCount); // Get our mode ISO2022Modes currentMode = ISO2022Modes.ModeASCII; // Mode ISO2022Modes shiftOutMode = ISO2022Modes.ModeASCII; // ModeKR if already stamped lead bytes // Check our encoder if (encoder != null) { // May have leftover stuff char charLeftOver = encoder.charLeftOver; currentMode = encoder.currentMode; shiftOutMode = encoder.shiftInOutMode; // We may have a l left over character from last time, try and process it. if (charLeftOver > 0) { Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP50225KR]leftover character should be high surrogate"); // It has to be a high surrogate, which we don't support, so it has to be a fallback buffer.Fallback(charLeftOver); } } while (buffer.MoreData) { // Get our data char ch = buffer.GetNextChar(); // Get our bytes ushort iBytes = mapUnicodeToBytes[ch]; // Check for double byte bytes byte bLeadByte = (byte)(iBytes >> 8); byte bTrailByte = (byte)(iBytes & 0xff); if (bLeadByte != 0) { // // It's a double byte character. // // If we haven't done our Korean designator, then do so, if we have any input if (shiftOutMode != ISO2022Modes.ModeKR) { // Add our code page designator sequence if (!buffer.AddByte(ESCAPE, unchecked((byte)'$'), unchecked((byte)')'), unchecked((byte)'C'))) break; // No room during convert. shiftOutMode = ISO2022Modes.ModeKR; } // May have to switch to ModeKR first if (currentMode != ISO2022Modes.ModeKR) { if (!buffer.AddByte(SHIFT_OUT)) break; // No convert room currentMode = ISO2022Modes.ModeKR; } // Add the bytes if (!buffer.AddByte(bLeadByte, bTrailByte)) break; // no convert room continue; } else if (iBytes != 0 || ch == 0) { // Its a single byte character, switch to ASCII if we have to if (currentMode != ISO2022Modes.ModeASCII) { if (!buffer.AddByte(SHIFT_IN)) break; currentMode = ISO2022Modes.ModeASCII; } // Add the ASCII char if (!buffer.AddByte(bTrailByte)) break; continue; } // Its unknown, do fallback, throws if recursive (knows because we called InternalGetNextChar) buffer.Fallback(ch); } // Switch back to ASCII if MustFlush or no encoder if (currentMode != ISO2022Modes.ModeASCII && (encoder == null || encoder.MustFlush)) { // Get back to ASCII to be safe. Only do it if it success. if (buffer.AddByte(SHIFT_IN)) currentMode = ISO2022Modes.ModeASCII; 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(); } // Remember our encoder state if (bytes != null && encoder != null) { // If we didn't use the encoder, then there's no chars left over if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = (char)0; } // This is ASCII if we had to flush encoder.currentMode = currentMode; // We don't use shift out mode, but if we've flushed we need to reset it so it doesn't // get output again. if (!encoder.MustFlush || encoder.charLeftOver != (char)0) { // We should be not flushing or converting Contract.Assert(!encoder.MustFlush || !encoder.m_throwOnOverflow, "[ISO2022Encoding.GetBytesCP50225KR]Expected no left over data or not flushing or not converting"); encoder.shiftInOutMode = shiftOutMode; } else encoder.shiftInOutMode = ISO2022Modes.ModeASCII; encoder.m_charsUsed = buffer.CharsUsed; } // Return our length return buffer.Count; }
internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder) { Encoder inEncoder = (Encoder) baseEncoder; int bits = 0; int bitCount = -1; Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, inEncoder, bytes, byteCount, chars, charCount); if (inEncoder != null) { bits = inEncoder.bits; bitCount = inEncoder.bitCount; while (bitCount >= 6) { bitCount -= 6; if (!buffer.AddByte(this.base64Bytes[(bits >> bitCount) & 0x3f])) { base.ThrowBytesOverflow(inEncoder, buffer.Count == 0); } } } while (buffer.MoreData) { char nextChar = buffer.GetNextChar(); if ((nextChar < '\x0080') && this.directEncode[nextChar]) { if (bitCount >= 0) { if (bitCount > 0) { if (!buffer.AddByte(this.base64Bytes[(bits << (6 - bitCount)) & 0x3f])) { break; } bitCount = 0; } if (!buffer.AddByte(0x2d)) { break; } bitCount = -1; } if (buffer.AddByte((byte) nextChar)) { continue; } break; } if ((bitCount < 0) && (nextChar == '+')) { if (buffer.AddByte(0x2b, (byte) 0x2d)) { continue; } break; } if (bitCount < 0) { if (!buffer.AddByte(0x2b)) { break; } bitCount = 0; } bits = (bits << 0x10) | nextChar; bitCount += 0x10; while (bitCount >= 6) { bitCount -= 6; if (!buffer.AddByte(this.base64Bytes[(bits >> bitCount) & 0x3f])) { bitCount += 6; nextChar = buffer.GetNextChar(); break; } } if (bitCount >= 6) { break; } } if ((bitCount >= 0) && ((inEncoder == null) || inEncoder.MustFlush)) { if ((bitCount > 0) && buffer.AddByte(this.base64Bytes[(bits << (6 - bitCount)) & 0x3f])) { bitCount = 0; } if (buffer.AddByte(0x2d)) { bits = 0; bitCount = -1; } else { buffer.GetNextChar(); } } if ((bytes != null) && (inEncoder != null)) { inEncoder.bits = bits; inEncoder.bitCount = bitCount; inEncoder.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }
internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder) { ISCIIEncoder inEncoder = (ISCIIEncoder) baseEncoder; Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, inEncoder, bytes, byteCount, chars, charCount); int defaultCodePage = this.defaultCodePage; bool bLastVirama = false; if (inEncoder != null) { defaultCodePage = inEncoder.currentCodePage; bLastVirama = inEncoder.bLastVirama; if (inEncoder.charLeftOver > '\0') { buffer.Fallback(inEncoder.charLeftOver); bLastVirama = false; } } while (buffer.MoreData) { char nextChar = buffer.GetNextChar(); if (nextChar < '\x00a0') { if (!buffer.AddByte((byte) nextChar)) { break; } bLastVirama = false; continue; } if ((nextChar < 'ँ') || (nextChar > '൯')) { if (bLastVirama && ((nextChar == '') || (nextChar == ''))) { if (nextChar == '') { if (!buffer.AddByte(0xe8)) { break; } } else if (!buffer.AddByte(0xe9)) { break; } bLastVirama = false; continue; } buffer.Fallback(nextChar); bLastVirama = false; continue; } int num2 = UnicodeToIndicChar[nextChar - 'ँ']; byte b = (byte) num2; int num4 = 15 & (num2 >> 8); int num5 = 0xf000 & num2; if (num2 == 0) { buffer.Fallback(nextChar); bLastVirama = false; } else { if (num4 != defaultCodePage) { if (!buffer.AddByte(0xef, (byte) (num4 | 0x40))) { break; } defaultCodePage = num4; } if (!buffer.AddByte(b, (num5 != 0) ? 1 : 0)) { break; } bLastVirama = b == 0xe8; if ((num5 != 0) && !buffer.AddByte(SecondIndicByte[num5 >> 12])) { break; } } } if ((defaultCodePage != this.defaultCodePage) && ((inEncoder == null) || inEncoder.MustFlush)) { if (buffer.AddByte(0xef, (byte) (this.defaultCodePage | 0x40))) { defaultCodePage = this.defaultCodePage; } else { buffer.GetNextChar(); } bLastVirama = false; } if ((inEncoder != null) && (bytes != null)) { if (!buffer.fallbackBuffer.bUsedEncoder) { inEncoder.charLeftOver = '\0'; } inEncoder.currentCodePage = defaultCodePage; inEncoder.bLastVirama = bLastVirama; inEncoder.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }
internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS encoder) { // Just need to ASSERT, this is called by something else internal that checked parameters already // We'll allow null bytes as a count // BCLDebug.Assert(bytes != null, "[GB18030Encoding.GetBytes]bytes is null"); BCLDebug.Assert(byteCount >= 0, "[GB18030Encoding.GetBytes]byteCount is negative"); BCLDebug.Assert(chars != null, "[GB18030Encoding.GetBytes]chars is null"); BCLDebug.Assert(charCount >= 0, "[GB18030Encoding.GetBytes]charCount is negative"); // Assert because we shouldn't be able to have a null encoder. BCLDebug.Assert(encoderFallback != null, "[GB18030Encoding.GetBytes]Attempting to use null encoder fallback"); // Get any left over characters char charLeftOver = (char)0; if (encoder != null) charLeftOver = encoder.charLeftOver; // prepare our helpers Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer( this, encoder, bytes, byteCount, chars, charCount); // Try again if we were MustFlush TryAgain: // Go ahead and do it, including the fallback. while (buffer.MoreData) { // Get next char char ch = buffer.GetNextChar(); // Have to check for charLeftOver if (charLeftOver != 0) { BCLDebug.Assert(Char.IsHighSurrogate(charLeftOver), "[GB18030Encoding.GetBytes] leftover character should be high surrogate, not 0x" + ((int)charLeftOver).ToString("X4", CultureInfo.InvariantCulture)); // If our next char isn't a low surrogate, then we need to do fallback. if (!Char.IsLowSurrogate(ch)) { // No low surrogate, fallback high surrogate & try this one again buffer.MovePrevious(false); // (Ignoring this character, don't thow) if (!buffer.Fallback(charLeftOver)) { charLeftOver = (char)0; break; } charLeftOver = (char)0; continue; } else { // Next is a surrogate, add it as surrogate pair // Need 4 bytes for surrogates // Get our offset int offset = ((charLeftOver - 0xd800) << 10) + (ch - 0xdc00); byte byte4 = (byte)((offset % 0x0a) + 0x30); offset /= 0x0a; byte byte3 = (byte)((offset % 0x7e) + 0x81); offset /= 0x7e; byte byte2 = (byte)((offset % 0x0a) + 0x30); offset /= 0x0a; BCLDebug.Assert(offset < 0x6f, "[GB18030Encoding.GetBytes](1) Expected offset < 0x6f, not 0x" + offset.ToString("X2", CultureInfo.InvariantCulture)); charLeftOver = (char)0; if (!buffer.AddByte((byte)(offset + 0x90),byte2,byte3,byte4)) { buffer.MovePrevious(false); // (don't throw) break; } } charLeftOver = '\0'; } // ASCII's easiest else if (ch <= 0x7f) { // Need a byte if (!buffer.AddByte((byte)ch)) break; } // See if its a surrogate pair else if (Char.IsHighSurrogate(ch)) { // Remember it for next time charLeftOver = ch; } else if (Char.IsLowSurrogate(ch)) { // Low surrogates should've been found already if (!buffer.Fallback(ch)) break; } else { // Not surrogate or ASCII, get value ushort iBytes = mapUnicodeToBytes[ch]; // See what kind it is if (Is4Byte(ch)) { // // This Unicode character will be converted to four-byte GB18030. // // Need 4 bytes byte byte4 = (byte)((iBytes % 0x0a) + 0x30); iBytes /= 0x0a; byte byte3 = (byte)((iBytes % 0x7e) + 0x81); iBytes /= 0x7e; byte byte2 = (byte)((iBytes % 0x0a) + 0x30); iBytes /= 0x0a; BCLDebug.Assert(iBytes < 0x7e, "[GB18030Encoding.GetBytes]Expected iBytes < 0x7e, not 0x" + iBytes.ToString("X2", CultureInfo.InvariantCulture)); if (!buffer.AddByte((byte)(iBytes + 0x81), byte2, byte3, byte4)) break; } else { // Its 2 byte, use it if (!buffer.AddByte(unchecked((byte)(iBytes >> 8)), unchecked((byte)(iBytes & 0xff)))) break; } } } // Do we need to flush our charLeftOver? if ((encoder == null || encoder.MustFlush) && (charLeftOver > 0)) { // Fall it back buffer.Fallback(charLeftOver); charLeftOver = (char)0; goto TryAgain; } // Fallback stuck it in encoder if necessary, but we have to clear MustFlash cases // (Check bytes != null, don't clear it if we're just counting) if (encoder != null) { // Remember our charLeftOver if (bytes != null) encoder.charLeftOver = charLeftOver; encoder.m_charsUsed = buffer.CharsUsed; } // Return our length return buffer.Count; }
private unsafe int GetBytesCP52936(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder) { Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount); ISO2022Modes modeASCII = ISO2022Modes.ModeASCII; if (encoder != null) { char charLeftOver = encoder.charLeftOver; modeASCII = encoder.currentMode; if (charLeftOver > '\0') { buffer.Fallback(charLeftOver); } } while (buffer.MoreData) { char nextChar = buffer.GetNextChar(); ushort num = base.mapUnicodeToBytes[nextChar]; if ((num == 0) && (nextChar != '\0')) { buffer.Fallback(nextChar); } else { byte num2 = (byte) (num >> 8); byte num3 = (byte) (num & 0xff); if (((num2 != 0) && (((num2 < 0xa1) || (num2 > 0xf7)) || ((num3 < 0xa1) || (num3 > 0xfe)))) || (((num2 == 0) && (num3 > 0x80)) && (num3 != 0xff))) { buffer.Fallback(nextChar); continue; } if (num2 != 0) { if (modeASCII != ISO2022Modes.ModeHZ) { if (!buffer.AddByte(0x7e, 0x7b, 2)) { break; } modeASCII = ISO2022Modes.ModeHZ; } if (buffer.AddByte((byte) (num2 & 0x7f), (byte) (num3 & 0x7f))) { continue; } break; } if (modeASCII != ISO2022Modes.ModeASCII) { if (!buffer.AddByte(0x7e, 0x7d, (num3 == 0x7e) ? 2 : 1)) { break; } modeASCII = ISO2022Modes.ModeASCII; } if (((num3 == 0x7e) && !buffer.AddByte(0x7e, 1)) || !buffer.AddByte(num3)) { break; } } } if ((modeASCII != ISO2022Modes.ModeASCII) && ((encoder == null) || encoder.MustFlush)) { if (buffer.AddByte(0x7e, (byte) 0x7d)) { modeASCII = ISO2022Modes.ModeASCII; } else { buffer.GetNextChar(); } } if ((encoder != null) && (bytes != null)) { encoder.currentMode = modeASCII; if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = '\0'; } encoder.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }
private unsafe int GetBytesCP5022xJP(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder) { Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount); ISO2022Modes modeASCII = ISO2022Modes.ModeASCII; ISO2022Modes shiftInOutMode = ISO2022Modes.ModeASCII; if (encoder != null) { char charLeftOver = encoder.charLeftOver; modeASCII = encoder.currentMode; shiftInOutMode = encoder.shiftInOutMode; if (charLeftOver > '\0') { buffer.Fallback(charLeftOver); } } while (buffer.MoreData) { byte num2; byte num3; char nextChar = buffer.GetNextChar(); ushort num = base.mapUnicodeToBytes[nextChar]; while (true) { num2 = (byte) (num >> 8); num3 = (byte) (num & 0xff); if (num2 != 0x10) { goto Label_010A; } if (this.CodePage != 0xc42c) { break; } if ((num3 < 0x21) || (num3 >= (0x21 + HalfToFullWidthKanaTable.Length))) { buffer.Fallback(nextChar); continue; } num = (ushort) (HalfToFullWidthKanaTable[num3 - 0x21] & 0x7f7f); } if (modeASCII != ISO2022Modes.ModeHalfwidthKatakana) { if (this.CodePage == 0xc42e) { if (!buffer.AddByte(14)) { break; } shiftInOutMode = modeASCII; modeASCII = ISO2022Modes.ModeHalfwidthKatakana; } else { if (!buffer.AddByte(0x1b, 40, (byte) 0x49)) { break; } modeASCII = ISO2022Modes.ModeHalfwidthKatakana; } } if (buffer.AddByte((byte) (num3 & 0x7f))) { continue; } break; Label_010A: if (num2 != 0) { if ((this.CodePage == 0xc42e) && (modeASCII == ISO2022Modes.ModeHalfwidthKatakana)) { if (!buffer.AddByte(15)) { break; } modeASCII = shiftInOutMode; } if (modeASCII != ISO2022Modes.ModeJIS0208) { if (!buffer.AddByte(0x1b, 0x24, (byte) 0x42)) { break; } modeASCII = ISO2022Modes.ModeJIS0208; } if (buffer.AddByte(num2, num3)) { continue; } break; } if ((num != 0) || (nextChar == '\0')) { if ((this.CodePage == 0xc42e) && (modeASCII == ISO2022Modes.ModeHalfwidthKatakana)) { if (!buffer.AddByte(15)) { break; } modeASCII = shiftInOutMode; } if (modeASCII != ISO2022Modes.ModeASCII) { if (!buffer.AddByte(0x1b, 40, (byte) 0x42)) { break; } modeASCII = ISO2022Modes.ModeASCII; } if (buffer.AddByte(num3)) { continue; } break; } buffer.Fallback(nextChar); } if ((modeASCII != ISO2022Modes.ModeASCII) && ((encoder == null) || encoder.MustFlush)) { if ((this.CodePage == 0xc42e) && (modeASCII == ISO2022Modes.ModeHalfwidthKatakana)) { if (buffer.AddByte(15)) { modeASCII = shiftInOutMode; } else { buffer.GetNextChar(); } } if ((modeASCII != ISO2022Modes.ModeASCII) && ((this.CodePage != 0xc42e) || (modeASCII != ISO2022Modes.ModeHalfwidthKatakana))) { if (buffer.AddByte(0x1b, 40, (byte) 0x42)) { modeASCII = ISO2022Modes.ModeASCII; } else { buffer.GetNextChar(); } } } if ((bytes != null) && (encoder != null)) { encoder.currentMode = modeASCII; encoder.shiftInOutMode = shiftInOutMode; if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = '\0'; } encoder.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }
private unsafe int GetBytesCP50225KR(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder) { Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount); ISO2022Modes modeASCII = ISO2022Modes.ModeASCII; ISO2022Modes shiftInOutMode = ISO2022Modes.ModeASCII; if (encoder != null) { char charLeftOver = encoder.charLeftOver; modeASCII = encoder.currentMode; shiftInOutMode = encoder.shiftInOutMode; if (charLeftOver > '\0') { buffer.Fallback(charLeftOver); } } while (buffer.MoreData) { char nextChar = buffer.GetNextChar(); ushort num = base.mapUnicodeToBytes[nextChar]; byte num2 = (byte) (num >> 8); byte num3 = (byte) (num & 0xff); if (num2 != 0) { if (shiftInOutMode != ISO2022Modes.ModeKR) { if (!buffer.AddByte(0x1b, 0x24, 0x29, (byte) 0x43)) { break; } shiftInOutMode = ISO2022Modes.ModeKR; } if (modeASCII != ISO2022Modes.ModeKR) { if (!buffer.AddByte(14)) { break; } modeASCII = ISO2022Modes.ModeKR; } if (buffer.AddByte(num2, num3)) { continue; } break; } if ((num != 0) || (nextChar == '\0')) { if (modeASCII != ISO2022Modes.ModeASCII) { if (!buffer.AddByte(15)) { break; } modeASCII = ISO2022Modes.ModeASCII; } if (buffer.AddByte(num3)) { continue; } break; } buffer.Fallback(nextChar); } if ((modeASCII != ISO2022Modes.ModeASCII) && ((encoder == null) || encoder.MustFlush)) { if (buffer.AddByte(15)) { modeASCII = ISO2022Modes.ModeASCII; } else { buffer.GetNextChar(); } } if ((bytes != null) && (encoder != null)) { if (!buffer.fallbackBuffer.bUsedEncoder) { encoder.charLeftOver = '\0'; } encoder.currentMode = modeASCII; if (!encoder.MustFlush || (encoder.charLeftOver != '\0')) { encoder.shiftInOutMode = shiftInOutMode; } else { encoder.shiftInOutMode = ISO2022Modes.ModeASCII; } encoder.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }
internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS encoder) { char charFallback = '\0'; if (encoder != null) { charFallback = encoder.charLeftOver; } Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount); Label_0183: while (buffer.MoreData) { char nextChar = buffer.GetNextChar(); if (charFallback != '\0') { if (!char.IsLowSurrogate(nextChar)) { buffer.MovePrevious(false); if (!buffer.Fallback(charFallback)) { charFallback = '\0'; break; } charFallback = '\0'; } else { int num = ((charFallback - 0xd800) << 10) + (nextChar - 0xdc00); byte num2 = (byte) ((num % 10) + 0x30); num /= 10; byte num3 = (byte) ((num % 0x7e) + 0x81); num /= 0x7e; byte num4 = (byte) ((num % 10) + 0x30); num /= 10; charFallback = '\0'; if (!buffer.AddByte((byte) (num + 0x90), num4, num3, num2)) { buffer.MovePrevious(false); break; } charFallback = '\0'; } } else { if (nextChar <= '\x007f') { if (buffer.AddByte((byte) nextChar)) { continue; } break; } if (char.IsHighSurrogate(nextChar)) { charFallback = nextChar; } else { if (char.IsLowSurrogate(nextChar)) { if (buffer.Fallback(nextChar)) { continue; } break; } ushort num5 = base.mapUnicodeToBytes[nextChar]; if (this.Is4Byte(nextChar)) { byte num6 = (byte) ((num5 % 10) + 0x30); num5 = (ushort) (num5 / 10); byte num7 = (byte) ((num5 % 0x7e) + 0x81); num5 = (ushort) (num5 / 0x7e); byte num8 = (byte) ((num5 % 10) + 0x30); num5 = (ushort) (num5 / 10); if (buffer.AddByte((byte) (num5 + 0x81), num8, num7, num6)) { continue; } break; } if (!buffer.AddByte((byte) (num5 >> 8), (byte) (num5 & 0xff))) { break; } } } } if (((encoder == null) || encoder.MustFlush) && (charFallback > '\0')) { buffer.Fallback(charFallback); charFallback = '\0'; goto Label_0183; } if (encoder != null) { if (bytes != null) { encoder.charLeftOver = charFallback; } encoder.m_charsUsed = buffer.CharsUsed; } return buffer.Count; }