Ejemplo n.º 1
0
size_t RenderV2ToFile(const ID3_TagImpl& tag, fstream& file)
{
  ID3D_NOTICE( "RenderV2ToFile: starting" );
  if (!file)
  {
    ID3D_WARNING( "RenderV2ToFile: error in file" );
    return 0;
  }

  String tagString;
  io::StringWriter writer(tagString);
  id3::v2::render(writer, tag);
  ID3D_NOTICE( "RenderV2ToFile: rendered v2" );

  const char* tagData = tagString.data();
  size_t tagSize = tagString.size();
  // if the new tag fits perfectly within the old and the old one
  // actually existed (ie this isn't the first tag this file has had)
  if ((!tag.GetPrependedBytes() && !ID3_GetDataSize(tag)) ||
      (tagSize == tag.GetPrependedBytes()))
  {
    file.seekp(0, ios::beg);
    file.write(tagData, tagSize);
  }
  else
  {
    String filename = tag.GetFileName();
    String sTmpSuffix = ".XXXXXX";
    if (filename.size() + sTmpSuffix.size() > ID3_PATH_LENGTH)
    {
      // log this
      return 0;
      //ID3_THROW_DESC(ID3E_NoFile, "filename too long");
    }
    char sTempFile[ID3_PATH_LENGTH];
    strcpy(sTempFile, filename.c_str());
    strcat(sTempFile, sTmpSuffix.c_str());

#if ((defined(__GNUC__) && __GNUC__ >= 3  ) || !defined(HAVE_MKSTEMP))
    // This section is for Windows folk && gcc 3.x folk
    fstream tmpOut;
    createFile(sTempFile, tmpOut);

    tmpOut.write(tagData, tagSize);
    file.seekg(tag.GetPrependedBytes(), ios::beg);
    char *tmpBuffer[BUFSIZ];
    while (!file.eof())
    {
      file.read((char *)tmpBuffer, BUFSIZ);
      size_t nBytes = file.gcount();
      tmpOut.write((char *)tmpBuffer, nBytes);
    }

#else //((defined(__GNUC__) && __GNUC__ >= 3  ) || !defined(HAVE_MKSTEMP))

    // else we gotta make a temp file, copy the tag into it, copy the
    // rest of the old file after the tag, delete the old file, rename
    // this new file to the old file's name and update the handle

    int fd = mkstemp(sTempFile);
    if (fd < 0)
    {
      remove(sTempFile);
      //ID3_THROW_DESC(ID3E_NoFile, "couldn't open temp file");
    }

    ofstream tmpOut(fd);
    if (!tmpOut)
    {
      tmpOut.close();
      remove(sTempFile);
      return 0;
      // log this
      //ID3_THROW(ID3E_ReadOnly);
    }

    tmpOut.write(tagData, tagSize);
    file.seekg(tag.GetPrependedBytes(), ios::beg);
    uchar tmpBuffer[BUFSIZ];
    while (file)
    {
      file.read(tmpBuffer, BUFSIZ);
      size_t nBytes = file.gcount();
      tmpOut.write(tmpBuffer, nBytes);
    }

    close(fd); //closes the file

#endif ////((defined(__GNUC__) && __GNUC__ >= 3  ) || !defined(HAVE_MKSTEMP))

    tmpOut.close();
    file.close();

    // the following sets the permissions of the new file
    // to be the same as the original
#if defined(HAVE_SYS_STAT_H)
    struct stat fileStat;
    if(stat(filename.c_str(), &fileStat) == 0)
    {
#endif //defined(HAVE_SYS_STAT_H)
      remove(filename.c_str());
      rename(sTempFile, filename.c_str());
#if defined(HAVE_SYS_STAT_H)
      chmod(filename.c_str(), fileStat.st_mode);
    }
#endif //defined(HAVE_SYS_STAT_H)

//    file = tmpOut;
    file.clear();//to clear the eof mark
    openWritableFile(filename, file);
  }

  return tagSize;
}
Ejemplo n.º 2
0
size_t RenderV2ToFile(const ID3_TagImpl& tag, fstream& file)
{
  ID3D_NOTICE( "RenderV2ToFile: starting" );
  if (!file)
  {
    ID3D_WARNING( "RenderV2ToFile: error in file" );
    return 0;
  }

  String tagString; 
  io::StringWriter writer(tagString);
  id3::v2::render(writer, tag);
  ID3D_NOTICE( "RenderV2ToFile: rendered v2" );

  const char* tagData = tagString.data();
  size_t tagSize = tagString.size();

  // if the new tag fits perfectly within the old and the old one
  // actually existed (ie this isn't the first tag this file has had)
  if ((!tag.GetPrependedBytes() && !ID3_GetDataSize(tag)) ||
      (tagSize == tag.GetPrependedBytes()))
  {
    file.seekp(0, ios::beg);
    file.write(tagData, tagSize);
  }
  else
  {
    String filename = tag.GetFileName();
#if !defined HAVE_MKSTEMP
    // This section is for Windows folk

    FILE *tempOut = tmpfile();
    if (NULL == tempOut)
    {
      // log this
      return 0;
      //ID3_THROW(ID3E_ReadOnly);
    }
    
    fwrite(tagData, 1, tagSize, tempOut);
    
    file.seekg(tag.GetPrependedBytes(), ios::beg);
    
    uchar tmpBuffer[BUFSIZ];
    while (!file)
    {
      file.read((char *)tmpBuffer, BUFSIZ);
      size_t nBytes = file.gcount();
      fwrite(tmpBuffer, 1, nBytes, tempOut);
    }
    
    rewind(tempOut);
    openWritableFile(filename, file);
    
    while (!feof(tempOut))
    {
      size_t nBytes = fread(tmpBuffer, 1, BUFSIZ, tempOut);
      file.write((char *)tmpBuffer, nBytes);
    }
    
    fclose(tempOut);
    
#else

    // else we gotta make a temp file, copy the tag into it, copy the
    // rest of the old file after the tag, delete the old file, rename
    // this new file to the old file's name and update the handle
    String sTmpSuffix = ".XXXXXX";
    if (filename.size() + sTmpSuffix.size() > ID3_PATH_LENGTH)
    {
      // log this
      return 0;
      //ID3_THROW_DESC(ID3E_NoFile, "filename too long");
    }
    char sTempFile[ID3_PATH_LENGTH];
    strcpy(sTempFile, filename.c_str());
    strcat(sTempFile, sTmpSuffix.c_str());
    
    int fd = mkstemp(sTempFile);
    if (fd < 0)
    {
      remove(sTempFile);
      //ID3_THROW_DESC(ID3E_NoFile, "couldn't open temp file");
    }

    ofstream tmpOut(fd);
    if (!tmpOut)
    {
      tmpOut.close();
      remove(sTempFile);
      return 0;
      // log this
      //ID3_THROW(ID3E_ReadOnly);
    }

    tmpOut.write(tagData, tagSize);
    file.seekg(tag.GetPrependedBytes(), ios::beg);
    uchar tmpBuffer[BUFSIZ];
    while (file)
    {
      file.read(tmpBuffer, BUFSIZ);
      size_t nBytes = file.gcount();
      tmpOut.write(tmpBuffer, nBytes);
    }
      
    tmpOut.close();

    file.close();

    remove(filename.c_str());
    rename(sTempFile, filename.c_str());

    openWritableFile(filename, file);
#endif
  }

  return tagSize;
}
Ejemplo n.º 3
0
size_t ID3_GetDataSize(const ID3_TagImpl& tag)
{
  return tag.GetFileSize() - tag.GetPrependedBytes() - tag.GetAppendedBytes();
}