text: /*-------------------------------------------------------------------------
   * drawElements Stream Library
   * ---------------------------
   *
   * Copyright 2014 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   *//*!
   * \file
   * \brief Stream wrapper for deFile
   *//*--------------------------------------------------------------------*/
  #include "deFileStream.h"
  
  #include <stdlib.h>
  
  typedef struct FileStream_s
  {
  	deFile*			file;
  	deStreamStatus	status;
  	const char*		error;
  } FileStream;
  
  static deStreamResult fileIOStream_read (deStreamData* stream, void* buf, deInt32 bufSize, deInt32* numRead)
  {
  	deInt64 _numRead = 0;
  	FileStream* fileStream = (FileStream*)stream;
  
  
  	deFileResult result = deFile_read(fileStream->file, buf, bufSize, &_numRead);
  	*numRead = (deInt32)_numRead;
  
  	switch (result)
  	{
  		case  DE_FILERESULT_SUCCESS:
  			return DE_STREAMRESULT_SUCCESS;
  			break;
  
  		case DE_FILERESULT_ERROR:
  			fileStream->error	= "deFile: DE_FILERESULT_ERROR";
  			fileStream->status	= DE_STREAMSTATUS_ERROR;
  			return DE_STREAMRESULT_ERROR;
  			break;
  
  		case DE_FILERESULT_END_OF_FILE:
  			return DE_STREAMRESULT_END_OF_STREAM;
  			break;
  
  		default:
  			fileStream->error	= "Uknown: DE_FILERESULT";
  			fileStream->status	= DE_STREAMSTATUS_ERROR;
  			return DE_STREAMRESULT_ERROR;
  			break;
  	};
  }
  
  static deStreamResult fileIOStream_write (deStreamData* stream, const void* buf, deInt32 bufSize, deInt32* numWritten)
  {
  	deInt64	_numWritten = 0;
  	FileStream* fileStream = (FileStream*)stream;
  
  	deFileResult result = deFile_write(fileStream->file, buf, bufSize, &_numWritten);
  	*numWritten = (deInt32)_numWritten;
  
  	switch (result)
  	{
  		case  DE_FILERESULT_SUCCESS:
  			return DE_STREAMRESULT_SUCCESS;
  			break;
  
  		case DE_FILERESULT_ERROR:
  			fileStream->error	= "deFile: DE_FILERESULT_ERROR";
  			fileStream->status	= DE_STREAMSTATUS_ERROR;
  			return DE_STREAMRESULT_ERROR;
  			break;
  
  		case DE_FILERESULT_END_OF_FILE:
  			return DE_STREAMRESULT_END_OF_STREAM;
  			break;
  
  		default:
  			fileStream->error	= "Uknown: DE_FILERESULT";
  			fileStream->status	= DE_STREAMSTATUS_ERROR;
  			return DE_STREAMRESULT_ERROR;
  			break;
  	};
  }
  
  static const char* fileIOStream_getError (deStreamData* stream)
  {
  	FileStream* fileStream = (FileStream*)stream;
  	/* \note [mika] There is only error reporting through return value in deFile */
  	return fileStream->error;
  }
  
  static deStreamResult fileIOStream_flush (deStreamData* stream)
  {
  	/* \todo mika deFile doesn't have flush, how should this be handled? */
  	DE_UNREF(stream);
  
  	return DE_STREAMRESULT_SUCCESS;
  }
  
  static deStreamResult fileIOStream_deinit (deStreamData* stream)
  {
  	FileStream* fileStream = (FileStream*)stream;
  
  	deFile_destroy(fileStream->file);
  
  	free(fileStream);
  
  	return DE_STREAMRESULT_SUCCESS;
  }
  
  static deStreamStatus fileIOStrem_getStatus (deStreamData* stream)
  {
  	FileStream* fileStream = (FileStream*)stream;
  	return fileStream->status;
  }
  
  static const deIOStreamVFTable fileIOStreamVFTable = {
  	fileIOStream_read,
  	fileIOStream_write,
  	fileIOStream_getError,
  	fileIOStream_flush,
  	fileIOStream_deinit,
  	fileIOStrem_getStatus
  };
  
  static const deIOStreamVFTable fileInStreamVFTable = {
  	fileIOStream_read,
  	DE_NULL,
  	fileIOStream_getError,
  	DE_NULL,
  	fileIOStream_deinit,
  	fileIOStrem_getStatus
  };
  
  static const deIOStreamVFTable fileOutStreamVFTable = {
  	DE_NULL,
  	fileIOStream_write,
  	fileIOStream_getError,
  	fileIOStream_flush,
  	fileIOStream_deinit,
  	fileIOStrem_getStatus
  };
  
  void fileIOStream_init (deIOStream* stream, const char* filename, deFileMode mode)
  {
  	FileStream* fileStream = DE_NULL;
  
  	DE_ASSERT(stream);
  
  	fileStream = malloc(sizeof(FileStream));
  
  	/* \note mika Check that file is readable and writeable, currently not supported by deFile */
  	stream->vfTable		= &fileIOStreamVFTable;
  	stream->streamData	= (deStreamData*)fileStream;
  
  	fileStream->file	= deFile_create(filename, mode);
  	fileStream->status	= DE_STREAMSTATUS_GOOD;
  	fileStream->error	= DE_NULL;
  
  	if (!fileStream->file)
  		fileStream->status = DE_STREAMSTATUS_ERROR;
  }
  
  void deFileInStream_init (deInStream* stream, const char* filename, deFileMode mode)
  {
  	FileStream* fileStream = DE_NULL;
  
  	DE_ASSERT(stream);
  
  	fileStream = malloc(sizeof(FileStream));
  
  	/* \note mika Check that file is readable, currently not supported by deFile */
  	stream->ioStream.vfTable		= &fileInStreamVFTable;
  	stream->ioStream.streamData		= (deStreamData*)fileStream;
  
  	fileStream->file	= deFile_create(filename, mode);
  	fileStream->status	= DE_STREAMSTATUS_GOOD;
  	fileStream->error	= DE_NULL;
  
  	if (!fileStream->file)
  		fileStream->status = DE_STREAMSTATUS_ERROR;
  }
  
  void deFileOutStream_init (deOutStream* stream, const char* filename, deFileMode mode)
  {
  	FileStream* fileStream = DE_NULL;
  
  	DE_ASSERT(stream);
  
  	fileStream = malloc(sizeof(FileStream));
  
  	/* \note mika Check that file is writeable, currently not supported by deFile */
  	stream->ioStream.vfTable		= &fileOutStreamVFTable;
  	stream->ioStream.streamData		= (deStreamData*)fileStream;
  
  	fileStream->file	= deFile_create(filename, mode);
  	fileStream->status	= DE_STREAMSTATUS_GOOD;
  	fileStream->error	= DE_NULL;
  
  	if (!fileStream->file)
  		fileStream->status = DE_STREAMSTATUS_ERROR;;
  }
  