1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 
  9 namespace System.Net.Http
 10 {
 11     public class MediaType
 12     {
 13         public nothrow MediaType() : name()
 14         {
 15         }
 16         public nothrow MediaType(const string& name_) : name(name_)
 17         {
 18         }
 19         public virtual default ~MediaType();
 20         public inline nothrow const string& Name() const
 21         {
 22             return name;
 23         }
 24         public nothrow void SetName(const string& name_)
 25         {
 26             name = name_;
 27         }
 28         private string name;
 29     }
 30     
 31     public class AnyMediaType : MediaType
 32     {
 33         public nothrow AnyMediaType() : base("*")
 34         {
 35         }
 36     }
 37     
 38     public class Subtype
 39     {
 40         public nothrow Subtype() : name()
 41         {
 42         }
 43         public nothrow Subtype(const string& name_) : name(name_)
 44         {
 45         }
 46         public virtual default ~Subtype();
 47         public inline nothrow const string& Name() const
 48         {
 49             return name;
 50         }
 51         public nothrow void SetName(const string& name_)
 52         {
 53             name = name_;
 54         }
 55         private string name;
 56     }
 57     
 58     public class AnySubtype : Subtype
 59     {
 60         public nothrow AnySubtype() : base("*")
 61         {
 62         }
 63     }
 64     
 65     public class TextMediaType : MediaType
 66     {
 67         public nothrow TextMediaType() : base("text")
 68         {
 69         }
 70     }
 71     
 72     public class PlainSubtype : Subtype
 73     {
 74         public nothrow PlainSubtype() : base("plain")
 75         {
 76         }
 77     }
 78     
 79     public class ImageMediaType : MediaType
 80     {
 81         public nothrow ImageMediaType() : base("image")
 82         {
 83         }
 84     }
 85     
 86     public class JpegSubtype : Subtype
 87     {
 88         public nothrow JpegSubtype() : base("jpeg")
 89         {
 90         }
 91     }
 92     
 93     public class AudioMediaType : MediaType
 94     {
 95         public nothrow AudioMediaType() : base("audio")
 96         {
 97         }
 98     }
 99     
100     public class BasicSubtype : Subtype
101     {
102         public BasicSubtype() : base("basic")
103         {
104         }
105     }
106     
107     public class VideoMediaType : MediaType
108     {
109         public nothrow VideoMediaType() : base("video")
110         {
111         }
112     }
113     
114     public class MpegSubtype : Subtype
115     {
116         public nothrow MpegSubtype() : base("mpeg")
117         {
118         }
119     }
120     
121     public class ApplicationMediaType : MediaType
122     {
123         public nothrow ApplicationMediaType() : base("application")
124         {
125         }
126     }
127     
128     public class OctetStreamSubtype : Subtype
129     {
130         public nothrow OctetStreamSubtype() : base("octet-stream")
131         {
132         }
133     }
134     
135     public class PostScriptSubtype : Subtype
136     {
137         public nothrow PostScriptSubtype() : base("postscript")
138         {
139         }
140     }
141     
142     public class MultipartMediaType : MediaType
143     {
144         public nothrow MultipartMediaType() : base("multipart")
145         {
146         }
147     }
148     
149     public class MessageMediaType : MediaType
150     {
151         public nothrow MessageMediaType() : base("message")
152         {
153         }
154     }
155     
156     public class Rfc822Subtype : Subtype
157     {
158         public nothrow Rfc822Subtype() : base("rfc822")
159         {
160         }
161     }
162     
163     public class PartialSubtype : Subtype
164     {
165         public nothrow PartialSubtype() : base("partial")
166         {
167         }
168     }
169     
170     public class ExternalBodySubtype : Subtype
171     {
172         public nothrow ExternalBodySubtype() : base("external-body")
173         {
174         }
175     }
176     
177     public class MimeType
178     {
179         public MimeType() : mediaType(new AnyMediaType())subtype(new AnySubtype())
180         {
181         }
182         suppress MimeType(const MimeType&);
183         suppress void operator=(const MimeType&);
184         public MimeType(MimeType&& that)
185         {
186             mediaType.Reset(that.mediaType.Release());
187             subtype.Reset(that.subtype.Release());
188         }
189         public default void operator=(MimeType&&);
190         public MimeType(UniquePtr<MediaType>&& mediaType_) : mediaType(mediaType_)subtype(new AnySubtype())
191         {
192         }
193         public MimeType(UniquePtr<MediaType>&& mediaType_UniquePtr<Subtype>&& subtype_) : mediaType(mediaType_)subtype(subtype_)
194         {
195         }
196         public inline nothrow MediaType* GetMediaType() const
197         {
198             return mediaType.Get();
199         }
200         public inline nothrow Subtype* GetSubtype() const
201         {
202             return subtype.Get();
203         }
204         public void SetValue(const string& mediaType_const string& subtype_)
205         {
206             mediaType.Reset(new MediaType(mediaType_));
207             subtype.Reset(new Subtype(subtype_));
208         }
209         public inline nothrow const Map<stringstring>& Parameters() const
210         {
211             return parameters;
212         }
213         public string GetParameter(const string& paramName) const
214         {
215             Map<stringstring>.ConstIterator it = parameters.CFind(paramName);
216             if (it != parameters.CEnd())
217             {
218                 return it->second;
219             }
220             return string();
221         }
222         public void SetParameter(const string& paramNameconst string& paramValue)
223         {
224             parameters[paramName] = paramValue;
225         }
226         public string ToString() const
227         {
228             if (parameters.IsEmpty())
229             {
230                 return mediaType->Name() + "/" + subtype->Name();
231             }
232             else
233             {
234                 string s = mediaType->Name() + "/" + subtype->Name();
235                 for (const Pair<stringstring>& p : parameters)
236                 {
237                     string paramValue = p.second;
238                     if (paramValue.Find('"') != -1)
239                     {
240                         paramValue = MakeStringLiteral(paramValue);
241                     }
242                     s.Append(';').Append(p.first).Append('=').Append(paramValue);
243                 }
244                 return s;
245             }
246         }
247         private UniquePtr<MediaType> mediaType;
248         private UniquePtr<Subtype> subtype;
249         private Map<stringstring> parameters;
250     }
251     
252     public class MediaRange
253     {
254         public MediaRange() : mimeType()quality(1)
255         {
256         }
257         public MediaRange(MimeType&& mimeType_) : mimeType(mimeType_)quality(1)
258         {
259         }
260         public Map<stringstring>& Params()
261         {
262             return params;
263         }
264         public HttpFieldValue ToHttpFieldValue() const
265         {
266             if (quality == 1 && params.IsEmpty())
267             {
268                 return HttpFieldValue(mimeType.ToString());
269             }
270             else
271             {
272                 HttpFieldValue fieldValue(mimeType.ToString());
273                 if (quality != 1)
274                 {
275                     fieldValue.SetParameter("q"ToString(quality3));
276                 }
277                 for (const Pair<stringstring>& p : params)
278                 {
279                     fieldValue.SetParameter(p.firstp.second);
280                 }
281                 return fieldValue;
282             }
283         }
284         private MimeType mimeType;
285         private double quality;
286         private Map<stringstring> params;
287     }
288 }
289