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 };