Sebastian,
Sebastian Moors wrote:
Oh, no problem. I think the zombie stuff is more important, so qtxml can
I've attached 2 patches... but wanted to discuss something about them.
* Patch A: Implements TinyXML compatability mode
for reading songs
* Patch B: Adds "xф" to tutorial_georgyporgy.h2song
title to text patch A. When read in, it should be interpreted
as the UTF-8 sequence for the Cyrillic letter EF "ф".
However, this only adds the compatability mode for reading a _song_. To
implement it for all the other files will require copying the code to several
places.
What if we do sort of a factory like this:
QDomDocument doc = LocalFileMng::openXmlDocument( filename );
The static function LocalFileMng::openXmlDocument() can do any redirection or
filtering that we need.
What do you think?
Peace,
Gabriel
diff --git a/libs/hydrogen/include/hydrogen/LocalFileMng.h b/libs/hydrogen/include/hydrogen/LocalFileMng.h
index d62e035..62c7530 100644
--- a/libs/hydrogen/include/hydrogen/LocalFileMng.h
+++ b/libs/hydrogen/include/hydrogen/LocalFileMng.h
@@ -90,6 +90,7 @@ public:
static float readXmlFloat( QDomNode , const QString& nodeName, float defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
static int readXmlInt( QDomNode , const QString& nodeName, int defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
static bool readXmlBool( QDomNode , const QString& nodeName, bool defaultValue, bool bShouldExists = true , bool tinyXmlCompatMode = false );
+ static void convertFromTinyXMLString( QByteArray* str );
static bool checkTinyXMLCompatMode( const QString& filename );
private:
diff --git a/libs/hydrogen/src/local_file_mgr.cpp b/libs/hydrogen/src/local_file_mgr.cpp
index 036ab18..c5a5f57 100644
--- a/libs/hydrogen/src/local_file_mgr.cpp
+++ b/libs/hydrogen/src/local_file_mgr.cpp
@@ -42,6 +42,7 @@
#include <cstdlib>
#include <cassert>
#include <sys/stat.h>
+#include <ctype.h>
#include <QDir>
#include <QApplication>
@@ -1194,6 +1195,59 @@ void LocalFileMng::writeXmlBool( QDomNode parent, const QString& name, bool valu
}
}
+/* Convert (in-place) an XML escape sequence into a literal byte,
+ * rather than the character it actually refers to.
+ */
+void LocalFileMng::convertFromTinyXMLString( QByteArray* str )
+{
+ /* When TinyXML encountered a non-ASCII character, it would
+ * simply write the character as "&#xx;" -- where "xx" is
+ * the hex character code. However, this doesn't respect
+ * any encodings (e.g. UTF-8, UTF-16). In XML, &#xx; literally
+ * means "the Unicode character # xx." However, in a UTF-8
+ * sequence, this could be an escape character that tells
+ * whether we have a 2, 3, or 4-byte UTF-8 sequence.
+ *
+ * For example, the UTF-8 sequence 0xD184 was being written
+ * by TinyXML as "Ñ„". However, this is the UTF-8
+ * sequence for the cyrillic small letter EF (which looks
+ * kind of like a thorn or a greek phi). This letter, in
+ * XML, should be saved as ф, or even literally
+ * (no escaping). As a consequence, when Ñ is read
+ * by an XML parser, it will be interpreted as capital N
+ * with a tilde (~). Then „ will be interpreted as
+ * an unknown or control character.
+ *
+ * So, when we know that TinyXML wrote the file, we can
+ * simply exchange these hex sequences to literal bytes.
+ */
+ int pos = 0;
+
+ pos = str->indexOf("&#x");
+ while( pos != -1 ) {
+ if( isxdigit(str->at(pos+3))
+ && isxdigit(str->at(pos+4))
+ && (str->at(pos+5) == ';') ) {
+ char w1 = str->at(pos+3);
+ char w2 = str->at(pos+4);
+
+ w1 = tolower(w1) - 0x30; // '0' = 0x30
+ if( w1 > 9 ) w1 -= 0x27; // '9' = 0x39, 'a' = 0x61
+ w1 = (w1 & 0xF);
+
+ w2 = tolower(w2) - 0x30; // '0' = 0x30
+ if( w2 > 9 ) w2 -= 0x27; // '9' = 0x39, 'a' = 0x61
+ w2 = (w2 & 0xF);
+
+ char ch = (w1 << 4) | w2;
+ (*str)[pos] = ch;
+ ++pos;
+ str->remove(pos, 5);
+ }
+ pos = str->indexOf("&#x");
+ }
+}
+
bool LocalFileMng::checkTinyXMLCompatMode( const QString& filename )
{
/*
@@ -1208,10 +1262,14 @@ bool LocalFileMng::checkTinyXMLCompatMode( const QString& filename )
return false;
QString line = file.readLine();
- if ( ! line.startsWith( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" )){
- return true;
- } else {
+ file.close();
+ if ( line.startsWith( "<?xml" )){
return false;
+ } else {
+ _WARNINGLOG( QString("File '%1' is being read in "
+ "TinyXML compatability mode")
+ .arg(filename) );
+ return true;
}
diff --git a/libs/hydrogen/src/song.cpp b/libs/hydrogen/src/song.cpp
index 2021a07..763dd76 100644
--- a/libs/hydrogen/src/song.cpp
+++ b/libs/hydrogen/src/song.cpp
@@ -247,21 +247,44 @@ Song* SongReader::readSong( const QString& filename )
}
+ bool TinyXMLCompat = LocalFileMng::checkTinyXMLCompatMode( filename );
+
QDomDocument doc( "song" );
QFile file( filename );
if ( !file.open(QIODevice::ReadOnly) )
return NULL;
- if ( !doc.setContent( &file ) ) {
+ if( TinyXMLCompat ) {
+ QString enc = QTextCodec::codecForLocale()->name();
+ if( enc == QString("System") ) {
+ enc = "UTF-8";
+ }
+ QByteArray line;
+ QByteArray buf = QString("<?xml version='1.0' encoding='%1' ?>\n")
+ .arg( enc )
+ .toLocal8Bit();
+
+ INFOLOG( QString("Using '%1' encoding for TinyXML file").arg(enc) );
+
+ while( !file.atEnd() ) {
+ line = file.readLine();
+ LocalFileMng::convertFromTinyXMLString( &line );
+ buf += line;
+ }
+
+ if( ! doc.setContent( buf ) ) {
file.close();
return NULL;
- }
- file.close();
+ }
- if (LocalFileMng::checkTinyXMLCompatMode( filename )){
- ERRORLOG( "old xml file!!!!" );
+ } else {
+ if( ! doc.setContent( &file ) ) {
+ file.close();
+ return NULL;
+ }
}
+ file.close();
QDomNodeList nodeList = doc.elementsByTagName( "song" );
diff --git a/data/demo_songs/tutorial_georgyporgy.h2song b/data/demo_songs/tutorial_georgyporgy.h2song
index 2d47e34..3befcbe 100644
--- a/data/demo_songs/tutorial_georgyporgy.h2song
+++ b/data/demo_songs/tutorial_georgyporgy.h2song
@@ -3,7 +3,7 @@
<bpm>98</bpm>
<volume>0.5</volume>
<metronomeVolume>0.5</metronomeVolume>
- <name>Georgy porgy</name>
+ <name>xфGeorgy porgy</name>
<author>Toto</author>
<notes>Drummer: Jeff Porcaro</notes>
<loopEnabled>false</loopEnabled>
------------------------------------------------------------------------------
_______________________________________________
Hydrogen-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hydrogen-devel