long AudioStreamPlaybackOGGVorbis::_ov_tell_func(void *_f) { //printf("close %p\n",_f); FileAccess *fa = (FileAccess *)_f; return fa->get_position(); }
int AudioStreamPlaybackOGGVorbis::_ov_seek_func(void *_f, ogg_int64_t offs, int whence) { //printf("seek to %p, offs %i, whence %i\n",_f,(int)offs,whence); #ifdef SEEK_SET //printf("seek set defined\n"); FileAccess *fa = (FileAccess *)_f; if (whence == SEEK_SET) { fa->seek(offs); } else if (whence == SEEK_CUR) { fa->seek(fa->get_position() + offs); } else if (whence == SEEK_END) { fa->seek_end(offs); } else { ERR_PRINT("Vorbis seek function failure: Unexpected value in _whence\n"); } int ret = fa->eof_reached() ? -1 : 0; //printf("returning %i\n",ret); return ret; #else return -1; // no seeking #endif }
int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) { // file FileAccess *file = reinterpret_cast<FileAccess *>(ptr); if (file) { size_t len = file->get_len(); switch (whence) { case SEEK_SET: { // Just for explicitness size_t new_pos = static_cast<size_t>(pos); if (new_pos > len) { return -1; } file->seek(new_pos); pos = static_cast<int64_t>(file->get_position()); return pos; } break; case SEEK_CUR: { // Just in case it doesn't exist if (pos < 0 && (size_t)-pos > file->get_position()) { return -1; } pos = pos + static_cast<int>(file->get_position()); file->seek(pos); pos = static_cast<int64_t>(file->get_position()); return pos; } break; case SEEK_END: { // Just in case something goes wrong if ((size_t)-pos > len) { return -1; } file->seek_end(pos); pos = static_cast<int64_t>(file->get_position()); return pos; } break; default: { // Only 4 possible options, hence default = AVSEEK_SIZE // Asks to return the length of file return static_cast<int64_t>(len); } break; } } // In case nothing works out. return -1; }
Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { //printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data()); Error err; FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ, &err); if (err) { ERR_PRINTS("Failed to open " + p_from); return err; } FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE, &err); if (err) { fsrc->close(); memdelete(fsrc); ERR_PRINTS("Failed to open " + p_to); return err; } fsrc->seek_end(0); int size = fsrc->get_position(); fsrc->seek(0); err = OK; while (size--) { if (fsrc->get_error() != OK) { err = fsrc->get_error(); break; } if (fdst->get_error() != OK) { err = fdst->get_error(); break; } fdst->store_8(fsrc->get_8()); } if (err == OK && p_chmod_flags != -1) { fdst->close(); err = FileAccess::set_unix_permissions(p_to, p_chmod_flags); // If running on a platform with no chmod support (i.e., Windows), don't fail if (err == ERR_UNAVAILABLE) err = OK; } memdelete(fsrc); memdelete(fdst); return err; }
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { FileAccess *f = (FileAccess *)opaque; int pos = offset; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: pos = f->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: pos = f->get_len() + offset; break; default: break; }; f->seek(pos); return 0; };
Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files) { EditorProgress ep("savepack", TTR("Packing"), 102, true); String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp"); FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE); ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE) PackData pd; pd.ep = &ep; pd.f = ftmp; pd.so_files = p_so_files; Error err = export_project_files(p_preset, _save_pack_file, &pd, _add_shared_object); memdelete(ftmp); //close tmp file if (err) return err; pd.file_ofs.sort(); //do sort, so we can do binary search later FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE); ERR_FAIL_COND_V(!f, ERR_CANT_CREATE) f->store_32(0x43504447); //GDPK f->store_32(1); //pack version f->store_32(VERSION_MAJOR); f->store_32(VERSION_MINOR); f->store_32(0); //hmph for (int i = 0; i < 16; i++) { //reserved f->store_32(0); } f->store_32(pd.file_ofs.size()); //amount of files size_t header_size = f->get_position(); //precalculate header size for (int i = 0; i < pd.file_ofs.size(); i++) { header_size += 4; // size of path string (32 bits is enough) uint32_t string_len = pd.file_ofs[i].path_utf8.length(); header_size += string_len + _get_pad(4, string_len); ///size of path string header_size += 8; // offset to file _with_ header size included header_size += 8; // size of file header_size += 16; // md5 } size_t header_padding = _get_pad(PCK_PADDING, header_size); for (int i = 0; i < pd.file_ofs.size(); i++) { uint32_t string_len = pd.file_ofs[i].path_utf8.length(); uint32_t pad = _get_pad(4, string_len); ; f->store_32(string_len + pad); f->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len); for (uint32_t j = 0; j < pad; j++) { f->store_8(0); } f->store_64(pd.file_ofs[i].ofs + header_padding + header_size); f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is f->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file } for (uint32_t j = 0; j < header_padding; j++) { f->store_8(0); } //save the rest of the data ftmp = FileAccess::open(tmppath, FileAccess::READ); if (!ftmp) { memdelete(f); ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE) }
static long godot_tell(voidpf opaque, voidpf stream) { FileAccess *f = (FileAccess *)opaque; return f->get_position(); };
Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) { ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER); FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); uint8_t header[4]; f->get_buffer(header, 4); if (header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T') { memdelete(f); ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT); } tw = f->get_32(); th = f->get_32(); flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format /* print_line("width: " + itos(tw)); print_line("height: " + itos(th)); print_line("flags: " + itos(flags)); print_line("df: " + itos(df)); */ #ifdef TOOLS_ENABLED if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) { //print_line("request detect 3D at " + p_path); VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this); } else { //print_line("not requesting detect 3D at " + p_path); VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL); } if (request_srgb_callback && df & FORMAT_BIT_DETECT_SRGB) { //print_line("request detect srgb at " + p_path); VS::get_singleton()->texture_set_detect_srgb_callback(texture, _requested_srgb, this); } else { //print_line("not requesting detect srgb at " + p_path); VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL); } if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) { //print_line("request detect srgb at " + p_path); VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this); } else { //print_line("not requesting detect normal at " + p_path); VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL); } #endif if (!(df & FORMAT_BIT_STREAM)) { p_size_limit = 0; } if (df & FORMAT_BIT_LOSSLESS || df & FORMAT_BIT_LOSSY) { //look for a PNG or WEBP file inside int sw = tw; int sh = th; uint32_t mipmaps = f->get_32(); uint32_t size = f->get_32(); //print_line("mipmaps: " + itos(mipmaps)); while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { f->seek(f->get_position() + size); mipmaps = f->get_32(); size = f->get_32(); sw = MAX(sw >> 1, 1); sh = MAX(sh >> 1, 1); mipmaps--; } //mipmaps need to be read independently, they will be later combined Vector<Ref<Image> > mipmap_images; int total_size = 0; for (uint32_t i = 0; i < mipmaps; i++) { if (i) { size = f->get_32(); } PoolVector<uint8_t> pv; pv.resize(size); { PoolVector<uint8_t>::Write w = pv.write(); f->get_buffer(w.ptr(), size); } Ref<Image> img; if (df & FORMAT_BIT_LOSSLESS) { img = Image::lossless_unpacker(pv); } else { img = Image::lossy_unpacker(pv); } if (img.is_null() || img->empty()) { memdelete(f); ERR_FAIL_COND_V(img.is_null() || img->empty(), ERR_FILE_CORRUPT); } total_size += img->get_data().size(); mipmap_images.push_back(img); } //print_line("mipmap read total: " + itos(mipmap_images.size())); memdelete(f); //no longer needed if (mipmap_images.size() == 1) { image = mipmap_images[0]; return OK; } else { PoolVector<uint8_t> img_data; img_data.resize(total_size); { PoolVector<uint8_t>::Write w = img_data.write(); int ofs = 0; for (int i = 0; i < mipmap_images.size(); i++) { PoolVector<uint8_t> id = mipmap_images[i]->get_data(); int len = id.size(); PoolVector<uint8_t>::Read r = id.read(); copymem(&w[ofs], r.ptr(), len); ofs += len; } } image->create(sw, sh, true, mipmap_images[0]->get_format(), img_data); return OK; } } else {