int w_newFileData(lua_State *L) { // Single argument: treat as filepath or File. if (lua_gettop(L) == 1) { // We don't use luax_getfiledata because we want to use an ioError. if (lua_isstring(L, 1)) luax_convobj(L, 1, "filesystem", "newFile"); // Get FileData from the File. if (luax_istype(L, 1, FILESYSTEM_FILE_ID)) { File *file = luax_checkfile(L, 1); FileData *data = 0; try { data = file->read(); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, data); data->release(); return 1; } else return luaL_argerror(L, 1, "filename or File expected"); } size_t length = 0; const char *str = luaL_checklstring(L, 1, &length); const char *filename = luaL_checkstring(L, 2); const char *decstr = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0; FileData::Decoder decoder = FileData::FILE; if (decstr && !FileData::getConstant(decstr, decoder)) return luaL_error(L, "Invalid FileData decoder: %s", decstr); FileData *t = 0; switch (decoder) { case FileData::FILE: t = instance()->newFileData((void *)str, (int)length, filename); break; case FileData::BASE64: t = instance()->newFileData(str, filename); break; default: return luaL_error(L, "Invalid FileData decoder: %s", decstr); } luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, t); t->release(); return 1; }
FileData *File::read(int64 size) { bool isopen = isOpen(); if (!isopen && !open(MODE_READ)) throw love::Exception("Could not read file %s.", getFilename().c_str()); int64 max = getSize(); int64 cur = tell(); size = (size == ALL) ? max : size; if (size < 0) throw love::Exception("Invalid read size."); // Clamping because the file offset may be in a weird position. if (cur < 0) cur = 0; else if (cur > max) cur = max; if (cur + size > max) size = max - cur; FileData *fileData = new FileData(size, getFilename()); int64 bytesRead = read(fileData->getData(), size); if (bytesRead < 0 || (bytesRead == 0 && bytesRead != size)) { delete fileData; throw love::Exception("Could not read from file."); } if (bytesRead < size) { FileData *tmpFileData = new FileData(bytesRead, getFilename()); memcpy(tmpFileData->getData(), fileData->getData(), (size_t) bytesRead); fileData->release(); fileData = tmpFileData; } if (!isopen) close(); return fileData; }