/// <summary> /// Updates an existing object with the contents of the given stream, ACL, and /// metadata. /// </summary> /// <param name="id">the identifier of the object to update.</param> /// <param name="stream">the stream to replace the object's current /// contents with. The stream will be read until an EOF is encountered.</param> /// <param name="acl">the ACL to update the object with. Optional. If not /// specified, the ACL will not be modified.</param> /// <param name="metadata">The metadata to assign to the object. /// Optional. If null, no user metadata will be modified.</param> /// <param name="closeStream">If true, the stream will be closed after /// the object is updated.</param> public void UpdateObject( Identifier id, Stream stream, Acl acl, MetadataList metadata, bool closeStream ) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (computeChecksums) { checksum = new Checksum(Checksum.Algorithm.SHA0); } else { checksum = null; } // First call uses a null extent to truncate the file. try { bool eof = ReadChunk(); this.esu.UpdateObjectFromSegment( id, acl, metadata, null, buffer, contentType, checksum ); if ( !eof ) { this.OnProgress( buffer.Count ); } else { // No data in file? Complete this.OnComplete(); return; } // Continue appending this.AppendChunks( id ); } catch ( EsuException e ) { this.OnFail( e ); throw e; } catch ( IOException e ) { this.OnFail( e ); throw new EsuException( "Error updating object", e ); } }
/// <summary> /// Creates a new object on the server with the contents of the given stream, /// acl and metadata. /// </summary> /// <param name="path">The ObjectPath to create the object on.</param> /// <param name="stream">the stream to upload. The stream will be read until /// an EOF is encountered.</param> /// <param name="acl">the ACL to assign to the new object. Optional. If null, /// the server will generate a default ACL for the file.</param> /// <param name="metadata">The metadata to assign to the new object. /// Optional. If null, no user metadata will be assigned to the new object.</param> /// <param name="closeStream">if true, the stream will be closed after /// the transfer completes. If false, the stream will not be closed.</param> /// <returns>the identifier of the newly-created object.</returns> public ObjectId CreateObjectOnPath(ObjectPath path, Stream stream, Acl acl, MetadataList metadata, bool closeStream) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (computeChecksums) { checksum = new Checksum(Checksum.Algorithm.SHA0); } else { checksum = null; } ObjectId id = null; // First call should be to create object try { bool eof = ReadChunk(); id = this.esu.CreateObjectFromSegmentOnPath(path, acl, metadata, buffer, contentType, checksum); if (!eof) { this.OnProgress(buffer.Count); } else { // No data in file? Complete this.OnComplete(); return id; } // Continue appending this.AppendChunks(path); } catch (EsuException e) { this.OnFail(e); throw e; } catch (IOException e) { this.OnFail(e); throw new EsuException("Error uploading object", e); } return id; }
/// <summary> /// Downloads the given object's contents to a stream. /// </summary> /// <param name="id">the identifier of the object to download.</param> /// <param name="stream">the stream to write the object's contents to.</param> /// <param name="closeStream">specifies whether to close the stream after /// the transfer is complete.</param> public void ReadObject( Identifier id, Stream stream, bool closeStream ) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (Checksumming) { checksum = new Checksum(Checksum.Algorithm.SHA0); } // Get the file size. Set to -1 if unknown. MetadataList sMeta = this.esu.GetSystemMetadata( id, null ); if ( sMeta.GetMetadata( "size" ) != null ) { string size = sMeta.GetMetadata( "size" ).Value; if ( size != null && size.Length > 0 ) { this.totalBytes = long.Parse( size ); } else { this.totalBytes = -1; } } else { this.totalBytes = -1; } // We need to know how big the object is to download it. Fail the // transfer if we can't determine the object size. if ( this.totalBytes == -1 ) { throw new EsuException( "Failed to get object size" ); } // Loop, downloading chunks until the transfer is complete. while ( true ) { try { Extent extent = null; // Determine how much data to download. If we're at the last // request in the transfer, only request as many bytes as needed // to get to the end of the file. Use bcmath since these values // can easily exceed 2GB. if ( currentBytes + buffer.Array.Length > totalBytes ) { // Would go past end of file. Request less bytes. extent = new Extent( this.currentBytes, totalBytes - currentBytes ); } else { extent = new Extent( this.currentBytes, buffer.Array.Length ); } if ( extent.Size != buffer.Count ) { buffer = new ArraySegment<byte>( buffer.Array, 0, (int)extent.Size ); } // Read data from the server. byte[] responseBuffer = this.esu.ReadObject( id, extent, buffer.Array, checksum ); // Write to the stream stream.Write( responseBuffer, 0, (int)extent.Size ); // Update progress this.OnProgress( buffer.Count ); // See if we're done. if ( this.currentBytes == this.totalBytes ) { if (Checksumming && checksum != null && checksum.ExpectedValue != null) { if (!checksum.ExpectedValue.Equals(checksum.ToString())) { throw new EsuException("Checksum validation failed. Expected " + checksum.ExpectedValue + " but computed " + checksum.ToString()); } Debug.WriteLine("Checksum OK: " + checksum.ExpectedValue); } this.OnComplete(); return; } } catch ( EsuException e ) { OnFail( e ); throw e; } catch ( IOException e ) { OnFail( e ); throw new EsuException( "Error downloading file", e ); } } }
public void testReadChecksum() { Checksum ck = new Checksum(EsuApiLib.Checksum.Algorithm.SHA0); ObjectId id = this.esu.CreateObject(null, null, Encoding.UTF8.GetBytes("Four score and seven years ago"), "text/plain", ck); Debug.WriteLine("Checksum: " + ck); cleanup.Add(id); // Read back. Checksum ck2 = new Checksum(Checksum.Algorithm.SHA0); string content = Encoding.UTF8.GetString(this.esu.ReadObject(id, null, null, ck2)); Assert.AreEqual("Four score and seven years ago", content, "object content wrong"); }
public void testCreateChecksum() { Checksum ck = new Checksum( EsuApiLib.Checksum.Algorithm.SHA0 ); ObjectId id = this.esu.CreateObject( null, null, Encoding.UTF8.GetBytes("hello"), "text/plain", ck ); Debug.WriteLine( "Checksum: " + ck ); cleanup.Add( id ); }
public void testAppendChecksum() { Checksum ck = new Checksum(Checksum.Algorithm.SHA0); ObjectId id = esu.CreateObject(null, null, Encoding.UTF8.GetBytes("hello"), "text/plain", ck); cleanup.Add(id); esu.UpdateObject(id, null, null, new Extent(5, 6), Encoding.UTF8.GetBytes(" world"), null, ck); }