public Blob(List <object> sources, object properties = null) { _sources = new List <BufferRegion>(); _pointer = 0; foreach (object source in sources) { if (source is FileInfo) { _sources.Add(new BufferRegion(new Buffer((FileInfo)source))); _pointer += ((FileInfo)source).Length; } else if (source is byte[]) { _sources.Add(new BufferRegion(new Buffer((byte[])source))); _pointer += ((byte[])source).Length; } else if (source is MemoryStream) { _sources.Add(new BufferRegion(new Buffer((MemoryStream)source))); _pointer += ((MemoryStream)source).Length; } else if (source is Blob) { ((Blob)source)._sources.ForEach(delegate(BufferRegion region) { region.buffer.refs++; _sources.Add(region); _pointer += ((Blob)source).size; }); } else if (source is BufferRegion) { BufferRegion bufferRegion = (BufferRegion)source; _sources.Add(new BufferRegion(bufferRegion.buffer, bufferRegion.start, bufferRegion.end)); _pointer += bufferRegion.end - bufferRegion.start; } } if (properties is string) { _type = (string)properties; } else if (properties is Dictionary <string, string> ) { string type; if (((Dictionary <string, string>)properties).TryGetValue("type", out type)) { _type = type; } } _size = _pointer; _uid = Utils.guid("uid_"); }
private void _readFromNextSource(byte[] buffer, int offset, int count) { int bytesRead = 0; if (_srcIdx >= _blob._sources.Count) { // we are out of sources return; } // get the next one BufferRegion src = _blob._sources[_srcIdx++]; // requested position is out of the boundaries of current source, bypass if (src.size <= _position) { _position -= src.size; _readFromNextSource(buffer, offset, count); return; } src.Position = _position; if ((bytesRead = src.Read(buffer, offset, count)) == 0) { return; } Position += bytesRead; offset += bytesRead; _bytesTotal += bytesRead; // we need more, proceed if possible if (bytesRead < count) { _position = 0; count -= bytesRead; _readFromNextSource(buffer, offset, count); } }