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