EmErrorCode MacDecoder::Open(const string& url) { int err; str_utf16* pFileName = GetUTF16FromUTF8((str_utf8*)url.c_str()); m_pDecompress = CreateIAPEDecompress(pFileName, &err); delete[] pFileName; if (m_pDecompress == nullptr || err != ERROR_SUCCESS) return ErrorCode::DecoderFailedToOpen; m_Channels = m_pDecompress->GetInfo(APE_INFO_CHANNELS); m_SampleRate = m_pDecompress->GetInfo(APE_INFO_SAMPLE_RATE); m_BitsPerSample = m_pDecompress->GetInfo(APE_INFO_BITS_PER_SAMPLE); m_Duration = m_pDecompress->GetInfo(APE_INFO_LENGTH_MS); m_BlockAlign = m_pDecompress->GetInfo(APE_INFO_BLOCK_ALIGN); m_BlocksPerFrame = m_pDecompress->GetInfo(APE_INFO_BLOCKS_PER_FRAME); m_BlockCount = m_pDecompress->GetInfo(APE_INFO_TOTAL_BLOCKS); m_BlocksPerRead = m_BlocksPerFrame / 16; m_BlockIndex = 0; return ErrorCode::Ok; }
void CAPELink::ParseData(const char * pData, const str_utf16 * pFilename) { // empty m_bIsLinkFile = FALSE; m_nStartBlock = 0; m_nFinishBlock = 0; m_cImageFilename[0] = 0; if (pData != NULL) { // parse out the information const char * pHeader = strstr(pData, APE_LINK_HEADER); const char * pImageFile = strstr(pData, APE_LINK_IMAGE_FILE_TAG); const char * pStartBlock = strstr(pData, APE_LINK_START_BLOCK_TAG); const char * pFinishBlock = strstr(pData, APE_LINK_FINISH_BLOCK_TAG); if (pHeader && pImageFile && pStartBlock && pFinishBlock) { if ((_strnicmp(pHeader, APE_LINK_HEADER, strlen(APE_LINK_HEADER)) == 0) && (_strnicmp(pImageFile, APE_LINK_IMAGE_FILE_TAG, strlen(APE_LINK_IMAGE_FILE_TAG)) == 0) && (_strnicmp(pStartBlock, APE_LINK_START_BLOCK_TAG, strlen(APE_LINK_START_BLOCK_TAG)) == 0) && (_strnicmp(pFinishBlock, APE_LINK_FINISH_BLOCK_TAG, strlen(APE_LINK_FINISH_BLOCK_TAG)) == 0)) { // get the start and finish blocks m_nStartBlock = atoi(&pStartBlock[strlen(APE_LINK_START_BLOCK_TAG)]); m_nFinishBlock = atoi(&pFinishBlock[strlen(APE_LINK_FINISH_BLOCK_TAG)]); // get the path char cImageFile[MAX_PATH + 1]; int nIndex = 0; const char * pImageCharacter = &pImageFile[strlen(APE_LINK_IMAGE_FILE_TAG)]; while ((*pImageCharacter != 0) && (*pImageCharacter != '\r') && (*pImageCharacter != '\n')) cImageFile[nIndex++] = *pImageCharacter++; cImageFile[nIndex] = 0; CSmartPtr<str_utf16> spImageFileUTF16(GetUTF16FromUTF8((unsigned char *) cImageFile), TRUE); // process the path if (wcsrchr(spImageFileUTF16, '\\') == NULL) { str_utf16 cImagePath[MAX_PATH + 1]; wcscpy(cImagePath, pFilename); wcscpy(wcsrchr(cImagePath, '\\') + 1, spImageFileUTF16); wcscpy(m_cImageFilename, cImagePath); } else { wcscpy(m_cImageFilename, spImageFileUTF16); } // this is a valid link file m_bIsLinkFile = TRUE; } } } }
int CAPETag::GetFieldString(const str_utf16 * pFieldName, str_utf16 * pBuffer, int * pBufferCharacters) { if (m_bAnalyzed == FALSE) { Analyze(); } int nRetVal = ERROR_UNDEFINED; if (*pBufferCharacters > 0) { CAPETagField * pAPETagField = GetTagField(pFieldName); if (pAPETagField == NULL) { // the field doesn't exist -- return an empty string memset(pBuffer, 0, *pBufferCharacters * sizeof(str_utf16)); *pBufferCharacters = 0; } else if (pAPETagField->GetIsUTF8Text() || (m_nAPETagVersion < 2000)) { // get the value in UTF-16 format CSmartPtr<str_utf16> spUTF16; if (m_nAPETagVersion >= 2000) spUTF16.Assign(GetUTF16FromUTF8((str_utf8 *) pAPETagField->GetFieldValue()), TRUE); else spUTF16.Assign(GetUTF16FromANSI(pAPETagField->GetFieldValue()), TRUE); // get the number of characters int nCharacters = (wcslen(spUTF16) + 1); if (nCharacters > *pBufferCharacters) { // we'll fail here, because it's not clear what would get returned (null termination, size, etc.) // and we really don't want to cause buffer overruns on the client side *pBufferCharacters = nCharacters; } else { // just copy in *pBufferCharacters = nCharacters; memcpy(pBuffer, spUTF16.GetPtr(), *pBufferCharacters * sizeof(str_utf16)); nRetVal = ERROR_SUCCESS; } } else { // memset the whole buffer to NULL (so everything left over is NULL terminated) memset(pBuffer, 0, *pBufferCharacters * sizeof(str_utf16)); // do a binary dump (need to convert from wchar's to bytes) int nBufferBytes = (*pBufferCharacters - 1) * sizeof(str_utf16); nRetVal = GetFieldBinary(pFieldName, pBuffer, &nBufferBytes); *pBufferCharacters = (nBufferBytes / sizeof(str_utf16)) + 1; } } return nRetVal; }
int CAPETag::LoadField(const char * pBuffer, int nMaximumBytes, int * pBytes) { // set bytes to 0 if (pBytes) *pBytes = 0; // size and flags int nLocation = 0; int nFieldValueSize = *((int *) &pBuffer[nLocation]); nLocation += 4; int nFieldFlags = *((int *) &pBuffer[nLocation]); nLocation += 4; // safety check (so we can't get buffer overflow attacked) int nMaximumRead = nMaximumBytes - 8 - nFieldValueSize; BOOL bSafe = TRUE; for (int z = 0; (z < nMaximumRead) && (bSafe == TRUE); z++) { int nCharacter = pBuffer[nLocation + z]; if (nCharacter == 0) break; if ((nCharacter < 0x20) || (nCharacter > 0x7E)) bSafe = FALSE; } if (bSafe == FALSE) return -1; // name int nNameCharacters = strlen(&pBuffer[nLocation]); CSmartPtr<str_utf8> spNameUTF8(new str_utf8 [nNameCharacters + 1], TRUE); memcpy(spNameUTF8, &pBuffer[nLocation], (nNameCharacters + 1) * sizeof(str_utf8)); nLocation += nNameCharacters + 1; CSmartPtr<str_utf16> spNameUTF16(GetUTF16FromUTF8(spNameUTF8.GetPtr()), TRUE); // value CSmartPtr<char> spFieldBuffer(new char [nFieldValueSize], TRUE); memcpy(spFieldBuffer, &pBuffer[nLocation], nFieldValueSize); nLocation += nFieldValueSize; // update the bytes if (pBytes) *pBytes = nLocation; // set return SetFieldBinary(spNameUTF16.GetPtr(), spFieldBuffer, nFieldValueSize, nFieldFlags); }