diff options
Diffstat (limited to 'samples/source/common')
-rw-r--r-- | samples/source/common/DumpFile.cpp | 308 | ||||
-rw-r--r-- | samples/source/common/TagTree.cpp | 19 | ||||
-rw-r--r-- | samples/source/common/TagTree.h | 3 | ||||
-rw-r--r-- | samples/source/common/globals.h | 2 |
4 files changed, 295 insertions, 37 deletions
diff --git a/samples/source/common/DumpFile.cpp b/samples/source/common/DumpFile.cpp index 32dd253..4d1e59f 100644 --- a/samples/source/common/DumpFile.cpp +++ b/samples/source/common/DumpFile.cpp @@ -28,7 +28,11 @@ // // DumpFile does depend on XMPCore and the packetscanner from XMPFiles. + #include <stdarg.h> + +#include "source/ExpatAdapter.hpp" + #include "samples/source/common/globals.h" #include "samples/source/common/DumpFile.h" #include "samples/source/common/LargeFileAccess.hpp" @@ -297,12 +301,12 @@ struct JpegMarker { }; typedef std::vector<JpegMarker> JpegMarkers; -static void DumpTIFF ( XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const char * label, std::string path ); +static void DumpTIFF ( XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const char * label, std::string path, bool isHeaderAbsent = false ); static void DumpTIFF ( const JpegMarkers& psirMarkers, XMP_Uns8 * dataStart, const char * label, std::string path ); static void DumpIPTC ( XMP_Uns8 * iptcOrigin, XMP_Uns32 iptcLen, XMP_Uns32 fileOffset, const char * label ); static void DumpImageResources ( XMP_Uns8 * psirOrigin, XMP_Uns32 psirLen, XMP_Uns32 fileOffset, const char * label ); static void DumpImageResources ( const JpegMarkers& psirMarkers, XMP_Uns8 * dataStart, const char * label ); -static void DumpIFDChain ( XMP_Uns8 * startPtr, XMP_Uns8 * endPtr, XMP_Uns8 * tiffContent, XMP_Uns32 fileOffset, const char * label, std::string path ); +static void DumpIFDChain ( XMP_Uns8 * startPtr, XMP_Uns8 * endPtr, XMP_Uns8 * tiffContent, XMP_Uns32 fileOffset, const char * label, std::string path, bool isHeaderAbsent = false ); // ================================================================================================= @@ -416,10 +420,11 @@ enum { kTIFF_SRational = 10, kTIFF_Float = 11, kTIFF_Double = 12, - kTIFF_TypeEnd + kTIFF_IFD = 13, + kTIFF_TypeEnd = kTIFF_IFD }; -static const int sTIFF_TypeSizes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 }; +static const int sTIFF_TypeSizes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4 }; static const char * sTIFF_TypeNames[] = { "", "BYTE", "ASCII", "SHORT", "LONG", "RATIONAL", "SBYTE", "UNDEFINED", "SSHORT", "SLONG", "SRATIONAL", "FLOAT", "DOUBLE" }; @@ -958,6 +963,12 @@ static const XMP_Uns32 kISOBrand_mp41 = 0x6D703431UL; static const XMP_Uns32 kISOBrand_mp42 = 0x6D703432UL; static const XMP_Uns32 kISOBrand_avc1 = 0x61766331UL; static const XMP_Uns32 kISOBrand_f4v = 0x66347620UL; +static const XMP_Uns32 kISOBrand_isom = 0x69736F6DUL; +static const XMP_Uns32 kISOBrand_3gp4 = 0x33677034UL; +static const XMP_Uns32 kISOBrand_3g2a = 0x33673261UL; +static const XMP_Uns32 kISOBrand_3g2b = 0x33673262UL; +static const XMP_Uns32 kISOBrand_3g2c = 0x33673263UL; + static const XMP_Uns32 kQTTag_XMP_ = 0x584D505FUL; @@ -1047,6 +1058,11 @@ CheckFileFormat ( const char * filePath, XMP_Uns8 * fileContent, XMP_Int64 fileS case kISOBrand_mp41: case kISOBrand_mp42: case kISOBrand_avc1: + case kISOBrand_isom: + case kISOBrand_3gp4: + case kISOBrand_3g2a: + case kISOBrand_3g2b: + case kISOBrand_3g2c: return kXMP_MPEG4File; break; @@ -1071,6 +1087,11 @@ CheckFileFormat ( const char * filePath, XMP_Uns8 * fileContent, XMP_Int64 fileS if ( LookupFileExtMapping (filePath) == kXMP_MPEGFile ) return kXMP_MPEGFile; if ( LookupFileExtMapping (filePath) == kXMP_MOVFile ) return kXMP_MOVFile; + std::string fileData = (char*)fileContent; + if ( (fileSize > 30) && (int)fileData.find ( "<svg" ) >= 0 ) { + return kXMP_SVGFile; + } + return kXMP_UnknownFile; } // CheckFileFormat @@ -1676,6 +1697,14 @@ DumpOneIFD (int ifdIndex, XMP_Uns8 * ifdPtr, XMP_Uns8 * endPtr, case kTIFF_Double : break; + case kTIFF_IFD: + if ( valueCount == 1 ) { + value32 = TIFF_GetUns32 ( valuePtr ); + tree->addComment ( "hex value = 0x%.8X", value32 ); + tree->changeValue ( "%u", value32 ); + } + break; + default : tree->addComment("** unknown type **"); break; @@ -1732,11 +1761,14 @@ DumpOneIFD (int ifdIndex, XMP_Uns8 * ifdPtr, XMP_Uns8 * endPtr, static void DumpIFDChain (XMP_Uns8 * startPtr, XMP_Uns8 * endPtr, - XMP_Uns8 * tiffContent, XMP_Uns32 fileOrigin, const char * label, std::string path) + XMP_Uns8 * tiffContent, XMP_Uns32 fileOrigin, const char * label, std::string path, bool isHeaderAbsent ) { XMP_Uns8 * ifdPtr = startPtr; XMP_Uns32 ifdOffset = startPtr - tiffContent; + if (isHeaderAbsent) // It's a kind of hack to iterate all the ifdboxes at least once. + ifdOffset = 1; + for (size_t ifdIndex = 0; ifdOffset != 0; ++ifdIndex) { if ((ifdPtr < tiffContent) || (ifdPtr >= endPtr)) { @@ -1757,7 +1789,7 @@ DumpIFDChain (XMP_Uns8 * startPtr, XMP_Uns8 * endPtr, // ================================================================================================= static void -DumpTIFF (XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const char * label, std::string path) +DumpTIFF (XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const char * label, std::string path, bool isHeaderAbsent) { tree->pushNode("TIFF content from %s", label); // ! TIFF can be nested because of the Photoshop 6 weiredness. Save and restore the procs. @@ -1765,27 +1797,43 @@ DumpTIFF (XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const GetUns32_Proc save_GetUns32 = TIFF_GetUns32; GetUns64_Proc save_GetUns64 = TIFF_GetUns64; - if (CheckBytes(tiffContent,"II\x2A\x00",4)) { + XMP_Uns32 ifdOffset = 0; + + if (!isHeaderAbsent) + { + if (CheckBytes(tiffContent, "II\x2A\x00", 4)) { + beTIFF = false; + TIFF_GetUns16 = GetUns16LE; + TIFF_GetUns32 = GetUns32LE; + TIFF_GetUns64 = GetUns64LE; + tree->addComment("Little endian "); + } + else if (CheckBytes(tiffContent, "MM\x00\x2A", 4)) { + beTIFF = true; + TIFF_GetUns16 = GetUns16BE; + TIFF_GetUns32 = GetUns32BE; + TIFF_GetUns64 = GetUns64BE; + tree->addComment("Big endian "); + } + else { + tree->comment("** Missing TIFF image file header tree."); + return; + } + + tree->addComment("TIFF from %s, offset %d (0x%X), size %d", label, fileOffset, fileOffset, tiffLen); + + ifdOffset = TIFF_GetUns32(tiffContent + 4); + } + else + { beTIFF = false; TIFF_GetUns16 = GetUns16LE; TIFF_GetUns32 = GetUns32LE; TIFF_GetUns64 = GetUns64LE; tree->addComment("Little endian "); - } else if (CheckBytes(tiffContent,"MM\x00\x2A",4)) { - beTIFF = true; - TIFF_GetUns16 = GetUns16BE; - TIFF_GetUns32 = GetUns32BE; - TIFF_GetUns64 = GetUns64BE; - tree->addComment("Big endian "); - } else { - tree->comment("** Missing TIFF image file header tree."); - return; } - tree->addComment("TIFF from %s, offset %d (0x%X), size %d", label, fileOffset, fileOffset, tiffLen); - - XMP_Uns32 ifdOffset = TIFF_GetUns32 (tiffContent+4); - DumpIFDChain (tiffContent+ifdOffset, tiffContent+tiffLen, tiffContent, fileOffset, label, path); + DumpIFDChain(tiffContent + ifdOffset, tiffContent + tiffLen, tiffContent, fileOffset, label, path, isHeaderAbsent); TIFF_GetUns16 = save_GetUns16; TIFF_GetUns32 = save_GetUns32; @@ -2017,7 +2065,6 @@ static const XMP_Uns8 kUUID_IPTC[16] = { 0x09, 0xA1, 0x4E, 0x97, 0xC0, 0xB4, 0x42, 0xE0, 0xBE, 0xBF, 0x36, 0xDF, 0x6F, 0x0C, 0xE3, 0x6F }; static const XMP_Uns8 kUUID_PSIR[16] = { 0x2C, 0x4C, 0x01, 0x00, 0x85, 0x04, 0x40, 0xB9, 0xA0, 0x3E, 0x56, 0x21, 0x48, 0xD6, 0xDF, 0xEB }; - // ------------------------------------------------------------------------------------------------- /** @@ -2077,13 +2124,13 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath ) // or, uhm, something garbage-ish... if ( LFA_Tell(file) + boxHeaderSize > endOfThisLevel ) { - XMP_Int64 numUnusedBytes = (LFA_Tell(file) + boxHeaderSize - endOfThisLevel); + XMP_Int64 numUnusedBytes = (endOfThisLevel - LFA_Tell(file)); tree->digestString( file, isoPath+"unused", numUnusedBytes, false ); tree->addComment( "'free' since too small for a box" ); bool ok; - LFA_Seek( file, maxBoxLen, SEEK_CUR, &ok ); - assertMsg("skippind to-small space failed (truncated file?)", ok ); + LFA_Seek( file, endOfThisLevel, SEEK_SET, &ok ); + assertMsg("skippind to-small space failed (truncated file?)", ok ); continue; // could just as well: return } @@ -2106,21 +2153,27 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath ) break; } - XMP_Uns32 tempBoxType = GetUns32LE(&boxType); - std::string boxString( fromArgs( "%.4s" , &tempBoxType) ); + XMP_Uns32 tempBoxType = GetUns32LE(&boxType); + std::string boxString( fromArgs( "%.4s" , &tempBoxType) ); - // substitute mac-copyright signs with an easier-to-handle "(c)" + if(boxString.size() != 0) + { + // substitute mac-copyright signs with an easier-to-handle "(c)" #if !IOS_ENV - if ( boxString.at(0) == 0xa9 ) + if ( boxString.at(0) == 0xa9 ) #else - if ( boxString.at(0) == 0xffffffa9 ) + if ( boxString.at(0) == 0xffffffa9 ) #endif - boxString = std::string("(c)") + boxString.substr(1); + boxString = std::string("(c)") + boxString.substr(1); + } + else + break; + isoPath = origIsoPath + boxString + "/"; // TEMP // Log::info("pushing %s, endOfThisLevel: 0x%X", isoPath.c_str(), endOfThisLevel ); - // printf ("%s \n", isoPath.c_str()); + // printf ("%s \n", isoPath.c_str()); tree->pushNode( isoPath ); tree->addComment("offset 0x%I64X, size 0x%I64X", boxPos , boxSize); @@ -2317,9 +2370,9 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath ) XMP_Int64 endOfTrailingBoxes = LFA_Tell(file) + remainingSize; while ( LFA_Tell(file) < endOfTrailingBoxes ) { - LFA_Tell( file ); - DumpISOBoxes( file, entrySize, isoPath ); - LFA_Tell( file ); + LFA_Tell(file); + DumpISOBoxes( file, entrySize, isoPath ); + LFA_Tell(file); } assertMsg( "did not boil down to zero", LFA_Tell(file) == endOfTrailingBoxes ); @@ -2385,7 +2438,7 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath ) } case 0x74727063: // cprt, FULLBOX - if ( isoPath == "moov/udta/cprt/") + if ( isoPath == "moov/udta/cprt/" || isoPath == "moov/uuid/udta/cprt/" ) { digestISOFullBoxExtension( file, isoPath, remainingSize, version, flags ); @@ -2421,6 +2474,18 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath ) // (c)-style quicktime boxes and boxes of no interest: default: + if ( (boxType & 0xA9) == 0xA9) // (c)something + { + if ( 0 == isoPath.compare( 0 , 10, "moov/udta/" )) + { // => Quicktime metadata "international text sequence" ( size, language code, value ) + digestInternationalTextSequence( file, isoPath, &remainingSize ); + } else + { + tree->addComment("WARNING: unknown flavor of (c)*** boxes, neither QT nor iTunes"); + } + break; + } + //boxes of no interest: break; } @@ -3385,6 +3450,10 @@ DumpRIFFChunk ( LFA_FileRef file, XMP_Int64 parentEnd, std::string origChunkPath isXMPchunk = true; } + bool isIDITChunk = + ( ( origChunkPath == "RIFF:AVI/LIST:hdrl" || origChunkPath == "RIFF:AVI /LIST:hdrl" ) + && idString == "IDIT" ); + // deal with chunks of interest ///////////////////////////////////////////// // a little prelude for disp chunk if ( isDispChunk ) @@ -3399,7 +3468,7 @@ DumpRIFFChunk ( LFA_FileRef file, XMP_Int64 parentEnd, std::string origChunkPath chunkSize -= 4; } - if ( isListInfo || isListTdat || isDispChunk ) + if (isListInfo || isListTdat || isDispChunk || isIDITChunk) { // dump that string: std::string value; @@ -3501,6 +3570,10 @@ DumpRIFFChunk ( LFA_FileRef file, XMP_Int64 parentEnd, std::string origChunkPath // parse till first \0 std::string description( descriptionBuffer ); + // Dumping the iXML chunk. Needed for testing + // Add iXML chunk as a node to tree + tree->setKeyValue( chunkPath+".ValueOfIXMLChunk", description ); + delete[] descriptionBuffer; tree->addComment("packet end: 0x%llX", LFA_Tell( file ) ); @@ -3940,6 +4013,93 @@ DumpInDesign (LFA_FileRef file, XMP_Uns32 inddLen) // ================================================================================================= +static void +DumpSVGTag ( std::string basePath, XML_NodePtr currentNode ) +{ + if ( currentNode ) + { + tree->pushNode ( basePath + currentNode->name ); + + // Iterating over all XML children. + XML_NodeVector currNodeVector = currentNode->content; + for ( int i = 0; i < currNodeVector.size ( ); i++ ) + { + // Dump all children who are element nodes. + if ( currNodeVector[i]->kind == kElemNode ) + DumpSVGTag ( basePath + currentNode->name + "/", currNodeVector[i] ); + + // Extract the value from datanodes and put in TagMap if it's not yet available. + if ( currNodeVector[i]->kind == kCDataNode && tree->getValue ( basePath + currentNode->name ) == "" ) + tree->updateKeyValue ( basePath + currentNode->name, currNodeVector[i]->value ); + } + } + +} // DumpSVGTag + +// ================================================================================================= + +static void +DumpSVG ( LFA_FileRef file, XMP_Uns32 svgLen ) +{ + // SVG is an XML based format.We consider any file as SVG file if the given file contains a SVG tag. + // Hence CheckFileFormat looks for presence of "<svg" in the file. + // + // For Dumping SVG elements we are using ExpatAdapter. Below code will parse given file using this + // adapter and add different tags in the TagMap tree. + // + // Below is the currently supported structure of known tags for this format. + // <svg> + // <title/> + // <desc/> + // <metadata> + // <x:xmpmeta/> + // <...> + // <...> + // </metadata> + // <...> + // <...> + // </svg> + + ExpatAdapter * pExpatAdapter = XMP_NewExpatAdapter ( false ); + + if ( pExpatAdapter == 0 ) + { + tree->comment ( "ExpatAdapter initialization failed. Cann't parse SVG file." ); + return; + } + + // Allocating big enough memory on heap to read file contents. + XMP_Uns8 *fileContent = new XMP_Uns8[svgLen + 1]; + memset ( fileContent, 0, (svgLen + 1)*sizeof ( XMP_Uns8 ) ); + + // Reading total file in buffer (fileContent) + LFA_Seek ( file, 0, SEEK_SET ); + LFA_Read ( file, fileContent, svgLen + 1, false ); + + // Parsing the file with ExpatAdapter + pExpatAdapter->ParseBuffer ( fileContent, svgLen + 1, false /* not the end */ ); + + // Finding <svg> element and adding to TagMap tree. + XML_NodePtr svgNode = pExpatAdapter->tree.GetNamedElement ( "http://www.w3.org/2000/svg", "svg" ); + DumpSVGTag ( "", svgNode ); + + // De-allocating all the resources. + if ( fileContent ) + { + delete[] fileContent; + fileContent = NULL; + } + + if ( pExpatAdapter ) + { + delete pExpatAdapter; + pExpatAdapter = NULL; + } + +} // DumpSVG + +// ================================================================================================= + #define kSWF_FileAttributesTag 69 #define kSWF_MetadataTag 77 @@ -4788,6 +4948,7 @@ static void DumpID3v22Frames ( LFA_FileRef file, XMP_Uns8 vMajor, XMP_Uns32 fram static void DumpID3v23Frames ( LFA_FileRef file, XMP_Uns8 vMajor, XMP_Uns32 framePos, XMP_Uns32 frameEnd ) { // Dump the frames in an ID3 v2.3 or v2.4 tag. + int iIterator = 0; while ( (framePos < frameEnd) && ((frameEnd - framePos) >= 10) ) { @@ -4879,9 +5040,76 @@ static void DumpID3v23Frames ( LFA_FileRef file, XMP_Uns8 vMajor, XMP_Uns32 fram } } + + else if ( CheckBytes ( frameHead.id , "APIC" , 4 ) ) { - framePos += (sizeof(frameHead) + frameHead.size); + ++iIterator; + unsigned int iOffset = 0; + CaptureFileData ( file , 0 , frameHead.size ); + + char encoding[2]; + memset ( encoding , 0x0 , 2 ); + encoding[0] = sDataPtr[iOffset++]; + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-encodingType_%d" , iIterator ) , encoding ); + char * mimeType = ( char* ) (sDataPtr + iOffset); + iOffset += strlen ( mimeType ) + 1; //1 is for null termination + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-mimeType_%d" , iIterator ) , mimeType ); + + char pictureType[2]; + memset ( pictureType , 0x0 , 2 ); + pictureType[0] = sDataPtr[iOffset++]; + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-pictureType_%1d" , iIterator ) , pictureType ); + + bool bigEndian = PrintID3Encoding ( encoding[0] , (sDataPtr + iOffset) ); + if ( encoding[0] == 0x00 ) { + + XMP_Uns8 * descrPtr = sDataPtr + iOffset; + XMP_Uns8 * valuePtr = descrPtr; + + while ( *valuePtr != 0 ) ++valuePtr; + ++valuePtr; //Null termination + + size_t descrBytes = valuePtr - descrPtr; + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-descr_%d" , iIterator ) , convert8Bit ( descrPtr , false , descrBytes - 1 ).c_str ( ) ); + iOffset += descrBytes; + } + else if ( encoding[0] == 0x01 ) { + + XMP_Uns16 * descrPtr = ( XMP_Uns16* ) (sDataPtr + iOffset); + XMP_Uns16 * valuePtr = descrPtr; + + while ( *valuePtr != 0 ) ++valuePtr; + ++valuePtr; //Null termination + + size_t descrBytes = 2 * (valuePtr - descrPtr); + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-descr_%d" , iIterator ) , convert16Bit ( bigEndian , ( XMP_Uns8* ) (descrPtr + 1) , false , descrBytes - 4 ).c_str ( ) ); + iOffset += descrBytes; + } + + XMP_Uns8 *picPtr = (sDataPtr + iOffset); + unsigned long size_PictureData = frameHead.size - iOffset; + + char picDataSize[8]; + memset ( picDataSize , 0x0 , 8 ); + sprintf ( picDataSize, "%d", size_PictureData ); + + std::string picData; + picData.assign ( ( char* ) picPtr , size_PictureData ); + + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-pictureData_%d" , iIterator ) , picData ); + tree->setKeyValue ( fromArgs ( "ID3v2:APIC-pictureDataSize_%d" , iIterator ) , picDataSize ); + } + + framePos += (sizeof(frameHead) + frameHead.size); + + } + + if ( iIterator ) { + char noOfAPICs[2]; + memset ( noOfAPICs , 0x0 , 2 ); + sprintf ( noOfAPICs , "%d" , iIterator ); + tree->setKeyValue ( "ID3v2:NoOfAPIC" , noOfAPICs ); } if ( framePos < frameEnd ) { @@ -5328,6 +5556,12 @@ void DumpFile::Scan (std::string filename, TagTree &tagTree, bool resetTree) DumpPS ( fileRef, fileLen ); tagTree.popNode(); + } else if ( format == kXMP_SVGFile ) { + + tagTree.pushNode ( "Dumping SVG file" ); + tagTree.addComment ( "size %lld (0x%llx)", fileLen, fileLen ); + DumpSVG ( fileRef, fileLen ); + tagTree.popNode ( ); } else if ( format == kXMP_UnknownFile ) { tagTree.pushNode ( "Unknown format. packet scanning, size %d (0x%X)", fileLen, fileLen ); diff --git a/samples/source/common/TagTree.cpp b/samples/source/common/TagTree.cpp index 7dfe369..6d0ae97 100644 --- a/samples/source/common/TagTree.cpp +++ b/samples/source/common/TagTree.cpp @@ -118,6 +118,25 @@ void TagTree::setKeyValue(const std::string key,const std::string value, const s Log::info( " setKeyValue( %s |-> %s) [%s]", key.c_str(), value.c_str(), _comment.c_str() ); } +void TagTree::updateKeyValue ( const std::string key, const std::string value, const std::string _comment ) +{ + Node* pCurNode = *nodeStack.rbegin ( ); //current Node + pCurNode->children.push_back ( Node ( key, value, _comment ) ); + + if ( key.size ( ) == 0 ) { // standalone comment? + if ( value.size ( ) != 0 ) // must have no value + Log::error ( "no key but value found." ); + return; // ==> do not add to tag-map + } + + //add to Map ----------------------------------- + lastNode = &*(pCurNode->children.rbegin ( )); + tagMap[key] = lastNode; + + if ( verbose ) + Log::info ( " setKeyValue( %s |-> %s) [%s]", key.c_str ( ), value.c_str ( ), _comment.c_str ( ) ); +} + void TagTree::digest(LFA_FileRef file,const std::string key /*=NULL*/, void* returnValue /*=""*/, XMP_Int32 numOfBytes /*=0*/ ) diff --git a/samples/source/common/TagTree.h b/samples/source/common/TagTree.h index 857b141..9bd46d3 100644 --- a/samples/source/common/TagTree.h +++ b/samples/source/common/TagTree.h @@ -107,6 +107,9 @@ public: //sets a key-value pair and optinal comment. value is also optional and may be set at a later time //can also be used to set pure, standalone comments (using key==value=="") void setKeyValue(const std::string key,const std::string value="", const std::string comment=""); + + //updates the value of key without creating new key, value pairs. + void updateKeyValue ( const std::string key, const std::string value, const std::string comment = "" ); // convenience functions ////////////////////////////////////////////////////////////////// // these functions read bytes (assert in file-length), dump them to screen (as hex or as number) diff --git a/samples/source/common/globals.h b/samples/source/common/globals.h index 1fb7cea..32c6a91 100644 --- a/samples/source/common/globals.h +++ b/samples/source/common/globals.h @@ -76,8 +76,10 @@ const char AEOEUE_UTF8_CSTRING[]={0xC3, 0x84, 0xC3, 0x96, 0xC3, 0x9C,'\0'}; const std::string AEOEUE_UTF8(AEOEUE_UTF8_CSTRING); const std::string AEOEUE_UTF8_BUGINESE("<C3 84 C3 96 C3 9C>"); + const std::string AEOEUE_UTF8_BUGINESE_EVEN ( "<C3 84 C3 96 C3 9C 00>" ); const std::string AEOEUE_WIN_LOCAL_BUGINESE("<C4 D6 DC>"); + const std::string AEOEUE_WIN_LOCAL_BUGINESE_EVEN ( "<C4 D6 DC 00>" ); const std::string AEOEUE_MAC_LOCAL_BUGINESE("<80 85 86>"); const std::string AEOEUE_WIN_MOJIBAKE_BUGINESE("<E2 82 AC E2 80 A6 E2 80 A0>"); |