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