Skip to content

Commit 7503e7d

Browse files
committed
Merge branch 'feature/parser_interface' into develop
Resolves #93
2 parents e290340 + 1cc61e1 commit 7503e7d

3 files changed

Lines changed: 88 additions & 55 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
namespace HttpMultipartParser
5+
{
6+
/// <summary>
7+
/// Class containing various extension methods.
8+
/// </summary>
9+
public static class Extensions
10+
{
11+
/// <summary>
12+
/// Returns true if the parameter has any values. False otherwise.
13+
/// </summary>
14+
/// <param name="parser">The multipart form parser.</param>
15+
/// <param name="name">The name of the parameter.</param>
16+
/// <returns>True if the parameter exists. False otherwise.</returns>
17+
public static bool HasParameter(this IMultipartFormDataParser parser, string name)
18+
{
19+
return parser.Parameters.Any(p => p.Name == name);
20+
}
21+
22+
/// <summary>
23+
/// Returns the value of a parameter or null if it doesn't exist.
24+
///
25+
/// You should only use this method if you're sure the parameter has only one value.
26+
///
27+
/// If you need to support multiple values use GetParameterValues.
28+
/// </summary>
29+
/// <param name="parser">The multipart form parser.</param>
30+
/// <param name="name">The name of the parameter.</param>
31+
/// <returns>The value of the parameter.</returns>
32+
public static string GetParameterValue(this IMultipartFormDataParser parser, string name)
33+
{
34+
return parser.GetParameterValues(name).FirstOrDefault();
35+
}
36+
37+
/// <summary>
38+
/// Returns the values of a parameter or an empty enumerable if the parameter doesn't exist.
39+
/// </summary>
40+
/// <param name="parser">The multipart form parser.</param>
41+
/// <param name="name">The name of the parameter.</param>
42+
/// <returns>The values of the parameter.</returns>
43+
public static IEnumerable<string> GetParameterValues(this IMultipartFormDataParser parser, string name)
44+
{
45+
return parser.Parameters
46+
.Where(p => p.Name == name)
47+
.Select(p => p.Data);
48+
}
49+
}
50+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
3+
namespace HttpMultipartParser
4+
{
5+
/// <summary>
6+
/// Provides methods to parse a
7+
/// <see href="http://www.ietf.org/rfc/rfc2388.txt">
8+
/// <c>multipart/form-data</c>
9+
/// </see>
10+
/// stream into it's parameters and file data.
11+
/// </summary>
12+
public interface IMultipartFormDataParser
13+
{
14+
/// <summary>
15+
/// Gets the mapping of parameters parsed files. The name of a given field
16+
/// maps to the parsed file data.
17+
/// </summary>
18+
IReadOnlyList<FilePart> Files { get; }
19+
20+
/// <summary>
21+
/// Gets the parameters. Several ParameterParts may share the same name.
22+
/// </summary>
23+
IReadOnlyList<ParameterPart> Parameters { get; }
24+
}
25+
}

Source/HttpMultipartParser/MultipartFormDataParser.cs

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ namespace HttpMultipartParser
8181
/// }
8282
/// </code>
8383
/// </example>
84-
public class MultipartFormDataParser
84+
public class MultipartFormDataParser : IMultipartFormDataParser
8585
{
86-
#region Constants
86+
#region Constants and fields
8787

8888
/// <summary>
8989
/// The default buffer size.
@@ -95,6 +95,9 @@ public class MultipartFormDataParser
9595
/// </remarks>
9696
private const int DefaultBufferSize = 4096;
9797

98+
private readonly List<FilePart> _files;
99+
private readonly List<ParameterPart> _parameters;
100+
98101
#endregion
99102

100103
#region Constructors and Destructors
@@ -104,6 +107,8 @@ public class MultipartFormDataParser
104107
/// </summary>
105108
private MultipartFormDataParser()
106109
{
110+
_files = new List<FilePart>();
111+
_parameters = new List<ParameterPart>();
107112
}
108113

109114
#endregion
@@ -114,12 +119,12 @@ private MultipartFormDataParser()
114119
/// Gets the mapping of parameters parsed files. The name of a given field
115120
/// maps to the parsed file data.
116121
/// </summary>
117-
public List<FilePart> Files { get; private set; }
122+
public IReadOnlyList<FilePart> Files => _files.AsReadOnly();
118123

119124
/// <summary>
120125
/// Gets the parameters. Several ParameterParts may share the same name.
121126
/// </summary>
122-
public List<ParameterPart> Parameters { get; private set; }
127+
public IReadOnlyList<ParameterPart> Parameters => _parameters.AsReadOnly();
123128

124129
#endregion
125130

@@ -239,47 +244,6 @@ public static async Task<MultipartFormDataParser> ParseAsync(Stream stream, stri
239244

240245
#endregion
241246

242-
#region Public Methods
243-
244-
/// <summary>
245-
/// Returns true if the parameter has any values. False otherwise.
246-
/// </summary>
247-
/// <param name="name">The name of the parameter.</param>
248-
/// <returns>True if the parameter exists. False otherwise.</returns>
249-
public bool HasParameter(string name)
250-
{
251-
return Parameters.Any(p => p.Name == name);
252-
}
253-
254-
/// <summary>
255-
/// Returns the value of a parameter or null if it doesn't exist.
256-
///
257-
/// You should only use this method if you're sure the parameter has only one value.
258-
///
259-
/// If you need to support multiple values use GetParameterValues.
260-
/// </summary>
261-
/// <param name="name">The name of the parameter.</param>
262-
/// <returns>The value of the parameter.</returns>
263-
public string GetParameterValue(string name)
264-
{
265-
var parameter = Parameters.FirstOrDefault(p => p.Name == name);
266-
return parameter?.Data;
267-
}
268-
269-
/// <summary>
270-
/// Returns the values of a parameter or an empty enumerable if the parameter doesn't exist.
271-
/// </summary>
272-
/// <param name="name">The name of the parameter.</param>
273-
/// <returns>The values of the parameter.</returns>
274-
public IEnumerable<string> GetParameterValues(string name)
275-
{
276-
return Parameters
277-
.Where(p => p.Name == name)
278-
.Select(p => p.Data);
279-
}
280-
281-
#endregion
282-
283247
#region Private Methods
284248

285249
/// <summary>
@@ -304,18 +268,15 @@ public IEnumerable<string> GetParameterValues(string name)
304268
/// </param>
305269
private void ParseStream(Stream stream, string boundary, Encoding encoding, int binaryBufferSize, string[] binaryMimeTypes)
306270
{
307-
Files = new List<FilePart>();
308-
Parameters = new List<ParameterPart>();
309-
310271
var streamingParser = new StreamingMultipartFormDataParser(stream, boundary, encoding ?? Encoding.UTF8, binaryBufferSize, binaryMimeTypes);
311-
streamingParser.ParameterHandler += parameterPart => Parameters.Add(parameterPart);
272+
streamingParser.ParameterHandler += parameterPart => _parameters.Add(parameterPart);
312273

313274
streamingParser.FileHandler += (name, fileName, type, disposition, buffer, bytes, partNumber, additionalProperties) =>
314275
{
315276
if (partNumber == 0)
316277
{
317278
// create file with first partNo
318-
Files.Add(new FilePart(name, fileName, Utilities.MemoryStreamManager.GetStream($"{typeof(MultipartFormDataParser).FullName}.{nameof(ParseStream)}"), additionalProperties, type, disposition));
279+
_files.Add(new FilePart(name, fileName, Utilities.MemoryStreamManager.GetStream($"{typeof(MultipartFormDataParser).FullName}.{nameof(ParseStream)}"), additionalProperties, type, disposition));
319280
}
320281

321282
Files[Files.Count - 1].Data.Write(buffer, 0, bytes);
@@ -352,18 +313,15 @@ private void ParseStream(Stream stream, string boundary, Encoding encoding, int
352313
/// </param>
353314
private async Task ParseStreamAsync(Stream stream, string boundary, Encoding encoding, int binaryBufferSize, string[] binaryMimeTypes)
354315
{
355-
Files = new List<FilePart>();
356-
Parameters = new List<ParameterPart>();
357-
358316
var streamingParser = new StreamingMultipartFormDataParser(stream, boundary, encoding ?? Encoding.UTF8, binaryBufferSize, binaryMimeTypes);
359-
streamingParser.ParameterHandler += parameterPart => Parameters.Add(parameterPart);
317+
streamingParser.ParameterHandler += parameterPart => _parameters.Add(parameterPart);
360318

361319
streamingParser.FileHandler += (name, fileName, type, disposition, buffer, bytes, partNumber, additionalProperties) =>
362320
{
363321
if (partNumber == 0)
364322
{
365323
// create file with first partNo
366-
Files.Add(new FilePart(name, fileName, Utilities.MemoryStreamManager.GetStream($"{typeof(MultipartFormDataParser).FullName}.{nameof(ParseStreamAsync)}"), additionalProperties, type, disposition));
324+
_files.Add(new FilePart(name, fileName, Utilities.MemoryStreamManager.GetStream($"{typeof(MultipartFormDataParser).FullName}.{nameof(ParseStreamAsync)}"), additionalProperties, type, disposition));
367325
}
368326

369327
Files[Files.Count - 1].Data.Write(buffer, 0, bytes);

0 commit comments

Comments
 (0)