// Standard ctor - Stream to be used to buffer, the Tag we read the data from public BlobReadStream(Stream s, FPTag t) : base(s, t) { myCallbacks = new Callbacks(holdingArea); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.OutputFromCentera, myCallbacks, IntPtr.Zero); fpStream.StreamLen = t.BlobSize; FPLogger.ConsoleMessage("\nStarting blob read thread"); blobThread = new Thread(delegate() { t.BlobRead(fpStream); }); blobThread.Name = "BlobReadThread"; blobThread.Start(); }
// Standard ctor - Stream to be used to buffer, the Tag we write the data to public BlobWriteStream(Stream s, FPTag t) : base(s, t) { myCallbacks = new Callbacks(holdingArea); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.InputToCentera, myCallbacks, (IntPtr)this.GetHashCode()); blobThread = new Thread(delegate() { theTag.BlobWrite(fpStream); }); blobThread.Name = "BlobWriteThread"; FPLogger.ConsoleMessage("\nStarted stream " + this.GetHashCode() + " blob write thread " + blobThread.GetHashCode()); // We keep track of the current "open" streams being used in a hashtable // When user closes the stream we remove this to signal the callback that we are done writing openStreams.Add(this.GetHashCode(), blobThread.GetHashCode()); }
// Standard ctor - as for BlobWriteStream but also specify the sequence number of the segment. public PartialBlobWriteStream(Stream s, FPTag t, int id) { // We cannot call the base constructor because we need use the additional id parameter // Even if we split out some of the functionality using a virtual init method with no // parameters, the sequenceId will not be initialized when the virtual function was called // by the base constructor. So we just have to duplicate the (small)initialization code. holdingArea = s; theTag = t; sequenceId = id; myCallbacks = new Callbacks(holdingArea); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.InputToCentera, myCallbacks, (IntPtr)this.GetHashCode()); FPLogger.ConsoleMessage("\n ** Partial blob write stream with sequence id = " + sequenceId); blobThread = new Thread(delegate() { theTag.BlobWritePartial(fpStream, sequenceId); }); blobThread.Name = "PartialBlobWriteThread"; }
// Standard ctor - as for BlobReadStream but also specify the offset and number of bytes for the partial read. public PartialBlobReadStream(Stream s, FPTag t, long offset, long numBytes) { // We cannot call the base constructor because we need use the additional offset and numBytes parameters // Even if we split out some of the functionality using a virtual init method with no // parameters, these paraameters will not be initialized when the virtual function was called // by the base constructor. So we just have to duplicate the (small)initialization code. holdingArea = s; theTag = t; myCallbacks = new Callbacks(holdingArea, 16 * 1024); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.OutputFromCentera, myCallbacks, IntPtr.Zero); fpStream.StreamLen = numBytes; blobThread = new Thread(delegate() { theTag.BlobReadPartial(fpStream, offset, numBytes); }); blobThread.Name = "PartialBlobReadThread"; blobThread.Start(); }
static void Main(string[] args) { IntPtr userData = new IntPtr(0); try { FPPool myPool = new FPPool("128.221.200.56?c:\\pea\\emea1.pea"); FPTag myTag; FPLogger log = new FPLogger(); log.LogPath = "C:\\GenStreamsLog.txt"; log.Start(); // First we'll write a test clip to the Centera string fileName = "c:\\discovery.xml"; FileInfo info = new FileInfo(fileName); FPClip myClip = myPool.ClipCreate("GenericStreamWrite_testClip"); myTag = myClip.AddTag("testTag"); FPGenericStream myStream = new FPGenericStream(File.OpenRead(fileName), userData); myStream.StreamLen = info.Length; myTag.BlobWrite(myStream); myTag.Close(); myStream.Close(); string clipID = myClip.Write(); myClip.Close(); FPLogger.ConsoleMessage("\nGenericStreamWrite test succeeded"); // Now we will test reading it back from the Centera { myClip = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); myTag = myClip.NextTag; myStream = new FPGenericStream(File.OpenWrite("c:\\test.out"), userData); myStream.StreamLen = myTag.BlobSize; myTag.BlobRead(myStream); myStream.Close(); FPLogger.ConsoleMessage("\nGenericStreamRead test succeeded for FileStream"); // We could use a Memory stream. As it is a bi-directional stream we // need to use a ctor that specifies the direction we want to use. // We'll set up the space first. MemoryStream s = new MemoryStream((int)myTag.BlobSize); myStream = new FPGenericStream(s, FPStream.StreamDirection.OutputFromCentera, userData); myStream.StreamLen = myTag.BlobSize; myTag.BlobRead(myStream, FPMisc.OPTION_DEFAULT_OPTIONS); myStream.Close(); FPLogger.ConsoleMessage("\nGenericStreamRead test succeeded for MemoryStream"); myTag.Close(); myClip.Close(); myPool.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }