00001 #include <string.h>
00002 #include "MemoryFile.h"
00003 #include "Utility.h"
00004
00005 namespace corona {
00006
00007 COR_EXPORT(File*) CorCreateMemoryFile(const void* buffer, int size) {
00008 if (size && !buffer) {
00009 return 0;
00010 }
00011 if (size < 0) {
00012 return 0;
00013 }
00014
00015 return new MemoryFile(buffer, size);
00016 }
00017
00018
00019 int getNextPowerOfTwo(int value) {
00020 int i = 1;
00021 while (i < value) {
00022 i *= 2;
00023 }
00024 return i;
00025 }
00026
00027 MemoryFile::MemoryFile(const void* buffer, int size) {
00028 m_capacity = getNextPowerOfTwo(size);
00029 m_size = size;
00030 m_buffer = new byte[m_capacity];
00031 memcpy(m_buffer, buffer, size);
00032
00033 m_position = 0;
00034 }
00035
00036 MemoryFile::~MemoryFile() {
00037 delete[] m_buffer;
00038 }
00039
00040 int COR_CALL MemoryFile::read(void* buffer, int size) {
00041 int real_read = std::min((m_size - m_position), size);
00042 memcpy(buffer, m_buffer + m_position, real_read);
00043 m_position += real_read;
00044 return real_read;
00045 }
00046
00047 int COR_CALL MemoryFile::write(const void* buffer, int size) {
00048 ensureSize(m_position + size);
00049 memcpy(m_buffer + m_position, buffer, size);
00050 m_position += size;
00051 return size;
00052 }
00053
00054 bool COR_CALL MemoryFile::seek(int position, SeekMode mode) {
00055 int real_pos;
00056 switch (mode) {
00057 case BEGIN: real_pos = position; break;
00058 case CURRENT: real_pos = m_position + position; break;
00059 case END: real_pos = m_size + position; break;
00060 default: return false;
00061 }
00062
00063 if (real_pos < 0 || real_pos > m_size) {
00064 m_position = 0;
00065 return false;
00066 } else {
00067 m_position = real_pos;
00068 return true;
00069 }
00070 }
00071
00072 int COR_CALL MemoryFile::tell() {
00073 return m_position;
00074 }
00075
00076 void MemoryFile::ensureSize(int min_size) {
00077 bool realloc_needed = false;
00078 while (m_capacity < min_size) {
00079 m_capacity *= 2;
00080 realloc_needed = true;
00081 }
00082
00083 if (realloc_needed) {
00084 byte* new_buffer = new byte[m_capacity];
00085 memcpy(new_buffer, m_buffer, m_size);
00086 delete[] m_buffer;
00087 m_buffer = new_buffer;
00088 }
00089
00090 m_size = min_size;
00091 }
00092
00093 };