Writing textual data

  • Revision slug: Writing_textual_data
  • Revision title: Writing textual data
  • Revision id: 96776
  • Created:
  • Creator: Biesi
  • Is current revision? No
  • Comment document convertToInputStream

Revision Content

Writing textual data to streams

Warning: This article uses unfrozen interfaces. These interfaces may change in newer Mozilla versions and your code may stop working.

When writing textual data to an output stream or to a file, you need to pick a character set.

Some character sets can represent "all" characters (the UTF-* character sets and UCS-4), others can only represent some characters.

When the file is to be read only by the application/extension itself, using UTF-8 is often the best choice - it can represent all characters, and ASCII characters are represented efficiently.

Writing to a stream

In Gecko 1.8 (SeaMonkey 1.0, Firefox 1.1), you can use nsIConverterOutputStream:

var charset = "UTF-8"; // Can be any charset name that Mozilla supports

var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
                   .createInstance(Components.interfaces.nsIConverterOutputStream);

// This assumes that fos is the nsIOutputStream you want to write to
os.init(fos, charset);

os.write("Umlaute: \u00FC \u00E4\n");
os.write("Hebrew:  \u05D0 \u05D1\n");
// etc.

os.close();

You can also write single characters using the writeChar function, although using write is simpler from JavaScript code.

Unsupported characters

By default, trying to write characters that are not supported by the selected character set throws an exception (with an error code of NS_ERROR_LOSS_OF_SIGNIFICANT_DATA), and no data will be written.

To instead write an replacement character in such cases, you can use the setReplacementChar function:

os.setReplacementChar("?".charCodeAt(0));

Note: If the replacement character is not a supported character in the chosen character set, attempts to write unsupported characters will fail with NS_ERROR_LOSS_OF_SIGNIFICANT_DATA.

Versions before Gecko 1.8

Firefox 1.0.x, Mozilla 1.7.x and older versions do not support nsIConverterOutputStream.

Alternative ways usable from JavaScript do not support character sets that use embedded nulls (such as UTF-16 or UCS-4). They work by manually converting the string you want to write to a byte sequence, and writing that to the stream.

Here's an example:

// First, get and initialize the converter
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* The charset you want, using UTF-8 for this example */ "UTF-8";

Now you can convert and write to the stream:

// This code assumes that os is your nsIOutputStream
// your_string here is the string you want to write.
var chunk = converter.ConvertFromUnicode(your_string);
os.write(chunk, chunk.length);
// Repeat as needed for further strings

At the end, you need to call Finish and write its data to the stream. Note that not many character sets need it, but for those that do calling this is important for proper output.

 var fin = converter.Finish();
 os.write(fin, fin.length);
 os.close();

Converting a string into a stream

Sometimes, it is useful to convert a string into a stream, for example for uploading it using nsIUploadChannel.

The example here requires Gecko 1.8 (Firefox 1.1, SeaMonkey 1.0).

nsIScriptableUnicodeConverter has a simple method to do that:

// First, get and initialize the converter
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* The charset you want to use. Using UTF-8 in this example */ "UTF-8";
// Now, convert a string to an nsIInputStream
var stream = converter.convertToInputStream("A string with non-ASCII characters: \u00FC \u05D0\n");
// stream can now be used as an nsIInputStream

See Also

Reading textual data

Revision Source

<h2 name="Writing_textual_data_to_streams"> Writing textual data to streams </h2>
<div style="border:red 1px inset; background-color: #dd0;">
<p><i>Warning</i>: This article uses unfrozen interfaces. These interfaces may change
in newer Mozilla versions and your code may stop working.
</p>
</div>
<p>When writing textual data to an output stream or to a file, you need to pick a <a href="en/Character_set">character set</a>.
</p><p>Some character sets can represent "all" characters (the UTF-* character sets and UCS-4), others can only
represent some characters.
</p><p>When the file is to be read only by the application/extension itself, using UTF-8 is often the best choice -
it can represent all characters, and ASCII characters are represented efficiently.
</p>
<h3 name="Writing_to_a_stream"> Writing to a stream </h3>
<p>In Gecko 1.8 (SeaMonkey 1.0, Firefox 1.1), you can use nsIConverterOutputStream:
</p>
<pre class="eval">var charset = "UTF-8"; // Can be any charset name that Mozilla supports

var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
                   .createInstance(Components.interfaces.nsIConverterOutputStream);

// This assumes that fos is the nsIOutputStream you want to write to
os.init(fos, charset);

os.write("Umlaute: \u00FC \u00E4\n");
os.write("Hebrew:  \u05D0 \u05D1\n");
// etc.

os.close();
</pre>
<p>You can also write single characters using the <code>writeChar</code> function, although using
<code>write</code> is simpler from JavaScript code.
</p>
<h4 name="Unsupported_characters"> Unsupported characters </h4>
<p>By default, trying to write characters that are not supported by the selected character set throws an exception 
(with an error code of NS_ERROR_LOSS_OF_SIGNIFICANT_DATA), and no data will be written.
</p><p>To instead write an replacement character in such cases, you can use the setReplacementChar function:
</p>
<pre class="eval">os.setReplacementChar("?".charCodeAt(0));
</pre>
<p><i>Note</i>: If the replacement character is not a supported character in the chosen character set, attempts to write
unsupported characters will fail with NS_ERROR_LOSS_OF_SIGNIFICANT_DATA.
</p>
<h3 name="Versions_before_Gecko_1.8"> Versions before Gecko 1.8 </h3>
<p>Firefox 1.0.x, Mozilla 1.7.x and older versions do not support <code>nsIConverterOutputStream</code>.
</p><p>Alternative ways usable from JavaScript <b>do not support character sets that use embedded nulls</b> (such as UTF-16 or UCS-4). They work by manually converting the string you want to write to a byte sequence, and writing that to the stream.
</p><p>Here's an example:
</p>
<pre class="eval">// First, get and initialize the converter
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* The charset you want, using UTF-8 for this example */ "UTF-8";
</pre>
<p>Now you can convert and write to the stream:
</p>
<pre class="eval">// This code assumes that os is your nsIOutputStream
// your_string here is the string you want to write.
var chunk = converter.ConvertFromUnicode(your_string);
os.write(chunk, chunk.length);
// Repeat as needed for further strings
</pre>
<p>At the end, you need to call <code>Finish</code> and write its data to the stream.
Note that not many character sets need it, but for those that do calling this is important
for proper output.
</p>
<pre class="eval"> var fin = converter.Finish();
 os.write(fin, fin.length);
 os.close();
</pre>
<h3 name="Converting_a_string_into_a_stream"> Converting a string into a stream </h3>
<p>Sometimes, it is useful to convert a string into a stream, for example for uploading it using <code><a href="en/NsIUploadChannel">nsIUploadChannel</a></code>.
</p><p>The example here requires Gecko 1.8 (Firefox 1.1, SeaMonkey 1.0).
</p><p><code><a href="en/NsIScriptableUnicodeConverter">nsIScriptableUnicodeConverter</a></code> has a simple method to do that:
</p>
<pre class="eval">// First, get and initialize the converter
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* The charset you want to use. Using UTF-8 in this example */ "UTF-8";
</pre>
<pre class="eval">// Now, convert a string to an nsIInputStream
var stream = converter.convertToInputStream("A string with non-ASCII characters: \u00FC \u05D0\n");
// stream can now be used as an nsIInputStream
</pre>
<h2 name="See_Also"> See Also </h2>
<p><a href="en/Reading_textual_data">Reading textual data</a>
</p>
Revert to this revision