UWP平台Taglib编译(2)
此文已由作者郑博授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验
#endif // _WIN32 }class FileStream::FileStreamPrivate { public:FileStreamPrivate(const FileName &fileName): file(InvalidFileHandle), name(fileName), readOnly(true){}FileHandle file;FileNameHandle name;bool readOnly; };// public membersFileStream::FileStream(FileName fileName, bool openReadOnly): d(new FileStreamPrivate(fileName)) {// First try with read / write mode, if that fails, fall back to read only.if(!openReadOnly)d->file = openFile(fileName, false);if(d->file != InvalidFileHandle)d->readOnly = false;elsed->file = openFile(fileName, true);if(d->file == InvalidFileHandle){ # ifdef _WIN32debug("Could not open file " + fileName.toString()); # elsedebug("Could not open file " + String(static_cast(d->name))); # endif} }FileStream::~FileStream() {if(isOpen())closeFile(d->file);delete d; }FileName FileStream::name() const {return d->name; }ByteVector FileStream::readBlock(ulong length) {if(!isOpen()) {debug("FileStream::readBlock() -- invalid file.");return ByteVector::null;}if(length == 0)return ByteVector::null;const ulong streamLength = static_cast(FileStream::length());if(length > bufferSize() && length > streamLength)length = streamLength;ByteVector buffer(static_cast(length));const size_t count = readFile(d->file, buffer);buffer.resize(static_cast(count));return buffer; }void FileStream::writeBlock(const ByteVector &data) {if(!isOpen()) {debug("FileStream::writeBlock() -- invalid file.");return;}if(readOnly()) {debug("FileStream::writeBlock() -- read only file.");return;}writeFile(d->file, data); }void FileStream::insert(const ByteVector &data, ulong start, ulong replace) {if(!isOpen()) {debug("FileStream::insert() -- invalid file.");return;}if(readOnly()) {debug("FileStream::insert() -- read only file.");return;}if(data.size() == replace) {seek(start);writeBlock(data);return;}else if(data.size() < replace) {seek(start);writeBlock(data);removeBlock(start + data.size(), replace - data.size());return;}// Woohoo! Faster (about 20%) than id3lib at last. I had to get hardcore// and avoid TagLib's high level API for rendering just copying parts of// the file that don't contain tag data.//// Now I'll explain the steps in this ugliness:// First, make sure that we're working with a buffer that is longer than// the *differnce* in the tag sizes. We want to avoid overwriting parts// that aren't yet in memory, so this is necessary.ulong bufferLength = bufferSize();while(data.size() - replace > bufferLength)bufferLength += bufferSize();// Set where to start the reading and writing.long readPosition = start + replace;long writePosition = start;ByteVector buffer = data;ByteVector aboutToOverwrite(static_cast(bufferLength));while(true){// Seek to the current read position and read the data that we're about// to overwrite. Appropriately increment the readPosition.seek(readPosition);const size_t bytesRead = readFile(d->file, aboutToOverwrite);aboutToOverwrite.resize(bytesRead);readPosition += bufferLength;// Check to see if we just read the last block. We need to call clear()// if we did so that the last write succeeds.if(bytesRead < bufferLength)clear();// Seek to the write position and write our buffer. Increment the// writePosition.seek(writePosition);writeBlock(buffer);// We hit the end of the file.if(bytesRead == 0)break;writePosition += buffer.size();// Make the current buffer the data that we read in the beginning.buffer = aboutToOverwrite;} }void FileStream::removeBlock(ulong start, ulong length) {if(!isOpen()) {debug("FileStream::removeBlock() -- invalid file.");return;}ulong bufferLength = bufferSize();long readPosition = start + length;long writePosition = start;ByteVector buffer(static_cast(bufferLength));for(size_t bytesRead = -1; bytesRead != 0;){seek(readPosition);bytesRead = readFile(d->file, buffer);readPosition += bytesRead;// Check to see if we just read the last block. We need to call clear()// if we did so that the last write succeeds.if(bytesRead < buffer.size()) {clear();buffer.resize(bytesRead);}seek(writePosition);writeFile(d->file, buffer);writePosition += bytesRead;}truncate(writePosition); }bool FileStream::readOnly() const {return d->readOnly; }bool FileStream::isOpen() const {return (d->file != InvalidFileHandle); }void FileStream::seek(long offset, Position p) {if(!isOpen()) {debug("FileStream::seek() -- invalid file.");return;}#ifdef _WIN32DWORD whence;switch(p) {case Beginning:whence = FILE_BEGIN;break;case Current:whence = FILE_CURRENT;break;case End:whence = FILE_END;break;default:debug("FileStream::seek() -- Invalid Position value.");return;}#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)LARGE_INTEGER distance = { 0 };distance.QuadPart = offset;if (!SetFilePointerEx(d->file, distance, NULL, whence)) #elseSetLastError(NO_ERROR);SetFilePointer(d->file, offset, NULL, whence);const int lastError = GetLastError();if(lastError != NO_ERROR && lastError != ERROR_NEGATIVE_SEEK) #endifdebug("FileStream::seek() -- Failed to set the file pointer.");#elseint whence;switch(p) {case Beginning:whence = SEEK_SET;break;case Current:whence = SEEK_CUR;break;case End:whence = SEEK_END;break;default:debug("FileStream::seek() -- Invalid Position value.");return;}fseek(d->file, offset, whence);#endif }void FileStream::clear() { #ifdef _WIN32// NOP#elseclearerr(d->file);#endif }long FileStream::tell() const { #ifdef _WIN32#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)LARGE_INTEGER distance = { 0 };LARGE_INTEGER position = { 0 };if (SetFilePointerEx(d->file, distance, &position, FILE_CURRENT)) {return static_cast(position.QuadPart);} #elseSetLastError(NO_ERROR);const DWORD position = SetFilePointer(d->file, 0, NULL, FILE_CURRENT);if(GetLastError() == NO_ERROR) {return static_cast(position);} #endifelse {debug("FileStream::tell() -- Failed to get the file pointer.");return 0;}#elsereturn ftell(d->file);#endif }long FileStream::length() {if(!isOpen()) {debug("FileStream::length() -- invalid file.");return 0;}#ifdef _WIN32#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)LARGE_INTEGER fileSize = { 0 };if (GetFileSizeEx(d->file, &fileSize)) {return static_cast(fileSize.QuadPart);} #elseSetLastError(NO_ERROR);const DWORD fileSize = GetFileSize(d->file, NULL);if (GetLastError() == NO_ERROR) {return static_cast(fileSize);} #endifelse {debug("FileStream::length() -- Failed to get the file size.");return 0;}#elseconst long curpos = tell();seek(0, End);const long endpos = tell();seek(curpos, Beginning);return endpos;#endif }// protected membersvoid FileStream::truncate(long length) { #ifdef _WIN32const long currentPos = tell();seek(length);SetLastError(NO_ERROR);SetEndOfFile(d->file);if(GetLastError() != NO_ERROR) {debug("FileStream::truncate() -- Failed to truncate the file.");}seek(currentPos);#elseconst int error = ftruncate(fileno(d->file), length);if(error != 0) {debug("FileStream::truncate() -- Coundn't truncate the file.");}#endif }TagLib::uint FileStream::bufferSize() {return 1024; }
为了便于调试,还需要修改taglib\toolkit\tdebuglistener.cpp,以便在调试直接在Output窗口输出调试信息,完整代码如下:
/***************************************************************************copyright : (C) 2013 by Tsuda Kageyuemail : tsuda.kageyu@gmail.com***************************************************************************//**************************************************************************** This library is free software; you can redistribute it and/or modify ** it under the terms of the GNU Lesser General Public License version ** 2.1 as published by the Free Software Foundation. ** ** This library is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ** 02110-1301 USA ** ** Alternatively, this file is available under the Mozilla Public ** License Version 1.1. You may obtain a copy of the License at ** http://www.mozilla.org/MPL/ ****************************************************************************/#include "tdebuglistener.h"#include #include #ifdef _WIN32 # include #endifusing namespace TagLib;namespace {class DefaultListener : public DebugListener{public:virtual void printMessage(const String &msg){ #ifdef _WIN32const wstring wstr = msg.toWString(); #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)OutputDebugStringW(wstr.c_str()); #elseconst int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);if(len != 0) {std::vector buf(len);WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &buf[0], len, NULL, NULL);std::cerr << std::string(&buf[0]);} #endif#elsestd::cerr << msg;#endif }};DefaultListener defaultListener; }namespace TagLib {DebugListener *debugListener = &defaultListener;DebugListener::DebugListener(){}DebugListener::~DebugListener(){}void setDebugListener(DebugListener *listener){if(listener)debugListener = listener;elsedebugListener = &defaultListener;} }
最后,编译吧,骚年!!!
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 Spring Boot 学习系列(11)—tomcat参数配置建
UWP平台Taglib编译(2)相关推荐
- UWP平台Taglib编译(1)
此文已由作者郑博授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验 最近开始开发UWP平台的App,项目需要用到Taglib进行音视频文件的标签信息读写,Google并没有现成的B ...
- 为什么unity 安装完模块还是找不到sdk_Unity填坑笔记(四)——移植UWP平台
0. 絮絮念 本来不想写这篇文章,一来做完这一波之后我再也不想做WSA平台--二来我觉得会做这个平台的人并不多,所以写下来意义也不大.不过在移植过程中ToLua的作者蒙哥给了我不少帮助,也说断断续续有 ...
- mysql windows编译_Windows平台下编译Mysql源码 | 学步园
最近由于项目的关系,需要使用到Mysql数据库,而我的工作任务与数据库有很大的关系,所以,决定好好学学Mysql,同时,也把Mysql的源码下载了,希望能有利于对它的学习.这里记录一下windows平 ...
- windows平台下载编译好的webrtc代码vs2015
windows平台下载编译好的webrtc代码vs2015 编译好的源码工程地址: https://github.com/hujianhua888/webrtc_vs2015,工程目录如下,包含所有 ...
- ubuntu平台下编译vlc-android视频播放器实践
音视频实践学习 android全平台编译ffmpeg以及x264与fdk-aac实践 ubuntu下使用nginx和nginx-rtmp-module配置直播推流服务器 android全平台编译ffm ...
- 【Jpeg】不同平台如何编译 jpeg-turbo 库文件
本文介绍不同平台下如何编译 jpeg-turbo 库文件. Mac/Linux 平台 Mac/Linux 平台编译 jpeg-turbo 库文件(libturbojpeg)的流程如下: 下载 jpeg ...
- 微软应用商店_微软:关于UWP平台,我们知道错了
早些时候我们提到知名科技网站编辑保罗认为微软 UWP 已经游戏结束,接下来这个平台可能会因此而停滞. 不过针对这些传闻微软似乎从某些方面是认同的但是也有不同,不同的主要是微软暂时不会放弃 UWP 平台 ...
- UWP平台和PC平台有什么区别
UWP平台和PC平台有什么区别 什么是UWP平台 定义不同 运行不同 起源不同 转载链接 什么是UWP平台 Universal Windows Platform(UWP)直译过来就是通用Win ...
- 使用VS在64位平台下编译代码,生成64位dll
最近要把一个之前在32位平台下编译的项目改成64位平台,之前从来没搞过关于64位的东西,所以到处查资料,所幸搞成功了,把过程记录一下,防止以后忘记. 首先声明:64位平台无法直接调用32位dll,32 ...
最新文章
- 中学计算机课 打字教案,初中信息技术《打字练习—易语言应用》教案
- 浅析正则表达式模式匹配的 String 方法
- Android开发 - 解决DialogFragment在全屏时View被状态栏遮住的问题
- XCode 6 出现 no identity found: Command /usr/bin/codesign failed with exit code 1 解决方法汇总...
- MOCTF-Web-我想要钱
- groovy 字符串截取最后一个_python数据类型总结——数字和字符串
- 高性价比手持机有哪些
- linux 查看进程启动路径
- python查找字符串数量_python如何实现从字符串中找出字符1的位置以及个数的示例...
- C#判断检测网络是否连接
- 服务提供者框架讲解 之 myJDBC
- 京东云,走进产业数字化深处
- KubeCon 上海 SOFAStack Cloud Native Workshop 报名中
- RN Error: 无法获取此包的编译时间戳。请更新react-native-update到最新版本后重新打包上传。
- CentOS 6.8安装Docker V1.0
- SVG——入门,路径变形动画
- 20个国内Android平台移动应用市场
- 大学计算机学院操行表个人小结,大学生操行鉴定表个人总结
- 【通信系统仿真系列】基于Matlab的汉明码(Hamming Code)纠错传输以及交织编码(Interleaved coding)仿真
- nvidia jetson nano 操作指南