Base64EncoderAsync.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System.Text;
  2. using System.Diagnostics;
  3. using System.Threading.Tasks;
  4. namespace System.Xml {
  5. internal abstract partial class Base64Encoder {
  6. internal abstract Task WriteCharsAsync(char[] chars, int index, int count);
  7. internal async Task EncodeAsync( byte[] buffer, int index, int count ) {
  8. if ( buffer == null ) {
  9. throw new ArgumentNullException( "buffer" );
  10. }
  11. if ( index < 0 ) {
  12. throw new ArgumentOutOfRangeException( "index" );
  13. }
  14. if ( count < 0 ) {
  15. throw new ArgumentOutOfRangeException( "count" );
  16. }
  17. if ( count > buffer.Length - index ) {
  18. throw new ArgumentOutOfRangeException( "count" );
  19. }
  20. // encode left-over buffer
  21. if( leftOverBytesCount > 0 ) {
  22. int i = leftOverBytesCount;
  23. while ( i < 3 && count > 0 ) {
  24. leftOverBytes[i++] = buffer[index++];
  25. count--;
  26. }
  27. // the total number of buffer we have is less than 3 -> return
  28. if ( count == 0 && i < 3 ) {
  29. leftOverBytesCount = i;
  30. return;
  31. }
  32. // encode the left-over buffer and write out
  33. int leftOverChars = Convert.ToBase64CharArray( leftOverBytes, 0, 3, charsLine, 0 );
  34. await WriteCharsAsync( charsLine, 0, leftOverChars ).ConfigureAwait(false);
  35. }
  36. // store new left-over buffer
  37. leftOverBytesCount = count % 3;
  38. if ( leftOverBytesCount > 0 ) {
  39. count -= leftOverBytesCount;
  40. if ( leftOverBytes == null ) {
  41. leftOverBytes = new byte[3];
  42. }
  43. for( int i = 0; i < leftOverBytesCount; i++ ) {
  44. leftOverBytes[i] = buffer[ index + count + i ];
  45. }
  46. }
  47. // encode buffer in 76 character long chunks
  48. int endIndex = index + count;
  49. int chunkSize = LineSizeInBytes;
  50. while( index < endIndex ) {
  51. if ( index + chunkSize > endIndex ) {
  52. chunkSize = endIndex - index;
  53. }
  54. int charCount = Convert.ToBase64CharArray( buffer, index, chunkSize, charsLine, 0 );
  55. await WriteCharsAsync( charsLine, 0, charCount ).ConfigureAwait(false);
  56. index += chunkSize;
  57. }
  58. }
  59. internal async Task FlushAsync() {
  60. if ( leftOverBytesCount > 0 ) {
  61. int leftOverChars = Convert.ToBase64CharArray( leftOverBytes, 0, leftOverBytesCount, charsLine, 0 );
  62. await WriteCharsAsync( charsLine, 0, leftOverChars ).ConfigureAwait(false);
  63. leftOverBytesCount = 0;
  64. }
  65. }
  66. }
  67. internal partial class XmlTextWriterBase64Encoder : Base64Encoder {
  68. internal override Task WriteCharsAsync(char[] chars, int index, int count) {
  69. throw new NotImplementedException();
  70. }
  71. }
  72. internal partial class XmlRawWriterBase64Encoder : Base64Encoder {
  73. internal override Task WriteCharsAsync( char[] chars, int index, int count ) {
  74. return rawWriter.WriteRawAsync( chars, index, count );
  75. }
  76. }
  77. }