// INTERNAL INCLUDES
#include "image-loaders/image-loader.h"
#include <resource-loader/network/file-download.h>
-#include <platform-abstractions/portable/file-closer.h>
+#include <platform-abstractions/portable/file-reader.h>
#include "pixel-buffer-impl.h"
namespace Dali
{
Integration::BitmapResourceType resourceType( size, fittingMode, samplingMode, orientationCorrection );
- Internal::Platform::FileCloser fc( url.c_str(), "rb");
- FILE * const fp = fc.GetFile();
+ Internal::Platform::FileReader fileReader( url );
+ FILE * const fp = fileReader.GetFile();
if( fp != NULL )
{
Integration::BitmapPtr bitmap;
MAXIMUM_DOWNLOAD_IMAGE_SIZE );
if( succeeded )
{
- void *blobBytes = static_cast<void*>(&dataBuffer[0]);
size_t blobSize = dataBuffer.Size();
DALI_ASSERT_DEBUG( blobSize > 0U );
- DALI_ASSERT_DEBUG( blobBytes != 0U );
- if( blobBytes != 0 && blobSize > 0U )
+ if( blobSize > 0U )
{
// Open a file handle on the memory buffer:
- Dali::Internal::Platform::FileCloser fileCloser( blobBytes, blobSize, "rb" );
- FILE * const fp = fileCloser.GetFile();
+ Dali::Internal::Platform::FileReader fileReader( dataBuffer, blobSize );
+ FILE * const fp = fileReader.GetFile();
if ( NULL != fp )
{
Integration::BitmapPtr bitmap;
*/
class FileCloser
{
-public:
+protected: // prevent this class being directly instantiated
/**
* @brief Construct a FileCloser guarding a new FILE* for accessing the path passed in.
*/
- FileCloser( const char * const filename, const char * const mode ) :
- mFile(fopen(filename, mode))
+ FileCloser( const char * const filename, const char * const mode )
+ : mFile(fopen(filename, mode))
{
DALI_ASSERT_DEBUG( filename != 0 && "Cant open a null filename." );
DALI_ASSERT_DEBUG( mode != 0 && "Null mode is undefined behaviour in spec." );
/**
* @brief Construct a FileCloser guarding a FILE* for reading out of the memory buffer passed in.
*/
- FileCloser( void * const buffer, const size_t bufferSize, const char * const mode ) :
- mFile( fmemopen( buffer, bufferSize, mode ) )
+ FileCloser( uint8_t* buffer, size_t dataSize, const char * const mode )
+ : mFile( fmemopen( buffer, dataSize, mode) )
+ {
+ }
+
+ FileCloser( Dali::Vector<uint8_t>& vector, size_t dataSize, const char * const mode )
{
+ // Resize the buffer to ensure any null that gets written by
+ // fmemopen is written past the end of any data that is written to the buffer.
+ // (Workaround for a bug in Ubuntu that overwrites null to the last byte of the
+ // data block regardless of whether binary mode was specified. Tizen doesn't write
+ // null if binary mode is specified).
+ size_t bufferSize = dataSize;
+ ++bufferSize;
+ vector.Resize( bufferSize );
+
+ void * const buffer = &vector[0];
+ mFile = fmemopen( buffer, bufferSize, mode );
+
DALI_ASSERT_DEBUG( buffer != 0 && "Cant open file on null buffer." );
- DALI_ASSERT_DEBUG( bufferSize > 0 && "Pointless to open file on empty buffer." );
+ DALI_ASSERT_DEBUG( dataSize > 0 && "Pointless to open file on empty buffer." );
DALI_ASSERT_DEBUG( mode != 0 && "Null mode is undefined behaviour in spec." );
if( mFile == 0 )
{
- DALI_LOG_WARNING( "File open failed for memory buffer at location: \"%p\", of size: \"%u\", in mode: \"%s\".\n", static_cast<void*>(buffer), static_cast<unsigned>(bufferSize), mode );
+ DALI_LOG_WARNING( "File open failed for memory buffer at location: \"%p\", of size: \"%u\", in mode: \"%s\".\n", static_cast<void*>(buffer), static_cast<unsigned>(dataSize), mode );
}
}
}
}
+public:
/**
* @return The FILE* guarded by this object.
*/
--- /dev/null
+#ifndef DALI_INTERNAL_PORTABLE_FILE_READER_H
+#define DALI_INTERNAL_PORTABLE_FILE_READER_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+// INTERNAL INCLUDES
+#include "file-closer.h"
+
+// EXTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Platform
+{
+
+class FileReader : public FileCloser
+{
+public:
+ FileReader( const std::string& filename )
+ : FileCloser( filename.c_str(), "rb" )
+ {
+ }
+
+ FileReader( Dali::Vector<uint8_t>& vector )
+ : FileCloser( &vector[0], vector.Size(), "rb" )
+ {
+ }
+
+ FileReader( Dali::Vector<uint8_t>& vector, size_t dataSize )
+ : FileCloser( &vector[0], dataSize, "rb" )
+ {
+ }
+
+ FileReader( uint8_t* data, size_t dataSize )
+ : FileCloser( data, dataSize, "rb" )
+ {
+ }
+};
+
+} /* namespace Platform */
+} /* namespace Internal */
+} /* namespace Dali */
+
+#endif // DALI_INTERNAL_PORTABLE_FILE_READER_H
--- /dev/null
+#ifndef DALI_INTERNAL_PORTABLE_FILE_WRITER_H
+#define DALI_INTERNAL_PORTABLE_FILE_WRITER_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+// INTERNAL INCLUDES
+#include "file-closer.h"
+
+// EXTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Platform
+{
+
+class FileWriter : public FileCloser
+{
+public:
+ /**
+ * Opens a file pointer onto the memory for writing to.
+ * Note, in some implementations, the vector may be resized to be larger than dataSize.
+ * @param[in,out] vector The vector to write to
+ * @param[in] dataSize the amount of data to be written
+ */
+ FileWriter( Dali::Vector<uint8_t>& vector, size_t dataSize )
+ : FileCloser( vector, dataSize, "wb" )
+ {
+ }
+};
+
+} /* namespace Platform */
+} /* namespace Internal */
+} /* namespace Dali */
+
+#endif // DALI_INTERNAL_PORTABLE_FILE_WRITER_H
#include "loader-wbmp.h"
#include "image-operations.h"
#include "image-loader-input.h"
-#include "portable/file-closer.h"
+#include "portable/file-reader.h"
using namespace Dali::Integration;
ResourcePointer result;
BitmapPtr bitmap = 0;
- Internal::Platform::FileCloser fc( path.c_str(), "rb");
- FILE * const fp = fc.GetFile();
+ Internal::Platform::FileReader fileReader( path );
+ FILE * const fp = fileReader.GetFile();
if( fp != NULL )
{
bool success = ConvertStreamToBitmap( resource, path, fp, bitmap );
unsigned int width = 0;
unsigned int height = 0;
- Internal::Platform::FileCloser fc(filename.c_str(), "rb");
- FILE *fp = fc.GetFile();
+ Internal::Platform::FileReader fileReader( filename );
+ FILE *fp = fileReader.GetFile();
if (fp != NULL)
{
LoadBitmapFunction loaderFunction;
return ImageDimensions( width, height );
}
-
-
ImageDimensions GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
ImageDimensions size,
FittingMode::Type fittingMode,
if( encodedBlob != 0 )
{
- const size_t blobSize = encodedBlob->GetVector().Size();
- uint8_t * const blobBytes = &(encodedBlob->GetVector()[0]);
- DALI_ASSERT_DEBUG( blobSize > 0U );
- DALI_ASSERT_DEBUG( blobBytes != 0U );
-
- if( blobBytes != 0 && blobSize > 0U )
+ if( encodedBlob->GetVector().Size() )
{
// Open a file handle on the memory buffer:
- Internal::Platform::FileCloser fc( blobBytes, blobSize, "rb" );
- FILE *fp = fc.GetFile();
+ Internal::Platform::FileReader fileReader( encodedBlob->GetVector() );
+ FILE *fp = fileReader.GetFile();
if ( fp != NULL )
{
LoadBitmapFunction loaderFunction;
#include <cstring>
// INTERNAL INCLUDES
-#include "portable/file-closer.h"
+#include "portable/file-writer.h"
#ifdef TPK_CURL_ENABLED
#include <tpkp_curl.h>
CURLcode DownloadFileDataWithSize( CURL* curlHandle, Dali::Vector<uint8_t>& dataBuffer, size_t dataSize )
{
CURLcode result( CURLE_OK );
- dataBuffer.Resize( dataSize );
// create
- Dali::Internal::Platform::FileCloser fileCloser( static_cast<void*>(&dataBuffer[0]), dataSize, "wb" );
- FILE* dataBufferFilePointer = fileCloser.GetFile();
+ Dali::Internal::Platform::FileWriter fileWriter( dataBuffer, dataSize );
+ FILE* dataBufferFilePointer = fileWriter.GetFile();
if( NULL != dataBufferFilePointer )
{
// we only want the body which contains the file data
}
else if( size > 0 )
{
+ // If we know the size up front, allocate once and avoid chunk copies.
dataSize = static_cast<size_t>( size );
result = DownloadFileDataWithSize( curlHandle, dataBuffer, dataSize );
}
// INTERNAL INCLUDES
#include "image-loaders/image-loader.h"
-#include "portable/file-closer.h"
+#include "portable/file-reader.h"
namespace Dali
{
{
Integration::BitmapPtr bitmap = 0;
- Dali::Internal::Platform::FileCloser fileCloser( buffer, size, "rb" );
- FILE * const fp = fileCloser.GetFile();
+ Dali::Internal::Platform::FileReader fileReader( buffer, size );
+ FILE * const fp = fileReader.GetFile();
if( fp )
{
bool result = ImageLoader::ConvertStreamToBitmap( resource, "", fp, bitmap );