http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/e387fc92/JSLib/src/odata-batch.js
----------------------------------------------------------------------
diff --git a/JSLib/src/odata-batch.js b/JSLib/src/odata-batch.js
index 770d875..3060223 100644
--- a/JSLib/src/odata-batch.js
+++ b/JSLib/src/odata-batch.js
@@ -1,393 +1,393 @@
-/// <reference path="odata-utils.js" />
-
-// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation 
-// files (the "Software"), to deal  in the Software without restriction, 
including without limitation the rights  to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the 
Software, and to permit persons to whom the 
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in 
all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE SOFTWARE.
-
-// odata-batch.js
-
-(function (window, undefined) {
-
-    var datajs = window.datajs || {};
-    var odata = window.OData || {};
-
-    // Imports
-
-    var extend = datajs.extend;
-    var isArray = datajs.isArray;
-    var trimString = datajs.trimString;
-
-    var contentType = odata.contentType;
-    var handler = odata.handler;
-    var isBatch = odata.isBatch;
-    var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
-    var normalizeHeaders = odata.normalizeHeaders;
-    var payloadTypeOf = odata.payloadTypeOf;
-    var prepareRequest = odata.prepareRequest;
-
-    // CONTENT START
-    var batchMediaType = "multipart/mixed";
-    var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
-    var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;
-
-    var hex16 = function () {
-        /// <summary>
-        /// Calculates a random 16 bit number and returns it in hexadecimal 
format.
-        /// </summary>
-        /// <returns type="String">A 16-bit number in hex format.</returns>
-
-        return Math.floor((1 + Math.random()) * 
0x10000).toString(16).substr(1);
-    };
-
-    var createBoundary = function (prefix) {
-        /// <summary>
-        /// Creates a string that can be used as a multipart request boundary.
-        /// </summary>
-        /// <param name="prefix" type="String" optional="true">String to use 
as the start of the boundary string</param>
-        /// <returns type="String">Boundary string of the format: 
<prefix><hex16>-<hex16>-<hex16></returns>
-
-        return prefix + hex16() + "-" + hex16() + "-" + hex16();
-    };
-
-    var partHandler = function (context) {
-        /// <summary>
-        /// Gets the handler for data serialization of individual requests / 
responses in a batch.
-        /// </summary>
-        /// <param name="context">Context used for data serialization.</param>
-        /// <returns>Handler object.</returns>
-
-        return context.handler.partHandler;
-    };
-
-    var currentBoundary = function (context) {
-        /// <summary>
-        /// Gets the current boundary used for parsing the body of a multipart 
response.
-        /// </summary>
-        /// <param name="context">Context used for parsing a multipart 
response.</param>
-        /// <returns type="String">Boundary string.</returns>
-
-        var boundaries = context.boundaries;
-        return boundaries[boundaries.length - 1];
-    };
-
-    var batchParser = function (handler, text, context) {
-        /// <summary>Parses a batch response.</summary>
-        /// <param name="handler">This handler.</param>
-        /// <param name="text" type="String">Batch text.</param>
-        /// <param name="context" type="Object">Object with parsing 
context.</param>
-        /// <returns>An object representation of the batch.</returns>
-
-        var boundary = context.contentType.properties["boundary"];
-        return { __batchResponses: readBatch(text, { boundaries: [boundary], 
handlerContext: context }) };
-    };
-
-    var batchSerializer = function (handler, data, context) {
-        /// <summary>Serializes a batch object representation into 
text.</summary>
-        /// <param name="handler">This handler.</param>
-        /// <param name="data" type="Object">Representation of a batch.</param>
-        /// <param name="context" type="Object">Object with parsing 
context.</param>
-        /// <returns>An text representation of the batch object; undefined if 
not applicable.</returns>
-
-        var cType = context.contentType = context.contentType || 
contentType(batchMediaType);
-        if (cType.mediaType === batchMediaType) {
-            return writeBatch(data, context);
-        }
-    };
-
-    var readBatch = function (text, context) {
-        /// <summary>
-        /// Parses a multipart/mixed response body from from the position 
defined by the context.
-        /// </summary>
-        /// <param name="text" type="String" optional="false">Body of the 
multipart/mixed response.</param>
-        /// <param name="context">Context used for parsing.</param>
-        /// <returns>Array of objects representing the individual 
responses.</returns>
-
-        var delimiter = "--" + currentBoundary(context);
-
-        // Move beyond the delimiter and read the complete batch
-        readTo(text, context, delimiter);
-
-        // Ignore the incoming line
-        readLine(text, context);
-
-        // Read the batch parts
-        var responses = [];
-        var partEnd;
-
-        while (partEnd !== "--" && context.position < text.length) {
-            var partHeaders = readHeaders(text, context);
-            var partContentType = contentType(partHeaders["Content-Type"]);
-
-            var changeResponses;
-            if (partContentType && partContentType.mediaType === 
batchMediaType) {
-                
context.boundaries.push(partContentType.properties["boundary"]);
-                try {
-                    changeResponses = readBatch(text, context);
-                } catch (e) {
-                    e.response = readResponse(text, context, delimiter);
-                    changeResponses = [e];
-                }
-                responses.push({ __changeResponses: changeResponses });
-                context.boundaries.pop();
-                readTo(text, context, "--" + currentBoundary(context));
-            } else {
-                if (!partContentType || partContentType.mediaType !== 
"application/http") {
-                    throw { message: "invalid MIME part type " };
-                }
-                // Skip empty line
-                readLine(text, context);
-                // Read the response
-                var response = readResponse(text, context, delimiter);
-                try {
-                    if (response.statusCode >= 200 && response.statusCode <= 
299) {
-                        partHandler(context.handlerContext).read(response, 
context.handlerContext);
-                    } else {
-                        // Keep track of failed responses and continue 
processing the batch.
-                        response = { message: "HTTP request failed", response: 
response };
-                    }
-                } catch (e) {
-                    response = e;
-                }
-
-                responses.push(response);
-            }
-
-            partEnd = text.substr(context.position, 2);
-
-            // Ignore the incoming line.
-            readLine(text, context);
-        }
-        return responses;
-    };
-
-    var readHeaders = function (text, context) {
-        /// <summary>
-        /// Parses the http headers in the text from the position defined by 
the context.
-        /// </summary>
-        /// <param name="text" type="String" optional="false">Text containing 
an http response's headers</param>
-        /// <param name="context">Context used for parsing.</param>
-        /// <returns>Object containing the headers as key value 
pairs.</returns>
-        /// <remarks>
-        /// This function doesn't support split headers and it will stop 
reading when it hits two consecutive line breaks.
-        /// </remarks>
-
-        var headers = {};
-        var parts;
-        var line;
-        var pos;
-
-        do {
-            pos = context.position;
-            line = readLine(text, context);
-            parts = responseHeaderRegex.exec(line);
-            if (parts !== null) {
-                headers[parts[1]] = parts[2];
-            } else {
-                // Whatever was found is not a header, so reset the context 
position.
-                context.position = pos;
-            }
-        } while (line && parts);
-
-        normalizeHeaders(headers);
-
-        return headers;
-    };
-
-    var readResponse = function (text, context, delimiter) {
-        /// <summary>
-        /// Parses an HTTP response.
-        /// </summary>
-        /// <param name="text" type="String" optional="false">Text 
representing the http response.</param>
-        /// <param name="context" optional="false">Context used for 
parsing.</param>
-        /// <param name="delimiter" type="String" optional="false">String used 
as delimiter of the multipart response parts.</param>
-        /// <returns>Object representing the http response.</returns>
-
-        // Read the status line.
-        var pos = context.position;
-        var match = responseStatusRegex.exec(readLine(text, context));
-
-        var statusCode;
-        var statusText;
-        var headers;
-
-        if (match) {
-            statusCode = match[1];
-            statusText = match[2];
-            headers = readHeaders(text, context);
-            readLine(text, context);
-        } else {
-            context.position = pos;
-        }
-
-        return {
-            statusCode: statusCode,
-            statusText: statusText,
-            headers: headers,
-            body: readTo(text, context, "\r\n" + delimiter)
-        };
-    };
-
-    var readLine = function (text, context) {
-        /// <summary>
-        /// Returns a substring from the position defined by the context up to 
the next line break (CRLF).
-        /// </summary>
-        /// <param name="text" type="String" optional="false">Input 
string.</param>
-        /// <param name="context" optional="false">Context used for reading 
the input string.</param>
-        /// <returns type="String">Substring to the first ocurrence of a line 
break or null if none can be found. </returns>
-
-        return readTo(text, context, "\r\n");
-    };
-
-    var readTo = function (text, context, str) {
-        /// <summary>
-        /// Returns a substring from the position given by the context up to 
value defined by the str parameter and increments the position in the context.
-        /// </summary>
-        /// <param name="text" type="String" optional="false">Input 
string.</param>
-        /// <param name="context" type="Object" optional="false">Context used 
for reading the input string.</param>
-        /// <param name="str" type="String" optional="true">Substring to read 
up to.</param>
-        /// <returns type="String">Substring to the first ocurrence of str or 
the end of the input string if str is not specified. Null if the marker is not 
found.</returns>
-
-        var start = context.position || 0;
-        var end = text.length;
-        if (str) {
-            end = text.indexOf(str, start);
-            if (end === -1) {
-                return null;
-            }
-            context.position = end + str.length;
-        } else {
-            context.position = end;
-        }
-
-        return text.substring(start, end);
-    };
-
-    var writeBatch = function (data, context) {
-        /// <summary>
-        /// Serializes a batch request object to a string.
-        /// </summary>
-        /// <param name="data" optional="false">Batch request object in 
payload representation format</param>
-        /// <param name="context" optional="false">Context used for the 
serialization</param>
-        /// <returns type="String">String representing the batch 
request</returns>
-
-        if (!isBatch(data)) {
-            throw { message: "Data is not a batch object." };
-        }
-
-        var batchBoundary = createBoundary("batch_");
-        var batchParts = data.__batchRequests;
-        var batch = "";
-        var i, len;
-        for (i = 0, len = batchParts.length; i < len; i++) {
-            batch += writeBatchPartDelimiter(batchBoundary, false) +
-                     writeBatchPart(batchParts[i], context);
-        }
-        batch += writeBatchPartDelimiter(batchBoundary, true);
-
-        // Register the boundary with the request content type.
-        var contentTypeProperties = context.contentType.properties;
-        contentTypeProperties.boundary = batchBoundary;
-
-        return batch;
-    };
-
-    var writeBatchPartDelimiter = function (boundary, close) {
-        /// <summary>
-        /// Creates the delimiter that indicates that start or end of an 
individual request.
-        /// </summary>
-        /// <param name="boundary" type="String" optional="false">Boundary 
string used to indicate the start of the request</param>
-        /// <param name="close" type="Boolean">Flag indicating that a close 
delimiter string should be generated</param>
-        /// <returns type="String">Delimiter string</returns>
-
-        var result = "\r\n--" + boundary;
-        if (close) {
-            result += "--";
-        }
-
-        return result + "\r\n";
-    };
-
-    var writeBatchPart = function (part, context, nested) {
-        /// <summary>
-        /// Serializes a part of a batch request to a string. A part can be 
either a GET request or
-        /// a change set grouping several CUD (create, update, delete) 
requests.
-        /// </summary>
-        /// <param name="part" optional="false">Request or change set object 
in payload representation format</param>
-        /// <param name="context" optional="false">Object containing context 
information used for the serialization</param>
-        /// <param name="nested" type="boolean" optional="true">Flag 
indicating that the part is nested inside a change set</param>
-        /// <returns type="String">String representing the serialized 
part</returns>
-        /// <remarks>
-        /// A change set is an array of request objects and they cannot be 
nested inside other change sets.
-        /// </remarks>
-
-        var changeSet = part.__changeRequests;
-        var result;
-        if (isArray(changeSet)) {
-            if (nested) {
-                throw { message: "Not Supported: change set nested in other 
change set" };
-            }
-
-            var changeSetBoundary = createBoundary("changeset_");
-            result = "Content-Type: " + batchMediaType + "; boundary=" + 
changeSetBoundary + "\r\n";
-            var i, len;
-            for (i = 0, len = changeSet.length; i < len; i++) {
-                result += writeBatchPartDelimiter(changeSetBoundary, false) +
-                     writeBatchPart(changeSet[i], context, true);
-            }
-
-            result += writeBatchPartDelimiter(changeSetBoundary, true);
-        } else {
-            result = "Content-Type: 
application/http\r\nContent-Transfer-Encoding: binary\r\n\r\n";
-            var partContext = extend({}, context);
-            partContext.handler = handler;
-            partContext.request = part;
-            partContext.contentType = null;
-
-            prepareRequest(part, partHandler(context), partContext);
-            result += writeRequest(part);
-        }
-
-        return result;
-    };
-
-    var writeRequest = function (request) {
-        /// <summary>
-        /// Serializes a request object to a string.
-        /// </summary>
-        /// <param name="request" optional="false">Request object to 
serialize</param>
-        /// <returns type="String">String representing the serialized 
request</returns>
-
-        var result = (request.method ? request.method : "GET") + " " + 
request.requestUri + " HTTP/1.1\r\n";
-        for (var name in request.headers) {
-            if (request.headers[name]) {
-                result = result + name + ": " + request.headers[name] + "\r\n";
-            }
-        }
-
-        result += "\r\n";
-
-        if (request.body) {
-            result += request.body;
-        }
-
-        return result;
-    };
-
-    odata.batchHandler = handler(batchParser, batchSerializer, batchMediaType, 
MAX_DATA_SERVICE_VERSION);
-
-    // DATAJS INTERNAL START
-    odata.batchSerializer = batchSerializer;
-    odata.writeRequest = writeRequest;
-    // DATAJS INTERNAL END
-
-    // CONTENT END
+/// <reference path="odata-utils.js" />
+
+// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation 
+// files (the "Software"), to deal  in the Software without restriction, 
including without limitation the rights  to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies of the 
Software, and to permit persons to whom the 
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in 
all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE SOFTWARE.
+
+// odata-batch.js
+
+(function (window, undefined) {
+
+    var datajs = window.datajs || {};
+    var odata = window.OData || {};
+
+    // Imports
+
+    var extend = datajs.extend;
+    var isArray = datajs.isArray;
+    var trimString = datajs.trimString;
+
+    var contentType = odata.contentType;
+    var handler = odata.handler;
+    var isBatch = odata.isBatch;
+    var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
+    var normalizeHeaders = odata.normalizeHeaders;
+    var payloadTypeOf = odata.payloadTypeOf;
+    var prepareRequest = odata.prepareRequest;
+
+    // CONTENT START
+    var batchMediaType = "multipart/mixed";
+    var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
+    var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;
+
+    var hex16 = function () {
+        /// <summary>
+        /// Calculates a random 16 bit number and returns it in hexadecimal 
format.
+        /// </summary>
+        /// <returns type="String">A 16-bit number in hex format.</returns>
+
+        return Math.floor((1 + Math.random()) * 
0x10000).toString(16).substr(1);
+    };
+
+    var createBoundary = function (prefix) {
+        /// <summary>
+        /// Creates a string that can be used as a multipart request boundary.
+        /// </summary>
+        /// <param name="prefix" type="String" optional="true">String to use 
as the start of the boundary string</param>
+        /// <returns type="String">Boundary string of the format: 
<prefix><hex16>-<hex16>-<hex16></returns>
+
+        return prefix + hex16() + "-" + hex16() + "-" + hex16();
+    };
+
+    var partHandler = function (context) {
+        /// <summary>
+        /// Gets the handler for data serialization of individual requests / 
responses in a batch.
+        /// </summary>
+        /// <param name="context">Context used for data serialization.</param>
+        /// <returns>Handler object.</returns>
+
+        return context.handler.partHandler;
+    };
+
+    var currentBoundary = function (context) {
+        /// <summary>
+        /// Gets the current boundary used for parsing the body of a multipart 
response.
+        /// </summary>
+        /// <param name="context">Context used for parsing a multipart 
response.</param>
+        /// <returns type="String">Boundary string.</returns>
+
+        var boundaries = context.boundaries;
+        return boundaries[boundaries.length - 1];
+    };
+
+    var batchParser = function (handler, text, context) {
+        /// <summary>Parses a batch response.</summary>
+        /// <param name="handler">This handler.</param>
+        /// <param name="text" type="String">Batch text.</param>
+        /// <param name="context" type="Object">Object with parsing 
context.</param>
+        /// <returns>An object representation of the batch.</returns>
+
+        var boundary = context.contentType.properties["boundary"];
+        return { __batchResponses: readBatch(text, { boundaries: [boundary], 
handlerContext: context }) };
+    };
+
+    var batchSerializer = function (handler, data, context) {
+        /// <summary>Serializes a batch object representation into 
text.</summary>
+        /// <param name="handler">This handler.</param>
+        /// <param name="data" type="Object">Representation of a batch.</param>
+        /// <param name="context" type="Object">Object with parsing 
context.</param>
+        /// <returns>An text representation of the batch object; undefined if 
not applicable.</returns>
+
+        var cType = context.contentType = context.contentType || 
contentType(batchMediaType);
+        if (cType.mediaType === batchMediaType) {
+            return writeBatch(data, context);
+        }
+    };
+
+    var readBatch = function (text, context) {
+        /// <summary>
+        /// Parses a multipart/mixed response body from from the position 
defined by the context.
+        /// </summary>
+        /// <param name="text" type="String" optional="false">Body of the 
multipart/mixed response.</param>
+        /// <param name="context">Context used for parsing.</param>
+        /// <returns>Array of objects representing the individual 
responses.</returns>
+
+        var delimiter = "--" + currentBoundary(context);
+
+        // Move beyond the delimiter and read the complete batch
+        readTo(text, context, delimiter);
+
+        // Ignore the incoming line
+        readLine(text, context);
+
+        // Read the batch parts
+        var responses = [];
+        var partEnd;
+
+        while (partEnd !== "--" && context.position < text.length) {
+            var partHeaders = readHeaders(text, context);
+            var partContentType = contentType(partHeaders["Content-Type"]);
+
+            var changeResponses;
+            if (partContentType && partContentType.mediaType === 
batchMediaType) {
+                
context.boundaries.push(partContentType.properties["boundary"]);
+                try {
+                    changeResponses = readBatch(text, context);
+                } catch (e) {
+                    e.response = readResponse(text, context, delimiter);
+                    changeResponses = [e];
+                }
+                responses.push({ __changeResponses: changeResponses });
+                context.boundaries.pop();
+                readTo(text, context, "--" + currentBoundary(context));
+            } else {
+                if (!partContentType || partContentType.mediaType !== 
"application/http") {
+                    throw { message: "invalid MIME part type " };
+                }
+                // Skip empty line
+                readLine(text, context);
+                // Read the response
+                var response = readResponse(text, context, delimiter);
+                try {
+                    if (response.statusCode >= 200 && response.statusCode <= 
299) {
+                        partHandler(context.handlerContext).read(response, 
context.handlerContext);
+                    } else {
+                        // Keep track of failed responses and continue 
processing the batch.
+                        response = { message: "HTTP request failed", response: 
response };
+                    }
+                } catch (e) {
+                    response = e;
+                }
+
+                responses.push(response);
+            }
+
+            partEnd = text.substr(context.position, 2);
+
+            // Ignore the incoming line.
+            readLine(text, context);
+        }
+        return responses;
+    };
+
+    var readHeaders = function (text, context) {
+        /// <summary>
+        /// Parses the http headers in the text from the position defined by 
the context.
+        /// </summary>
+        /// <param name="text" type="String" optional="false">Text containing 
an http response's headers</param>
+        /// <param name="context">Context used for parsing.</param>
+        /// <returns>Object containing the headers as key value 
pairs.</returns>
+        /// <remarks>
+        /// This function doesn't support split headers and it will stop 
reading when it hits two consecutive line breaks.
+        /// </remarks>
+
+        var headers = {};
+        var parts;
+        var line;
+        var pos;
+
+        do {
+            pos = context.position;
+            line = readLine(text, context);
+            parts = responseHeaderRegex.exec(line);
+            if (parts !== null) {
+                headers[parts[1]] = parts[2];
+            } else {
+                // Whatever was found is not a header, so reset the context 
position.
+                context.position = pos;
+            }
+        } while (line && parts);
+
+        normalizeHeaders(headers);
+
+        return headers;
+    };
+
+    var readResponse = function (text, context, delimiter) {
+        /// <summary>
+        /// Parses an HTTP response.
+        /// </summary>
+        /// <param name="text" type="String" optional="false">Text 
representing the http response.</param>
+        /// <param name="context" optional="false">Context used for 
parsing.</param>
+        /// <param name="delimiter" type="String" optional="false">String used 
as delimiter of the multipart response parts.</param>
+        /// <returns>Object representing the http response.</returns>
+
+        // Read the status line.
+        var pos = context.position;
+        var match = responseStatusRegex.exec(readLine(text, context));
+
+        var statusCode;
+        var statusText;
+        var headers;
+
+        if (match) {
+            statusCode = match[1];
+            statusText = match[2];
+            headers = readHeaders(text, context);
+            readLine(text, context);
+        } else {
+            context.position = pos;
+        }
+
+        return {
+            statusCode: statusCode,
+            statusText: statusText,
+            headers: headers,
+            body: readTo(text, context, "\r\n" + delimiter)
+        };
+    };
+
+    var readLine = function (text, context) {
+        /// <summary>
+        /// Returns a substring from the position defined by the context up to 
the next line break (CRLF).
+        /// </summary>
+        /// <param name="text" type="String" optional="false">Input 
string.</param>
+        /// <param name="context" optional="false">Context used for reading 
the input string.</param>
+        /// <returns type="String">Substring to the first ocurrence of a line 
break or null if none can be found. </returns>
+
+        return readTo(text, context, "\r\n");
+    };
+
+    var readTo = function (text, context, str) {
+        /// <summary>
+        /// Returns a substring from the position given by the context up to 
value defined by the str parameter and increments the position in the context.
+        /// </summary>
+        /// <param name="text" type="String" optional="false">Input 
string.</param>
+        /// <param name="context" type="Object" optional="false">Context used 
for reading the input string.</param>
+        /// <param name="str" type="String" optional="true">Substring to read 
up to.</param>
+        /// <returns type="String">Substring to the first ocurrence of str or 
the end of the input string if str is not specified. Null if the marker is not 
found.</returns>
+
+        var start = context.position || 0;
+        var end = text.length;
+        if (str) {
+            end = text.indexOf(str, start);
+            if (end === -1) {
+                return null;
+            }
+            context.position = end + str.length;
+        } else {
+            context.position = end;
+        }
+
+        return text.substring(start, end);
+    };
+
+    var writeBatch = function (data, context) {
+        /// <summary>
+        /// Serializes a batch request object to a string.
+        /// </summary>
+        /// <param name="data" optional="false">Batch request object in 
payload representation format</param>
+        /// <param name="context" optional="false">Context used for the 
serialization</param>
+        /// <returns type="String">String representing the batch 
request</returns>
+
+        if (!isBatch(data)) {
+            throw { message: "Data is not a batch object." };
+        }
+
+        var batchBoundary = createBoundary("batch_");
+        var batchParts = data.__batchRequests;
+        var batch = "";
+        var i, len;
+        for (i = 0, len = batchParts.length; i < len; i++) {
+            batch += writeBatchPartDelimiter(batchBoundary, false) +
+                     writeBatchPart(batchParts[i], context);
+        }
+        batch += writeBatchPartDelimiter(batchBoundary, true);
+
+        // Register the boundary with the request content type.
+        var contentTypeProperties = context.contentType.properties;
+        contentTypeProperties.boundary = batchBoundary;
+
+        return batch;
+    };
+
+    var writeBatchPartDelimiter = function (boundary, close) {
+        /// <summary>
+        /// Creates the delimiter that indicates that start or end of an 
individual request.
+        /// </summary>
+        /// <param name="boundary" type="String" optional="false">Boundary 
string used to indicate the start of the request</param>
+        /// <param name="close" type="Boolean">Flag indicating that a close 
delimiter string should be generated</param>
+        /// <returns type="String">Delimiter string</returns>
+
+        var result = "\r\n--" + boundary;
+        if (close) {
+            result += "--";
+        }
+
+        return result + "\r\n";
+    };
+
+    var writeBatchPart = function (part, context, nested) {
+        /// <summary>
+        /// Serializes a part of a batch request to a string. A part can be 
either a GET request or
+        /// a change set grouping several CUD (create, update, delete) 
requests.
+        /// </summary>
+        /// <param name="part" optional="false">Request or change set object 
in payload representation format</param>
+        /// <param name="context" optional="false">Object containing context 
information used for the serialization</param>
+        /// <param name="nested" type="boolean" optional="true">Flag 
indicating that the part is nested inside a change set</param>
+        /// <returns type="String">String representing the serialized 
part</returns>
+        /// <remarks>
+        /// A change set is an array of request objects and they cannot be 
nested inside other change sets.
+        /// </remarks>
+
+        var changeSet = part.__changeRequests;
+        var result;
+        if (isArray(changeSet)) {
+            if (nested) {
+                throw { message: "Not Supported: change set nested in other 
change set" };
+            }
+
+            var changeSetBoundary = createBoundary("changeset_");
+            result = "Content-Type: " + batchMediaType + "; boundary=" + 
changeSetBoundary + "\r\n";
+            var i, len;
+            for (i = 0, len = changeSet.length; i < len; i++) {
+                result += writeBatchPartDelimiter(changeSetBoundary, false) +
+                     writeBatchPart(changeSet[i], context, true);
+            }
+
+            result += writeBatchPartDelimiter(changeSetBoundary, true);
+        } else {
+            result = "Content-Type: 
application/http\r\nContent-Transfer-Encoding: binary\r\n\r\n";
+            var partContext = extend({}, context);
+            partContext.handler = handler;
+            partContext.request = part;
+            partContext.contentType = null;
+
+            prepareRequest(part, partHandler(context), partContext);
+            result += writeRequest(part);
+        }
+
+        return result;
+    };
+
+    var writeRequest = function (request) {
+        /// <summary>
+        /// Serializes a request object to a string.
+        /// </summary>
+        /// <param name="request" optional="false">Request object to 
serialize</param>
+        /// <returns type="String">String representing the serialized 
request</returns>
+
+        var result = (request.method ? request.method : "GET") + " " + 
request.requestUri + " HTTP/1.1\r\n";
+        for (var name in request.headers) {
+            if (request.headers[name]) {
+                result = result + name + ": " + request.headers[name] + "\r\n";
+            }
+        }
+
+        result += "\r\n";
+
+        if (request.body) {
+            result += request.body;
+        }
+
+        return result;
+    };
+
+    odata.batchHandler = handler(batchParser, batchSerializer, batchMediaType, 
MAX_DATA_SERVICE_VERSION);
+
+    // DATAJS INTERNAL START
+    odata.batchSerializer = batchSerializer;
+    odata.writeRequest = writeRequest;
+    // DATAJS INTERNAL END
+
+    // CONTENT END
 })(this);
\ No newline at end of file

Reply via email to