<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.mozilla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dantman</id>
	<title>MozillaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mozilla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dantman"/>
	<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/Special:Contributions/Dantman"/>
	<updated>2026-09-03T09:08:49Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.10</generator>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS&amp;diff=167562</id>
		<title>ServerJS</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS&amp;diff=167562"/>
		<updated>2009-09-09T22:18:09Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;big&amp;gt;Wiki has moved to http://wiki.commonjs.org/ please make all further edits there&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background: #999; border: 1px inset #aaa;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name change underway!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This site is a starting point for collecting up ideas, links and any draft API suggestions for the [http://groups.google.com/group/commonjs CommonJS group]. Discussions occur on that mailing list and [http://log.serverjs.org/mochabot/join on IRC (#serverjs on freenode)].&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Introduction|Introduction]]&lt;br /&gt;
* [[ServerJS/FAQ|FAQ]]&lt;br /&gt;
* [[ServerJS/Process|Process]]&lt;br /&gt;
* [[ServerJS/Target_Platforms|Target Platforms]]&lt;br /&gt;
* [[ServerJS/Coding_Standards|Coding Standards]]&lt;br /&gt;
&lt;br /&gt;
== Current Efforts ==&lt;br /&gt;
&lt;br /&gt;
This is a list of issues currently being discussed / standardized. They come from the &amp;quot;Low level&amp;quot; department, as we need to have a solid basics prior to building a tower.&lt;br /&gt;
&lt;br /&gt;
# [[ServerJS/Modules|Modules]]&lt;br /&gt;
# [[ServerJS/Filesystem_API|Filesystem API]]&lt;br /&gt;
# [[ServerJS/Binary|Binary Data Objects]] (byte arrays and/or strings)&lt;br /&gt;
# [[ServerJS/IO|I/O Streams]]&lt;br /&gt;
# [[ServerJS/Encodings|Encodings and character sets]]&lt;br /&gt;
# [[ServerJS/System|System Interface]] (stdin, stdout, stderr, &amp;amp;c)&lt;br /&gt;
# [[ServerJS/C_API|C unified API]] to our Target Platforms&lt;br /&gt;
# [[ServerJS/Unit_Testing|Unit testing]]&lt;br /&gt;
&lt;br /&gt;
[[ServerJS/Status|Pending Business / Calls for Action / Status Report]]&lt;br /&gt;
&lt;br /&gt;
== Future Efforts ==&lt;br /&gt;
&lt;br /&gt;
=== Low-level APIs ===&lt;br /&gt;
&lt;br /&gt;
This is the collection of APIs that we&#039;d like to see behaving consistently across JavaScript interpreters.&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Runtime_Services|Language and Runtime Services]]&lt;br /&gt;
* [[ServerJS/Sockets|Socket I/O]] (TCP/IP) &lt;br /&gt;
* [[ServerJS/Command_Line|Command line processing]] &lt;br /&gt;
* [[ServerJS/Logging|Logging]]&lt;br /&gt;
* [[ServerJS/RDBMS|Relational database interface]]&lt;br /&gt;
* ResultSets (collections of data maybe from RDBMS, maybe from other sources)&lt;br /&gt;
* [[ServerJS/WSGI|Web server to application interface]] (plus middleware) &lt;br /&gt;
* [[ServerJS/Concurrency|Concurrency]]&lt;br /&gt;
* [[ServerJS/String_IO|String / ByteString I/O]]&lt;br /&gt;
* [[ServerJS/Promises|Promises]]&lt;br /&gt;
&lt;br /&gt;
=== High-level APIs ===&lt;br /&gt;
&lt;br /&gt;
This is the collection of APIs that implement common functionality on top of the low-level API.&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/HTTP_Client|HTTP client]] APIs&lt;br /&gt;
* [[ServerJS/Email|Email]]&lt;br /&gt;
* [[ServerJS/XMPP|Jabber (XMPP)]]&lt;br /&gt;
* [[ServerJS/i18n|Internationalization]]&lt;br /&gt;
* [[ServerJS/Promise_Manager|Promise Manager]]&lt;br /&gt;
&lt;br /&gt;
== Implementations ==&lt;br /&gt;
&lt;br /&gt;
* [http://github.com/tlrobinson/narwhal Narwhal] (Rhino, v8; SecurableModules, File API draft 4 tier 1)&lt;br /&gt;
* [http://flusspferd.org/ Flusspferd] (Spidermonkey/C++; SecurableModules)&lt;br /&gt;
* [http://dev.helma.org/ng/ Helma NG] (Rhino; SecurableModules)&lt;br /&gt;
* [http://code.google.com/p/v8cgi/ Ondrej Zara&#039;s v8cgi] (v8; SecurableModules)&lt;br /&gt;
* [http://kenai.com/projects/gpsee/pages/Home Wes Garland&#039;s GPSEE] (Spidermonkey/C; SecurableModules)&lt;br /&gt;
* [http://github.com/kriskowal/chiron/ Kris Kowal&#039;s chiron] (Web browsers; SecurableModules)&lt;br /&gt;
* [http://www.persvr.org/ Persevere] (Rhino; SecurableModules)&lt;br /&gt;
&lt;br /&gt;
In development:&lt;br /&gt;
* nathan smith is implementing SecurableModules for JScript and ASP at http://github.com/smith/interoperablejscript/tree/master&lt;br /&gt;
* mob is implementing SecurableModules in Ejscript http://www.ejscript.org&lt;br /&gt;
* pmuellr posted a sample loader for SecurableModules: http://wiki.github.com/pmuellr/modjewel&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
* [http://github.com/tlrobinson/narwhal/tree/master/tests/serverjs ServerJS tests] compatible with [http://github.com/tlrobinson/narwhal/tree/master/lib/test this test framework].&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Existing APIs|Existing APIs]]&lt;br /&gt;
* [[ServerJS/Infrastructure|Infrastructure]]&lt;br /&gt;
* [[ServerJS/High Level Tools|High Level Tools]]&lt;br /&gt;
* [[ServerJS/Random Links|Random Links]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Index&amp;diff=167558</id>
		<title>ServerJS/Index</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Index&amp;diff=167558"/>
		<updated>2009-09-09T22:07:19Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[ServerJS]]&lt;br /&gt;
* [[ServerJS/API]]&lt;br /&gt;
* [[ServerJS/API/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/binary]]&lt;br /&gt;
* [[ServerJS/API/binary/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/console]]&lt;br /&gt;
* [[ServerJS/API/dict/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/file]]&lt;br /&gt;
* [[ServerJS/API/file/Names]]&lt;br /&gt;
* [[ServerJS/API/file/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/io/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/iter/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/list/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/posix/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/set/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/system]]&lt;br /&gt;
* [[ServerJS/API/url/ProposalK]]&lt;br /&gt;
* [[ServerJS/Binary]]&lt;br /&gt;
* [[ServerJS/Binary/A]]&lt;br /&gt;
* [[ServerJS/Binary/B]]&lt;br /&gt;
* [[ServerJS/Binary/C]]&lt;br /&gt;
* [[ServerJS/Binary/C/Essay]]&lt;br /&gt;
* [[ServerJS/Binary/C/Show of hands]]&lt;br /&gt;
* [[ServerJS/Binary/C/Unpacking]]&lt;br /&gt;
* [[ServerJS/C API]]&lt;br /&gt;
* [[ServerJS/Coding Standards]]&lt;br /&gt;
* [[ServerJS/Command Line]]&lt;br /&gt;
* [[ServerJS/Concurrency]]&lt;br /&gt;
* [[ServerJS/Current Efforts]]&lt;br /&gt;
* [[ServerJS/DateTime]]&lt;br /&gt;
* [[ServerJS/Doctools]]&lt;br /&gt;
* [[ServerJS/Email]]&lt;br /&gt;
* [[ServerJS/Encodings]]&lt;br /&gt;
* [[ServerJS/Encodings/OldClass]]&lt;br /&gt;
* [[ServerJS/Existing APIs]]&lt;br /&gt;
* [[ServerJS/FAQ]]&lt;br /&gt;
* [[ServerJS/File/A]]&lt;br /&gt;
* [[ServerJS/Filesystem API]]&lt;br /&gt;
* [[ServerJS/Filesystem API/A]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Hierarchy]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Join]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Names]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Show of hands]]&lt;br /&gt;
* [[ServerJS/Future Efforts]]&lt;br /&gt;
* [[ServerJS/HTTP Client]]&lt;br /&gt;
* [[ServerJS/HTTP Client/A]]&lt;br /&gt;
* [[ServerJS/High Level Tools]]&lt;br /&gt;
* [[ServerJS/IO]]&lt;br /&gt;
* [[ServerJS/IO/A]]&lt;br /&gt;
* [[ServerJS/Index]]&lt;br /&gt;
* [[ServerJS/Infrastructure]]&lt;br /&gt;
* [[ServerJS/Introduction]]&lt;br /&gt;
* [[ServerJS/Logging]]&lt;br /&gt;
* [[ServerJS/Modules]]&lt;br /&gt;
* [[ServerJS/Modules/CompiledModules]]&lt;br /&gt;
* [[ServerJS/Modules/Environment]]&lt;br /&gt;
* [[ServerJS/Modules/GlobalFileLoading]]&lt;br /&gt;
* [[ServerJS/Modules/GlobalObjectLoading]]&lt;br /&gt;
* [[ServerJS/Modules/Loaders]]&lt;br /&gt;
* [[ServerJS/Modules/Meta]]&lt;br /&gt;
* [[ServerJS/Modules/PythonicModules]]&lt;br /&gt;
* [[ServerJS/Modules/ScriptModules]]&lt;br /&gt;
* [[ServerJS/Modules/SecurableModules]]&lt;br /&gt;
* [[ServerJS/Modules/Secure]]&lt;br /&gt;
* [[ServerJS/Packaging]]&lt;br /&gt;
* [[ServerJS/Pending Business]]&lt;br /&gt;
* [[ServerJS/Process]]&lt;br /&gt;
* [[ServerJS/Promise Manager]]&lt;br /&gt;
* [[ServerJS/Promises]]&lt;br /&gt;
* [[ServerJS/ProposalProcess]]&lt;br /&gt;
* [[ServerJS/RDBMS]]&lt;br /&gt;
* [[ServerJS/Random Links]]&lt;br /&gt;
* [[ServerJS/Runtime Services]]&lt;br /&gt;
* [[ServerJS/Sockets]]&lt;br /&gt;
* [[ServerJS/Status]]&lt;br /&gt;
* [[ServerJS/System]]&lt;br /&gt;
* [[ServerJS/System/AmendmentProposals]]&lt;br /&gt;
* [[ServerJS/System/ArchivedShowOfHands]]&lt;br /&gt;
* [[ServerJS/Target Platforms]]&lt;br /&gt;
* [[ServerJS/Unit Testing]]&lt;br /&gt;
* [[ServerJS/Unit Testing/A]]&lt;br /&gt;
* [[ServerJS/WSGI]]&lt;br /&gt;
* [[ServerJS/XMPP]]&lt;br /&gt;
* [[ServerJS/i18n]]&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166707</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166707"/>
		<updated>2009-09-05T11:32:31Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands/]] as well as the [[/Unpacking/]] and [[/Essay/]] portions which were removed.&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String and a Buffer system which works on either type.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
;memcopy&lt;br /&gt;
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does add .append to Array). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
Java&#039;s StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return &#039;blob&#039; and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form &lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.copy(data, offset, length, [dataOffset]);&lt;br /&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== Abstract API ==&lt;br /&gt;
One of the primary focuses was interoperability between Strings and Blobs so that abstract algorithms could be written which work on either strings or blobs.&lt;br /&gt;
&lt;br /&gt;
The entire Buffer api was designed for this purpose, and the following methods on String and Blob are usable in abstract programming:&lt;br /&gt;
* seq.length;&lt;br /&gt;
* seq.contentConstructor (can be used as seq.contentConstructor() to return an empty seq of the same type)&lt;br /&gt;
* seq.valueAt(idx); // Sequence at index&lt;br /&gt;
* seq.codeAt(idx); // Number at index&lt;br /&gt;
* seq.valueOf(); // Returns the same seq (on a buffer returns the equiv Blob or String)&lt;br /&gt;
* seq.indexOf(seq, [off]); and seq.lastIndexOf(seq, [off]); // finding the location of a subsequence&lt;br /&gt;
* seq.concat(...seq); // combining sequences together&lt;br /&gt;
* seq.slice(begin, end); // extracting a portion of a sequence&lt;br /&gt;
* seq.split(sep, [limit]); // split up a sequence using another sequence as a separator&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Unpacking&amp;diff=166706</id>
		<title>ServerJS/Binary/C/Unpacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Unpacking&amp;diff=166706"/>
		<updated>2009-09-05T11:31:01Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Created page with &amp;#039;These methods are related to unpacking, they were  be removed from the proposal in favor of specifying that at a higher layer but are here for reference until we write a proposal…&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These methods are related to unpacking, they were  be removed from the proposal in favor of specifying that at a higher layer but are here for reference until we write a proposal for unpacking of binary data.&lt;br /&gt;
&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166705</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166705"/>
		<updated>2009-09-05T11:30:03Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands/]] as well as the [[/Unpacking/]] and [[/Essay/]] portions which were removed.&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
;memcopy&lt;br /&gt;
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does add .append to Array). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
Java&#039;s StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return &#039;blob&#039; and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form &lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.copy(data, offset, length, [dataOffset]);&lt;br /&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== Abstract API ==&lt;br /&gt;
One of the primary focuses was interoperability between Strings and Blobs so that abstract algorithms could be written which work on either strings or blobs.&lt;br /&gt;
&lt;br /&gt;
The entire Buffer api was designed for this purpose, and the following methods on String and Blob are usable in abstract programming:&lt;br /&gt;
* seq.length;&lt;br /&gt;
* seq.contentConstructor (can be used as seq.contentConstructor() to return an empty seq of the same type)&lt;br /&gt;
* seq.valueAt(idx); // Sequence at index&lt;br /&gt;
* seq.codeAt(idx); // Number at index&lt;br /&gt;
* seq.valueOf(); // Returns the same seq (on a buffer returns the equiv Blob or String)&lt;br /&gt;
* seq.indexOf(seq, [off]); and seq.lastIndexOf(seq, [off]); // finding the location of a subsequence&lt;br /&gt;
* seq.concat(...seq); // combining sequences together&lt;br /&gt;
* seq.slice(begin, end); // extracting a portion of a sequence&lt;br /&gt;
* seq.split(sep, [limit]); // split up a sequence using another sequence as a separator&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166704</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166704"/>
		<updated>2009-09-05T11:28:34Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands/]] and [[/Essay/]] portion.&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
;memcopy&lt;br /&gt;
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does add .append to Array). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
Java&#039;s StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return &#039;blob&#039; and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form &lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.copy(data, offset, length, [dataOffset]);&lt;br /&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== Abstract API ==&lt;br /&gt;
One of the primary focuses was interoperability between Strings and Blobs so that abstract algorithms could be written which work on either strings or blobs.&lt;br /&gt;
&lt;br /&gt;
The entire Buffer api was designed for this purpose, and the following methods on String and Blob are usable in abstract programming:&lt;br /&gt;
* seq.length;&lt;br /&gt;
* seq.contentConstructor (can be used as seq.contentConstructor() to return an empty seq of the same type)&lt;br /&gt;
* seq.valueAt(idx); // Sequence at index&lt;br /&gt;
* seq.codeAt(idx); // Number at index&lt;br /&gt;
* seq.valueOf(); // Returns the same seq (on a buffer returns the equiv Blob or String)&lt;br /&gt;
* seq.indexOf(seq, [off]); and seq.lastIndexOf(seq, [off]); // finding the location of a subsequence&lt;br /&gt;
* seq.concat(...seq); // combining sequences together&lt;br /&gt;
* seq.slice(begin, end); // extracting a portion of a sequence&lt;br /&gt;
* seq.split(sep, [limit]); // split up a sequence using another sequence as a separator&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Essay&amp;diff=166702</id>
		<title>ServerJS/Binary/C/Essay</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Essay&amp;diff=166702"/>
		<updated>2009-09-05T11:07:18Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Created page with &amp;#039;This page contains the essay like portions of Binary/C which were essay like and were moved out of the spec.  == ByteArray? == From the discussions in the ServerJS mailin…&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains the essay like portions of [[../|Binary/C]] which were essay like and were moved out of the spec.&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166701</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166701"/>
		<updated>2009-09-05T11:07:03Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands/]] and [[/Essay/]] portion.&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
;memcopy&lt;br /&gt;
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does add .append to Array). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
Java&#039;s StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return &#039;blob&#039; and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form &lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.copy(data, offset, length, [dataOffset]);&lt;br /&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166700</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=166700"/>
		<updated>2009-09-05T11:00:18Z</updated>

		<summary type="html">&lt;p&gt;Dantman: /* Differences between a Sequence and an Array */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands]].&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
;memcopy&lt;br /&gt;
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does add .append to Array). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
Java&#039;s StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return &#039;blob&#039; and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form &lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.copy(data, offset, length, [dataOffset]);&lt;br /&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;s&amp;gt;buf.reverse();&amp;lt;/s&amp;gt;&lt;br /&gt;
:&amp;lt;s&amp;gt;Causes the sequence to be replaced by the reverse of the sequence.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Process&amp;diff=166697</id>
		<title>ServerJS/Process</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Process&amp;diff=166697"/>
		<updated>2009-09-05T07:32:46Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The goal of this project is to have something that people can run and build web frameworks and applications on.&lt;br /&gt;
&lt;br /&gt;
The process needs to support that goal, plus the goal of having a specification that allows people to make other JS interpreters/platforms compatible.&lt;br /&gt;
&lt;br /&gt;
There are two parts to the process:&lt;br /&gt;
&lt;br /&gt;
# Creating the specs and code&lt;br /&gt;
# Handling disagreements&lt;br /&gt;
&lt;br /&gt;
Number 1 is how things get done. Number 2 is how we ensure that number 1 is able to continue in face of inevitable disagreements.&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/ProposalProcess|CommonJS Proposal Process]]&lt;br /&gt;
&lt;br /&gt;
(to be continued...)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prior Art ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.python.org/dev/peps/pep-0001/ Python Enhancement Proposal] (PEP). This process is not completely applicable, because Python has a dictator that keeps things from spiraling out of control.&lt;br /&gt;
* [http://srfi.schemers.org/ Scheme Requests For Implementation]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Request_for_Comments#RFC_production_and_evolution Request for Comments] (RFC)&lt;br /&gt;
* [http://www.apache.org/foundation/voting.html Apache Voting]&lt;br /&gt;
&lt;br /&gt;
== Related Discussions ==&lt;br /&gt;
&lt;br /&gt;
* [http://groups.google.com/group/commonjs/browse_thread/thread/280c8b0375783604 Organisation and Making Decisions]&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Index&amp;diff=166392</id>
		<title>ServerJS/Index</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Index&amp;diff=166392"/>
		<updated>2009-09-03T17:42:50Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Index so we can see changs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[ServerJS]]&lt;br /&gt;
* [[ServerJS/API]]&lt;br /&gt;
* [[ServerJS/API/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/binary]]&lt;br /&gt;
* [[ServerJS/API/binary/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/console]]&lt;br /&gt;
* [[ServerJS/API/dict/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/file]]&lt;br /&gt;
* [[ServerJS/API/file/Names]]&lt;br /&gt;
* [[ServerJS/API/file/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/io/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/iter/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/list/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/posix/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/set/ProposalK]]&lt;br /&gt;
* [[ServerJS/API/system]]&lt;br /&gt;
* [[ServerJS/API/url/ProposalK]]&lt;br /&gt;
* [[ServerJS/Binary]]&lt;br /&gt;
* [[ServerJS/Binary/A]]&lt;br /&gt;
* [[ServerJS/Binary/B]]&lt;br /&gt;
* [[ServerJS/Binary/C]]&lt;br /&gt;
* [[ServerJS/Binary/C/Show of hands]]&lt;br /&gt;
* [[ServerJS/C API]]&lt;br /&gt;
* [[ServerJS/Coding Standards]]&lt;br /&gt;
* [[ServerJS/Command Line]]&lt;br /&gt;
* [[ServerJS/Concurrency]]&lt;br /&gt;
* [[ServerJS/Current Efforts]]&lt;br /&gt;
* [[ServerJS/DateTime]]&lt;br /&gt;
* [[ServerJS/Doctools]]&lt;br /&gt;
* [[ServerJS/Email]]&lt;br /&gt;
* [[ServerJS/Encodings]]&lt;br /&gt;
* [[ServerJS/Encodings/OldClass]]&lt;br /&gt;
* [[ServerJS/Existing APIs]]&lt;br /&gt;
* [[ServerJS/FAQ]]&lt;br /&gt;
* [[ServerJS/File/A]]&lt;br /&gt;
* [[ServerJS/Filesystem API]]&lt;br /&gt;
* [[ServerJS/Filesystem API/A]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Hierarchy]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Join]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Names]]&lt;br /&gt;
* [[ServerJS/Filesystem API/Show of hands]]&lt;br /&gt;
* [[ServerJS/Future Efforts]]&lt;br /&gt;
* [[ServerJS/HTTP Client]]&lt;br /&gt;
* [[ServerJS/High Level Tools]]&lt;br /&gt;
* [[ServerJS/Infrastructure]]&lt;br /&gt;
* [[ServerJS/Introduction]]&lt;br /&gt;
* [[ServerJS/Logging]]&lt;br /&gt;
* [[ServerJS/Modules]]&lt;br /&gt;
* [[ServerJS/Modules/CompiledModules]]&lt;br /&gt;
* [[ServerJS/Modules/Environment]]&lt;br /&gt;
* [[ServerJS/Modules/GlobalFileLoading]]&lt;br /&gt;
* [[ServerJS/Modules/GlobalObjectLoading]]&lt;br /&gt;
* [[ServerJS/Modules/Loaders]]&lt;br /&gt;
* [[ServerJS/Modules/Meta]]&lt;br /&gt;
* [[ServerJS/Modules/PythonicModules]]&lt;br /&gt;
* [[ServerJS/Modules/ScriptModules]]&lt;br /&gt;
* [[ServerJS/Modules/SecurableModules]]&lt;br /&gt;
* [[ServerJS/Modules/Secure]]&lt;br /&gt;
* [[ServerJS/Packaging]]&lt;br /&gt;
* [[ServerJS/Pending Business]]&lt;br /&gt;
* [[ServerJS/Process]]&lt;br /&gt;
* [[ServerJS/Promise Manager]]&lt;br /&gt;
* [[ServerJS/Promises]]&lt;br /&gt;
* [[ServerJS/RDBMS]]&lt;br /&gt;
* [[ServerJS/Random Links]]&lt;br /&gt;
* [[ServerJS/Runtime Services]]&lt;br /&gt;
* [[ServerJS/Sockets]]&lt;br /&gt;
* [[ServerJS/Status]]&lt;br /&gt;
* [[ServerJS/System]]&lt;br /&gt;
* [[ServerJS/System/AmendmentProposals]]&lt;br /&gt;
* [[ServerJS/System/ArchivedShowOfHands]]&lt;br /&gt;
* [[ServerJS/Target Platforms]]&lt;br /&gt;
* [[ServerJS/Unit Testing]]&lt;br /&gt;
* [[ServerJS/Unit Testing/A]]&lt;br /&gt;
* [[ServerJS/WSGI]]&lt;br /&gt;
* [[ServerJS/XMPP]]&lt;br /&gt;
* [[ServerJS/i18n]]&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sandbox&amp;diff=166384</id>
		<title>Sandbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sandbox&amp;diff=166384"/>
		<updated>2009-09-03T17:17:00Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Test&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre class=&amp;quot;brush:java&amp;quot;&amp;gt; &lt;br /&gt;
// Hello1.cs&lt;br /&gt;
public class Hello1&lt;br /&gt;
{&lt;br /&gt;
   public static void Main()&lt;br /&gt;
   {&lt;br /&gt;
      System.Console.WriteLine(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: interface Storage {&lt;br /&gt;
  readonly attribute unsigned long length;&lt;br /&gt;
  [IndexGetter] DOMString key(in unsigned long index);&lt;br /&gt;
  [NameGetter] DOMString getItem(in DOMString key);&lt;br /&gt;
  [NameSetter, NameCreator] void setItem(in DOMString key, in DOMString data);&lt;br /&gt;
  [NameDeleter] void removeItem(in DOMString key);&lt;br /&gt;
  void clear();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
asdf&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Filesystem_API/Show_of_hands&amp;diff=165103</id>
		<title>ServerJS/Filesystem API/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Filesystem_API/Show_of_hands&amp;diff=165103"/>
		<updated>2009-08-28T23:33:21Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Created page with &amp;#039;;.write operations on a stream: :A.1) May do partial writes and return the data that has not yet been read. :A.2) May do partial writes and return the length of data that has bee…&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;;.write operations on a stream:&lt;br /&gt;
:A.1) May do partial writes and return the data that has not yet been read.&lt;br /&gt;
:A.2) May do partial writes and return the length of data that has been written.&lt;br /&gt;
* Wes Garland&lt;br /&gt;
:B) Block until all the data has been written to the underlying layer (partial writes may be handled with a different method or options; unspecified atm).&lt;br /&gt;
* Daniel Friesen&lt;br /&gt;
* Kris Kowal&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
* Kris Kowal thinks that B).write should return `this` to allow chaining.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Filesystem_API&amp;diff=165101</id>
		<title>ServerJS/Filesystem API</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Filesystem_API&amp;diff=165101"/>
		<updated>2009-08-28T23:25:59Z</updated>

		<summary type="html">&lt;p&gt;Dantman: /* Requirements/Proposals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirements/Proposals ==&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Filesystem_API/A|Filesystem API Proposal A]]&lt;br /&gt;
* [[ServerJS/Filesystem_API/Hierarchy|File API Class hierarchy proposal]]&lt;br /&gt;
* [[ServerJS/Filesystem_API/Names|File API name preferences questionnaire]]&lt;br /&gt;
* Summary/Comparison of current File APIs used by JS engines: [http://spreadsheets.google.com/pub?key=p9uiX8MUHeTiP0kPT591RUw ServerJS File Object Survey]&lt;br /&gt;
* [[/Show of hands|Show of hands]]&lt;br /&gt;
&lt;br /&gt;
== Prior Art ==&lt;br /&gt;
&lt;br /&gt;
* Microsoft [http://msdn.microsoft.com/en-us/library/z9ty6h50.aspx Scripting.FileSystemObject]. Used in classic ASP, WSH, HTAs.&lt;br /&gt;
* [http://www.mozilla.org/js/js-file-object.html JavaScript File object proposal] (~1998)&lt;br /&gt;
* [https://developer.mozilla.org/En/SpiderMonkey:File_object Spidermonkey File object]&lt;br /&gt;
* [http://synchro.net/ Synchronet] provides a [http://synchro.net/docs/jsobjs.html#File File Class] that was originally inspired by SpiderMonkey&#039;s jsfile.c, but has been widely used and enhanced over the years.&lt;br /&gt;
* Ejscript&#039;s [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/ejs.io-File.html File class] is still evolving, but is fairly comprehensive. It supports stackable streams such as BinaryStream, StringStream. It can also do I/O to and from a ByteArray class.&lt;br /&gt;
* [http://jsext.sourceforge.net/JSEXT1.File.html JSExt.File]&lt;br /&gt;
* [http://code.google.com/p/jslibs/wiki/jsio jslibs jsio module]&lt;br /&gt;
* [http://www.wxjavascript.net/io/index.html wxJavascript IO module]&lt;br /&gt;
* v8cgi has a [http://code.google.com/p/v8cgi/wiki/API#File_functions File] and [http://code.google.com/p/v8cgi/wiki/API#Directory_functions Directory] interfaces&lt;br /&gt;
* helma has two File apis. One [http://helma.zumbrunn.com/reference/File.html deprecated] and one [http://helma.zumbrunn.com/reference/helma.File.html current]&lt;br /&gt;
* adobe&#039;s extendscript has a File constructor.Documentation is difficult to find online.&lt;br /&gt;
* generic [http://koberg.com/ripple/docs/api/ collection/document resource] (java) api (work in process)&lt;br /&gt;
* Opera Software&#039;s [http://dev.opera.com/articles/view/file-i-o-api-for-widgets/ File I/O API for widgets], which will probably be standardized by the [http://www.w3.org/2006/webapi/ W3C Web API Working Group].&lt;br /&gt;
&lt;br /&gt;
=== Inspiration  ===&lt;br /&gt;
&lt;br /&gt;
* (Python) PEP on new File IO http://www.python.org/dev/peps/pep-3116/&lt;br /&gt;
* Java File API http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html&lt;br /&gt;
* Java Output API http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileOutputStream.html&lt;br /&gt;
* Java Input API http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileInputStream.html&lt;br /&gt;
* E Secure File API http://www.erights.org/javadoc/java/io/File.html&lt;br /&gt;
* Joe-E Secure File System API http://www.cs.berkeley.edu/~daw/joe-e/api/org/joe_e/file/Filesystem.html&lt;br /&gt;
* Python Path API http://docs.python.org/library/os.path.html&lt;br /&gt;
* Ruby File API http://www.ruby-doc.org/core/classes/File.html&lt;br /&gt;
* Ruby IO API http://www.ruby-doc.org/core/classes/IO.html&lt;br /&gt;
* Perl Path::Class http://search.cpan.org/perldoc?Path::Class&lt;br /&gt;
* PHP Filesystem http://php.net/manual/book.filesystem.php&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=164713</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=164713"/>
		<updated>2009-08-27T07:24:23Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
----&lt;br /&gt;
Method parameter preference for new methods like .clear .fill .remove (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring, Java)&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
----&lt;br /&gt;
blob[idx]:&lt;br /&gt;
:A) Leave blob[idx] out of the standard (easier to implement in js-only rhino)&lt;br /&gt;
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)&lt;br /&gt;
----&lt;br /&gt;
Property used on String, Blob, Buffer, Streams, and so on to refer to the mode it is running in (binary or text) by returning the String or the Blob constructor. (If you can think of a better name, just add a new item)&lt;br /&gt;
:A) Content&lt;br /&gt;
:B) Value&lt;br /&gt;
:C) contentConstructor&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:D) contentPrototype&lt;br /&gt;
:E) content&lt;br /&gt;
:F) value&lt;br /&gt;
:G) Unit&lt;br /&gt;
:H) Element&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Modules/Meta&amp;diff=164282</id>
		<title>ServerJS/Modules/Meta</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Modules/Meta&amp;diff=164282"/>
		<updated>2009-08-25T21:05:43Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Contract ==&lt;br /&gt;
&lt;br /&gt;
=== Module Context ===&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;In a module, there is a free variable &amp;quot;require&amp;quot;, that is a function.&#039;&#039;&lt;br /&gt;
## …&lt;br /&gt;
## …&lt;br /&gt;
## …&lt;br /&gt;
## …&lt;br /&gt;
## The &amp;quot;require&amp;quot; function may have a &amp;quot;main&amp;quot; property that is the top-level &amp;quot;id&amp;quot; of the program.&lt;br /&gt;
## The &amp;quot;require&amp;quot; function may have a &amp;quot;paths&amp;quot; attribute, that is a prioritized Array of path Strings, from high to low, of paths to top-level module directories.&lt;br /&gt;
### The &amp;quot;paths&amp;quot; property must not exist in &amp;quot;sandbox&amp;quot; (a secured module system).&lt;br /&gt;
### The &amp;quot;paths&amp;quot; attribute must be referentially identical in all modules.&lt;br /&gt;
### Replacing the &amp;quot;paths&amp;quot; object with an alternate object may have no affect.&lt;br /&gt;
### If the &amp;quot;paths&amp;quot; attribute exists, in-place modification of the contents of &amp;quot;paths&amp;quot; must be reflected by corresponding module search behavior.&lt;br /&gt;
### If the &amp;quot;paths&amp;quot; attribute exists, it may not be an exhaustive list of search paths, as the loader may internally look in other locations before or after the mentioned paths.&lt;br /&gt;
### If the &amp;quot;paths&amp;quot; attribute exists, it is the loader&#039;s prorogative to resolve, normalize, or canonicalize the paths provided.&lt;br /&gt;
# In a module, there must be a free variable &amp;quot;module&amp;quot;, that is an Object.&lt;br /&gt;
## The &amp;quot;module&amp;quot; object must have an &amp;quot;id&amp;quot; that is the top-level &amp;quot;id&amp;quot; of the module.&lt;br /&gt;
## The &amp;quot;module&amp;quot; object may have a &amp;quot;path&amp;quot; String that is the fully-qualified path to the file from which the module was created.  The &amp;quot;path&amp;quot; property must not exist in a sandbox.&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
&lt;br /&gt;
* [http://groups.google.com/group/serverjs/browse_thread/thread/6ad5c2c3b005cb3b/5a0f17e43d347673 RFC reqiure.paths behaviour]&lt;br /&gt;
&lt;br /&gt;
== Show of Hands ==&lt;br /&gt;
&lt;br /&gt;
# Do not integrate this amendment into the next version of the SecurableModules specification:&lt;br /&gt;
# Integrate this amendment into the next version of the SecurableModules specification:&lt;br /&gt;
#* Hannes Wallnoefer&lt;br /&gt;
#* Kris Kowal&lt;br /&gt;
#* Tom Robinson&lt;br /&gt;
#* Daniel Friesen&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=164190</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=164190"/>
		<updated>2009-08-25T17:57:22Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
----&lt;br /&gt;
Method parameter preference for new methods (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring)&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
----&lt;br /&gt;
blob[idx]:&lt;br /&gt;
:A) Leave blob[idx] out of the standard (easier to implement in js-only rhino)&lt;br /&gt;
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)&lt;br /&gt;
----&lt;br /&gt;
Property used on String, Blob, Buffer, Streams, and so on to refer to the mode it is running in (binary or text) by returning the String or the Blob constructor. (If you can think of a better name, just add a new item)&lt;br /&gt;
:A) Content&lt;br /&gt;
:B) Value&lt;br /&gt;
:C) contentConstructor&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:D) contentPrototype&lt;br /&gt;
:E) content&lt;br /&gt;
:F) value&lt;br /&gt;
:G) Unit&lt;br /&gt;
:H) Element&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=164186</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=164186"/>
		<updated>2009-08-25T17:55:20Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
----&lt;br /&gt;
Method parameter preference for new methods (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring)&lt;br /&gt;
&lt;br /&gt;
blob[idx]:&lt;br /&gt;
:A) Leave blob[idx] out of the standard (easier to implement in js-only rhino)&lt;br /&gt;
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)&lt;br /&gt;
----&lt;br /&gt;
Property used on String, Blob, Buffer, Streams, and so on to refer to the mode it is running in (binary or text) by returning the String or the Blob constructor. (If you can think of a better name, just add a new item)&lt;br /&gt;
:A) Content&lt;br /&gt;
:B) Value&lt;br /&gt;
:C) contentConstructor&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:D) contentPrototype&lt;br /&gt;
:E) content&lt;br /&gt;
:F) value&lt;br /&gt;
:G) Unit&lt;br /&gt;
:H) Element&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Status&amp;diff=164178</id>
		<title>ServerJS/Status</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Status&amp;diff=164178"/>
		<updated>2009-08-25T17:42:45Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page summarizes the group&#039;s status.&lt;br /&gt;
&lt;br /&gt;
== Require Discussion ==&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Binary|Binary Proposal Ratification]]&lt;br /&gt;
* [[ServerJS/Filesystem API/A#Todo|Filesystem API Proposal Todo List]]&lt;br /&gt;
* [[ServerJS/Encodings|Encodings API Proposal Ratification]]&lt;br /&gt;
* [[ServerJS/System|System Module Additional Proposed Names]]&lt;br /&gt;
* [[ServerJS/Modules/Loaders|Standard Module Loader API]] (not ready for discussion, pending rewrite - KrisKowal)&lt;br /&gt;
* C Runtime Linkage API Proposals&lt;br /&gt;
* C Module API Proposals&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Filesystem_API/A|Filesystem API Proposal A]]&lt;br /&gt;
* [[ServerJS/Filesystem_API/Hierarchy|Filesystem API Class Hierarchy Proposal]]&lt;br /&gt;
&lt;br /&gt;
== Show of Hands ==&lt;br /&gt;
&lt;br /&gt;
* Module System: Meta Object Amendment [[ServerJS/Modules/Meta]] (pending consensus)&lt;br /&gt;
* Filesystem API: Clarifications on the features of  &amp;quot;[[ServerJS/Filesystem_API/Join|join]]&amp;quot; (pending attention)&lt;br /&gt;
* Binary/C: [[ServerJS/Binary/C/Show of hands]] (pending attention)&lt;br /&gt;
&lt;br /&gt;
== Resolutions ==&lt;br /&gt;
&lt;br /&gt;
* [[ServerJS/Modules/SecurableModules|Modules]] (ratified)&lt;br /&gt;
* [[ServerJS/System|System Module]] (ratified)&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163598</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163598"/>
		<updated>2009-08-22T12:24:16Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands]].&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
;memcopy&lt;br /&gt;
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
Java&#039;s StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return &#039;blob&#039; and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form &lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.copy(data, offset, length, [dataOffset]);&lt;br /&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;s&amp;gt;buf.reverse();&amp;lt;/s&amp;gt;&lt;br /&gt;
:&amp;lt;s&amp;gt;Causes the sequence to be replaced by the reverse of the sequence.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163597</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163597"/>
		<updated>2009-08-22T11:47:20Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands]].&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
;blob.contentConstructor;&lt;br /&gt;
:Returns Blob to indicate this has binary content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
:(May be removed in favor of a better idiom)&lt;br /&gt;
:Get the type of the buffer. Binary buffers return false, text buffers return true.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.contentConstructor;&lt;br /&gt;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
;string.contentConstructor;&lt;br /&gt;
:Returns String to indicate this has text content.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=163596</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=163596"/>
		<updated>2009-08-22T11:39:52Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
&lt;br /&gt;
Method parameter preference for new methods (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring)&lt;br /&gt;
&lt;br /&gt;
blob[idx]:&lt;br /&gt;
:A) Leave blob[idx] out of the standard (easier to implement in js-only rhino)&lt;br /&gt;
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)&lt;br /&gt;
&lt;br /&gt;
Property used on String, Blob, Buffer, Streams, and so on to refer to the mode it is running in (binary or text) by returning the String or the Blob constructor. (If you can think of a better name, just add a new item)&lt;br /&gt;
:A) Content&lt;br /&gt;
:B) Value&lt;br /&gt;
:C) contentConstructor&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:D) contentPrototype&lt;br /&gt;
:E) content&lt;br /&gt;
:F) value&lt;br /&gt;
:G) Unit&lt;br /&gt;
:H) Element&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163595</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163595"/>
		<updated>2009-08-22T11:32:26Z</updated>

		<summary type="html">&lt;p&gt;Dantman: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands]].&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
:(May be removed in favor of a better idiom)&lt;br /&gt;
:Get the type of the buffer. Binary buffers return false, text buffers return true.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;br /&gt;
&lt;br /&gt;
== Relevant discussion ==&lt;br /&gt;
* http://groups.google.com/group/serverjs/browse_thread/thread/3b0a3a20a67987d8&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163594</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=163594"/>
		<updated>2009-08-22T11:30:16Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;See also: the [[/Show of hands]].&#039;&#039;&lt;br /&gt;
This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
:(May be removed in favor of a better idiom)&lt;br /&gt;
:Get the type of the buffer. Binary buffers return false, text buffers return true.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=161647</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=161647"/>
		<updated>2009-08-12T18:01:36Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
&lt;br /&gt;
Method parameter preference for new methods (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring)&lt;br /&gt;
&lt;br /&gt;
blob[idx]:&lt;br /&gt;
:A) Leave blob[idx] out of the standard (easier to implement in js-only rhino)&lt;br /&gt;
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=159938</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=159938"/>
		<updated>2009-08-04T17:31:13Z</updated>

		<summary type="html">&lt;p&gt;Dantman: /* Buffer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &amp;lt;code&amp;gt;buf instanceof Buffer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:No-op... This simply creates an instanceof of Buffer. On it&#039;s own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.&lt;br /&gt;
;new StringBuffer();&lt;br /&gt;
:Creates a new empty text buffer.&lt;br /&gt;
;new BlobBuffer();&lt;br /&gt;
:Creates a new empty binary buffer.&lt;br /&gt;
;new StringBuffer(len);&lt;br /&gt;
:Creates a new text buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new BlobBuffer(len);&lt;br /&gt;
:Creates a new binary buffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty StringBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;);&lt;br /&gt;
:Creates a new empty BlobBuffer.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;String&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new StringBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(&#039;&#039;&#039;Blob&#039;&#039;&#039;, len);&lt;br /&gt;
:Creates a new BlobBuffer of &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; size.&lt;br /&gt;
;new Buffer(string);&lt;br /&gt;
:Creates a new StringBuffer with the same size and contents as the string.&lt;br /&gt;
;new Buffer(blob);&lt;br /&gt;
:Creates a new BlobBuffer with the same size and contents as the blob.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
:(May be removed in favor of a better idiom)&lt;br /&gt;
:Get the type of the buffer. Binary buffers return false, text buffers return true.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In a StringBuffer this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=159924</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=159924"/>
		<updated>2009-08-04T17:14:15Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
&lt;br /&gt;
Method parameter preference for new methods (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring)&lt;br /&gt;
&lt;br /&gt;
blob[idx]:&lt;br /&gt;
:A) Leave blob[idx] out of the standard (easier to implement)&lt;br /&gt;
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=159920</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=159920"/>
		<updated>2009-08-04T17:09:04Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Ash Berlin&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:* Mario Valente&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;br /&gt;
&lt;br /&gt;
Method parameter preference for new methods (methods based on existing js methods will keep the same parameters.&lt;br /&gt;
:A) offset, length (used in .splice .substr)&lt;br /&gt;
:* Daniel Friesen&lt;br /&gt;
:B) begin, end (used in .slice .substring)&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=159757</id>
		<title>ServerJS/Binary/C/Show of hands</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C/Show_of_hands&amp;diff=159757"/>
		<updated>2009-08-03T22:15:53Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Created page with &amp;#039;This page lists the various show of hands for points within the Binary/C proposal.  Blob and Buffer in what module: :A) Blob and Buffer in require(&amp;#039;binary&amp;#039;); :* Kris Kowa…&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the various show of hands for points within the [[../|Binary/C]] proposal.&lt;br /&gt;
&lt;br /&gt;
Blob and Buffer in what module:&lt;br /&gt;
:A) Blob and Buffer in require(&#039;binary&#039;);&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:B) Blob in require(&#039;binary&#039;); and Buffer in require(&#039;io&#039;);&lt;br /&gt;
:C) Blob and Buffer as globals&lt;br /&gt;
:* Kris Kowal&lt;br /&gt;
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)&lt;br /&gt;
:D) Blob as global and Buffer in require(&#039;io&#039;);&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=159755</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=159755"/>
		<updated>2009-08-03T22:03:42Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms and reading notes ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;as if by&amp;quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class&#039; prototype.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. &amp;lt;del&amp;gt;Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&amp;lt;/del&amp;gt; (Waiting on show of hands)&lt;br /&gt;
&lt;br /&gt;
;blob.byteCodeAt(index);&lt;br /&gt;
;blob.codeAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers as if by &amp;lt;code&amp;gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray(fromCharset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points as if by &amp;lt;code&amp;gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is a &#039;&#039;&#039;&#039;&#039;generic&#039;&#039;&#039;&#039;&#039; buffer which may act on either binary or textual data using the same api (Two purposes in one class is derived from the [http://draft.monkeyscript.org/api/_std/Buffer.html MonkeyScript Buffer]; the .text = bool; idiom came from the .text property in MonkeyScript&#039;s Stream class, the idea is to make it as easy as possible to create a buffer of the same type without needing to use a ternary, this point is up for discussion on the list).&lt;br /&gt;
&lt;br /&gt;
(Note: Whether to allow type conversion of a buffer with no content or not could be discussed) A Buffer may initially be created as untyped without any length, or may be given a type and/or length when created. A Buffer which has a type assigned to it (binary or text) and has content within it (length &amp;gt; 0) may not be converted to another type and should throw an error if attempted.&lt;br /&gt;
&lt;br /&gt;
A buffer gains a type when .text is assigned a true or false value, or it inherits the data type of the first piece of data added to the buffer. After it is typed a buffer should throw an error if someone attempts to insert a different type of data into the buffer (If you want to insert a string into a binary buffer, you should convert it to a blob first yourself; automatic type conversion in these cases would cause gotchas).&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:Construct an empty buffer with no set type&lt;br /&gt;
;new Buffer([String or Blob], [len]);&lt;br /&gt;
:Construct a new buffer.&lt;br /&gt;
:The constructor may accept the &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; function or the &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; function as a hint of what type to set on the buffer.&lt;br /&gt;
:The constructor also may accept a length argument to set the default length of the buffer.&lt;br /&gt;
;new Buffer(sequence);&lt;br /&gt;
:Construct a buffer based on a string or a blob. The Buffer will be the same length as the sequence, inherit the same type, and start off with the same content as the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
;buf.text = bool;&lt;br /&gt;
:Get or set the type of the buffer. Binary buffers return false, text buffers return true, buffers which have not been assigned a type yet return undefined.&lt;br /&gt;
:This will throw a TypeError if you try to set a type on a buffer that already has a type and has a length greater than 0.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.fill(start, length, seq);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In binary mode this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In text mode this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
;string.codeAt(index);&lt;br /&gt;
:An alias for string.charCodeAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=159706</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=159706"/>
		<updated>2009-08-03T21:13:20Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the [[ServerJS/Binary/B|Binary/B]] proposal.&lt;br /&gt;
&lt;br /&gt;
This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
This proposal has a Buffer instead of Binary/B&#039;s ByteArray. None of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B&#039;s ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an Array.&lt;br /&gt;
&lt;br /&gt;
One goal of this proposal is interoperability between Strings and Blobs.  That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API&#039;s.  However, unlike Binary/B, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection.  Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String.&lt;br /&gt;
&lt;br /&gt;
This proposal is based off of API&#039;s drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(begin, end);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charaset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers. &lt;br /&gt;
;blob.toArray(charset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points. &lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Unpacking ===&lt;br /&gt;
::&#039;&#039;These methods are related to unpacking. They will likely be removed from this proposal but are here for reference until we write a proposal for unpacking of binary data.&#039;&#039;&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is a &#039;&#039;&#039;&#039;&#039;generic&#039;&#039;&#039;&#039;&#039; buffer which may act on either binary or textual data using the same api (Two purposes in one class is derived from the [http://draft.monkeyscript.org/api/_std/Buffer.html MonkeyScript Buffer]; the .text = bool; idiom came from the .text property in MonkeyScript&#039;s Stream class, the idea is to make it as easy as possible to create a buffer of the same type without needing to use a ternary, this point is up for discussion on the list).&lt;br /&gt;
&lt;br /&gt;
(Note: Whether to allow type conversion of a buffer with no content or not could be discussed) A Buffer may initially be created as untyped without any length, or may be given a type and/or length when created. A Buffer which has a type assigned to it (binary or text) and has content within it (length &amp;gt; 0) may not be converted to another type and should throw an error if attempted.&lt;br /&gt;
&lt;br /&gt;
A buffer gains a type when .text is assigned a true or false value, or it inherits the data type of the first piece of data added to the buffer. After it is typed a buffer should throw an error if someone attempts to insert a different type of data into the buffer (If you want to insert a string into a binary buffer, you should convert it to a blob first yourself; automatic type conversion in these cases would cause gotchas).&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:Construct an empty buffer with no set type&lt;br /&gt;
;new Buffer([String or Blob], [len]);&lt;br /&gt;
:Construct a new buffer.&lt;br /&gt;
:The constructor may accept the &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; function or the &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; function as a hint of what type to set on the buffer.&lt;br /&gt;
:The constructor also may accept a length argument to set the default length of the buffer.&lt;br /&gt;
;new Buffer(sequence);&lt;br /&gt;
:Construct a buffer based on a string or a blob. The Buffer will be the same length as the sequence, inherit the same type, and start off with the same content as the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
;buf.text = bool;&lt;br /&gt;
:Get or set the type of the buffer. Binary buffers return false, text buffers return true, buffers which have not been assigned a type yet return undefined.&lt;br /&gt;
:This will throw a TypeError if you try to set a type on a buffer that already has a type and has a length greater than 0.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(start, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In binary mode this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In text mode this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158937</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158937"/>
		<updated>2009-07-30T22:04:06Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the Binary/B proposal.&lt;br /&gt;
&lt;br /&gt;
It reflects the Blob type that is used in a number of existing Server-side JavaScript&lt;br /&gt;
implementations, as well as a Buffer type reflecting the existing StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
ByteArray is excluded and Buffer proposed instead. A short note, none of the prior&lt;br /&gt;
art actually implemented a ByteArray as Binary/B proposes. Most implementations&lt;br /&gt;
implemented a Blob type, and any that implemented something called &amp;quot;ByteArray&amp;quot;&lt;br /&gt;
actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an array.&lt;br /&gt;
&lt;br /&gt;
One of the important points thought about in this proposal was interoperability between strings and blobs.&lt;br /&gt;
ie: The ability to write code that can abstractly extract, combine, buffer, and whatnot strings and blobs with a api ignorant of whether the data is binary or text. As well things which seamed counter-intuitive (putting .charAt on Blob) were avoided.&lt;br /&gt;
&lt;br /&gt;
Most of this was based off of APIs drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
::@showofhands (ashb suggests .byteAt could return Number (byte) instead of a single unit blob; .valueAt would still return blob so that abstract code still works)&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(offset, length);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charaset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers. &lt;br /&gt;
;blob.toArray(charset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points. &lt;br /&gt;
&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is a &#039;&#039;&#039;&#039;&#039;generic&#039;&#039;&#039;&#039;&#039; buffer which may act on either binary or textual data using the same api (Two purposes in one class is derived from the [http://draft.monkeyscript.org/api/_std/Buffer.html MonkeyScript Buffer]; the .text = bool; idiom came from the .text property in MonkeyScript&#039;s Stream class, the idea is to make it as easy as possible to create a buffer of the same type without needing to use a ternary, this point is up for discussion on the list).&lt;br /&gt;
&lt;br /&gt;
(Note: Whether to allow type conversion of a buffer with no content or not could be discussed) A Buffer may initially be created as untyped without any length, or may be given a type and/or length when created. A Buffer which has a type assigned to it (binary or text) and has content within it (length &amp;gt; 0) may not be converted to another type and should throw an error if attempted.&lt;br /&gt;
&lt;br /&gt;
A buffer gains a type when .text is assigned a true or false value, or it inherits the data type of the first piece of data added to the buffer. After it is typed a buffer should throw an error if someone attempts to insert a different type of data into the buffer (If you want to insert a string into a binary buffer, you should convert it to a blob first yourself; automatic type conversion in these cases would cause gotchas).&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:Construct an empty buffer with no set type&lt;br /&gt;
;new Buffer([String or Blob], [len]);&lt;br /&gt;
:Construct a new buffer.&lt;br /&gt;
:The constructor may accept the &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; function or the &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; function as a hint of what type to set on the buffer.&lt;br /&gt;
:The constructor also may accept a length argument to set the default length of the buffer.&lt;br /&gt;
;new Buffer(sequence);&lt;br /&gt;
:Construct a buffer based on a string or a blob. The Buffer will be the same length as the sequence, inherit the same type, and start off with the same content as the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
;buf.text = bool;&lt;br /&gt;
:Get or set the type of the buffer. Binary buffers return false, text buffers return true, buffers which have not been assigned a type yet return undefined.&lt;br /&gt;
:This will throw a TypeError if you try to set a type on a buffer that already has a type and has a length greater than 0.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(offset, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In binary mode this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In text mode this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;br /&gt;
* Aristid Breitkreuz notes Buffer could be moved to IO.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158927</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158927"/>
		<updated>2009-07-30T21:36:56Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Fix cases where &amp;quot;bit&amp;quot; should have been &amp;quot;byte&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the Binary/B proposal.&lt;br /&gt;
&lt;br /&gt;
It reflects the Blob type that is used in a number of existing Server-side JavaScript&lt;br /&gt;
implementations, as well as a Buffer type reflecting the existing StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
ByteArray is excluded and Buffer proposed instead. A short note, none of the prior&lt;br /&gt;
art actually implemented a ByteArray as Binary/B proposes. Most implementations&lt;br /&gt;
implemented a Blob type, and any that implemented something called &amp;quot;ByteArray&amp;quot;&lt;br /&gt;
actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an array.&lt;br /&gt;
&lt;br /&gt;
One of the important points thought about in this proposal was interoperability between strings and blobs.&lt;br /&gt;
ie: The ability to write code that can abstractly extract, combine, buffer, and whatnot strings and blobs with a api ignorant of whether the data is binary or text. As well things which seamed counter-intuitive (putting .charAt on Blob) were avoided.&lt;br /&gt;
&lt;br /&gt;
Most of this was based off of APIs drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(offset, length);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions.&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charaset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers. &lt;br /&gt;
;blob.toArray(charset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points. &lt;br /&gt;
&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is a &#039;&#039;&#039;&#039;&#039;generic&#039;&#039;&#039;&#039;&#039; buffer which may act on either binary or textual data using the same api (Two purposes in one class is derived from the [http://draft.monkeyscript.org/api/_std/Buffer.html MonkeyScript Buffer]; the .text = bool; idiom came from the .text property in MonkeyScript&#039;s Stream class, the idea is to make it as easy as possible to create a buffer of the same type without needing to use a ternary, this point is up for discussion on the list).&lt;br /&gt;
&lt;br /&gt;
(Note: Whether to allow type conversion of a buffer with no content or not could be discussed) A Buffer may initially be created as untyped without any length, or may be given a type and/or length when created. A Buffer which has a type assigned to it (binary or text) and has content within it (length &amp;gt; 0) may not be converted to another type and should throw an error if attempted.&lt;br /&gt;
&lt;br /&gt;
A buffer gains a type when .text is assigned a true or false value, or it inherits the data type of the first piece of data added to the buffer. After it is typed a buffer should throw an error if someone attempts to insert a different type of data into the buffer (If you want to insert a string into a binary buffer, you should convert it to a blob first yourself; automatic type conversion in these cases would cause gotchas).&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:Construct an empty buffer with no set type&lt;br /&gt;
;new Buffer([String or Blob], [len]);&lt;br /&gt;
:Construct a new buffer.&lt;br /&gt;
:The constructor may accept the &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; function or the &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; function as a hint of what type to set on the buffer.&lt;br /&gt;
:The constructor also may accept a length argument to set the default length of the buffer.&lt;br /&gt;
;new Buffer(sequence);&lt;br /&gt;
:Construct a buffer based on a string or a blob. The Buffer will be the same length as the sequence, inherit the same type, and start off with the same content as the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
;buf.text = bool;&lt;br /&gt;
:Get or set the type of the buffer. Binary buffers return false, text buffers return true, buffers which have not been assigned a type yet return undefined.&lt;br /&gt;
:This will throw a TypeError if you try to set a type on a buffer that already has a type and has a length greater than 0.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(offset, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (This methods when used on text buffers may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In binary mode this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In text mode this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158878</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158878"/>
		<updated>2009-07-30T19:50:29Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the Binary/B proposal.&lt;br /&gt;
&lt;br /&gt;
It reflects the Blob type that is used in a number of existing Server-side JavaScript&lt;br /&gt;
implementations, as well as a Buffer type reflecting the existing StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
ByteArray is excluded and Buffer proposed instead. A short note, none of the prior&lt;br /&gt;
art actually implemented a ByteArray as Binary/B proposes. Most implementations&lt;br /&gt;
implemented a Blob type, and any that implemented something called &amp;quot;ByteArray&amp;quot;&lt;br /&gt;
actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an array.&lt;br /&gt;
&lt;br /&gt;
One of the important points thought about in this proposal was interoperability between strings and blobs.&lt;br /&gt;
ie: The ability to write code that can abstractly extract, combine, buffer, and whatnot strings and blobs with a api ignorant of whether the data is binary or text. As well things which seamed counter-intuitive (putting .charAt on Blob) were avoided.&lt;br /&gt;
&lt;br /&gt;
Most of this was based off of APIs drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a bit. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bits. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(offset, length);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions.&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charaset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers. &lt;br /&gt;
;blob.toArray(charset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points. &lt;br /&gt;
&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is a &#039;&#039;&#039;&#039;&#039;generic&#039;&#039;&#039;&#039;&#039; buffer which may act on either binary or textual data using the same api (Two purposes in one class is derived from the [http://draft.monkeyscript.org/api/_std/Buffer.html MonkeyScript Buffer]; the .text = bool; idiom came from the .text property in MonkeyScript&#039;s Stream class, the idea is to make it as easy as possible to create a buffer of the same type without needing to use a ternary, this point is up for discussion on the list).&lt;br /&gt;
&lt;br /&gt;
(Note: Whether to allow type conversion of a buffer with no content or not could be discussed) A Buffer may initially be created as untyped without any length, or may be given a type and/or length when created. A Buffer which has a type assigned to it (binary or text) and has content within it (length &amp;gt; 0) may not be converted to another type and should throw an error if attempted.&lt;br /&gt;
&lt;br /&gt;
A buffer gains a type when .text is assigned a true or false value, or it inherits the data type of the first piece of data added to the buffer. After it is typed a buffer should throw an error if someone attempts to insert a different type of data into the buffer (If you want to insert a string into a binary buffer, you should convert it to a blob first yourself; automatic type conversion in these cases would cause gotchas).&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:Construct an empty buffer with no set type&lt;br /&gt;
;new Buffer([String or Blob], [len]);&lt;br /&gt;
:Construct a new buffer.&lt;br /&gt;
:The constructor may accept the &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; function or the &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; function as a hint of what type to set on the buffer.&lt;br /&gt;
:The constructor also may accept a length argument to set the default length of the buffer.&lt;br /&gt;
;new Buffer(sequence);&lt;br /&gt;
:Construct a buffer based on a string or a blob. The Buffer will be the same length as the sequence, inherit the same type, and start off with the same content as the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
;buf.text = bool;&lt;br /&gt;
:Get or set the type of the buffer. Binary buffers return false, text buffers return true, buffers which have not been assigned a type yet return undefined.&lt;br /&gt;
:This will throw a TypeError if you try to set a type on a buffer that already has a type and has a length greater than 0.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(offset, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (This methods when used on text buffers may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In binary mode this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In text mode this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary&amp;diff=158876</id>
		<title>ServerJS/Binary</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary&amp;diff=158876"/>
		<updated>2009-07-30T19:46:15Z</updated>

		<summary type="html">&lt;p&gt;Dantman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;JavaScript does not have a binary data type. However, in server-side scenarios, binary data needs to be often processed. That is why we need some working byte or binary array or string class.&lt;br /&gt;
&lt;br /&gt;
= Proposals =&lt;br /&gt;
&lt;br /&gt;
# [[ServerJS/Binary/A]] Proposal A from Ondras&lt;br /&gt;
# [[ServerJS/Binary/B]] Proposal B from Kris Kowal&lt;br /&gt;
# [[ServerJS/Binary/C]] Proposal C from Daniel Friesen&lt;br /&gt;
&lt;br /&gt;
= Prior Art =&lt;br /&gt;
&lt;br /&gt;
* [http://help.adobe.com/en_US/AIR/1.1/jslr/flash/utils/ByteArray.html Adobe AIR&#039;s ByteArray]&lt;br /&gt;
* [https://developer.mozilla.org/En/NsIBinaryInputStream Mozilla&#039;s nsIBinaryInputStream]&lt;br /&gt;
* [https://developer.mozilla.org/En/NsIBinaryOutputStream Mozilla&#039;s nsIBinaryOutputStream]&lt;br /&gt;
* [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/intrinsic-ByteArray.html EJScript ByteArray]&lt;br /&gt;
* [http://code.google.com/apis/gears/api_blob.html Google Gears Blob]&lt;br /&gt;
* [http://code.google.com/p/jslibs/wiki/jslang#jslang::Blob_class  JSlibs Blob]&lt;br /&gt;
* [http://flusspferd.org/docs/js/Blob Flusspferd Blob]&lt;br /&gt;
&lt;br /&gt;
= Relevant Discussions =&lt;br /&gt;
&lt;br /&gt;
* [http://groups.google.com/group/serverjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst First Proposal]&lt;br /&gt;
* [http://groups.google.com/group/serverjs/browse_thread/thread/da076076c965d069/2cd8ac336387ceb3?lnk=gst Comments on Binary object]&lt;br /&gt;
*  [http://groups.google.com/group/serverjs/browse_thread/thread/e866544eb3aff182/16ed57b3c78b86e1?lnk=gst Binary API Brouhaha]&lt;br /&gt;
* [http://groups.google.com/group/serverjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal] regarding proposal B&lt;br /&gt;
&lt;br /&gt;
[[ServerJS/Encodings|Encodings]] are a related topic.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158874</id>
		<title>ServerJS/Binary/C</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Binary/C&amp;diff=158874"/>
		<updated>2009-07-30T19:42:03Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Created page with &amp;#039;This proposal was written by Daniel Friesen as an alternative to the Binary/B proposal.  It reflects the Blob type that is used in a number of existing Server-side JavaScript imp…&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This proposal was written by Daniel Friesen as an alternative to the Binary/B proposal.&lt;br /&gt;
&lt;br /&gt;
It reflects the Blob type that is used in a number of existing Server-side JavaScript&lt;br /&gt;
implementations, as well as a Buffer type reflecting the existing StringBuffer/StringBuilder within Java.&lt;br /&gt;
&lt;br /&gt;
ByteArray is excluded and Buffer proposed instead. A short note, none of the prior&lt;br /&gt;
art actually implemented a ByteArray as Binary/B proposes. Most implementations&lt;br /&gt;
implemented a Blob type, and any that implemented something called &amp;quot;ByteArray&amp;quot;&lt;br /&gt;
actually implemented something more like a stream API based buffer rather than&lt;br /&gt;
anything remotely resembling an array.&lt;br /&gt;
&lt;br /&gt;
Most of this was based off of APIs drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).&lt;br /&gt;
&lt;br /&gt;
== Terms ==&lt;br /&gt;
To avoid confusion and ambiguity these are the basic definitions of terms used&lt;br /&gt;
within this document.&lt;br /&gt;
;List&lt;br /&gt;
:A type which groups a series of items in a specific order.&lt;br /&gt;
;Sequence&lt;br /&gt;
:A type of list which manages a list of fixed-unit pieces of data.&lt;br /&gt;
:These units of data are normally either bytes or characters. &amp;quot;Sequence&amp;quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.&lt;br /&gt;
;Array&lt;br /&gt;
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.&lt;br /&gt;
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.&lt;br /&gt;
&lt;br /&gt;
== Differences between a Sequence and an Array ==&lt;br /&gt;
While this may not be the case in lower level languages, JavaScript&#039;s API does&lt;br /&gt;
make a clear distinction between strings and arrays.&lt;br /&gt;
&lt;br /&gt;
;Units&lt;br /&gt;
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &amp;quot;abc&amp;quot; is made up of 3 units { a, b, c } whilst [1,&amp;quot;asdf&amp;quot;,3,{}] is made up of 4 items { 1, &amp;quot;asdf&amp;quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.&lt;br /&gt;
;Spillover&lt;br /&gt;
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &amp;quot;spill&amp;quot; or &amp;quot;overflow&amp;quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.&lt;br /&gt;
:* sequence.indexOf(sequence, [offset]);&lt;br /&gt;
:* array.indexOf(item, [offset]);&lt;br /&gt;
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.&lt;br /&gt;
:This is apparent from how &amp;lt;code&amp;gt;&amp;quot;foobarbaz&amp;quot;.index(&amp;quot;bar&amp;quot;);&amp;lt;/code&amp;gt; returns the index of &amp;quot;bar&amp;quot; despite the fact that &#039;b&#039;, &#039;a&#039;, and &#039;r&#039; are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &amp;lt;code&amp;gt;[1,2,3,4,5].indexOf([2,3,4]);&amp;lt;/code&amp;gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.&lt;br /&gt;
;Pushing and Popping&lt;br /&gt;
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don&#039;t need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...&lt;br /&gt;
:.pop() and .shift() remove ONE item from an array and return it.&lt;br /&gt;
:As well given one argument .push() and .unshift() add ONE item to an array.&lt;br /&gt;
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].&lt;br /&gt;
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.&lt;br /&gt;
:&lt;br /&gt;
:There is another name which does fit this kind of operation, &amp;quot;Append&amp;quot; (Side note, Wrench.js does .append to the array type). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].&lt;br /&gt;
&lt;br /&gt;
== ByteArray? ==&lt;br /&gt;
From the discussions in the ServerJS mailing list I do not recall anyone saying&lt;br /&gt;
&amp;quot;[I] want to mutate a [sequence] with the Array api&amp;quot;. I only recall the statements&lt;br /&gt;
&amp;quot;[I] want a way to mutate a [sequence]&amp;quot; and &amp;quot;mutable, like an Array&amp;quot;.&lt;br /&gt;
The decision to use the name &amp;quot;ByteArray&amp;quot; had nothing to do with wanting an Array&lt;br /&gt;
type sequence. It had to do with wanting to mutate a sequence, and Arrays being&lt;br /&gt;
the other type of list.&lt;br /&gt;
&lt;br /&gt;
Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.&lt;br /&gt;
&lt;br /&gt;
== Prior art ==&lt;br /&gt;
Java&#039;s [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it&#039;s a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.&lt;br /&gt;
&lt;br /&gt;
The StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.&lt;br /&gt;
&lt;br /&gt;
== The API ==&lt;br /&gt;
The api for this spec defines two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it&#039;s a fairly long-standing name and normally works similarly) and Buffer.&lt;br /&gt;
&lt;br /&gt;
It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &amp;lt;code&amp;gt;require(&#039;binary&#039;);&amp;lt;/code&amp;gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &amp;lt;code&amp;gt;exports.Blob = Blob; exports.Buffer = Buffer;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Blob ===&lt;br /&gt;
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.&lt;br /&gt;
&lt;br /&gt;
;[new] Blob();&lt;br /&gt;
:Construct an empty blob&lt;br /&gt;
;[new] Blob(number);&lt;br /&gt;
:Construct a single unit blob, converting the number a bit. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(arrayOfNumbers);&lt;br /&gt;
:Construct an blob the same length as the array, converting numbers 0..255 into bits. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.&lt;br /&gt;
;[new] Blob(blob);&lt;br /&gt;
:Passes the blob through.&lt;br /&gt;
;[new] Blob(string, toCharset);&lt;br /&gt;
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &amp;lt;code&amp;gt;toCharset&amp;lt;/code&amp;gt; argument and represented in the new blob in 8bit bytes.&lt;br /&gt;
&lt;br /&gt;
;blob.length;&lt;br /&gt;
:Returns the length of the blob. This is immutable.&lt;br /&gt;
&lt;br /&gt;
;blob[index]; // Optional&lt;br /&gt;
;blob.byteAt(index);&lt;br /&gt;
;blob.valueAt(index);&lt;br /&gt;
:Extracts a single byte from the blob and returns a new blob object containing only it. Note that the blob[i] form is optional, implementations may chose to exclude support for it. This should be ideally be relevant to support for string[i], thus if the interpreter being used supports string[i] it is expected that an implementation should attempt to support it as well.&lt;br /&gt;
&lt;br /&gt;
;blob.indexOf(blob, offset=0);&lt;br /&gt;
;blob.lastIndexOf(blob, offset=0);&lt;br /&gt;
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;blob.concat(otherBlob, ...);&lt;br /&gt;
:Combines the content of multiple blobs together and returns a new blob.&lt;br /&gt;
&lt;br /&gt;
;blob.slice(offset, length);&lt;br /&gt;
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)&lt;br /&gt;
&lt;br /&gt;
;blob.split();&lt;br /&gt;
;blob.split(separator);&lt;br /&gt;
;blob.split(separator, limit);&lt;br /&gt;
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions.&lt;br /&gt;
&lt;br /&gt;
;blob.toBlob([fromCharset, toCharset]);&lt;br /&gt;
:If passed with no argument returns the same blob.&lt;br /&gt;
:If passed with two charaset arguments transcodes the data from one charset to the other and returns the data as a new blob.&lt;br /&gt;
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.&lt;br /&gt;
&lt;br /&gt;
;blob.toString();&lt;br /&gt;
:Returns a debug representation like &amp;quot;[Blob length=2]&amp;quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.&lt;br /&gt;
&lt;br /&gt;
;blob.toString(fromCharset);&lt;br /&gt;
:Converts the binary data in the blob from the charset specified by &amp;lt;code&amp;gt;fromCharset&amp;lt;/code&amp;gt; to the native UTF-16 charset and returns a new string with that content.&lt;br /&gt;
&lt;br /&gt;
;blob.toArray();&lt;br /&gt;
:Returns an array containing the bytes as numbers. &lt;br /&gt;
;blob.toArray(charset);&lt;br /&gt;
:Returns an array containing the decoded Unicode code points. &lt;br /&gt;
&lt;br /&gt;
;blob.integerAt(offset, size=1, signed=false, networkEndian=false);&lt;br /&gt;
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.&lt;br /&gt;
&lt;br /&gt;
;blob.floatAt(offset, size);&lt;br /&gt;
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.&lt;br /&gt;
&lt;br /&gt;
;blob.stringAt(offset, size, fromCharset=UTF-16);&lt;br /&gt;
:Extracts a string out from a blob. This method is similar to if you had done &amp;lt;code&amp;gt;blob.slice(offset, size).toString(fromCharset||&amp;quot;UTF-16&amp;quot;);&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;blob.toSource();&lt;br /&gt;
:This method is optional, it should be included if the interpreter being used supports .toSource() on it&#039;s various objects and types.&lt;br /&gt;
:Returns a representation of the blob in the format &amp;quot;(Blob([]))&amp;quot; or &amp;quot;(new Blob([]))&amp;quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
Buffer is a &#039;&#039;&#039;&#039;&#039;generic&#039;&#039;&#039;&#039;&#039; buffer which may act on either binary or textual data using the same api (Two purposes in one class is derived from the [http://draft.monkeyscript.org/api/_std/Buffer.html MonkeyScript Buffer]; the .text = bool; idiom came from the .text property in MonkeyScript&#039;s Stream class, the idea is to make it as easy as possible to create a buffer of the same type without needing to use a ternary, this point is up for discussion on the list).&lt;br /&gt;
&lt;br /&gt;
(Note: Whether to allow type conversion of a buffer with no content or not could be discussed) A Buffer may initially be created as untyped without any length, or may be given a type and/or length when created. A Buffer which has a type assigned to it (binary or text) and has content within it (length &amp;gt; 0) may not be converted to another type and should throw an error if attempted.&lt;br /&gt;
&lt;br /&gt;
A buffer gains a type when .text is assigned a true or false value, or it inherits the data type of the first piece of data added to the buffer. After it is typed a buffer should throw an error if someone attempts to insert a different type of data into the buffer (If you want to insert a string into a binary buffer, you should convert it to a blob first yourself; automatic type conversion in these cases would cause gotchas).&lt;br /&gt;
&lt;br /&gt;
Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.&lt;br /&gt;
&lt;br /&gt;
;new Buffer();&lt;br /&gt;
:Construct an empty buffer with no set type&lt;br /&gt;
;new Buffer([String or Blob], [len]);&lt;br /&gt;
:Construct a new buffer.&lt;br /&gt;
:The constructor may accept the &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; function or the &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; function as a hint of what type to set on the buffer.&lt;br /&gt;
:The constructor also may accept a length argument to set the default length of the buffer.&lt;br /&gt;
;new Buffer(sequence);&lt;br /&gt;
:Construct a buffer based on a string or a blob. The Buffer will be the same length as the sequence, inherit the same type, and start off with the same content as the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.length;&lt;br /&gt;
;buf.length = len;&lt;br /&gt;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).&lt;br /&gt;
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and &#039;\0&#039; (null characters) for text.&lt;br /&gt;
&lt;br /&gt;
;buf.text;&lt;br /&gt;
;buf.text = bool;&lt;br /&gt;
:Get or set the type of the buffer. Binary buffers return false, text buffers return true, buffers which have not been assigned a type yet return undefined.&lt;br /&gt;
:This will throw a TypeError if you try to set a type on a buffer that already has a type and has a length greater than 0.&lt;br /&gt;
&lt;br /&gt;
;buf[index];&lt;br /&gt;
;buf.valueAt(index);&lt;br /&gt;
:Returns a string or blob representing the unit at a specified index.&lt;br /&gt;
&lt;br /&gt;
;buf.append(data);&lt;br /&gt;
:Append a chunk of data to the end of the buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.insert(data, index);&lt;br /&gt;
:Insert a chunk of data into a buffer growing it by &amp;lt;code&amp;gt;data.length&amp;lt;/code&amp;gt; and shifting the data to the right of the specified index towards the end of the buffer.&lt;br /&gt;
&lt;br /&gt;
;buf.clear(offset, length);&lt;br /&gt;
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with &#039;\0&#039; (null characters).&lt;br /&gt;
&lt;br /&gt;
;buf.remove(offset, length);&lt;br /&gt;
:Remove a section of the buffer starting at &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; and continuing for &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; units, shrinking it by &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;buf.splice(offset, length, data, ...);&lt;br /&gt;
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from.&lt;br /&gt;
&lt;br /&gt;
;buf.slice();&lt;br /&gt;
;buf.slice(start);&lt;br /&gt;
;buf.slice(start, end);&lt;br /&gt;
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)&lt;br /&gt;
&lt;br /&gt;
;buf.split();&lt;br /&gt;
;buf.split(separator);&lt;br /&gt;
;buf.split(separator, limit);&lt;br /&gt;
:Splits the buffer based on a sequence and returns an array of strings or blobs. (This methods when used on text buffers may or may not chose to support regular expressions)&lt;br /&gt;
&lt;br /&gt;
;buf.indexOf(sequence, offset=0);&lt;br /&gt;
;buf.lastIndexOf(sequence, offset=0);&lt;br /&gt;
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.&lt;br /&gt;
&lt;br /&gt;
;buf.reverse();&lt;br /&gt;
:Causes the sequence to be replaced by the reverse of the sequence.&lt;br /&gt;
&lt;br /&gt;
;buf.valueOf();&lt;br /&gt;
:Return the non-mutable sequence for the buffer.&lt;br /&gt;
:* In binary mode this returns a Blob which matches the contents of the buffer.&lt;br /&gt;
:* In text mode this returns a String which matches the contents of the buffer.&lt;br /&gt;
&lt;br /&gt;
=== String extensions ===&lt;br /&gt;
These extensions may be optional, however it would be ideal if implementations added these prototypes to the standard objects. Implementations may chose how to implement these (load binary themselves beforehand, prototype methods that use require(&#039;binary&#039;) within them, etc...)&lt;br /&gt;
&lt;br /&gt;
;string.toBlob(toCharset);&lt;br /&gt;
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.&lt;br /&gt;
&lt;br /&gt;
;string.valueAt(index);&lt;br /&gt;
:An alias for string.charAt(index);&lt;br /&gt;
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.&lt;br /&gt;
&lt;br /&gt;
== General requirements ==&lt;br /&gt;
Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &amp;quot;us-ascii&amp;quot; and &amp;quot;utf-8&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.&lt;br /&gt;
&lt;br /&gt;
Charsets are case insensitive.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.&lt;br /&gt;
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.&lt;br /&gt;
** Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn&#039;t care which mode it is in.&lt;br /&gt;
*** Note how Buffer accepts &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Blob&amp;lt;/code&amp;gt; to determine it&#039;s data type. You could actually write code like &amp;lt;code&amp;gt;var buf = new Buffer(sequence.constructor);&amp;lt;/code&amp;gt; and create a buffer based on the type of a sequence without checking what it is.&lt;br /&gt;
** While same-type rules apply .slice can be used abstractly on both strings and blobs (arrays to actually), and the same goes for .concat, .length, .split (without regex), and .indexOf/lastIndexOf.&lt;br /&gt;
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &amp;gt; and &amp;lt; make use of it as well as a few other cases). It would be nice to see if it&#039;s possible to use the native &amp;lt; and &amp;gt; operators to compare blobs on their binary order.&lt;br /&gt;
* For now I&#039;ve ignored things like .eq/equals, .lt, gt, etc... do note that Rhino actually implements .equals on String already. Also if we do add these things to blob we should probably implement the same on string.&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Filesystem_API/Join&amp;diff=154928</id>
		<title>ServerJS/Filesystem API/Join</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Filesystem_API/Join&amp;diff=154928"/>
		<updated>2009-07-14T01:43:51Z</updated>

		<summary type="html">&lt;p&gt;Dantman: /* Show of Hands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
== Unit Tests ==&lt;br /&gt;
&lt;br /&gt;
== Show of Hands ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A&#039;&#039;&#039;: implicitly uses &amp;quot;normal&amp;quot; to normalize the result, so all empty, &amp;quot;.&amp;quot;, and &amp;quot;..&amp;quot; path components are resolved if possible.  This is our &amp;quot;normal&amp;quot; definition, which is distinct from &amp;quot;canonical&amp;quot; and &amp;quot;absolute&amp;quot; in that it does not consult the underlying storage or the current working directory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039;: &amp;lt;code&amp;gt;join(&amp;quot;foo&amp;quot;, &amp;quot;..&amp;quot;, &amp;quot;bar&amp;quot;) == &amp;quot;bar&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;join(&amp;quot;..&amp;quot;, &amp;quot;foo&amp;quot;) == &amp;quot;../foo&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Kris Kowal&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;against&#039;&#039;: &amp;lt;code&amp;gt;join(&amp;quot;foo&amp;quot;, &amp;quot;..&amp;quot;, &amp;quot;bar&amp;quot;) == &amp;quot;foo/../bar&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Ash Berlin&lt;br /&gt;
* Daniel Friesen&lt;br /&gt;
* Mário Valente&lt;br /&gt;
* Zachary Carter&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;B&#039;&#039;&#039;: recognizes and follows absolute paths.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039;: &amp;lt;code&amp;gt;join(&amp;quot;foo&amp;quot;, &amp;quot;/bar&amp;quot;) == &amp;quot;/bar&amp;quot;&amp;lt;/code&amp;gt; (Unix) &amp;lt;code&amp;gt;join(&amp;quot;Foo&amp;quot;, &amp;quot;c:\\Bar&amp;quot;) == &amp;quot;c:\\Bar&amp;quot;&amp;lt;/code&amp;gt; (Microsoft)&lt;br /&gt;
* Kris Kowal&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;against&#039;&#039;: &amp;lt;code&amp;gt;join(&amp;quot;foo&amp;quot;, &amp;quot;/bar&amp;quot;) == &amp;quot;foo/bar&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Mário Valente&lt;br /&gt;
* Zachary Carter&lt;br /&gt;
* &#039;&#039;Daniel Friesen (fuzzy)&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Unit_Testing&amp;diff=145569</id>
		<title>ServerJS/Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Unit_Testing&amp;diff=145569"/>
		<updated>2009-05-24T12:51:40Z</updated>

		<summary type="html">&lt;p&gt;Dantman: /* Prior Art */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Unit testing =&lt;br /&gt;
&lt;br /&gt;
Automated tests are an important part of software development today. Providing a standard test library will help encourage more people to write more tests. Additionally, the API specification will likely be written in the form of tests, so this component will be needed by the ServerJS project itself.&lt;br /&gt;
&lt;br /&gt;
Testing involves both an API for easily defining tests and running assertions, plus a tool (or tools) for locating and running the tests.&lt;br /&gt;
&lt;br /&gt;
== Prior Art ==&lt;br /&gt;
&lt;br /&gt;
* [http://jsunit.berlios.de/ JsUnit] - browser, native, Ant, and Maven based test runners&lt;br /&gt;
* [http://code.google.com/p/rhinounit/ rhinounit] - Ant based test runner&lt;br /&gt;
* JavaScript Assertion Unit -&lt;br /&gt;
* [http://docs.jquery.com/QUnit QUnit] jQuery&#039;s unit testing framework, browser based&lt;br /&gt;
* [http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/util/doh/ DOH]  JavaScript unit testing framework (used by Dojo, but without Dojo dependencies), supports browsers and stand-alone JavaScript environments.&lt;br /&gt;
* JSSpec is a Javascript BDD(Behavior Driven Development) framework. http://code.google.com/p/jsspec/&lt;br /&gt;
* JSpec is a minimalistic JavaScript behavior driven development framework http://github.com/visionmedia/jspec/tree/master&lt;br /&gt;
* Better Javascript testing through ScrewUnit http://pivotallabs.com/users/nick/bl...ough-screwunit&lt;br /&gt;
* Mochitest is an [https://developer.mozilla.org/En/Mozilla_automated_testing automated testing framework] built on top of the MochiKit JavaScript libraries https://developer.mozilla.org/en/Mochitest&lt;br /&gt;
* Yahoo! UI Library: YUI Test http://developer.yahoo.com/yui/yuitest/&lt;br /&gt;
* JSMock is a fully featured Mock Object library for JavaScript that provides the necessary tools to do effective interactive based testing. http://jsmock.sourceforge.net/&lt;br /&gt;
* JSLitmus is a lightweight tool for creating ad-hoc JavaScript benchmark tests. http://www.broofa.com/Tools/JSLitmus/&lt;br /&gt;
* Jack is a toolkit for mocking JavaScript objects and functions. http://boss.bekk.no/display/BOSS/Jack&lt;br /&gt;
* MockMe for JavaScript http://johanneslink.net/projects/mockme.html&lt;br /&gt;
* qMock is a standalone, lightweight mocking framework that facilitates integration testing for JavaScript programs. http://code.google.com/p/qmock/&lt;br /&gt;
* TDD JS with JsMock http://www.pathf.com/blogs/2006/11/tdd_and_javascr/&lt;br /&gt;
* Test Driven Javascript http://www.testdrivenjavascript.com/Practice/5.aspx&lt;br /&gt;
* jsUnity is a lightweight JavaScript testing framework that is context-agnostic http://jsunity.com/&lt;br /&gt;
* JsUnitTest is based off unittest.js from prototypejs, except this library has no dependencies http://jsunittest.com&lt;br /&gt;
* Inspec BDD style test framework http://github.com/aq1018/inspec&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Existing_APIs&amp;diff=140076</id>
		<title>ServerJS/Existing APIs</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Existing_APIs&amp;diff=140076"/>
		<updated>2009-04-15T17:01:57Z</updated>

		<summary type="html">&lt;p&gt;Dantman: Use names for links to make the document more readable; Cross out dead link; Notate a few pieces of information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links to existing server-side JS APIs which may act as an inspiration for some coordinated progress.&lt;br /&gt;
&lt;br /&gt;
* [http://code.google.com/p/piston/ Piston]&lt;br /&gt;
* [http://code.google.com/p/chironjs/ chironjs]&lt;br /&gt;
* [http://code.google.com/p/v8cgi/w/list v8cgi]&lt;br /&gt;
* [http://code.google.com/p/jslibs/wiki/JSLibs JSLibs]&lt;br /&gt;
* [http://www.ejscript.org/products/ejs/doc/ref/ejs/index.html EJScript]&lt;br /&gt;
* [http://www.ejscript.org/products/ejs/doc/api/ejscript/index.html EJScript API]&lt;br /&gt;
* [http://docs.persvr.org/documentation/server-side-js Persevere]&lt;br /&gt;
* [http://jsext.sourceforge.net/Object%20reference.html JSExt]&lt;br /&gt;
* [http://www.jsdb.org/reference.html jsdb]&lt;br /&gt;
* [http://www.jnext.org/index.html jnext]&lt;br /&gt;
* [http://www.modjs.org/ modjs]&lt;br /&gt;
* [http://helma.zumbrunn.com/reference/ helma]&lt;br /&gt;
* [http://www.wxjavascript.net/modules.html wxJavaScript]&lt;br /&gt;
* [http://appjet.com/docs/librefbrowser appjet]&lt;br /&gt;
* [http://www.10gen.com/apidocs/ 10gen]&lt;br /&gt;
* [http://www.aptana.com/reference/jaxer/api/Jaxer.index-frame.html Jaxer API]&lt;br /&gt;
* [http://freebaseapps.com/ Freebase Apps]&lt;br /&gt;
* [http://github.com/mvalente/starbucks/tree/master STARBUCKS SSJS Web Dev Framework] (uses JSLibs, moving to Jaxer?)&lt;br /&gt;
* [http://monkeyscript.org/ MonkeyScript] (uses JSLibs)&lt;br /&gt;
* [http://spiderape.sourceforge.net/ SpiderApe]&lt;br /&gt;
* [http://synchro.net/docs/jsobjs.html Synchronet]&lt;br /&gt;
* [http://www.adobe.com/devnet/acrobat/javascript.html JavaScript for Acrobat]&lt;br /&gt;
* &amp;lt;s&amp;gt;http://www.adobe.com/livedocs/flashm..._cs_asd_1.html&amp;lt;/s&amp;gt; (dead)&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ServerJS/Existing_APIs&amp;diff=140073</id>
		<title>ServerJS/Existing APIs</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ServerJS/Existing_APIs&amp;diff=140073"/>
		<updated>2009-04-15T16:53:02Z</updated>

		<summary type="html">&lt;p&gt;Dantman: http://monkeyscript.nadir-point.com/wiki/MonkeyScript -&amp;gt; http://monkeyscript.org/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links to existing server-side JS APIs which may act as an inspiration for some coordinated progress.&lt;br /&gt;
&lt;br /&gt;
* http://code.google.com/p/piston/&lt;br /&gt;
* http://code.google.com/p/chironjs/&lt;br /&gt;
* http://code.google.com/p/v8cgi/w/list&lt;br /&gt;
* http://code.google.com/p/jslibs/wiki/JSLibs&lt;br /&gt;
* http://www.ejscript.org/products/ejs/doc/api/ejscript/index.html&lt;br /&gt;
* http://www.ejscript.org/products/ejs/doc/ref/ejs/index.html&lt;br /&gt;
* http://docs.persvr.org/documentation/server-side-js&lt;br /&gt;
* http://jsext.sourceforge.net/Object%20reference.html&lt;br /&gt;
* http://www.jsdb.org/reference.html&lt;br /&gt;
* http://www.jnext.org/index.html&lt;br /&gt;
* http://www.modjs.org/&lt;br /&gt;
* http://helma.zumbrunn.com/reference/&lt;br /&gt;
* http://www.wxjavascript.net/modules.html&lt;br /&gt;
* http://appjet.com/docs/librefbrowser&lt;br /&gt;
* http://www.10gen.com/apidocs/&lt;br /&gt;
* [http://www.aptana.com/reference/jaxer/api/Jaxer.index-frame.html Jaxer API]&lt;br /&gt;
* http://freebaseapps.com/&lt;br /&gt;
* http://github.com/mvalente/starbucks/tree/master&lt;br /&gt;
* http://monkeyscript.org/&lt;br /&gt;
* http://spiderape.sourceforge.net/ &lt;br /&gt;
* http://synchro.net/docs/jsobjs.html&lt;br /&gt;
* http://www.adobe.com/devnet/acrobat/javascript.html&lt;br /&gt;
* http://www.adobe.com/livedocs/flashm..._cs_asd_1.html&lt;/div&gt;</summary>
		<author><name>Dantman</name></author>
	</entry>
</feed>