2010-01-13 67 views
4

我很驚訝Google沒有找到解決方案。我正在尋找一種解決方案,允許SDL_RWops與std :: istream一起使用。 SDL_RWops是用於在SDL中讀取/寫入數據的替代機制。從std :: istream中讀取SDL_RWops

任何鏈接到解決問題的網站?

一個明顯的解決方案是預先讀取足夠的數據到內存然後使用SDL_RWFromMem。然而,這有缺點,我需要事先知道文件大小。

好像能以某種方式被「重寫」 SDL_RWops功能要解決的問題......

+0

你的意思是你想從istream創建一個RWops結構? –

+0

好暗示,我會試試。 –

+0

這並不是什麼大問題,我不明白你在做什麼。 –

回答

5

我覺得不好回答我的問題,但它preocupied我有一段時間了,這是我想出瞭解決方案:

int istream_seek(struct SDL_RWops *context, int offset, int whence) 
{ 
    std::istream* stream = (std::istream*) context->hidden.unknown.data1; 

     if (whence == SEEK_SET) 
     stream->seekg (offset, std::ios::beg); 
    else if (whence == SEEK_CUR) 
     stream->seekg (offset, std::ios::cur); 
    else if (whence == SEEK_END) 
     stream->seekg (offset, std::ios::end); 

    return stream->fail() ? -1 : stream->tellg(); 
} 


int istream_read(SDL_RWops *context, void *ptr, int size, int maxnum) 
{ 
    if (size == 0) return -1; 
    std::istream* stream = (std::istream*) context->hidden.unknown.data1; 
    stream->read((char*)ptr, size * maxnum); 

    return stream->bad() ? -1 : stream->gcount()/size; 
} 

int istream_close(SDL_RWops *context) 
{ 
    if (context) { 
     SDL_FreeRW(context); 
    } 
    return 0; 
} 


SDL_RWops *SDL_RWFromIStream(std::istream& stream) 
{ 
    SDL_RWops *rwops; 
    rwops = SDL_AllocRW(); 

    if (rwops != NULL) 
    { 
     rwops->seek = istream_seek; 
     rwops->read = istream_read; 
     rwops->write = NULL; 
     rwops->close = istream_close; 
     rwops->hidden.unknown.data1 = &stream; 
    } 
    return rwops; 
} 

根據istream從未被SDL釋放的假設工作(並且他們通過操作生活)。也只有istream支持,ostream會完成一個單獨的函數 - 我知道我可以通過iostream,但是不允許將istream傳遞給轉換函數:/。

歡迎提出任何關於錯誤或升級的提示。

+4

,您可以允許istream,ostream或iostream。使用NULL作爲寫入功能的 –

+3

看起來很可怕。創建一個使用SDL_SetError的函數可能會更好,並返回-1。 –

+0

@卡斯賓,謝謝,非常有用的提示!儘管如此,代碼發佈不起作用....我試圖調試它,但沒有線索:/ –

1

如果您試圖從istream獲取SDL_RWops結構,可以通過將整個istream讀入內存然後使用SDL_RWFromMem獲取一個結構體來表示它。

以下是一個簡單的例子;注意這是不安全的,因爲沒有完成健康檢查。例如,如果文件大小爲0,則訪問緩衝區[0]可能會在調試版本中引發異常或斷言。

// Open a bitmap 
std::ifstream bitmap("bitmap.bmp"); 

// Find the bitmap file's size 
bitmap.seekg(0, std::ios_base::end); 
std::istream::pos_tye fileSize = bitmap.tellg(); 
bitmap.seekg(0); 

// Allocate a buffer to store the file in 
std::vector<unsigned char> buffer(fileSize); 

// Copy the istream into the buffer 
std::copy(std::istreambuf_iterator<unsigned char>(bitmap), std::istreambuf_iterator<unsigned char>(), buffer.begin()); 

// Get an SDL_RWops struct for the file 
SDL_RWops* rw = SDL_RWFromMem(&buffer[0], buffer.size()); 

// Do stuff with the SDL_RWops struct 
+0

我已經寫道,我不能這樣做,因爲我不想將整個文件預加載到內存中。如果我想從文件中讀取,我會使用IMG_Load :)。我想從通過istream訪問的自定義容器中加載。 –

+0

你只提到這是一個問題,因爲'你事先不知道文件的大小' –

+0

嗯,是的,這可以與任何istream一起工作,我只是使用ifstream作爲例子,因爲它是最簡單的方法istream的。 –