⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io_helpers.cpp

📁 更新mp3
💻 CPP
字号:
// $Id: io_helpers.cpp,v 1.13 2002/07/02 22:13:56 t1mpy Exp $// id3lib: a C++ library for creating and manipulating id3v1/v2 tags// Copyright 1999, 2000  Scott Thomas Haug// This library is free software; you can redistribute it and/or modify it// under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2 of the License, or (at your// option) any later version.//// 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 Library General Public// License for more details.//// You should have received a copy of the GNU Library General Public License// along with this library; if not, write to the Free Software Foundation,// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// The id3lib authors encourage improvements and optimisations to be sent to// the id3lib coordinator.  Please see the README file for details on where to// send such submissions.  See the AUTHORS file for a list of people who have// contributed to id3lib.  See the ChangeLog file for a list of changes to// id3lib.  These files are distributed with id3lib at// http://download.sourceforge.net/id3lib/#if defined HAVE_CONFIG_H#include <config.h>#endif#include "id3/io_decorators.h" //has "readers.h" "io_helpers.h" "utils.h"using namespace dami;String io::readString(ID3_Reader& reader){  String str;  while (!reader.atEnd())  {    ID3_Reader::char_type ch = reader.readChar();    if (ch == '\0')    {      break;    }    str += static_cast<char>(ch);  }  return str;}String io::readText(ID3_Reader& reader, size_t len){  String str;  str.reserve(len);  const size_t SIZE = 1024;  ID3_Reader::char_type buf[SIZE];  size_t remaining = len;  while (remaining > 0 && !reader.atEnd())  {    size_t numRead = reader.readChars(buf, min(remaining, SIZE));    remaining -= numRead;    str.append(reinterpret_cast<String::value_type *>(buf), numRead);  }  return str;}namespace{  bool isNull(unsigned char ch1, unsigned char ch2)  {    return ch1 == '\0' && ch2 == '\0';  }  int isBOM(unsigned char ch1, unsigned char ch2)  {  // The following is taken from the following URL:  // http://community.roxen.com/developers/idocs/rfc/rfc2781.html  /* The Unicode Standard and ISO 10646 define the character "ZERO WIDTH     NON-BREAKING SPACE" (0xFEFF), which is also known informally as     "BYTE ORDER MARK" (abbreviated "BOM"). The latter name hints at a     second possible usage of the character, in addition to its normal     use as a genuine "ZERO WIDTH NON-BREAKING SPACE" within text. This     usage, suggested by Unicode section 2.4 and ISO 10646 Annex F     (informative), is to prepend a 0xFEFF character to a stream of     Unicode characters as a "signature"; a receiver of such a serialized     stream may then use the initial character both as a hint that the     stream consists of Unicode characters and as a way to recognize the     serialization order. In serialized UTF-16 prepended with such a     signature, the order is big-endian if the first two octets are 0xFE     followed by 0xFF; if they are 0xFF followed by 0xFE, the order is     little-endian. Note that 0xFFFE is not a Unicode character,     precisely to preserve the usefulness of 0xFEFF as a byte-order     mark. */    if (ch1 == 0xFE && ch2 == 0xFF)    {      return 1;    }    else if (ch1 == 0xFF && ch2 == 0xFE)    {      return -1;    }    return 0;  }  bool readTwoChars(ID3_Reader& reader,                     ID3_Reader::char_type& ch1,                     ID3_Reader::char_type& ch2)  {    if (reader.atEnd())    {      return false;    }    io::ExitTrigger et(reader);    ch1 = reader.readChar();    if (reader.atEnd())    {      return false;    }    et.release();    ch2 = reader.readChar();    return true;  }}String io::readUnicodeString(ID3_Reader& reader){  String unicode;  ID3_Reader::char_type ch1, ch2;  if (!readTwoChars(reader, ch1, ch2) || isNull(ch1, ch2))  {    return unicode;  }  int bom = isBOM(ch1, ch2);  if (!bom)  {    unicode += static_cast<char>(ch1);    unicode += static_cast<char>(ch2);  }  while (!reader.atEnd())  {    if (!readTwoChars(reader, ch1, ch2) || isNull(ch1, ch2))    {      break;    }    if (bom == -1)    {      unicode += static_cast<char>(ch2);      unicode += static_cast<char>(ch1);    }    else    {      unicode += static_cast<char>(ch1);      unicode += static_cast<char>(ch2);    }  }  return unicode;}String io::readUnicodeText(ID3_Reader& reader, size_t len){  String unicode;  ID3_Reader::char_type ch1, ch2;  if (!readTwoChars(reader, ch1, ch2))  {    return unicode;  }  len -= 2;  int bom = isBOM(ch1, ch2);  if (!bom)  {    unicode += ch1;    unicode += ch2;    unicode += readText(reader, len);  }  else if (bom == 1)  {    unicode = readText(reader, len);  }  else  {    for (size_t i = 0; i < len; i += 2)    {      if (!readTwoChars(reader, ch1, ch2))      {        break;      }      unicode += ch2;      unicode += ch1;    }  }  return unicode;}BString io::readAllBinary(ID3_Reader& reader){  return readBinary(reader, reader.remainingBytes());}BString io::readBinary(ID3_Reader& reader, size_t len){  BString binary;  binary.reserve(len);    size_t remaining = len;  const size_t SIZE = 1024;  ID3_Reader::char_type buf[SIZE];  while (!reader.atEnd() && remaining > 0)  {    size_t numRead = reader.readChars(buf, min(remaining, SIZE));    remaining -= numRead;    binary.append(reinterpret_cast<BString::value_type *>(buf), numRead);  }    return binary;}uint32 io::readLENumber(ID3_Reader& reader, size_t len){  uint32 val = 0;  for (size_t i = 0; i < len; i++)  {    if (reader.atEnd())    {      break;    }    val += (static_cast<uint32>(0xFF & reader.readChar()) << (i * 8));  }  return val;}uint32 io::readBENumber(ID3_Reader& reader, size_t len){  uint32 val = 0;    for (ID3_Reader::size_type i = 0; i < len && !reader.atEnd(); ++i)  {    val *= 256; // 2^8    val += static_cast<uint32>(0xFF & reader.readChar());  }  return val;}String io::readTrailingSpaces(ID3_Reader& reader, size_t len){  io::WindowedReader wr(reader, len);  String str;  String spaces;  str.reserve(len);  spaces.reserve(len);  while (!wr.atEnd())  {    ID3_Reader::char_type ch = wr.readChar();    if (ch == '\0' || ch == ' ')    {      spaces += ch;    }    else    {      str += spaces + (char) ch;      spaces.erase();    }  }  return str;}uint32 io::readUInt28(ID3_Reader& reader){  uint32 val = 0;  const unsigned short BITSUSED = 7;  const uint32 MAXVAL = MASK(BITSUSED * sizeof(uint32));  // For each byte of the first 4 bytes in the string...  for (size_t i = 0; i < sizeof(uint32); ++i)  {    if (reader.atEnd())    {      break;    }    // ...append the last 7 bits to the end of the temp integer...    val = (val << BITSUSED) | static_cast<uint32>(reader.readChar()) & MASK(BITSUSED);  }  // We should always parse 4 characters  return min(val, MAXVAL);}size_t io::writeBENumber(ID3_Writer& writer, uint32 val, size_t len){  ID3_Writer::char_type bytes[sizeof(uint32)];  ID3_Writer::size_type size = min<ID3_Reader::size_type>(len, sizeof(uint32));  renderNumber(bytes, val, size);  return writer.writeChars(bytes, size);}size_t io::writeTrailingSpaces(ID3_Writer& writer, String buf, size_t len){  ID3_Writer::pos_type beg = writer.getCur();  ID3_Writer::size_type strLen = buf.size();  ID3_Writer::size_type size = min((unsigned int)len, (unsigned int)strLen);  writer.writeChars(buf.data(), size);  for (; size < len; ++size)  {    writer.writeChar('\0');  }  return writer.getCur() - beg;}size_t io::writeUInt28(ID3_Writer& writer, uint32 val){  uchar data[sizeof(uint32)];  const unsigned short BITSUSED = 7;  const uint32 MAXVAL = MASK(BITSUSED * sizeof(uint32));  val = min(val, MAXVAL);  // This loop renders the value to the character buffer in reverse order, as   // it is easy to extract the last 7 bits of an integer.  This is why the  // loop shifts the value of the integer by 7 bits for each iteration.  for (size_t i = 0; i < sizeof(uint32); ++i)  {    // Extract the last BITSUSED bits from val and put it in its appropriate    // place in the data buffer    data[sizeof(uint32) - i - 1] = static_cast<uchar>(val & MASK(BITSUSED));    // The last BITSUSED bits were extracted from the val.  So shift it to the    // right by that many bits for the next iteration    val >>= BITSUSED;  }    // Should always render 4 bytes  return writer.writeChars(data, sizeof(uint32));}size_t io::writeString(ID3_Writer& writer, String data){  size_t size = writeText(writer, data);  writer.writeChar('\0');  return size + 1;}size_t io::writeText(ID3_Writer& writer, String data){  ID3_Writer::pos_type beg = writer.getCur();  writer.writeChars(data.data(), data.size());  return writer.getCur() - beg;}size_t io::writeUnicodeString(ID3_Writer& writer, String data, bool bom){  size_t size = writeUnicodeText(writer, data, bom);  unicode_t null = NULL_UNICODE;  writer.writeChars((const unsigned char*) &null, 2);  return size + 2;}size_t io::writeUnicodeText(ID3_Writer& writer, String data, bool bom){  ID3_Writer::pos_type beg = writer.getCur();  size_t size = (data.size() / 2) * 2;  if (size == 0)  {    return 0;  }  if (bom)  {    // Write the BOM: 0xFEFF    unicode_t BOM = 0xFEFF;    writer.writeChars((const unsigned char*) &BOM, 2);    for (size_t i = 0; i < size; i += 2)    {      unicode_t ch = (data[i] << 8) | data[i+1];      writer.writeChars((const unsigned char*) &ch, 2);    }  }  return writer.getCur() - beg;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -