===========================================
Controlling the reading and writing process
===========================================
 
Overview
========

In addition to the high-level read/write functions which support reading from and writing to a disk file, the HOOPS/Stream Toolkit also supports writing and reading HOOPS Stream File information to and from a user-specified location. This is a powerful feature which enables the application developer to store the HOOPS Stream File information within a custom application specific file format (or any location) and retrieve it from the custom location, rather than use a separate *.hsf* file. More importantly, the data can be incrementally streamed into the HOOPS/3dGS scene-graph. 

For example, many technical applications that also visualize 2D/3D information utilize a custom file format that contains application specific data. When the file is read in, the application then goes through a laborious process of recreating the 2D/3D information associated with the application data. By utilizing the HOOPS/3dGS and the HOOPS/Stream Toolkit, a developer could cache the HOOPS/3dGS scene-graph geometry in their own proprietary file format file by embedding the *.hsf* information. File load time and initial rendering is drastically reduced, the custom file format remains intact, and the highly compressed *.hsf* information minimizes the increase of file size. 

Support for controlling the reading and writing process is provided by the ``HStreamFileToolkit`` class. An instance of an ``HStreamFileToolkit`` object should be created for each file that is being read or written, and then either the ``ParseBuffer`` or ``GenerateBuffer`` method should be called to control reading and writing, respectively. A HOOPS segment must currently be open before calling ``ParseBuffer`` or ``GenerateBuffer``.
 
  
Controlling reading
===================

To control the reading process, a piece of binary data that has been read from an *.hsf* file is presented to the ``HStreamFileToolkit`` object for parsing and insertion into the HOOPS database by calling the ``HStreamFileToolkit::ParseBuffer`` method. This method doesn't care where the data originated from, but simply reads the data from the buffer passed to it, converts it to the appropriate HOOPS segment, attribute and geometry information, and inserts the information into the HOOPS database. 

The following code example demonstrates how data could be manually read from a local file and inserted into HOOPS using ``ParseBuffer``. A file is open and pieces of data are read from it using the HStreamFileToolkit wrapper functions for file opening and reading ( ``HStreamFileToolkit::OpenFile`` and ``HStreamFileToolkit::ReadBuffer`` ) Data is continually read and passed to ``ParseBuffer`` until it returns ``#TK_Complete``, indicating that reading is complete, or until an error occurs. Example::
  
	void Read_Stream_File (char const * filename)  
	{ 
		auto	char		block[BUFFER_SIZE]; 
		auto	TK_Status	status = TK_Normal; 
		auto	int			amount; 
				 
		HStreamFileToolkit  * tk = new HStreamFileToolkit;   
			   
		if ((status = tk->OpenFile (filename)) != TK_Normal) 
			return status;          
		do 
		{ 
			if (tk->ReadBuffer (block, BUFFER_SIZE, amount) != TK_Normal)            
				break; 
						 
			status = tk->ParseBuffer (block, amount); 
					 
			if (status == TK_Error) 
			{ 
				// whatever... 
				break; 
			} 
		} while (status != TK_Complete);  
				
		tk->CloseFile ();  
				
		delete  tk; 
	}       


Controlling writing
===================
  
To control the writing process, the ``HStreamFileToolkit::GenerateBuffer`` method of the ``HStreamFileToolkit`` object is called to retrieve a piece of binary data from the toolkit, and then the user can deal with the data as necessary. The ``GenerateBuffer`` method doesn't care where the data is eventually going to end up, but simply writes data into the buffer passed to it. The data consists of HOOPS segment, attribute and geometry information which has been converted to HSF formatted data. 

The following code example demonstrates how data could be manually retrieved from the toolkit using ``GenerateBuffer``, and then written to a file. It continually calls ``GenerateBuffer`` to obtain data from the toolkit and writes it to a file until ``GenerateBuffer`` indicates that it is complete. Example::

	void Write_Stream_File (char const * filename)  
	{ 
		auto	char		block[BUFFER_SIZE]; 
		auto	TK_Status	status = TK_Normal; 
		auto	int			amount;          
		
		HStreamFileToolkit * tk = new HStreamFileToolkit; 
				 
		if ((status = tk->OpenFile (filename)) != TK_Normal) 
			return status;          
		do 
		{ 
			status = tk->GenerateBuffer (block, BUFFER_SIZE, amount); 
					 
			if (status == TK_Error) 
			{ 
				// whatever... 
				break; 
			}  
					
			if (tk->WriteBuffer (block, amount) != TK_Normal) 
				break;    
					  
		} while (status != TK_Complete);    
			  
		tk->CloseFile ();   
			   
		delete tk; 
	}       

The toolkit also allows you to explicitly exclude certain segments from being written to the HSF buffer. Via ``HStreamFileToolkit::AddExcludedSegments(..)`` a developer can specify which segments should be ignored when the HSF data is being created for a portion of a HOOPS segment tree. When a segment is excluded, that segment including the geometry, segments and attributes contained within it will not be written to the supplied HSF buffer.
