30 #include "io_strings.h"
35 #if !defined HAVE_MKSTEMP
39 #if defined HAVE_UNISTD_H
43 #if defined HAVE_SYS_STAT_H
44 # include <sys/stat.h>
47 #if defined WIN32 && (!defined(WINCE))
49 static int truncate(
const char *path,
size_t length)
54 fh = ::CreateFile(path,
55 GENERIC_WRITE | GENERIC_READ,
59 FILE_ATTRIBUTE_NORMAL,
62 if(INVALID_HANDLE_VALUE != fh)
64 SetFilePointer(fh, length,
NULL, FILE_BEGIN);
74 # if defined CreateFile
82 static int truncate(
const char *path,
size_t length)
85 wchar_t wcTempPath[256];
86 mbstowcs(wcTempPath,path,255);
88 fh = ::CreateFile(wcTempPath,
89 GENERIC_WRITE | GENERIC_READ,
93 FILE_ATTRIBUTE_NORMAL,
96 if (INVALID_HANDLE_VALUE != fh)
98 SetFilePointer(fh, length,
NULL, FILE_BEGIN);
107 #elif defined(macintosh)
109 static int truncate(
const char *path,
size_t length)
128 return this->Link(fileInfo, tt);
133 _tags_to_parse.set(tag_types);
135 if (
NULL == fileInfo)
140 _file_name = fileInfo;
145 return this->GetPrependedBytes();
151 _tags_to_parse.set(tag_types);
156 this->ParseReader(reader);
158 return this->GetPrependedBytes();
174 file.seekp(0, ios::end);
196 file.seekp(0, ios::end);
209 ID3D_NOTICE(
"RenderV2ToFile: starting" );
212 ID3D_WARNING(
"RenderV2ToFile: error in file" );
217 io::StringWriter writer(tagString);
219 ID3D_NOTICE(
"RenderV2ToFile: rendered v2" );
221 const char* tagData = tagString.data();
222 size_t tagSize = tagString.size();
228 file.seekp(0, ios::beg);
229 file.write(tagData, tagSize);
234 String sTmpSuffix =
".XXXXXX";
242 strcpy(sTempFile, filename.c_str());
243 strcat(sTempFile, sTmpSuffix.c_str());
245 #if !defined(HAVE_MKSTEMP)
250 tmpOut.write(tagData, tagSize);
252 char *tmpBuffer[BUFSIZ];
255 file.read((
char *)tmpBuffer, BUFSIZ);
256 size_t nBytes = file.gcount();
257 tmpOut.write((
char *)tmpBuffer, nBytes);
266 int fd = mkstemp(sTempFile);
273 ofstream tmpOut(sTempFile);
283 tmpOut.write(tagData, tagSize);
285 uchar tmpBuffer[BUFSIZ];
288 file.read((
char *)tmpBuffer, BUFSIZ);
289 size_t nBytes = file.gcount();
290 tmpOut.write((
char *)tmpBuffer, nBytes);
302 #if defined(HAVE_SYS_STAT_H)
303 struct stat fileStat;
304 if(stat(filename.c_str(), &fileStat) == 0)
307 remove(filename.c_str());
308 rename(sTempFile, filename.c_str());
309 #if defined(HAVE_SYS_STAT_H)
310 chmod(filename.c_str(), fileStat.st_mode);
328 String filename = this->GetFileName();
341 if ((ulTagFlag &
ID3TT_ID3V2) && this->HasChanged())
344 if (_prepended_bytes)
351 (!this->HasTagType(
ID3TT_ID3V1) || this->HasChanged()))
359 _appended_bytes += tag_bytes;
365 _file_tags.add(tags);
390 file.seekg(this->GetPrependedBytes(), ios::beg);
392 uchar aucBuffer[BUFSIZ];
395 size_t nBytesToCopy = data_size;
401 nBytesToCopy += this->GetAppendedBytes();
408 size_t nBytesRemaining = nBytesToCopy,
412 #if (defined(__GNUC__) && __GNUC__ == 2)
413 size_t nBytesToRead = (size_t)
dami::min((
unsigned int)(nBytesRemaining - nBytesCopied), (
unsigned int)BUFSIZ);
415 size_t nBytesToRead =
min((
unsigned int)(nBytesRemaining - nBytesCopied), (
unsigned int)BUFSIZ);
417 file.read((
char *)aucBuffer, nBytesToRead);
418 size_t nBytesRead = file.gcount();
420 if (nBytesRead != nBytesToRead)
428 long offset = nBytesRead + this->GetPrependedBytes();
429 file.seekp(-offset, ios::cur);
430 file.write((
char *)aucBuffer, nBytesRead);
431 file.seekg(this->GetPrependedBytes(), ios::cur);
432 nBytesCopied += nBytesRead;
435 if (nBytesCopied == nBytesToCopy || nBytesToRead < BUFSIZ)
443 size_t nNewFileSize = data_size;
453 nNewFileSize += this->GetAppendedBytes();
467 nNewFileSize += this->GetPrependedBytes();
470 if (ulTags && (truncate(_file_name.c_str(), nNewFileSize) == -1))
478 _appended_bytes = (ulTags &
ID3TT_APPENDED) ? 0 : _appended_bytes;
479 _file_size = data_size + _prepended_bytes + _appended_bytes;
481 _changed = _file_tags.remove(ulTags) || _changed;
flags_t Strip(flags_t=(flags_t) ID3TT_ALL)
size_t GetFileSize() const
dami::String GetFileName() const
size_t GetPrependedBytes() const
flags_t Update(flags_t=(flags_t) ID3TT_ALL)
size_t Link(const char *fileInfo, flags_t=(flags_t) ID3TT_ALL)
ID3_Err
Predefined id3lib error types.
@ ID3E_ReadOnly
Attempting to write to a read-only file.
@ ID3E_NoError
No error reported.
@ ID3E_NoFile
No file to parse.
@ ID3TT_APPENDED
Represents all tag types that can be appended to a file.
@ ID3TT_ID3V2
Represents an id3v2 tag.
@ ID3TT_PREPENDED
Represents all tag types that can be prepended to a file.
@ ID3TT_ID3V1
Represents an id3v1 or id3v1.1 tag.
@ ID3TT_NONE
Represents an empty or non-existant tag.
void render(ID3_Writer &, const ID3_TagImpl &)
void render(ID3_Writer &writer, const ID3_TagImpl &tag)
size_t ID3_C_EXPORT getFileSize(fstream &)
const T & min(const T &a, const T &b)
ID3_Err ID3_C_EXPORT openWritableFile(String, fstream &)
ID3_Err ID3_C_EXPORT createFile(String, fstream &)
size_t RenderV1ToFile(ID3_TagImpl &tag, fstream &file)
size_t RenderV2ToFile(const ID3_TagImpl &tag, fstream &file)
size_t ID3_GetDataSize(const ID3_TagImpl &tag)