Encoding.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. /*
  2. * Encoding.cs - Implementation of the "System.Text.Encoding" class.
  3. *
  4. * Copyright (c) 2001, 2002 Southern Storm Software, Pty Ltd
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the "Software"),
  8. * to deal in the Software without restriction, including without limitation
  9. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. * and/or sell copies of the Software, and to permit persons to whom the
  11. * Software is furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included
  14. * in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22. * OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. namespace System.Text
  25. {
  26. using System;
  27. using System.Reflection;
  28. using System.Globalization;
  29. using System.Security;
  30. [Serializable]
  31. public abstract class Encoding
  32. {
  33. // Code page used by this encoding.
  34. internal int codePage;
  35. // Constructor.
  36. protected Encoding()
  37. {
  38. codePage = 0;
  39. }
  40. #if ECMA_COMPAT
  41. protected internal
  42. #else
  43. protected
  44. #endif
  45. Encoding(int codePage)
  46. {
  47. this.codePage = codePage;
  48. }
  49. // until we change the callers:
  50. internal static string _ (string arg) {
  51. return arg;
  52. }
  53. // Convert between two encodings.
  54. public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
  55. byte[] bytes)
  56. {
  57. if(srcEncoding == null)
  58. {
  59. throw new ArgumentNullException("srcEncoding");
  60. }
  61. if(dstEncoding == null)
  62. {
  63. throw new ArgumentNullException("dstEncoding");
  64. }
  65. if(bytes == null)
  66. {
  67. throw new ArgumentNullException("bytes");
  68. }
  69. return dstEncoding.GetBytes(srcEncoding.GetChars
  70. (bytes, 0, bytes.Length));
  71. }
  72. public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
  73. byte[] bytes, int index, int count)
  74. {
  75. if(srcEncoding == null)
  76. {
  77. throw new ArgumentNullException("srcEncoding");
  78. }
  79. if(dstEncoding == null)
  80. {
  81. throw new ArgumentNullException("dstEncoding");
  82. }
  83. if(bytes == null)
  84. {
  85. throw new ArgumentNullException("bytes");
  86. }
  87. if(index < 0 || index > bytes.Length)
  88. {
  89. throw new ArgumentOutOfRangeException
  90. ("index", _("ArgRange_Array"));
  91. }
  92. if(count < 0 || (bytes.Length - index) < count)
  93. {
  94. throw new ArgumentOutOfRangeException
  95. ("count", _("ArgRange_Array"));
  96. }
  97. return dstEncoding.GetBytes(srcEncoding.GetChars
  98. (bytes, index, count));
  99. }
  100. // Determine if two Encoding objects are equal.
  101. public override bool Equals(Object obj)
  102. {
  103. Encoding enc = (obj as Encoding);
  104. if(enc != null)
  105. {
  106. return (codePage == enc.codePage);
  107. }
  108. else
  109. {
  110. return false;
  111. }
  112. }
  113. // Get the number of characters needed to encode a character buffer.
  114. public abstract int GetByteCount(char[] chars, int index, int count);
  115. // Convenience wrappers for "GetByteCount".
  116. public virtual int GetByteCount(String s)
  117. {
  118. if(s != null)
  119. {
  120. char[] chars = s.ToCharArray();
  121. return GetByteCount(chars, 0, chars.Length);
  122. }
  123. else
  124. {
  125. throw new ArgumentNullException("s");
  126. }
  127. }
  128. public virtual int GetByteCount(char[] chars)
  129. {
  130. if(chars != null)
  131. {
  132. return GetByteCount(chars, 0, chars.Length);
  133. }
  134. else
  135. {
  136. throw new ArgumentNullException("chars");
  137. }
  138. }
  139. // Get the bytes that result from encoding a character buffer.
  140. public abstract int GetBytes(char[] chars, int charIndex, int charCount,
  141. byte[] bytes, int byteIndex);
  142. // Convenience wrappers for "GetBytes".
  143. public virtual int GetBytes(String s, int charIndex, int charCount,
  144. byte[] bytes, int byteIndex)
  145. {
  146. if(s == null)
  147. {
  148. throw new ArgumentNullException("s");
  149. }
  150. return GetBytes(s.ToCharArray(), charIndex, charCount,
  151. bytes, byteIndex);
  152. }
  153. public virtual byte[] GetBytes(String s)
  154. {
  155. if(s == null)
  156. {
  157. throw new ArgumentNullException("s");
  158. }
  159. char[] chars = s.ToCharArray();
  160. int numBytes = GetByteCount(chars, 0, chars.Length);
  161. byte[] bytes = new byte [numBytes];
  162. GetBytes(chars, 0, chars.Length, bytes, 0);
  163. return bytes;
  164. }
  165. public virtual byte[] GetBytes(char[] chars, int index, int count)
  166. {
  167. int numBytes = GetByteCount(chars, index, count);
  168. byte[] bytes = new byte [numBytes];
  169. GetBytes(chars, index, count, bytes, 0);
  170. return bytes;
  171. }
  172. public virtual byte[] GetBytes(char[] chars)
  173. {
  174. int numBytes = GetByteCount(chars, 0, chars.Length);
  175. byte[] bytes = new byte [numBytes];
  176. GetBytes(chars, 0, chars.Length, bytes, 0);
  177. return bytes;
  178. }
  179. // Get the number of characters needed to decode a byte buffer.
  180. public abstract int GetCharCount(byte[] bytes, int index, int count);
  181. // Convenience wrappers for "GetCharCount".
  182. public virtual int GetCharCount(byte[] bytes)
  183. {
  184. if(bytes == null)
  185. {
  186. throw new ArgumentNullException("bytes");
  187. }
  188. return GetCharCount(bytes, 0, bytes.Length);
  189. }
  190. // Get the characters that result from decoding a byte buffer.
  191. public abstract int GetChars(byte[] bytes, int byteIndex, int byteCount,
  192. char[] chars, int charIndex);
  193. // Convenience wrappers for "GetChars".
  194. public virtual char[] GetChars(byte[] bytes, int index, int count)
  195. {
  196. int numChars = GetCharCount(bytes, index, count);
  197. char[] chars = new char [numChars];
  198. GetChars(bytes, index, count, chars, 0);
  199. return chars;
  200. }
  201. public virtual char[] GetChars(byte[] bytes)
  202. {
  203. if(bytes == null)
  204. {
  205. throw new ArgumentNullException("bytes");
  206. }
  207. int numChars = GetCharCount(bytes, 0, bytes.Length);
  208. char[] chars = new char [numChars];
  209. GetChars(bytes, 0, bytes.Length, chars, 0);
  210. return chars;
  211. }
  212. // Get a decoder that forwards requests to this object.
  213. public virtual Decoder GetDecoder()
  214. {
  215. return new ForwardingDecoder(this);
  216. }
  217. // Get an encoder that forwards requests to this object.
  218. public virtual Encoder GetEncoder()
  219. {
  220. return new ForwardingEncoder(this);
  221. }
  222. // Loaded copy of the "I18N" assembly. We need to move
  223. // this into a class in "System.Private" eventually.
  224. private static Assembly i18nAssembly;
  225. private static bool i18nDisabled;
  226. // Invoke a specific method on the "I18N" manager object.
  227. // Returns NULL if the method failed.
  228. private static Object InvokeI18N(String name, params Object[] args)
  229. {
  230. lock(typeof(Encoding))
  231. {
  232. // Bail out if we previously detected that there
  233. // is insufficent engine support for I18N handling.
  234. if(i18nDisabled)
  235. {
  236. return null;
  237. }
  238. // Find or load the "I18N" assembly.
  239. if(i18nAssembly == null)
  240. {
  241. try
  242. {
  243. try
  244. {
  245. i18nAssembly = Assembly.Load("I18N");
  246. }
  247. catch(NotImplementedException)
  248. {
  249. // Assembly loading unsupported by the engine.
  250. i18nDisabled = true;
  251. return null;
  252. }
  253. if(i18nAssembly == null)
  254. {
  255. return null;
  256. }
  257. }
  258. catch(SystemException)
  259. {
  260. return null;
  261. }
  262. }
  263. // Find the "I18N.Common.Manager" class.
  264. Type managerClass;
  265. try
  266. {
  267. managerClass =
  268. i18nAssembly.GetType("I18N.Common.Manager");
  269. }
  270. catch(NotImplementedException)
  271. {
  272. // "GetType" is not supported by the engine.
  273. i18nDisabled = true;
  274. return null;
  275. }
  276. if(managerClass == null)
  277. {
  278. return null;
  279. }
  280. // Get the value of the "PrimaryManager" property.
  281. Object manager;
  282. try
  283. {
  284. manager = managerClass.InvokeMember
  285. ("PrimaryManager",
  286. BindingFlags.GetProperty |
  287. BindingFlags.Static |
  288. BindingFlags.Public,
  289. null, null, null, null, null, null);
  290. if(manager == null)
  291. {
  292. return null;
  293. }
  294. }
  295. catch(MissingMethodException)
  296. {
  297. return null;
  298. }
  299. catch(SecurityException)
  300. {
  301. return null;
  302. }
  303. catch(NotImplementedException)
  304. {
  305. // "InvokeMember" is not supported by the engine.
  306. i18nDisabled = true;
  307. return null;
  308. }
  309. // Invoke the requested method on the manager.
  310. try
  311. {
  312. return managerClass.InvokeMember
  313. (name,
  314. BindingFlags.InvokeMethod |
  315. BindingFlags.Instance |
  316. BindingFlags.Public,
  317. null, manager, args, null, null, null);
  318. }
  319. catch(MissingMethodException)
  320. {
  321. return null;
  322. }
  323. catch(SecurityException)
  324. {
  325. return null;
  326. }
  327. }
  328. }
  329. // Get an encoder for a specific code page.
  330. #if ECMA_COMPAT
  331. private
  332. #else
  333. public
  334. #endif
  335. static Encoding GetEncoding(int codePage)
  336. {
  337. // Check for the builtin code pages first.
  338. switch(codePage)
  339. {
  340. case 0: return Default;
  341. case ASCIIEncoding.ASCII_CODE_PAGE:
  342. return ASCII;
  343. case UTF7Encoding.UTF7_CODE_PAGE:
  344. return UTF7;
  345. case UTF8Encoding.UTF8_CODE_PAGE:
  346. return UTF8;
  347. case UnicodeEncoding.UNICODE_CODE_PAGE:
  348. return Unicode;
  349. case UnicodeEncoding.BIG_UNICODE_CODE_PAGE:
  350. return BigEndianUnicode;
  351. case Latin1Encoding.ISOLATIN_CODE_PAGE:
  352. return ISOLatin1;
  353. default: break;
  354. }
  355. // Try to obtain a code page handler from the I18N handler.
  356. Encoding enc = (Encoding)(InvokeI18N("GetEncoding", codePage));
  357. if(enc != null)
  358. {
  359. return enc;
  360. }
  361. #if false
  362. // Build a code page class name.
  363. String cpName = "System.Text.CP" + codePage.ToString();
  364. // Look for a code page converter in this assembly.
  365. Assembly assembly = Assembly.GetExecutingAssembly();
  366. Type type = assembly.GetType(cpName);
  367. if(type != null)
  368. {
  369. return (Encoding)(Activator.CreateInstance(type));
  370. }
  371. // Look in any assembly, in case the application
  372. // has provided its own code page handler.
  373. type = Type.GetType(cpName);
  374. if(type != null)
  375. {
  376. return (Encoding)(Activator.CreateInstance(type));
  377. }
  378. #endif
  379. // We have no idea how to handle this code page.
  380. throw new NotSupportedException
  381. (String.Format
  382. (_("NotSupp_CodePage"), codePage.ToString()));
  383. }
  384. #if !ECMA_COMPAT
  385. // Table of builtin web encoding names and the corresponding code pages.
  386. private static readonly String[] encodingNames =
  387. {"us-ascii", "utf-7", "utf-8", "utf-16",
  388. "unicodeFFFE", "iso-8859-1"};
  389. private static readonly int[] encodingCodePages =
  390. {ASCIIEncoding.ASCII_CODE_PAGE,
  391. UTF7Encoding.UTF7_CODE_PAGE,
  392. UTF8Encoding.UTF8_CODE_PAGE,
  393. UnicodeEncoding.UNICODE_CODE_PAGE,
  394. UnicodeEncoding.BIG_UNICODE_CODE_PAGE,
  395. Latin1Encoding.ISOLATIN_CODE_PAGE};
  396. // Get an encoding object for a specific web encoding name.
  397. public static Encoding GetEncoding(String name)
  398. {
  399. // Validate the parameters.
  400. if(name == null)
  401. {
  402. throw new ArgumentNullException("name");
  403. }
  404. // Search the table for a name match.
  405. int posn;
  406. for(posn = 0; posn < encodingNames.Length; ++posn)
  407. {
  408. if(String.Compare(name, encodingNames[posn], true,
  409. CultureInfo.InvariantCulture) == 0)
  410. {
  411. return GetEncoding(encodingCodePages[posn]);
  412. }
  413. }
  414. // Try to obtain a web encoding handler from the I18N handler.
  415. Encoding enc = (Encoding)(InvokeI18N("GetEncoding", name));
  416. if(enc != null)
  417. {
  418. return enc;
  419. }
  420. #if false
  421. // Build a web encoding class name.
  422. String encName = "System.Text.ENC" +
  423. name.ToLower(CultureInfo.InvariantCulture)
  424. .Replace('-', '_');
  425. // Look for a code page converter in this assembly.
  426. Assembly assembly = Assembly.GetExecutingAssembly();
  427. Type type = assembly.GetType(encName);
  428. if(type != null)
  429. {
  430. return (Encoding)(Activator.CreateInstance(type));
  431. }
  432. // Look in any assembly, in case the application
  433. // has provided its own code page handler.
  434. type = Type.GetType(encName);
  435. if(type != null)
  436. {
  437. return (Encoding)(Activator.CreateInstance(type));
  438. }
  439. #endif
  440. // We have no idea how to handle this encoding name.
  441. throw new NotSupportedException
  442. (String.Format(_("NotSupp_EncodingName"), name));
  443. }
  444. #endif // !ECMA_COMPAT
  445. // Get a hash code for this instance.
  446. public override int GetHashCode()
  447. {
  448. return codePage;
  449. }
  450. // Get the maximum number of bytes needed to encode a
  451. // specified number of characters.
  452. public abstract int GetMaxByteCount(int charCount);
  453. // Get the maximum number of characters needed to decode a
  454. // specified number of bytes.
  455. public abstract int GetMaxCharCount(int byteCount);
  456. // Get the identifying preamble for this encoding.
  457. public virtual byte[] GetPreamble()
  458. {
  459. return new byte [0];
  460. }
  461. // Decode a buffer of bytes into a string.
  462. public virtual String GetString(byte[] bytes, int index, int count)
  463. {
  464. return new String(GetChars(bytes, index, count));
  465. }
  466. public virtual String GetString(byte[] bytes)
  467. {
  468. return new String(GetChars(bytes));
  469. }
  470. #if !ECMA_COMPAT
  471. // Get the mail body name for this encoding.
  472. public virtual String BodyName
  473. {
  474. get
  475. {
  476. return null;
  477. }
  478. }
  479. // Get the code page represented by this object.
  480. public virtual int CodePage
  481. {
  482. get
  483. {
  484. return codePage;
  485. }
  486. }
  487. // Get the human-readable name for this encoding.
  488. public virtual String EncodingName
  489. {
  490. get
  491. {
  492. return null;
  493. }
  494. }
  495. // Get the mail agent header name for this encoding.
  496. public virtual String HeaderName
  497. {
  498. get
  499. {
  500. return null;
  501. }
  502. }
  503. // Determine if this encoding can be displayed in a Web browser.
  504. public virtual bool IsBrowserDisplay
  505. {
  506. get
  507. {
  508. return false;
  509. }
  510. }
  511. // Determine if this encoding can be saved from a Web browser.
  512. public virtual bool IsBrowserSave
  513. {
  514. get
  515. {
  516. return false;
  517. }
  518. }
  519. // Determine if this encoding can be displayed in a mail/news agent.
  520. public virtual bool IsMailNewsDisplay
  521. {
  522. get
  523. {
  524. return false;
  525. }
  526. }
  527. // Determine if this encoding can be saved from a mail/news agent.
  528. public virtual bool IsMailNewsSave
  529. {
  530. get
  531. {
  532. return false;
  533. }
  534. }
  535. // Get the IANA-preferred Web name for this encoding.
  536. public virtual String WebName
  537. {
  538. get
  539. {
  540. return null;
  541. }
  542. }
  543. // Get the Windows code page represented by this object.
  544. public virtual int WindowsCodePage
  545. {
  546. get
  547. {
  548. // We make no distinction between normal and
  549. // Windows code pages in this implementation.
  550. return codePage;
  551. }
  552. }
  553. #endif // !ECMA_COMPAT
  554. // Storage for standard encoding objects.
  555. private static Encoding asciiEncoding = null;
  556. private static Encoding bigEndianEncoding = null;
  557. private static Encoding defaultEncoding = null;
  558. private static Encoding utf7Encoding = null;
  559. private static Encoding utf8Encoding = null;
  560. private static Encoding unicodeEncoding = null;
  561. private static Encoding isoLatin1Encoding = null;
  562. // Get the standard ASCII encoding object.
  563. public static Encoding ASCII
  564. {
  565. get
  566. {
  567. lock(typeof(Encoding))
  568. {
  569. if(asciiEncoding == null)
  570. {
  571. asciiEncoding = new ASCIIEncoding();
  572. }
  573. return asciiEncoding;
  574. }
  575. }
  576. }
  577. // Get the standard big-endian Unicode encoding object.
  578. public static Encoding BigEndianUnicode
  579. {
  580. get
  581. {
  582. lock(typeof(Encoding))
  583. {
  584. if(bigEndianEncoding == null)
  585. {
  586. bigEndianEncoding = new UnicodeEncoding(true, true);
  587. }
  588. return bigEndianEncoding;
  589. }
  590. }
  591. }
  592. // Get the default encoding object.
  593. public static Encoding Default
  594. {
  595. get
  596. {
  597. lock(typeof(Encoding))
  598. {
  599. if(defaultEncoding == null)
  600. {
  601. // See if the underlying system knows what
  602. // code page handler we should be using.
  603. int codePage = DefaultEncoding.InternalCodePage();
  604. if(codePage != 0)
  605. {
  606. try
  607. {
  608. defaultEncoding = GetEncoding(codePage);
  609. }
  610. catch(NotSupportedException)
  611. {
  612. defaultEncoding = new DefaultEncoding();
  613. }
  614. }
  615. else
  616. {
  617. defaultEncoding = new DefaultEncoding();
  618. }
  619. }
  620. return defaultEncoding;
  621. }
  622. }
  623. }
  624. // Get the ISO Latin1 encoding object.
  625. private static Encoding ISOLatin1
  626. {
  627. get
  628. {
  629. lock(typeof(Encoding))
  630. {
  631. if(isoLatin1Encoding == null)
  632. {
  633. isoLatin1Encoding = new Latin1Encoding();
  634. }
  635. return isoLatin1Encoding;
  636. }
  637. }
  638. }
  639. // Get the standard UTF-7 encoding object.
  640. #if ECMA_COMPAT
  641. private
  642. #else
  643. public
  644. #endif
  645. static Encoding UTF7
  646. {
  647. get
  648. {
  649. lock(typeof(Encoding))
  650. {
  651. if(utf7Encoding == null)
  652. {
  653. utf7Encoding = new UTF7Encoding();
  654. }
  655. return utf7Encoding;
  656. }
  657. }
  658. }
  659. // Get the standard UTF-8 encoding object.
  660. public static Encoding UTF8
  661. {
  662. get
  663. {
  664. lock(typeof(Encoding))
  665. {
  666. if(utf8Encoding == null)
  667. {
  668. utf8Encoding = new UTF8Encoding();
  669. }
  670. return utf8Encoding;
  671. }
  672. }
  673. }
  674. // Get the standard little-endian Unicode encoding object.
  675. public static Encoding Unicode
  676. {
  677. get
  678. {
  679. lock(typeof(Encoding))
  680. {
  681. if(unicodeEncoding == null)
  682. {
  683. unicodeEncoding = new UnicodeEncoding();
  684. }
  685. return unicodeEncoding;
  686. }
  687. }
  688. }
  689. // Forwarding decoder implementation.
  690. private sealed class ForwardingDecoder : Decoder
  691. {
  692. private Encoding encoding;
  693. // Constructor.
  694. public ForwardingDecoder(Encoding enc)
  695. {
  696. encoding = enc;
  697. }
  698. // Override inherited methods.
  699. public override int GetCharCount(byte[] bytes, int index, int count)
  700. {
  701. return encoding.GetCharCount(bytes, index, count);
  702. }
  703. public override int GetChars(byte[] bytes, int byteIndex,
  704. int byteCount, char[] chars,
  705. int charIndex)
  706. {
  707. return encoding.GetChars(bytes, byteIndex, byteCount,
  708. chars, charIndex);
  709. }
  710. } // class ForwardingDecoder
  711. // Forwarding encoder implementation.
  712. private sealed class ForwardingEncoder : Encoder
  713. {
  714. private Encoding encoding;
  715. // Constructor.
  716. public ForwardingEncoder(Encoding enc)
  717. {
  718. encoding = enc;
  719. }
  720. // Override inherited methods.
  721. public override int GetByteCount(char[] chars, int index,
  722. int count, bool flush)
  723. {
  724. return encoding.GetByteCount(chars, index, count);
  725. }
  726. public override int GetBytes(char[] chars, int charIndex,
  727. int charCount, byte[] bytes,
  728. int byteCount, bool flush)
  729. {
  730. return encoding.GetBytes(chars, charIndex, charCount,
  731. bytes, byteCount);
  732. }
  733. } // class ForwardingEncoder
  734. }; // class Encoding
  735. }; // namespace System.Text