/// <summary> /// Takes all of the data in the stream and returns it as an array of bytes /// </summary> /// <param name="Input">Input stream</param> /// <returns>A byte array</returns> public static byte[] ReadAllBinary(this Stream Input) { Input.ThrowIfNull("Input"); if (Input is MemoryStream) { return(((MemoryStream)Input).ToArray()); } byte[] Buffer = new byte[1024]; byte[] ReturnValue = null; using (MemoryStream Temp = new MemoryStream()) { while (true) { int Count = Input.Read(Buffer, 0, Buffer.Length); if (Count <= 0) { ReturnValue = Temp.ToArray(); break; } Temp.Write(Buffer, 0, Count); } Temp.Close(); } return(ReturnValue); }
/// <summary> /// Uploads a provided file to the target parent folder /// If the file already exists, an error will be thrown /// </summary> /// <param name="fileRequest"></param> /// <param name="stream"></param> /// <returns></returns> public async Task<BoxFile> UploadAsync(BoxFileRequest fileRequest, Stream stream, List<string> fields = null) { stream.ThrowIfNull("stream"); fileRequest.ThrowIfNull("fileRequest") .Name.ThrowIfNullOrWhiteSpace("filedRequest.Name"); fileRequest.Parent.ThrowIfNull("fileRequest.Parent") .Id.ThrowIfNullOrWhiteSpace("fileRequest.Parent.Id"); BoxMultiPartRequest request = new BoxMultiPartRequest(_config.FilesUploadEndpointUri) .Param(ParamFields, fields) .FormPart(new BoxStringFormPart() { Name = "metadata", Value = _converter.Serialize(fileRequest) }) .FormPart(new BoxFileFormPart() { Name = "file", Value = stream, FileName = fileRequest.Name }); IBoxResponse<BoxCollection<BoxFile>> response = await ToResponseAsync<BoxCollection<BoxFile>>(request).ConfigureAwait(false); // We can only upload one file at a time, so return the first entry return response.ResponseObject.Entries.FirstOrDefault(); }
/// <summary> /// Publishes the image data provided by the specified stream as the user's /// avatar. /// </summary> /// <param name="stream">A stream containing the image data to publish as /// the user's avatar.</param> /// <exception cref="ArgumentNullException">The stream parameter is /// null.</exception> /// <exception cref="ArgumentException">The stream does not have a valid /// image format.</exception> /// <exception cref="NotSupportedException">The server does not support /// the 'Personal Eventing Protocol' extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public void Publish(Stream stream) { stream.ThrowIfNull("stream"); using (Image image = Image.FromStream(stream)) { string mimeType = GetMimeType(image); int width = image.Width; int height = image.Height; long size = 0; string hash = String.Empty, base64Data = String.Empty; using (var ms = new MemoryStream()) { image.Save(ms, image.RawFormat); size = ms.Length; // Calculate the SHA-1 hash of the image data. byte[] data = ms.ToArray(); hash = Hash(data); // Convert the binary data into a BASE64-string. base64Data = Convert.ToBase64String(data); } // Publish the image- and meta data. pep.Publish("urn:xmpp:avatar:data", hash, Xml.Element("data", "urn:xmpp:avatar:data").Text(base64Data)); pep.Publish("urn:xmpp:avatar:metadata", hash, Xml.Element("metadata", "urn:xmpp:avatar:metadata").Child( Xml.Element("info") .Attr("bytes", size.ToString()) .Attr("height", height.ToString()) .Attr("width", width.ToString()) .Attr("id", hash) .Attr("type", mimeType)) ); } }
/// <summary> /// Initializes a new instance of the SISession class. /// </summary> /// <param name="sid">The identifier of the session.</param> /// <param name="stream">The IO-stream from which data is read, or to /// which data is written.</param> /// <param name="size">The total number of bytes to read from, or to /// write to the stream.</param> /// <param name="receiving">true if data is being received over the session; /// Otherwise false.</param> /// <param name="from">The JID of the XMPP entity that wishes to send data.</param> /// <param name="to">The JID of the XMPP entity that wishes to receive /// data.</param> /// <param name="extension">The instance of the data-stream extension /// negotiated during session-initiation.</param> /// <exception cref="ArgumentNullException">The sid parameter or the stream /// parameter or the from parameter or the to parameter or the extension /// parameter is null.</exception> /// <exception cref="ArgumentException">The receiving parameter is true, but /// the specified stream cannot be written, or the receiving parameter is /// false, but the specified stream cannot be read.</exception> /// <exception cref="ArgumentOutOfRangeException">The size parameter is /// negative.</exception> public SISession(string sid, Stream stream, long size, bool receiving, Jid from, Jid to, IDataStream extension) { sid.ThrowIfNull("sid"); stream.ThrowIfNull("stream"); size.ThrowIfOutOfRange(0, Int64.MaxValue); from.ThrowIfNull("from"); to.ThrowIfNull("to"); extension.ThrowIfNull("extension"); if (receiving && !stream.CanWrite) { throw new ArgumentException("The specified stream cannot be written."); } if (!receiving && !stream.CanRead) { throw new ArgumentException("The specified stream cannot be read."); } Sid = sid; Stream = stream; Size = size; Count = 0; Receiving = receiving; From = from; To = to; Extension = extension; }
/// <summary> /// Deserializes an object. /// </summary> /// <typeparam name="T">Target type.</typeparam> /// <param name="stream">The stream that contains the JSON string.</param> /// <param name="enc">The charset to use the JSON string is encoded by.</param> /// <returns>The deserialized object.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="stream" /> and/or <paramref name="enc" /> are <see langword="null" />. /// </exception> public static T Deserialize <T>(Stream stream, Encoding enc) { stream.ThrowIfNull(() => stream); MemoryStream ms = null; var disposeMs = false; try { ms = stream as MemoryStream; if (ms == null) { disposeMs = true; ms = new MemoryStream(); stream.CopyTo(ms); } return(Deserialize <T>(enc.GetString(ms.ToArray()))); } finally { if (ms != null && disposeMs) { ms.Dispose(); } } }
/// <summary> /// Uploads a provided file to the target parent folder /// If the file already exists, an error will be thrown. /// A proper timeout should be provided for large uploads /// </summary> /// <param name="fileRequest"></param> /// <param name="stream"></param> /// <param name="fields"></param> /// <param name="timeout"></param> /// <returns></returns> public async Task <BoxFile> UploadAsync(BoxFileRequest fileRequest, Stream stream, List <string> fields = null, TimeSpan?timeout = null) { stream.ThrowIfNull("stream"); fileRequest.ThrowIfNull("fileRequest") .Name.ThrowIfNullOrWhiteSpace("filedRequest.Name"); fileRequest.Parent.ThrowIfNull("fileRequest.Parent") .Id.ThrowIfNullOrWhiteSpace("fileRequest.Parent.Id"); BoxMultiPartRequest request = new BoxMultiPartRequest(_config.FilesUploadEndpointUri) { Timeout = timeout } .Param(ParamFields, fields) .FormPart(new BoxStringFormPart() { Name = "metadata", Value = _converter.Serialize(fileRequest) }) .FormPart(new BoxFileFormPart() { Name = "file", Value = stream, FileName = fileRequest.Name }); IBoxResponse <BoxCollection <BoxFile> > response = await ToResponseAsync <BoxCollection <BoxFile> >(request).ConfigureAwait(false); // We can only upload one file at a time, so return the first entry return(response.ResponseObject.Entries.FirstOrDefault()); }
//http://www.xmpp.org/extensions/xep-0153.html public void SetAvatar(Stream stream) { stream.ThrowIfNull("stream"); string mimeType = "image/png"; string hash = String.Empty, base64Data = String.Empty; MemoryStream ms = new MemoryStream(); stream.CopyTo(ms); using (ms) { // await image.Save(Splat.CompressedBitmapFormat.Jpeg,1, ms); // // Calculate the SHA-1 hash of the image data. byte[] data = ms.ToArray(); hash = Hash(data); // // Convert the binary data into a BASE64-string. base64Data = Convert.ToBase64String(data); } var xml = Xml.Element("vCard", "vcard-temp").Child(Xml.Element("Photo").Child(Xml.Element("Type").Text(mimeType)).Child(Xml.Element("BINVAL").Text(base64Data))); im.IqRequestAsync(IqType.Set, null, im.Jid, xml, null, (id, iq) => { if (iq.Type == IqType.Result) { // Result must contain a 'feature' element. im.SendPresence(new Sharp.Xmpp.Im.Presence(null, null, PresenceType.Available, null, null, Xml.Element("x", "vcard-temp:x:update").Child(Xml.Element("photo").Text(hash)))); } }); //var result = im.IqRequest(IqType.Set, null, im.Jid, xml); // }
/// <summary> /// Detect Shapes /// </summary> /// <param name="imageStream">Image Stream</param> /// <returns>Results Received from the Computer Vision Service</returns> public async Task <DetectResult> DetectShapes(Stream imageStream) { imageStream.ThrowIfNull(nameof(imageStream)); var result = await _client.DetectObjectsInStreamAsync(imageStream); return(result); }
public static string Decompress([NotNull] Stream stream, Encoding?encoding, bool leaveOpen = false) { stream.ThrowIfNull(nameof(stream)); encoding ??= Encoding.ASCII; return(encoding.GetString(Decompress(stream, leaveOpen))); }
public static async Task CopyToAsync(this Stream source, string fileName) { source.ThrowIfNull(nameof(source)); using var file = File.Create(fileName); await source.CopyToAsync(file); await file.FlushAsync(); }
public void Serialize(Stream stream) { stream.ThrowIfNull("stream"); var serializer = new XmlSerializer(typeof(ActionResult)); serializer.Serialize(stream, this); }
/// <summary> /// Add data to the storage /// </summary> /// <param name="key">Unique identifier of the stream, cannot be null or empty</param> /// <param name="data">Non empty stream with data, cannot be null or empty </param> /// <param name="parameters">Optional parameters. Instead of null use StreamInfo.Empty</param> /// <exception cref="System.ArgumentException"> /// An element with the same key already exists or /// provided hash or length does not match the data. /// </exception> /// <exception cref="System.ArgumentNullException"> /// key is null, data is null, parameters is null /// </exception> /// <exception cref="System.IO.IOException"> /// I/O exception occurred during persisting data /// </exception> public void Add(string key, Stream data, StreamInfo parameters) { key.ThrowIfNull(nameof(key)); data.ThrowIfNull(nameof(data)); parameters.ThrowIfNull(nameof(parameters)); storageFileAppender.Write(data, key, parameters, cancellationOnDispose.Token); }
public static void AppendFileName(Stream stream, string fileName) { fileName.ThrowIfEmptyString(); stream.ThrowIfNull(); WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream"; WebOperationContext.Current.OutgoingResponse.ContentLength = stream.Length; WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "attachment;filename=" + Uri.EscapeUriString(fileName)); }
private static void RewindStream(this Stream stream) { stream.ThrowIfNull("Input stream cannot ne null."); if (stream.CanSeek) { stream.Position = 0; } }
/// <summary> /// Creates a <see cref="ResumableUpload"/> instance. /// </summary> /// <param name="contentStream">The data to be uploaded. Must not be null.</param> /// <param name="options">The options for the upload operation. May be null.</param> protected ResumableUpload(Stream contentStream, ResumableUploadOptions options) { contentStream.ThrowIfNull(nameof(contentStream)); ContentStream = contentStream; // Check if the stream length is known. StreamLength = ContentStream.CanSeek ? ContentStream.Length : UnknownSize; HttpClient = options?.ConfigurableHttpClient ?? new ConfigurableHttpClient(new ConfigurableMessageHandler(new HttpClientHandler())); Options = options; }
public User Deserialize(Stream source) { source.ThrowIfNull(nameof(source)); using (var streamReader = new StreamReader(source)) { return((User)JsonSerializer.CreateDefault().Deserialize(streamReader, typeof(User))); } }
public ProgressStreamContent(Stream content, IProgress <int> progress, int bufferSize, CancellationToken cancellationToken) { content.ThrowIfNull(nameof(content)); bufferSize.ThrowIf(b => b <= 0, () => new ArgumentOutOfRangeException(nameof(bufferSize))); _content = content; _progress = progress; _bufferSize = bufferSize; _cancellationToken = CancellationToken.None; }
/// <summary> /// Completely reads a stream from its current position and returns the data as an array of bytes. /// </summary> /// <param name="stream">The stream to read.</param> /// <returns>Array of bytes from the stream.</returns> public static byte[] ReadFully(this Stream stream) { stream.ThrowIfNull("stream"); using (var ms = new MemoryStream()) { stream.CopyTo(ms); return(ms.ToArray()); } }
public void Serialize(Stream destination, User obj) { destination.ThrowIfNull(nameof(destination)); obj.ThrowIfNull(nameof(obj)); using (var streamWriter = new StreamWriter(destination, Encoding.UTF8, 1024, true)) { JsonSerializer.CreateDefault().Serialize(streamWriter, obj); } }
private static void CheckParameters(Stream source, Stream destination, byte[] key) { source.ThrowIfNull(nameof(source)); destination.ThrowIfNull(nameof(destination)); key.ThrowIfNull(nameof(key)); if (key.Length != RequiredKeySize) { throw new ArgumentException("Invalid key size", nameof(key)); } }
public static byte[] Decompress([NotNull] Stream stream, bool leaveOpen = false) { stream.ThrowIfNull(nameof(stream)); stream.Position = 0; using GZipStream gZipStream = new(stream, CompressionMode.Decompress, leaveOpen); using MemoryStream outputStream = new(); gZipStream.CopyTo(outputStream); return(outputStream.GetBuffer()); }
public void Serialize(Stream destination) { destination.ThrowIfNull(nameof(destination)); var saltSize = BitConverter.GetBytes(kdf.salt.Length); var iterations = BitConverter.GetBytes(kdf.iterations); destination.Write(saltSize, 0, saltSize.Length); destination.Write(kdf.salt, 0, kdf.salt.Length); destination.Write(iterations, 0, iterations.Length); }
public async Task <T> Deserialize <T> (Stream data) { data.ThrowIfNull("data"); return(await Task.Run(() => { var serializer = new XmlSerializer(typeof(T)); var obj = (T)serializer.Deserialize(new StreamReader(data)); return obj; })); }
/// <summary> /// Creates a <see cref="ResumableUpload"/> instance. /// </summary> /// <param name="contentStream">The data to be uploaded. Must not be null.</param> /// <param name="options">The options for the upload operation. May be null.</param> protected ResumableUpload(Stream contentStream, ResumableUploadOptions options) { contentStream.ThrowIfNull(nameof(contentStream)); ContentStream = contentStream; // Check if the stream length is known. StreamLength = ContentStream.CanSeek ? ContentStream.Length : UnknownSize; HttpClient = options?.ConfigurableHttpClient ?? new HttpClientFactory().CreateHttpClient(new CreateHttpClientArgs { ApplicationName = "ResumableUpload", GZipEnabled = true }); Options = options; }
/// <summary> /// Copies the contents of input to output. Doesn't close either stream. /// </summary> public static MemoryStream Copy([NotNull] this Stream source) { source.ThrowIfNull(nameof(source)); source.Position = 0; MemoryStream result = new(); source.CopyTo(result); result.Position = 0; return(result); }
public static T Read <T>([NotNull] this Stream source, int offset) where T : struct { source.ThrowIfNull(nameof(source)); T result = default; var size = Marshal.SizeOf(result); var data = new byte[size]; source.Read(data, offset, size); return(data.ToStruct <T>()); }
internal NpkReader(Stream npkStream, bool disposeStream, Action <object, ErrorDetectedEventArgs> extraErrorHandler) { if (extraErrorHandler != null) { DoExtraErrorChecks = true; ErrorDetected += extraErrorHandler; } npkStream.ThrowIfNull("npkStream"); m_npkStream = npkStream; m_disposeStream = disposeStream; Initialize(); }
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { stream.ThrowIfNull(nameof(stream)); TrySeekContentToStart(); if (stream.CanWrite) { return(_content.ProgressCopyToAsync(stream, _progress, _bufferSize, _cancellationToken)); } return(Task.FromResult(false)); }
/// <summary> /// Initializes a new instance of the StreamParser class for the specified /// stream. /// </summary> /// <param name="stream">The stream to read the XML data from.</param> /// <param name="leaveOpen">true to leave the stream open when the StreamParser /// instance is closed, otherwise false.</param> /// <exception cref="ArgumentNullException">The stream parameter is /// null.</exception> /// <exception cref="XmlException">The parser has encountered invalid /// or unexpected XML data.</exception> /// <exception cref="CultureNotFoundException">The culture specified by the /// XML-stream in it's 'xml:lang' attribute could not be found.</exception> public StreamParser(Stream stream, bool leaveOpen = false) { stream.ThrowIfNull("stream"); this.leaveOpen = leaveOpen; this.stream = stream; reader = XmlReader.Create(stream, new XmlReaderSettings() { // Ignore restricted XML data (Refer to RFC 3920, 11.1 Restrictions). IgnoreProcessingInstructions = true, IgnoreComments = true, IgnoreWhitespace = true }); // Read up to the opening stream tag. ReadRootElement(); }
/// <summary> /// Create a resumable upload instance with the required parameters. /// </summary> /// <param name="service">The client service.</param> /// <param name="path">The path for this media upload method.</param> /// <param name="httpMethod">The HTTP method to start this upload.</param> /// <param name="contentStream">The stream containing the content to upload.</param> /// <param name="contentType">Content type of the content to be uploaded. Some services /// may allow this to be null; others require a content type to be specified and will /// fail when the upload is started if the value is null.</param> /// <remarks> /// Caller is responsible for maintaining the <paramref name="contentStream"/> open until the upload is /// completed. /// Caller is responsible for closing the <paramref name="contentStream"/>. /// </remarks> protected ResumableUpload(IClientService service, string path, string httpMethod, Stream contentStream, string contentType) { service.ThrowIfNull(nameof(service)); path.ThrowIfNull(nameof(path)); httpMethod.ThrowIfNullOrEmpty(nameof(httpMethod)); contentStream.ThrowIfNull(nameof(contentStream)); this.Service = service; this.Path = path; this.HttpMethod = httpMethod; this.ContentStream = contentStream; this.ContentType = contentType; }
/// <summary> /// Adds a StreamContent to the request. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="request">The request.</param> /// <param name="stream">The stream to be added.</param> /// <param name="mediaType">The media type of the stream.</param> /// <param name="buffersize">The buffer size used to process the stream. Default is 1024.</param> /// <param name="name">A name needed when content is a MultipartFormDataContent already.</param> /// <param name="fileName">A file name needed when content is a MultipartFormDataContent already.</param> /// <returns> /// this. /// </returns> public static T AddStream <T>(this T request, Stream stream, string mediaType, int buffersize = 1024, string name = "", string fileName = "") where T : RestRequest { stream.ThrowIfNull("stream"); mediaType.ThrowIfNullOrEmpty("mediaType"); buffersize.ThrowIf(b => b <= 0, "bufferSize"); var content = new StreamContent(stream, buffersize); content.Headers.ContentType = new MediaTypeHeaderValue(mediaType); return(request.AddContent(content, name, fileName)); }
/// <summary> /// Uploads a binary (file) stream using StreamContent. /// </summary> /// <typeparam name="T">The type of the deserialized data. Set to IVoid if no deserialization is wanted.</typeparam> /// <param name="request">The request.</param> /// <param name="streamContent">The (file) stream that will be uploaded.</param> /// <param name="contentType">The file content type.</param> /// <param name="successAction">Action that is called on success. (No exceptions and HttpStatus code is ok).</param> /// <param name="errorAction">Action that is called when an error occures. (Exceptions or HttpStatus code not ok).</param> /// <returns> /// A taks containing the RestResponse with the deserialized data if T is not IVoid and no error occured. /// </returns> public static async Task <RestResponse <T> > UploadFileBinary <T>( this RestRequest request, Stream streamContent, string contentType, Action <RestResponse <T> > successAction = null, Action <RestResponse <T> > errorAction = null) { streamContent.ThrowIfNull("fileStream"); contentType.ThrowIfNullOrEmpty("contentType"); request.AddStream(streamContent, contentType); return(await request.BuildAndSendRequest(successAction, errorAction)); }
/// <summary> /// Copies <paramref name="numBytes"/> bytes from <paramref name="input"/> to <paramref name="output"/>. /// </summary> /// <param name="input"></param> /// <param name="output"></param> /// <param name="numBytes"></param> public static void CopyToPartially(this Stream input, Stream output, int numBytes) { if (numBytes < 0) { throw new ArgumentOutOfRangeException("numBytes", numBytes, "Cannot copy a negative number of bytes ({0}).".F(numBytes)); } input.ThrowIfNull("input"); output.ThrowIfNull("output"); const int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; int numBytesCopied = 0; while (numBytesCopied < numBytes) { int numBytesToRead = bufferSize; if (numBytes - numBytesCopied < bufferSize) { numBytesToRead = numBytes - numBytesCopied; } input.ReadOrDie(buffer, numBytesToRead); output.Write(buffer, 0, numBytesToRead); numBytesCopied += numBytesToRead; } }
/// <summary> /// The core download logic. It downloads the media in parts, where each part's size is defined by /// <see cref="ChunkSize"/> (in bytes). /// </summary> /// <param name="url">The URL of the resource to download.</param> /// <param name="stream">The download will download the resource into this stream.</param> /// <param name="cancellationToken">A cancellation token to cancel this download in the middle.</param> /// <returns>A task with the download progress object. If an exception occurred during the download, its /// <see cref="IDownloadProgress.Exception "/> property will contain the exception.</returns> private async Task<IDownloadProgress> DownloadCoreAsync(string url, Stream stream, CancellationToken cancellationToken) { url.ThrowIfNull("url"); stream.ThrowIfNull("stream"); if (!stream.CanWrite) { throw new ArgumentException("stream doesn't support write operations"); } RequestBuilder builder = null; var uri = new Uri(url); if (string.IsNullOrEmpty(uri.Query)) { builder = new RequestBuilder() { BaseUri = new Uri(url) }; } else { builder = new RequestBuilder() { BaseUri = new Uri(url.Substring(0, url.IndexOf("?"))) }; // Remove '?' at the beginning. var query = uri.Query.Substring(1); var pairs = from parameter in query.Split('&') select parameter.Split('='); // Add each query parameter. each pair contains the key [0] and then its value [1]. foreach (var p in pairs) { builder.AddParameter(RequestParameterType.Query, p[0], p[1]); } } builder.AddParameter(RequestParameterType.Query, "alt", "media"); long currentRequestFirstBytePos = 0; try { // This "infinite" loop stops when the "to" byte position in the "Content-Range" header is the last // byte of the media ("length"-1 in the "Content-Range" header). // e.g. "Content-Range: 200-299/300" - "to"(299) = "length"(300) - 1. while (true) { var currentRequestLastBytePos = currentRequestFirstBytePos + ChunkSize - 1; // Create the request and set the Range header. var request = builder.CreateRequest(); request.Headers.Range = new RangeHeaderValue(currentRequestFirstBytePos, currentRequestLastBytePos); using (var response = await service.HttpClient.SendAsync(request, cancellationToken). ConfigureAwait(false)) { // Read the content and copy to the parameter's stream. var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); responseStream.CopyTo(stream); // Read the headers and check if all the media content was already downloaded. var contentRange = response.Content.Headers.ContentRange; long mediaContentLength; if (contentRange == null) { // Content range is null when the server doesn't adhere the media download protocol, in // that case we got all the media in one chunk. currentRequestFirstBytePos = mediaContentLength = response.Content.Headers.ContentLength.Value; } else { currentRequestFirstBytePos = contentRange.To.Value + 1; mediaContentLength = contentRange.Length.Value; } if (currentRequestFirstBytePos == mediaContentLength) { var progress = new DownloadProgress(DownloadStatus.Completed, mediaContentLength); UpdateProgress(progress); return progress; } } UpdateProgress(new DownloadProgress(DownloadStatus.Downloading, currentRequestFirstBytePos)); } } catch (TaskCanceledException ex) { Logger.Error(ex, "Download media was canceled"); UpdateProgress(new DownloadProgress(ex, currentRequestFirstBytePos)); throw ex; } catch (Exception ex) { Logger.Error(ex, "Exception occurred while downloading media"); var progress = new DownloadProgress(ex, currentRequestFirstBytePos); UpdateProgress(progress); return progress; } }
/// <summary> /// The core download logic. We download the media and write it to an output stream /// ChunkSize bytes at a time, raising the ProgressChanged event after each chunk. /// /// The chunking behavior is largely a historical artifact: a previous implementation /// issued multiple web requests, each for ChunkSize bytes. Now we do everything in /// one request, but the API and client-visible behavior are retained for compatibility. /// </summary> /// <param name="url">The URL of the resource to download.</param> /// <param name="stream">The download will download the resource into this stream.</param> /// <param name="cancellationToken">A cancellation token to cancel this download in the middle.</param> /// <returns>A task with the download progress object. If an exception occurred during the download, its /// <see cref="IDownloadProgress.Exception "/> property will contain the exception.</returns> private async Task<IDownloadProgress> DownloadCoreAsync(string url, Stream stream, CancellationToken cancellationToken) { url.ThrowIfNull("url"); stream.ThrowIfNull("stream"); if (!stream.CanWrite) { throw new ArgumentException("stream doesn't support write operations"); } // Add alt=media to the query parameters. var uri = new UriBuilder(url); if (uri.Query == null || uri.Query.Length <= 1) { uri.Query = "alt=media"; } else { // Remove the leading '?'. UriBuilder.Query doesn't round-trip. uri.Query = uri.Query.Substring(1) + "&alt=media"; } var request = new HttpRequestMessage(HttpMethod.Get, uri.ToString()); // Number of bytes sent to the caller's stream. long bytesReturned = 0; try { // Signal SendAsync to return as soon as the response headers are read. // We'll stream the content ourselves as it becomes available. var completionOption = HttpCompletionOption.ResponseHeadersRead; using (var response = await service.HttpClient.SendAsync(request, completionOption, cancellationToken).ConfigureAwait(false)) { if (!response.IsSuccessStatusCode) { throw await MediaApiErrorHandling.ExceptionForResponseAsync(service, response).ConfigureAwait(false); } using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { // We send ChunkSize bytes at a time to the caller, but we keep ChunkSize + 1 bytes // buffered. That way we can tell when we've reached the end of the response, even if the // response length is evenly divisible by ChunkSize, and we can avoid sending a Downloading // event followed by a Completed event with no bytes downloaded in between. // // This maintains the client-visible behavior of a previous implementation. var buffer = new CountedBuffer(ChunkSize + 1); while (true) { await buffer.Fill(responseStream, cancellationToken).ConfigureAwait(false); // Send one chunk to the caller's stream. int bytesToReturn = Math.Min(ChunkSize, buffer.Count); await stream.WriteAsync(buffer.Data, 0, bytesToReturn, cancellationToken).ConfigureAwait(false); bytesReturned += bytesToReturn; buffer.RemoveFromFront(ChunkSize); if (buffer.IsEmpty) { // We had <= ChunkSize bytes buffered, so we've read and returned the entire response. // Skip sending a Downloading event. We'll send Completed instead. break; } UpdateProgress(new DownloadProgress(DownloadStatus.Downloading, bytesReturned)); } } var finalProgress = new DownloadProgress(DownloadStatus.Completed, bytesReturned); UpdateProgress(finalProgress); return finalProgress; } } catch (TaskCanceledException ex) { Logger.Error(ex, "Download media was canceled"); UpdateProgress(new DownloadProgress(ex, bytesReturned)); throw; } catch (Exception ex) { Logger.Error(ex, "Exception occurred while downloading media"); var progress = new DownloadProgress(ex, bytesReturned); UpdateProgress(progress); return progress; } }
/// <summary> /// Uploads a provided file to the target parent folder. /// If the file already exists, an error will be thrown. /// A proper timeout should be provided for large uploads. /// </summary> /// <param name="fileRequest">BoxFileRequest object.</param> /// <param name="stream">Stream of uploading file.</param> /// <param name="fields">Fields which shall be returned in result.</param> /// <param name="timeout">Timeout for response.</param> /// <param name="contentMD5">The SHA1 hash of the file.</param> /// <param name="setStreamPositionToZero">Set position for input stream to 0.</param> /// <param name="uploadUri">Uri to use for upload. Default upload endpoint URI is used if not specified.</param> /// <returns>A full file object is returned inside of a collection if the ID is valid and if the update is successful.</returns> public async Task<BoxFile> UploadAsync(BoxFileRequest fileRequest, Stream stream, List<string> fields = null, TimeSpan? timeout = null, byte[] contentMD5 = null, bool setStreamPositionToZero = true, Uri uploadUri = null) { stream.ThrowIfNull("stream"); fileRequest.ThrowIfNull("fileRequest") .Name.ThrowIfNullOrWhiteSpace("filedRequest.Name"); fileRequest.Parent.ThrowIfNull("fileRequest.Parent") .Id.ThrowIfNullOrWhiteSpace("fileRequest.Parent.Id"); if (setStreamPositionToZero) stream.Position = 0; uploadUri = uploadUri == null ? _config.FilesUploadEndpointUri : uploadUri; BoxMultiPartRequest request = new BoxMultiPartRequest(uploadUri) { Timeout = timeout } .Param(ParamFields, fields) .FormPart(new BoxStringFormPart() { Name = "attributes", Value = _converter.Serialize(fileRequest) }) .FormPart(new BoxFileFormPart() { Name = "file", Value = stream, FileName = fileRequest.Name }); if (contentMD5 != null) request.Header(Constants.RequestParameters.ContentMD5, HexStringFromBytes(contentMD5)); IBoxResponse<BoxCollection<BoxFile>> response = await ToResponseAsync<BoxCollection<BoxFile>>(request).ConfigureAwait(false); // We can only upload one file at a time, so return the first entry return response.ResponseObject.Entries.FirstOrDefault(); }
/// <summary> /// Creates a service factory for the discovery version requested, with the given parameters /// </summary> /// <param name="discovery">A stream which contains information about the service to construct</param> /// <param name="version">The discovery version to use</param> /// <param name="parameters"> /// A set of (optional) factory parameters used to construct the service. /// If this parameter is null, then a default set of FactoryParameters is created /// </param> public static IServiceFactory CreateServiceFactory(Stream discovery, DiscoveryVersion version, IFactoryParameter parameters) { discovery.ThrowIfNull("discovery"); version.ThrowIfNull("version"); JsonDictionary information = JsonReader.Parse(discovery) as JsonDictionary; switch (version) { case DiscoveryVersion.Version_0_3: return new ServiceFactoryDiscoveryV0_3( information, (FactoryParameterV0_3) (parameters ?? new FactoryParameterV0_3())); case DiscoveryVersion.Version_1_0: return new ServiceFactoryDiscoveryV1_0( information, (FactoryParameterV1_0) (parameters ?? new FactoryParameterV1_0())); default: throw new NotSupportedException("The Version " + version + " is not supported"); } }
/// <summary> /// This method is used to upload a new version of an existing file in a user’s account. Similar to regular file uploads, /// these are performed as multipart form uploads. An optional If-Match header can be included to ensure that client only /// overwrites the file if it knows about the latest version. The filename on Box will remain the same as the previous version. /// To update the file’s name, you can specify a new name for the file using the fileName parameter. /// A proper timeout should be provided for large uploads. /// </summary> /// <param name="fileName">Name of the file.</param> /// <param name="fileId">Id of the file to upload a new version to.</param> /// <param name="stream">Stream of the uploading file.</param> /// <param name="etag">This ‘etag’ field of the file, which will be set in the If-Match header.</param> /// <param name="fields">Fields which shall be returned in result.</param> /// <param name="timeout">Optional timeout for response.</param> /// <param name="contentMD5">The SHA1 hash of the file.</param> /// <param name="setStreamPositionToZero">Set position for input stream to 0.</param> /// <param name="uploadUri">Optional url for uploading file.</param> /// <returns>A full file object is returned.</returns> public async Task<BoxFile> UploadNewVersionAsync(string fileName, string fileId, Stream stream, string etag = null, List<string> fields = null, TimeSpan? timeout = null, byte[] contentMD5 = null, bool setStreamPositionToZero = true, Uri uploadUri = null) { fileName.ThrowIfNullOrWhiteSpace("fileName"); fileId.ThrowIfNullOrWhiteSpace("fileId"); stream.ThrowIfNull("stream"); if (setStreamPositionToZero) stream.Position = 0; uploadUri = uploadUri == null ? new Uri(string.Format(Constants.FilesNewVersionEndpointString, fileId)) : uploadUri; BoxMultiPartRequest request = new BoxMultiPartRequest(uploadUri) { Timeout = timeout } .Header(Constants.RequestParameters.IfMatch, etag) .Param(ParamFields, fields) .FormPart(new BoxFileFormPart() { Name = "filename", Value = stream, FileName = fileName }); if (contentMD5 != null) request.Header(Constants.RequestParameters.ContentMD5, HexStringFromBytes(contentMD5)); IBoxResponse<BoxCollection<BoxFile>> response = await ToResponseAsync<BoxCollection<BoxFile>>(request).ConfigureAwait(false); // We can only upload one file at a time, so return the first entry return response.ResponseObject.Entries.FirstOrDefault(); }
internal NpkReader(Stream npkStream, bool disposeStream, Action<object, ErrorDetectedEventArgs> extraErrorHandler) { if (extraErrorHandler != null) { DoExtraErrorChecks = true; ErrorDetected += extraErrorHandler; } npkStream.ThrowIfNull("npkStream"); m_npkStream = npkStream; m_disposeStream = disposeStream; Initialize(); }
/// <summary> /// This method is used to upload a new version of an existing file in a user’s account. Similar to regular file uploads, /// these are performed as multipart form uploads An optional If-Match header can be included to ensure that client only /// overwrites the file if it knows about the latest version. The filename on Box will remain the same as the previous version. /// </summary> /// <param name="fileName"></param> /// <param name="stream"></param> /// <param name="etag"></param> /// <returns></returns> public async Task<BoxFile> UploadNewVersionAsync(string fileName, string fileId, Stream stream, string etag = null, List<string> fields = null) { stream.ThrowIfNull("stream"); fileName.ThrowIfNullOrWhiteSpace("fileName"); BoxMultiPartRequest request = new BoxMultiPartRequest(new Uri(string.Format(Constants.FilesNewVersionEndpointString, fileId))) .Header("If-Match", etag) .Param(ParamFields, fields) .FormPart(new BoxFileFormPart() { Name = "filename", Value = stream, FileName = fileName }); IBoxResponse<BoxCollection<BoxFile>> response = await ToResponseAsync<BoxCollection<BoxFile>>(request).ConfigureAwait(false); // We can only upload one file at a time, so return the first entry return response.ResponseObject.Entries.FirstOrDefault(); }
/// <summary> /// Offers the XMPP user with the specified JID the file with the specified /// name and, if accepted by the user, transfers the file using the supplied /// stream. /// </summary> /// <param name="to">The JID of the XMPP user to offer the file to.</param> /// <param name="stream">The stream to read the file-data from.</param> /// <param name="name">The name of the file, as offered to the XMPP user /// with the specified JID.</param> /// <param name="size">The number of bytes to transfer.</param> /// <param name="cb">A callback method invoked once the other site has /// accepted or rejected the file-transfer request.</param> /// <param name="description">A description of the file so the receiver can /// better understand what is being sent.</param> /// <returns>Sid of file transfer</returns> /// <exception cref="ArgumentNullException">The to parameter or the stream /// parameter or the name parameter is null.</exception> /// <exception cref="ArgumentOutOfRangeException">The value of the size /// parameter is negative.</exception> /// <exception cref="NotSupportedException">The XMPP entity with the /// specified JID does not support the 'SI File Transfer' XMPP /// extension.</exception> /// <exception cref="XmppErrorException">The server or the XMPP entity /// with the specified JID returned an XMPP error code. Use the Error /// property of the XmppErrorException to obtain the specific error /// condition.</exception> /// <exception cref="XmppException">The server returned invalid data or /// another unspecified XMPP error occurred.</exception> public string InitiateFileTransfer(Jid to, Stream stream, string name, long size, string description = null, Action<bool, FileTransfer> cb = null) { to.ThrowIfNull("to"); stream.ThrowIfNull("stream"); name.ThrowIfNull("name"); size.ThrowIfOutOfRange(0, Int64.MaxValue); //FIXME FIXME //if (!ecapa.Supports(to, Extension.SIFileTransfer)) { // throw new NotSupportedException("The XMPP entity does not support the " + // "'SI File Transfer' extension."); //} //FIXME FIXME // Perform stream-initiation asynchronously so that the caller is not // blocked until the other site has either accepted or rejected our offer. return InitiateStreamAsync(to, name, size, description, (result, iq) => { OnInitiationResult(result, to, name, stream, size, description, cb); }); }
/// <summary> /// Initializes a new instance of the SISession class. /// </summary> /// <param name="sid">The identifier of the session.</param> /// <param name="stream">The IO-stream from which data is read, or to /// which data is written.</param> /// <param name="size">The total number of bytes to read from, or to /// write to the stream.</param> /// <param name="receiving">true if data is being received over the session; /// Otherwise false.</param> /// <param name="from">The JID of the XMPP entity that wishes to send data.</param> /// <param name="to">The JID of the XMPP entity that wishes to receive /// data.</param> /// <param name="extension">The instance of the data-stream extension /// negotiated during session-initiation.</param> /// <exception cref="ArgumentNullException">The sid parameter or the stream /// parameter or the from parameter or the to parameter or the extension /// parameter is null.</exception> /// <exception cref="ArgumentException">The receiving parameter is true, but /// the specified stream cannot be written, or the receiving parameter is /// false, but the specified stream cannot be read.</exception> /// <exception cref="ArgumentOutOfRangeException">The size parameter is /// negative.</exception> public SISession(string sid, Stream stream, long size, bool receiving, Jid from, Jid to, IDataStream extension) { sid.ThrowIfNull("sid"); stream.ThrowIfNull("stream"); size.ThrowIfOutOfRange(0, Int64.MaxValue); from.ThrowIfNull("from"); to.ThrowIfNull("to"); extension.ThrowIfNull("extension"); if (receiving && !stream.CanWrite) throw new ArgumentException("The specified stream cannot be written."); if (!receiving && !stream.CanRead) throw new ArgumentException("The specified stream cannot be read."); Sid = sid; Stream = stream; Size = size; Count = 0; Receiving = receiving; From = from; To = to; Extension = extension; }
/// <summary> /// Copies the input stream to the output stream. /// </summary> /// <param name="input"></param> /// <param name="output"></param> /// <exception cref="System.IO.IOException"></exception> /// <exception cref="System.NotSupportedException"></exception> /// <exception cref="System.ObjectDisposedException"></exception> /// <exception cref="System.ArgumentNullException"></exception> public static void CopyTo(this Stream input, Stream output) { output.ThrowIfNull("output"); const int bufferSize = 8192; byte[] buffer = new byte[bufferSize]; int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, read); } }