aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs')
-rw-r--r--csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs112
1 files changed, 112 insertions, 0 deletions
diff --git a/csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs b/csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
new file mode 100644
index 00000000..270af64b
--- /dev/null
+++ b/csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
@@ -0,0 +1,112 @@
+using System;
+using System.IO;
+using System.Xml;
+using System.Text;
+
+namespace Google.ProtocolBuffers.Serialization.Http
+{
+ /// <summary>
+ /// Extensions and helpers to abstract the reading/writing of messages by a client-specified content type.
+ /// </summary>
+ public static class MessageFormatFactory
+ {
+ /// <summary>
+ /// Constructs an ICodedInputStream from the input stream based on the contentType provided
+ /// </summary>
+ /// <param name="options">Options specific to reading this message and/or content type</param>
+ /// <param name="contentType">The mime type of the input stream content</param>
+ /// <param name="input">The stream to read the message from</param>
+ /// <returns>The ICodedInputStream that can be given to the IBuilder.MergeFrom(...) method</returns>
+ public static ICodedInputStream CreateInputStream(MessageFormatOptions options, string contentType, Stream input)
+ {
+ ICodedInputStream codedInput = ContentTypeToInputStream(contentType, options, input);
+
+ if (codedInput is XmlFormatReader)
+ {
+ XmlFormatReader reader = (XmlFormatReader)codedInput;
+ reader.RootElementName = options.XmlReaderRootElementName;
+ reader.Options = options.XmlReaderOptions;
+ }
+
+ return codedInput;
+ }
+
+ /// <summary>
+ /// Writes the message instance to the stream using the content type provided
+ /// </summary>
+ /// <param name="options">Options specific to writing this message and/or content type</param>
+ /// <param name="contentType">The mime type of the content to be written</param>
+ /// <param name="output">The stream to write the message to</param>
+ /// <remarks> If you do not dispose of ICodedOutputStream some formats may yield incomplete output </remarks>
+ public static ICodedOutputStream CreateOutputStream(MessageFormatOptions options, string contentType, Stream output)
+ {
+ ICodedOutputStream codedOutput = ContentTypeToOutputStream(contentType, options, output);
+
+ if (codedOutput is JsonFormatWriter)
+ {
+ JsonFormatWriter writer = (JsonFormatWriter)codedOutput;
+ if (options.FormattedOutput)
+ {
+ writer.Formatted();
+ }
+ }
+ else if (codedOutput is XmlFormatWriter)
+ {
+ XmlFormatWriter writer = (XmlFormatWriter)codedOutput;
+ if (options.FormattedOutput)
+ {
+ XmlWriterSettings settings = new XmlWriterSettings()
+ {
+ CheckCharacters = false,
+ NewLineHandling = NewLineHandling.Entitize,
+ OmitXmlDeclaration = true,
+ Encoding = new UTF8Encoding(false),
+ Indent = true,
+ IndentChars = " ",
+ };
+ // Don't know how else to change xml writer options?
+ codedOutput = writer = XmlFormatWriter.CreateInstance(XmlWriter.Create(output, settings));
+ }
+ writer.RootElementName = options.XmlWriterRootElementName;
+ writer.Options = options.XmlWriterOptions;
+ }
+
+ return codedOutput;
+ }
+
+ private static ICodedInputStream ContentTypeToInputStream(string contentType, MessageFormatOptions options, Stream input)
+ {
+ contentType = (contentType ?? String.Empty).Split(';')[0].Trim();
+
+ CodedInputBuilder factory;
+ if(!options.MimeInputTypesReadOnly.TryGetValue(contentType, out factory) || factory == null)
+ {
+ if(String.IsNullOrEmpty(options.DefaultContentType) ||
+ !options.MimeInputTypesReadOnly.TryGetValue(options.DefaultContentType, out factory) || factory == null)
+ {
+ throw new ArgumentOutOfRangeException("contentType");
+ }
+ }
+
+ return factory(input);
+ }
+
+ private static ICodedOutputStream ContentTypeToOutputStream(string contentType, MessageFormatOptions options, Stream output)
+ {
+ contentType = (contentType ?? String.Empty).Split(';')[0].Trim();
+
+ CodedOutputBuilder factory;
+ if (!options.MimeOutputTypesReadOnly.TryGetValue(contentType, out factory) || factory == null)
+ {
+ if (String.IsNullOrEmpty(options.DefaultContentType) ||
+ !options.MimeOutputTypesReadOnly.TryGetValue(options.DefaultContentType, out factory) || factory == null)
+ {
+ throw new ArgumentOutOfRangeException("contentType");
+ }
+ }
+
+ return factory(output);
+ }
+
+ }
+} \ No newline at end of file